달력 위젯 구현
This commit is contained in:
117
frontend/components/admin/dashboard/widgets/MonthView.tsx
Normal file
117
frontend/components/admin/dashboard/widgets/MonthView.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
"use client";
|
||||
|
||||
import { CalendarConfig } from "../types";
|
||||
import { CalendarDay, getWeekDayNames } from "./calendarUtils";
|
||||
|
||||
interface MonthViewProps {
|
||||
days: CalendarDay[];
|
||||
config: CalendarConfig;
|
||||
isCompact?: boolean; // 작은 크기 (2x2, 3x3)
|
||||
}
|
||||
|
||||
/**
|
||||
* 월간 달력 뷰 컴포넌트
|
||||
*/
|
||||
export function MonthView({ days, config, isCompact = false }: MonthViewProps) {
|
||||
const weekDayNames = getWeekDayNames(config.startWeekOn);
|
||||
|
||||
// 테마별 스타일
|
||||
const getThemeStyles = () => {
|
||||
if (config.theme === "custom" && config.customColor) {
|
||||
return {
|
||||
todayBg: config.customColor,
|
||||
holidayText: config.customColor,
|
||||
weekendText: "#dc2626",
|
||||
};
|
||||
}
|
||||
|
||||
if (config.theme === "dark") {
|
||||
return {
|
||||
todayBg: "#3b82f6",
|
||||
holidayText: "#f87171",
|
||||
weekendText: "#f87171",
|
||||
};
|
||||
}
|
||||
|
||||
// light 테마
|
||||
return {
|
||||
todayBg: "#3b82f6",
|
||||
holidayText: "#dc2626",
|
||||
weekendText: "#dc2626",
|
||||
};
|
||||
};
|
||||
|
||||
const themeStyles = getThemeStyles();
|
||||
|
||||
// 날짜 셀 스타일 클래스
|
||||
const getDayCellClass = (day: CalendarDay) => {
|
||||
const baseClass = "flex aspect-square items-center justify-center rounded-lg transition-colors";
|
||||
const sizeClass = isCompact ? "text-xs" : "text-sm";
|
||||
|
||||
let colorClass = "text-gray-700";
|
||||
|
||||
// 현재 월이 아닌 날짜
|
||||
if (!day.isCurrentMonth) {
|
||||
colorClass = "text-gray-300";
|
||||
}
|
||||
// 오늘
|
||||
else if (config.highlightToday && day.isToday) {
|
||||
colorClass = "text-white font-bold";
|
||||
}
|
||||
// 공휴일
|
||||
else if (config.showHolidays && day.isHoliday) {
|
||||
colorClass = "font-semibold";
|
||||
}
|
||||
// 주말
|
||||
else if (config.highlightWeekends && day.isWeekend) {
|
||||
colorClass = "text-red-600";
|
||||
}
|
||||
|
||||
const bgClass = config.highlightToday && day.isToday ? "" : "hover:bg-gray-100";
|
||||
|
||||
return `${baseClass} ${sizeClass} ${colorClass} ${bgClass}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col p-2">
|
||||
{/* 요일 헤더 */}
|
||||
{!isCompact && (
|
||||
<div className="mb-2 grid grid-cols-7 gap-1">
|
||||
{weekDayNames.map((name, index) => {
|
||||
const isWeekend = config.startWeekOn === "sunday" ? index === 0 || index === 6 : index === 5 || index === 6;
|
||||
return (
|
||||
<div
|
||||
key={name}
|
||||
className={`text-center text-xs font-semibold ${isWeekend && config.highlightWeekends ? "text-red-600" : "text-gray-600"}`}
|
||||
>
|
||||
{name}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 날짜 그리드 */}
|
||||
<div className="grid flex-1 grid-cols-7 gap-1">
|
||||
{days.map((day, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={getDayCellClass(day)}
|
||||
style={{
|
||||
backgroundColor:
|
||||
config.highlightToday && day.isToday ? themeStyles.todayBg : undefined,
|
||||
color:
|
||||
config.showHolidays && day.isHoliday && day.isCurrentMonth
|
||||
? themeStyles.holidayText
|
||||
: undefined,
|
||||
}}
|
||||
title={day.isHoliday ? day.holidayName : undefined}
|
||||
>
|
||||
{day.day}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user