Skip to content

Commit 3d92639

Browse files
committed
[frontend] basic settings page
1 parent 8f6faaa commit 3d92639

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

frontend/src/Tab.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { PlaygroundPage } from "./pages/PlaygroundPage";
1212
import { createMenu } from "./components/Menu";
1313
import { AboutPage } from "./pages/AboutPage";
1414
import { HistoryPage } from "./pages/HistoryPage";
15+
import { SettingsPage } from "./pages/SettingsPage";
1516

1617
const requestInspectElement = createDelegate<[HTMLElement, Tab]>();
1718

@@ -126,6 +127,11 @@ export class Tab extends StatefulClass {
126127
case "version":
127128
this.title = "About Version";
128129
this.internalpage = <AboutPage tab={this} />;
130+
break;
131+
case "settings":
132+
this.title = "Settings";
133+
this.internalpage = <SettingsPage tab={this} />;
134+
break;
129135
}
130136
} else {
131137
this.internalpage = null;
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { css, type Component } from "dreamland/core";
2+
import type { Tab } from "../Tab";
3+
import { scramjet } from "../main";
4+
import type { IconifyIcon } from "@iconify/types";
5+
import { Icon } from "../components/Icon";
6+
7+
import iconSettings from "@ktibow/iconset-ion/settings-outline";
8+
import iconSearch from "@ktibow/iconset-ion/search-outline";
9+
import iconExtension from "@ktibow/iconset-ion/extension-puzzle-outline";
10+
11+
export const SettingsPage: Component<
12+
{
13+
tab: Tab;
14+
},
15+
{
16+
selected: string;
17+
}
18+
> = function () {
19+
this.selected = "general";
20+
21+
const button = (id: string, icon: IconifyIcon, name: string) => {
22+
return (
23+
<div
24+
class="button"
25+
class:active={use(this.selected).map((s) => s === id)}
26+
on:click={() => {
27+
this.selected = id;
28+
}}
29+
>
30+
<Icon icon={icon} />
31+
<span>{name}</span>
32+
</div>
33+
);
34+
};
35+
36+
const tabs = {
37+
general: (
38+
<div>
39+
<h2>General Settings</h2>
40+
</div>
41+
),
42+
search: (
43+
<div>
44+
<h2>Search Settings</h2>
45+
<label for="search-engine">Search Engine:</label>
46+
<select id="search-engine">
47+
<option value="google">Google</option>
48+
<option value="bing">Bing</option>
49+
<option value="duckduckgo">DuckDuckGo</option>
50+
<option value="yahoo">Yahoo</option>
51+
</select>
52+
</div>
53+
),
54+
extensions: (
55+
<div>
56+
<h2>Extensions Settings</h2>
57+
</div>
58+
),
59+
};
60+
61+
return (
62+
<div>
63+
<div class="sidebar">
64+
<h1>Settings</h1>
65+
{button("general", iconSettings, "General")}
66+
{button("search", iconSearch, "Search")}
67+
{button("extensions", iconExtension, "Extension")}
68+
</div>
69+
<div class="content">
70+
<div class="top">
71+
<input type="text" placeholder="Search settings..." />
72+
</div>
73+
{use(this.selected).map((s) => tabs[s])}
74+
</div>
75+
</div>
76+
);
77+
};
78+
SettingsPage.style = css`
79+
:scope {
80+
width: 100%;
81+
height: 100%;
82+
display: flex;
83+
font-family: sans-serif;
84+
}
85+
86+
h1,
87+
h2,
88+
h3 {
89+
padding: 0;
90+
margin: 0;
91+
}
92+
93+
.sidebar {
94+
padding: 2em;
95+
display: flex;
96+
flex-direction: column;
97+
}
98+
.sidebar h1 {
99+
margin-bottom: 1em;
100+
}
101+
102+
.sidebar .button {
103+
width: 15rem;
104+
display: flex;
105+
align-items: center;
106+
gap: 0.54rem;
107+
cursor: pointer;
108+
padding: 1rem;
109+
border-radius: 4px;
110+
111+
font-size: 1.2em;
112+
}
113+
.sidebar .button.active {
114+
background: rgba(0, 0, 255, 0.1);
115+
}
116+
.sidebar .button:hover {
117+
background: rgba(0, 0, 255, 0.05);
118+
}
119+
120+
.content {
121+
flex: 1;
122+
padding: 2em;
123+
}
124+
.content .top {
125+
display: flex;
126+
align-items: center;
127+
justify-content: right;
128+
gap: 1em;
129+
margin-bottom: 2em;
130+
}
131+
.content .top input {
132+
width: 20rem;
133+
height: 2.5rem;
134+
font-size: 1.2em;
135+
padding: 0.5em;
136+
border: 1px solid #ccc;
137+
border-radius: 4px;
138+
outline: none;
139+
}
140+
`;

0 commit comments

Comments
 (0)