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

132 lines
3.8 KiB
TypeScript
Raw Normal View History

"use client";
import { useState, useEffect } from "react";
import { DashboardElement, ClockConfig } from "../types";
import { AnalogClock } from "./AnalogClock";
import { DigitalClock } from "./DigitalClock";
import { ClockSettings } from "./ClockSettings";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { Settings } from "lucide-react";
interface ClockWidgetProps {
element: DashboardElement;
onConfigUpdate?: (config: ClockConfig) => void;
}
/**
*
* - 1
* - //
* -
* - UI
*/
export function ClockWidget({ element, onConfigUpdate }: ClockWidgetProps) {
const [currentTime, setCurrentTime] = useState(new Date());
const [settingsOpen, setSettingsOpen] = useState(false);
// 기본 설정값
const config = element.clockConfig || {
style: "digital",
timezone: "Asia/Seoul",
showDate: true,
showSeconds: true,
format24h: true,
theme: "light",
customColor: "#3b82f6",
};
// 설정 저장 핸들러
const handleSaveSettings = (newConfig: ClockConfig) => {
onConfigUpdate?.(newConfig);
setSettingsOpen(false);
};
// 1초마다 시간 업데이트
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(new Date());
}, 1000);
// cleanup: 컴포넌트 unmount 시 타이머 정리
return () => clearInterval(timer);
}, []);
// 시계 콘텐츠 렌더링
const renderClockContent = () => {
if (config.style === "analog") {
return (
2025-10-14 10:12:40 +09:00
<AnalogClock
time={currentTime}
theme={config.theme}
timezone={config.timezone}
customColor={config.customColor}
/>
);
}
if (config.style === "digital") {
return (
<DigitalClock
time={currentTime}
timezone={config.timezone}
showDate={config.showDate}
showSeconds={config.showSeconds}
format24h={config.format24h}
theme={config.theme}
2025-10-14 10:12:40 +09:00
customColor={config.customColor}
/>
);
}
// 'both' - 아날로그 + 디지털
return (
<div className="flex h-full w-full flex-col overflow-hidden">
<div className="flex-[55] overflow-hidden">
<AnalogClock
time={currentTime}
theme={config.theme}
timezone={config.timezone}
customColor={config.customColor}
/>
</div>
<div className="flex-[45] overflow-hidden">
<DigitalClock
time={currentTime}
timezone={config.timezone}
showDate={false}
showSeconds={config.showSeconds}
format24h={config.format24h}
theme={config.theme}
customColor={config.customColor}
compact={true}
/>
</div>
</div>
);
};
return (
<div className="relative h-full w-full">
{/* 시계 콘텐츠 */}
{renderClockContent()}
{/* 설정 버튼 - 우측 상단 (디자이너 모드에서만 표시) */}
{onConfigUpdate && (
<div className="absolute top-2 right-2">
<Popover open={settingsOpen} onOpenChange={setSettingsOpen}>
<PopoverTrigger asChild>
2025-10-29 17:53:03 +09:00
<Button variant="ghost" size="icon" className="h-8 w-8 bg-background/80 hover:bg-background">
<Settings className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[500px] p-0" align="end">
<ClockSettings config={config} onSave={handleSaveSettings} onClose={() => setSettingsOpen(false)} />
</PopoverContent>
</Popover>
</div>
)}
</div>
);
}