diff --git a/frontend/src/components/calendar/MiniCalendar.tsx b/frontend/src/components/calendar/MiniCalendar.tsx index 123e121..87871d1 100644 --- a/frontend/src/components/calendar/MiniCalendar.tsx +++ b/frontend/src/components/calendar/MiniCalendar.tsx @@ -1,8 +1,8 @@ -import { useState, useEffect, useMemo, memo } from 'react'; +import { useState, useEffect, useMemo, useCallback, memo } from 'react'; import { startOfMonth, endOfMonth, startOfWeek, endOfWeek, eachDayOfInterval, format, isSameDay, isSameMonth, isToday, - addMonths, subMonths, + addMonths, subMonths, parse, } from 'date-fns'; import { ChevronLeft, ChevronRight } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -30,10 +30,17 @@ function getOrderedLabels(firstDay: number) { const MiniCalendar = memo(function MiniCalendar({ onDateClick, currentDate, - firstDayOfWeek = 1, + firstDayOfWeek = 0, }: MiniCalendarProps) { + const REF_DATE = useMemo(() => new Date(), []); + + const parseDate = useCallback( + (dateStr: string) => parse(dateStr, 'yyyy-MM-dd', REF_DATE), + [REF_DATE] + ); + const [displayedMonth, setDisplayedMonth] = useState(() => - currentDate ? startOfMonth(new Date(currentDate)) : startOfMonth(new Date()) + currentDate ? startOfMonth(parseDate(currentDate)) : startOfMonth(new Date()) ); const [selectedDate, setSelectedDate] = useState( currentDate ?? null @@ -42,12 +49,12 @@ const MiniCalendar = memo(function MiniCalendar({ // Sync displayed month when main calendar navigates across months useEffect(() => { if (!currentDate) return; - const incoming = startOfMonth(new Date(currentDate)); + const incoming = startOfMonth(parseDate(currentDate)); setDisplayedMonth((prev) => prev.getTime() === incoming.getTime() ? prev : incoming ); - setSelectedDate(currentDate); - }, [currentDate]); + setSelectedDate((prev) => prev === currentDate ? prev : currentDate); + }, [currentDate, parseDate]); const days = useMemo( () => buildGrid(displayedMonth, firstDayOfWeek), @@ -59,10 +66,10 @@ const MiniCalendar = memo(function MiniCalendar({ [firstDayOfWeek] ); - const handlePrev = () => setDisplayedMonth((m) => subMonths(m, 1)); - const handleNext = () => setDisplayedMonth((m) => addMonths(m, 1)); + const handlePrev = useCallback(() => setDisplayedMonth((m) => subMonths(m, 1)), []); + const handleNext = useCallback(() => setDisplayedMonth((m) => addMonths(m, 1)), []); - const handleDayClick = (day: Date) => { + const handleDayClick = useCallback((day: Date) => { const dateStr = format(day, 'yyyy-MM-dd'); setSelectedDate(dateStr); // If clicking a day in another month, also shift the displayed month @@ -70,9 +77,12 @@ const MiniCalendar = memo(function MiniCalendar({ setDisplayedMonth(startOfMonth(day)); } onDateClick(dateStr); - }; + }, [displayedMonth, onDateClick]); - const selectedDateObj = selectedDate ? new Date(selectedDate) : null; + const selectedDateObj = useMemo( + () => selectedDate ? parseDate(selectedDate) : null, + [selectedDate, parseDate] + ); return (
@@ -120,15 +130,15 @@ const MiniCalendar = memo(function MiniCalendar({ return (