refactor: appearance card component

This commit is contained in:
monoid 2025-10-01 00:29:18 +09:00
parent 26b55be260
commit 8047b93ffc
2 changed files with 90 additions and 80 deletions

View file

@ -0,0 +1,87 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { type TernaryDarkMode, useTernaryDarkMode, useMediaQuery } from "usehooks-ts";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
function LightModeView() {
return <div className="items-center rounded-md border-2 border-muted p-1 hover:border-accent">
<div className="space-y-2 rounded-sm bg-[#ecedef] p-2">
<div className="space-y-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-2 w-[80px] rounded-lg bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
</div>
</div>;
}
function DarkModeView() {
return <div className="items-center rounded-md border-2 border-muted bg-popover p-1 hover:bg-accent hover:text-accent-foreground">
<div className="space-y-2 rounded-sm bg-slate-950 p-2">
<div className="space-y-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-2 w-[80px] rounded-lg bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
</div>
</div>
}
export function AppearanceCard() {
const { setTernaryDarkMode, ternaryDarkMode } = useTernaryDarkMode();
const isSystemDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
return (
<Card>
<CardHeader>
<CardTitle className="text-lg">Appearance</CardTitle>
<span className="text-muted-foreground text-sm">Dark mode</span>
</CardHeader>
<CardContent>
<RadioGroup
value={ternaryDarkMode}
onValueChange={(v) => setTernaryDarkMode(v as TernaryDarkMode)}
className="flex space-x-2 items-center"
>
<RadioGroupItem id="dark" value="dark" className="sr-only" />
<Label htmlFor="dark">
<div className="grid place-items-center">
<DarkModeView />
<span>Dark Mode</span>
</div>
</Label>
<RadioGroupItem id="light" value="light" className="sr-only" />
<Label htmlFor="light">
<div className="grid place-items-center">
<LightModeView />
<span>Light Mode</span>
</div>
</Label>
<RadioGroupItem id="system" value="system" className="sr-only" />
<Label htmlFor="system">
<div className="grid place-items-center">
{isSystemDarkMode ? <DarkModeView /> : <LightModeView />}
<span>System Mode</span>
</div>
</Label>
</RadioGroup>
</CardContent>
</Card>
);
}
export default AppearanceCard;

View file

@ -1,56 +1,15 @@
import { useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { type TernaryDarkMode, useTernaryDarkMode, useMediaQuery } from "usehooks-ts";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import BuildInfoCard from "@/components/BuildInfoCard";
import AppearanceCard from "@/components/AppearanceCard";
import { useServerSettings } from "@/hook/useServerSettings";
import { useLogin } from "@/state/user";
import { fetcher } from "@/hook/fetcher";
import type { ServerSettingResponse, ServerSettingUpdate } from "dbtype/mod.ts";
import { ServerSettingCard } from "@/components/ServerSettingCard";
function LightModeView() {
return <div className="items-center rounded-md border-2 border-muted p-1 hover:border-accent">
<div className="space-y-2 rounded-sm bg-[#ecedef] p-2">
<div className="space-y-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-2 w-[80px] rounded-lg bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-white p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-[#ecedef]" />
<div className="h-2 w-[100px] rounded-lg bg-[#ecedef]" />
</div>
</div>
</div>;
}
function DarkModeView() {
return <div className="items-center rounded-md border-2 border-muted bg-popover p-1 hover:bg-accent hover:text-accent-foreground">
<div className="space-y-2 rounded-sm bg-slate-950 p-2">
<div className="space-y-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-2 w-[80px] rounded-lg bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
<div className="flex items-center space-x-2 rounded-md bg-slate-800 p-2 shadow-sm">
<div className="h-4 w-4 rounded-full bg-slate-400" />
<div className="h-2 w-[100px] rounded-lg bg-slate-400" />
</div>
</div>
</div>
}
export function SettingPage() {
const { setTernaryDarkMode, ternaryDarkMode } = useTernaryDarkMode();
const isSystemDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
const login = useLogin();
const isAdmin = login?.username === "admin";
@ -70,44 +29,8 @@ export function SettingPage() {
return (
<div className="p-4 space-y-4">
<Card>
<CardHeader>
<CardTitle className="text-2xl">Settings</CardTitle>
</CardHeader>
<CardContent>
<div className="grid gap-4">
<div>
<h3 className="text-lg">Appearance</h3>
<span className="text-muted-foreground text-sm">Dark mode</span>
</div>
<RadioGroup value={ternaryDarkMode} onValueChange={(v) => setTernaryDarkMode(v as TernaryDarkMode)}
className="flex space-x-2 items-center"
>
<RadioGroupItem id="dark" value="dark" className="sr-only" />
<Label htmlFor="dark">
<div className="grid place-items-center">
<DarkModeView />
<span>Dark Mode</span>
</div>
</Label>
<RadioGroupItem id="light" value="light" className="sr-only" />
<Label htmlFor="light">
<div className="grid place-items-center">
<LightModeView />
<span>Light Mode</span>
</div>
</Label>
<RadioGroupItem id="system" value="system" className="sr-only" />
<Label htmlFor="system">
<div className="grid place-items-center">
{isSystemDarkMode ? <DarkModeView /> : <LightModeView />}
<span>System Mode</span>
</div>
</Label>
</RadioGroup>
</div>
</CardContent>
</Card>
<h1 className="text-3xl font-bold">Settings</h1>
<AppearanceCard />
<ServerSettingCard
isAdmin={isAdmin}
loading={serverLoading}