Phase 6-9에서 추가된 파일 제거
- react-device-detect 미사용 문제로 인한 구조 재설계
- 올바른 폴더 구조로 재시작 예정:
- pages/{feature}/pc/, pages/{feature}/mobile/ 구조
- react-device-detect BrowserView/MobileView 사용
- components/pc/, components/mobile/ 레이아웃 분리
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
104 lines
2.8 KiB
JavaScript
104 lines
2.8 KiB
JavaScript
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 {
|
|
...calendarData,
|
|
currentDate,
|
|
selectedDate,
|
|
canGoPrevMonth,
|
|
goToPrevMonth,
|
|
goToNextMonth,
|
|
goToMonth,
|
|
goToToday,
|
|
selectDate,
|
|
setSelectedDate,
|
|
};
|
|
}
|