Files
invyone/frontend/components/layout/SettingsModal.tsx
T
gbpark b3ad787179
Build & Deploy to K8s / build-and-deploy (push) Successful in 5m4s
대시보드 구현 완료 세세한 오류 수정 진행중
2026-04-19 21:15:25 +09:00

101 lines
3.5 KiB
TypeScript

"use client";
import { useTheme } from "next-themes";
import { Check, Moon, Sun } from "lucide-react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
} from "@/components/ui/dialog";
import { useColorTheme, COLOR_THEMES, type ColorTheme } from "@/hooks/useColorTheme";
import { animatedThemeChange } from "@/lib/themeTransition";
import { animatedColorChange } from "@/lib/colorTransition";
interface SettingsModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export function SettingsModal({ open, onOpenChange }: SettingsModalProps) {
const { color, setColor } = useColorTheme();
const { theme, setTheme } = useTheme();
const isDark = theme === "dark";
const handleModeClick = (next: "light" | "dark", e: React.MouseEvent) => {
if (next === theme) return;
animatedThemeChange(next, setTheme, { x: e.clientX, y: e.clientY });
};
const handleColorClick = (id: ColorTheme, e: React.MouseEvent<HTMLButtonElement>) => {
if (id === color) return;
const rect = e.currentTarget.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
const meta = COLOR_THEMES.find((c) => c.id === id);
const swatchColor = (isDark ? meta?.dark : meta?.light) ?? "#6c5ce7";
animatedColorChange(id, () => setColor(id), { x: cx, y: cy, color: swatchColor });
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[480px]">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription> .</DialogDescription>
</DialogHeader>
{/* === 모드 (라이트/다크) === */}
<div className="settings-section">
<div className="settings-label"> </div>
<div className="settings-mode-row">
<button
type="button"
className={`settings-mode-btn ${!isDark ? "on" : ""}`}
onClick={(e) => handleModeClick("light", e)}
>
<Sun size={14} />
<span></span>
</button>
<button
type="button"
className={`settings-mode-btn ${isDark ? "on" : ""}`}
onClick={(e) => handleModeClick("dark", e)}
>
<Moon size={14} />
<span></span>
</button>
</div>
</div>
{/* === 색상 테마 === */}
<div className="settings-section">
<div className="settings-label"> </div>
<div className="settings-color-grid">
{COLOR_THEMES.map((c) => {
const swatch = isDark ? c.dark : c.light;
const isActive = color === c.id;
return (
<button
key={c.id}
type="button"
className={`settings-color-swatch ${isActive ? "on" : ""}`}
onClick={(e) => handleColorClick(c.id as ColorTheme, e)}
title={c.label}
aria-label={c.label}
>
<span className="swatch-circle" style={{ background: swatch }}>
{isActive && <Check size={12} strokeWidth={3} />}
</span>
<span className="swatch-label">{c.label}</span>
</button>
);
})}
</div>
</div>
</DialogContent>
</Dialog>
);
}