diff --git a/frontend/src/pages/pc/Schedule.jsx b/frontend/src/pages/pc/Schedule.jsx index af1804b..94894a3 100644 --- a/frontend/src/pages/pc/Schedule.jsx +++ b/frontend/src/pages/pc/Schedule.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef, useMemo } from 'react'; +import { useState, useEffect, useRef, useMemo, useDeferredValue, memo } from 'react'; import { useNavigate } from 'react-router-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2 } from 'lucide-react'; @@ -26,6 +26,7 @@ function Schedule() { // 카테고리 필터 툴팁 const [showCategoryTooltip, setShowCategoryTooltip] = useState(false); const categoryRef = useRef(null); + const scrollContainerRef = useRef(null); // 일정 목록 스크롤 컨테이너 // 검색 상태 const [isSearchMode, setIsSearchMode] = useState(false); @@ -128,6 +129,13 @@ function Schedule() { return () => document.removeEventListener('mousedown', handleClickOutside); }, []); + // 날짜 변경 시 스크롤 맨 위로 초기화 + useEffect(() => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTop = 0; + } + }, [selectedDate]); + // 달력 관련 함수 const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate(); const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay(); @@ -139,21 +147,34 @@ function Schedule() { const days = ['일', '월', '화', '수', '목', '금', '토']; - // 스케줄이 있는 날짜 목록 (ISO 형식에서 YYYY-MM-DD 추출) - const scheduleDates = schedules.map(s => s.date ? s.date.split('T')[0] : ''); + // 스케줄 데이터를 지연 처리하여 달력 UI 응답성 향상 + const deferredSchedules = useDeferredValue(schedules); - // 해당 날짜의 첫 번째 일정 카테고리 색상 + // 일정 날짜별 맵 (O(1) 조회용) - 지연된 데이터로 점 표시 + const scheduleDateMap = useMemo(() => { + const map = new Map(); + deferredSchedules.forEach(s => { + const dateStr = s.date ? s.date.split('T')[0] : ''; + if (!map.has(dateStr)) { + map.set(dateStr, s); + } + }); + return map; + }, [deferredSchedules]); + + // 해당 날짜의 첫 번째 일정 카테고리 색상 (O(1)) const getScheduleColor = (day) => { const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const schedule = schedules.find(s => (s.date ? s.date.split('T')[0] : '') === dateStr); + const schedule = scheduleDateMap.get(dateStr); if (!schedule) return null; const cat = categories.find(c => c.id === schedule.category_id); return cat?.color || '#4A7C59'; }; + // 해당 날짜에 일정이 있는지 확인 (O(1)) const hasSchedule = (day) => { const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - return scheduleDates.includes(dateStr); + return scheduleDateMap.has(dateStr); }; const prevMonth = () => { @@ -768,6 +789,7 @@ function Schedule() {