import { useState, useMemo, useCallback } from 'react'; import { MIN_YEAR, WEEKDAYS, MONTH_NAMES } from '@/constants'; import { getTodayKST } from '@/utils'; /** * 캘린더 훅 * 날짜 선택, 월 이동 등 캘린더 로직 제공 * @param {Date} initialDate - 초기 날짜 */ export function useCalendar(initialDate = new Date()) { const [currentDate, setCurrentDate] = useState(initialDate); const [selectedDate, setSelectedDate] = useState(getTodayKST()); const year = currentDate.getFullYear(); const month = currentDate.getMonth(); // 캘린더 데이터 계산 const calendarData = useMemo(() => { const firstDay = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); const prevMonthDays = new Date(year, month, 0).getDate(); return { year, month, monthName: MONTH_NAMES[month], firstDay, daysInMonth, prevMonthDays, weekdays: WEEKDAYS, }; }, [year, month]); // 이전 월로 이동 가능 여부 const canGoPrevMonth = !(year === MIN_YEAR && month === 0); // 선택 날짜 업데이트 헬퍼 const updateSelectedDate = useCallback((newDate) => { const today = new Date(); if ( newDate.getFullYear() === today.getFullYear() && newDate.getMonth() === today.getMonth() ) { setSelectedDate(getTodayKST()); } else { const firstDay = `${newDate.getFullYear()}-${String(newDate.getMonth() + 1).padStart(2, '0')}-01`; setSelectedDate(firstDay); } }, []); // 이전 월로 이동 const goToPrevMonth = useCallback(() => { if (!canGoPrevMonth) return; const newDate = new Date(year, month - 1, 1); setCurrentDate(newDate); updateSelectedDate(newDate); }, [year, month, canGoPrevMonth, updateSelectedDate]); // 다음 월로 이동 const goToNextMonth = useCallback(() => { const newDate = new Date(year, month + 1, 1); setCurrentDate(newDate); updateSelectedDate(newDate); }, [year, month, updateSelectedDate]); // 특정 월로 이동 const goToMonth = useCallback( (newYear, newMonth) => { const newDate = new Date(newYear, newMonth, 1); setCurrentDate(newDate); updateSelectedDate(newDate); }, [updateSelectedDate] ); // 오늘로 이동 const goToToday = useCallback(() => { const today = new Date(); setCurrentDate(today); setSelectedDate(getTodayKST()); }, []); // 날짜 선택 const selectDate = useCallback( (day) => { const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`; setSelectedDate(dateStr); }, [year, month] ); // 반환 객체 메모이제이션 return useMemo( () => ({ ...calendarData, currentDate, selectedDate, canGoPrevMonth, goToPrevMonth, goToNextMonth, goToMonth, goToToday, selectDate, setSelectedDate, }), [ calendarData, currentDate, selectedDate, canGoPrevMonth, goToPrevMonth, goToNextMonth, goToMonth, goToToday, selectDate, ] ); }