ERP-node/frontend/components/admin/dashboard/widgets/ClockSettings.tsx

213 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState } from "react";
import { ClockConfig } from "../types";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Input } from "@/components/ui/input";
import { Card } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
interface ClockSettingsProps {
config: ClockConfig;
onSave: (config: ClockConfig) => void;
onClose: () => void;
}
/**
* 시계 위젯 설정 UI (Popover 내부용)
* - 모달 없이 순수 설정 폼만 제공
*/
export function ClockSettings({ config, onSave, onClose }: ClockSettingsProps) {
const [localConfig, setLocalConfig] = useState<ClockConfig>(config);
const handleSave = () => {
onSave(localConfig);
};
return (
<div className="flex max-h-[600px] flex-col">
{/* 헤더 */}
<div className="border-b p-4">
<h3 className="flex items-center gap-2 text-lg font-semibold">
<span></span>
</h3>
</div>
{/* 내용 - 스크롤 가능 */}
<div className="flex-1 space-y-4 overflow-y-auto p-4">
{/* 스타일 선택 */}
<div className="space-y-2">
<Label className="text-sm font-semibold"> </Label>
<div className="grid grid-cols-3 gap-2">
{[
{ value: "digital", label: "디지털" },
{ value: "analog", label: "아날로그" },
{ value: "both", label: "둘 다" },
].map((style) => (
<Button
key={style.value}
type="button"
variant={localConfig.style === style.value ? "default" : "outline"}
onClick={() => setLocalConfig({ ...localConfig, style: style.value as any })}
className="flex h-auto flex-col items-center gap-1 py-3"
size="sm"
>
<span className="text-xs">{style.label}</span>
</Button>
))}
</div>
</div>
<Separator />
{/* 타임존 선택 */}
<div className="space-y-2">
<Label className="text-sm font-semibold"></Label>
<Select
value={localConfig.timezone}
onValueChange={(value) => setLocalConfig({ ...localConfig, timezone: value })}
>
<SelectTrigger className="w-full" size="sm">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="Asia/Seoul">🇰🇷 (KST)</SelectItem>
<SelectItem value="Asia/Tokyo">🇯🇵 (JST)</SelectItem>
<SelectItem value="Asia/Shanghai">🇨🇳 (CST)</SelectItem>
<SelectItem value="America/New_York">🇺🇸 (EST)</SelectItem>
<SelectItem value="America/Los_Angeles">🇺🇸 LA (PST)</SelectItem>
<SelectItem value="Europe/London">🇬🇧 (GMT)</SelectItem>
<SelectItem value="Europe/Paris">🇫🇷 (CET)</SelectItem>
<SelectItem value="Australia/Sydney">🇦🇺 (AEDT)</SelectItem>
</SelectContent>
</Select>
</div>
<Separator />
{/* 테마 선택 */}
<div className="space-y-2">
<Label className="text-sm font-semibold"></Label>
<div className="grid grid-cols-3 gap-2">
{[
{
value: "light",
label: "Light",
gradient: "bg-gradient-to-br from-background to-muted",
text: "text-foreground",
},
{
value: "dark",
label: "Dark",
gradient: "bg-gradient-to-br from-foreground to-foreground",
text: "text-background",
},
{
value: "custom",
label: "사용자",
gradient: "bg-gradient-to-br from-primary to-primary/80",
text: "text-primary-foreground",
},
].map((theme) => (
<Button
key={theme.value}
type="button"
variant="outline"
onClick={() => setLocalConfig({ ...localConfig, theme: theme.value as any })}
className={`relative h-auto overflow-hidden p-0 ${
localConfig.theme === theme.value ? "ring-primary ring-2 ring-offset-2" : ""
}`}
size="sm"
>
<div className={`${theme.gradient} ${theme.text} w-full rounded px-3 py-2 text-xs font-medium`}>
{theme.label}
</div>
</Button>
))}
</div>
{/* 사용자 지정 색상 */}
{localConfig.theme === "custom" && (
<Card className="mt-2 border p-3">
<Label className="mb-2 block text-xs font-medium"> </Label>
<div className="flex items-center gap-2">
<Input
type="color"
value={localConfig.customColor || "#3b82f6"}
onChange={(e) => setLocalConfig({ ...localConfig, customColor: e.target.value })}
className="h-10 w-16 cursor-pointer"
/>
<Input
type="text"
value={localConfig.customColor || "#3b82f6"}
onChange={(e) => setLocalConfig({ ...localConfig, customColor: e.target.value })}
placeholder="#3b82f6"
className="flex-1 font-mono text-xs"
/>
</div>
</Card>
)}
</div>
<Separator />
{/* 옵션 토글 */}
<div className="space-y-2">
<Label className="text-sm font-semibold"> </Label>
<div className="space-y-2">
{/* 날짜 표시 */}
<div className="flex items-center justify-between rounded-lg border p-3">
<div className="flex items-center gap-2">
<span className="text-lg">📅</span>
<Label className="cursor-pointer text-sm"> </Label>
</div>
<Switch
checked={localConfig.showDate}
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, showDate: checked })}
/>
</div>
{/* 초 표시 */}
<div className="flex items-center justify-between rounded-lg border p-3">
<div className="flex items-center gap-2">
<span className="text-lg"></span>
<Label className="cursor-pointer text-sm"> </Label>
</div>
<Switch
checked={localConfig.showSeconds}
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, showSeconds: checked })}
/>
</div>
{/* 24시간 형식 */}
<div className="flex items-center justify-between rounded-lg border p-3">
<div className="flex items-center gap-2">
<span className="text-lg">🕐</span>
<Label className="cursor-pointer text-sm">24 </Label>
</div>
<Switch
checked={localConfig.format24h}
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, format24h: checked })}
/>
</div>
</div>
</div>
</div>
{/* 푸터 */}
<div className="flex justify-end gap-2 border-t p-4">
<Button variant="outline" size="sm" onClick={onClose}>
</Button>
<Button size="sm" onClick={handleSave}>
</Button>
</div>
</div>
);
}