You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
2.2 KiB
TypeScript

// frontend/components/settings/AppearanceTab.tsx — 테마(라이트/다크) — next-themes 실제 적용
"use client";
import { useEffect, useState } from "react";
import { useTheme } from "next-themes";
import { Icon } from "@/components/Icon";
import type { ToastFn } from "./SettingsClient";
const THEMES = [
{ id: "light", label: "라이트", icon: "sun" as const, desc: "밝은 글래스" },
{ id: "dark", label: "다크", icon: "moon" as const, desc: "어두운 글래스" },
];
export function AppearanceTab({ toast }: { toast: ToastFn }) {
const { theme, resolvedTheme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
const current = mounted ? (resolvedTheme ?? theme ?? "light") : "light";
const pick = (id: string) => {
setTheme(id);
toast(`${id === "dark" ? "다크" : "라이트"} 테마로 바꿨어요`, "blue");
};
return (
<section className="set-sec" aria-label="외관">
<header className="set-sechead">
<h2></h2>
<p> .</p>
</header>
<div className="set-card">
<div className="set-field">
<label></label>
<div className="set-themes" role="radiogroup" aria-label="테마 선택">
{THEMES.map((t) => (
<button
key={t.id}
type="button"
role="radio"
aria-checked={current === t.id}
className={"set-theme th-" + t.id + (current === t.id ? " on" : "")}
onClick={() => pick(t.id)}
>
<span className="th-preview" aria-hidden>
<i className="th-bar" />
<i className="th-dot" />
</span>
<span className="th-label">
<Icon name={t.icon} />
<b>{t.label}</b>
<small>{t.desc}</small>
</span>
{current === t.id && <span className="th-check" aria-hidden><Icon name="tick" /></span>}
</button>
))}
</div>
</div>
</div>
</section>
);
}