Skip to content

Commit fde4402

Browse files
committed
chore: settings dev mode switch
1 parent 6101de7 commit fde4402

File tree

6 files changed

+125
-1
lines changed

6 files changed

+125
-1
lines changed

package-lock.json

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@radix-ui/react-checkbox": "^1.1.4",
2121
"@radix-ui/react-dialog": "^1.1.6",
2222
"@radix-ui/react-hover-card": "^1.1.6",
23+
"@radix-ui/react-label": "^2.1.2",
2324
"@radix-ui/react-popover": "^1.1.6",
2425
"@radix-ui/react-progress": "^1.1.2",
2526
"@radix-ui/react-scroll-area": "^1.2.3",

src/components/ui/label.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from "react"
2+
import * as LabelPrimitive from "@radix-ui/react-label"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
function Label({
7+
className,
8+
...props
9+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
10+
return (
11+
<LabelPrimitive.Root
12+
data-slot="label"
13+
className={cn(
14+
"text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
15+
className
16+
)}
17+
{...props}
18+
/>
19+
)
20+
}
21+
22+
export { Label }

src/hooks/use-local-storage.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { useState } from "react";
2+
import { getItem, setItem, removeItem } from "@/utils/local-storage";
3+
4+
type DispatchAction<T> = T | ((prevState: T) => T);
5+
6+
export default function useLocalStorage<T>(key: string, initialValue: T) {
7+
const [value, setValue] = useState(() => {
8+
const data = getItem(key);
9+
return (data || initialValue) as T;
10+
});
11+
12+
function handleDispatch(action: DispatchAction<T>) {
13+
if (typeof action === "function") {
14+
setValue((prevState) => {
15+
const newValue = (action as (prevState: T) => T)(prevState);
16+
setItem(key, newValue);
17+
return newValue;
18+
});
19+
} else {
20+
setValue(action);
21+
setItem(key, action);
22+
}
23+
}
24+
25+
function clearState() {
26+
setValue(undefined as T);
27+
removeItem(key);
28+
}
29+
30+
return [value, handleDispatch, clearState] as const;
31+
}

src/pages/settings/SettingsPage.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Breadcrumbs } from "@/components/Breadcrumbs"
22
import { PageTitle } from "@/components/PageTitle"
3+
import { Label } from "@/components/ui/label"
34
import { Skeleton } from "@/components/ui/skeleton"
5+
import { Switch } from "@/components/ui/switch"
6+
import useLocalStorage from "@/hooks/use-local-storage"
47
import { Suspense } from "react"
58

69
function Loader() {
@@ -12,7 +15,25 @@ function Loader() {
1215
}
1316

1417
function PageBody() {
15-
return <></>
18+
const [devMode, setDevMode] = useLocalStorage("devMode", false)
19+
20+
return (
21+
<>
22+
<div className="my-2">
23+
<div className="flex items-center space-x-2">
24+
<Switch
25+
id="developer-mode"
26+
className="cursor-pointer"
27+
checked={devMode}
28+
onCheckedChange={() => {
29+
setDevMode((it) => !it)
30+
}}
31+
/>
32+
<Label htmlFor="developer-mode">Developer Mode</Label>
33+
</div>
34+
</div>
35+
</>
36+
)
1637
}
1738

1839
export default function SettingsPage() {

src/utils/local-storage.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
export function setItem(key: string, value: unknown) {
3+
try {
4+
window.localStorage.setItem(key, JSON.stringify(value));
5+
} catch (err) {
6+
console.error(err);
7+
}
8+
}
9+
10+
export function getItem<T>(key: string): T | undefined {
11+
try {
12+
const data = window.localStorage.getItem(key);
13+
return data ? (JSON.parse(data) as T) : undefined;
14+
} catch (err) {
15+
console.error(err);
16+
}
17+
}
18+
19+
export function removeItem(key: string) {
20+
try {
21+
window.localStorage.removeItem(key);
22+
} catch (err) {
23+
console.error(err);
24+
}
25+
}

0 commit comments

Comments
 (0)