118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
"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>
|
|
);
|
|
}
|
|
|