2025-10-14 10:48:17 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
import { CalendarConfig } 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 CalendarSettingsProps {
|
|
|
|
|
config: CalendarConfig;
|
|
|
|
|
onSave: (config: CalendarConfig) => void;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 달력 위젯 설정 UI (Popover 내부용)
|
|
|
|
|
*/
|
|
|
|
|
export function CalendarSettings({ config, onSave, onClose }: CalendarSettingsProps) {
|
|
|
|
|
const [localConfig, setLocalConfig] = useState<CalendarConfig>(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">
|
|
|
|
|
{/* 뷰 타입 선택 (현재는 month만) */}
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label className="text-sm font-semibold">뷰 타입</Label>
|
|
|
|
|
<Select
|
|
|
|
|
value={localConfig.view}
|
|
|
|
|
onValueChange={(value) => setLocalConfig({ ...localConfig, view: value as any })}
|
|
|
|
|
>
|
|
|
|
|
<SelectTrigger className="w-full" size="sm">
|
|
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="month">월간 뷰</SelectItem>
|
|
|
|
|
{/* <SelectItem value="week">주간 뷰 (준비 중)</SelectItem>
|
|
|
|
|
<SelectItem value="day">일간 뷰 (준비 중)</SelectItem> */}
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Separator />
|
|
|
|
|
|
|
|
|
|
{/* 시작 요일 선택 */}
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label className="text-sm font-semibold">주 시작 요일</Label>
|
|
|
|
|
<div className="grid grid-cols-2 gap-2">
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant={localConfig.startWeekOn === "sunday" ? "default" : "outline"}
|
|
|
|
|
onClick={() => setLocalConfig({ ...localConfig, startWeekOn: "sunday" })}
|
|
|
|
|
size="sm"
|
|
|
|
|
>
|
|
|
|
|
일요일
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant={localConfig.startWeekOn === "monday" ? "default" : "outline"}
|
|
|
|
|
onClick={() => setLocalConfig({ ...localConfig, startWeekOn: "monday" })}
|
|
|
|
|
size="sm"
|
|
|
|
|
>
|
|
|
|
|
월요일
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</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",
|
2025-10-29 17:53:03 +09:00
|
|
|
gradient: "bg-gradient-to-br from-background to-muted",
|
|
|
|
|
text: "text-foreground",
|
2025-10-14 10:48:17 +09:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: "dark",
|
|
|
|
|
label: "Dark",
|
2025-10-29 17:53:03 +09:00
|
|
|
gradient: "bg-gradient-to-br from-foreground to-foreground",
|
2025-10-14 10:48:17 +09:00
|
|
|
text: "text-white",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: "custom",
|
|
|
|
|
label: "사용자",
|
2025-10-29 17:53:03 +09:00
|
|
|
gradient: "bg-gradient-to-br from-primary to-purple-500",
|
2025-10-14 10:48:17 +09:00
|
|
|
text: "text-white",
|
|
|
|
|
},
|
|
|
|
|
].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.highlightToday}
|
|
|
|
|
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, highlightToday: 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.highlightWeekends}
|
|
|
|
|
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, highlightWeekends: 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.showHolidays}
|
|
|
|
|
onCheckedChange={(checked) => setLocalConfig({ ...localConfig, showHolidays: 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>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|