diff --git a/frontend/src/pages/pc/Schedule.jsx b/frontend/src/pages/pc/Schedule.jsx index 9a66a65..e4aa835 100644 --- a/frontend/src/pages/pc/Schedule.jsx +++ b/frontend/src/pages/pc/Schedule.jsx @@ -280,6 +280,28 @@ function Schedule() { }); }, [schedules, selectedDate, currentYearMonth, selectedCategories, isSearchMode, searchTerm, searchResults]); + // 카테고리별 카운트 맵 (useMemo로 미리 계산) - 선택된 날짜 기준 + const categoryCounts = useMemo(() => { + const source = (isSearchMode && searchTerm) ? searchResults : schedules; + const counts = new Map(); + let total = 0; + + source.forEach(s => { + const scheduleDate = s.date ? s.date.split('T')[0] : ''; + // 선택된 날짜가 있으면 해당 날짜만 카운트 + if (selectedDate) { + if (scheduleDate !== selectedDate) return; + } + + const catId = s.category_id; + counts.set(catId, (counts.get(catId) || 0) + 1); + total++; + }); + + counts.set('total', total); + return counts; + }, [schedules, searchResults, isSearchMode, searchTerm, selectedDate]); + const formatDate = (dateStr) => { const date = new Date(dateStr); const dayNames = ['일', '월', '화', '수', '목', '금', '토']; @@ -296,25 +318,22 @@ function Schedule() { if (!schedule.description && schedule.source_url) { window.open(schedule.source_url, '_blank'); } else { - // 상세 페이지로 이동 (추후 구현) + // 상세 페이지로 이동 navigate(`/schedule/${schedule.id}`); } }; - // 년도 범위 - const startYear = Math.floor(year / 10) * 10 - 1; - const yearRange = Array.from({ length: 12 }, (_, i) => startYear + i); - - const isCurrentYear = (y) => new Date().getFullYear() === y; + const currentYear = new Date().getFullYear(); + const isCurrentYear = (y) => y === currentYear; const isCurrentMonth = (m) => { - const today = new Date(); - return today.getFullYear() === year && today.getMonth() === m; + const now = new Date(); + return year === now.getFullYear() && m === now.getMonth(); }; - - const monthNames = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']; - - const prevYearRange = () => setCurrentDate(new Date(year - 10, month, 1)); - const nextYearRange = () => setCurrentDate(new Date(year + 10, month, 1)); + + // 연도 선택 범위 + const [yearRangeStart, setYearRangeStart] = useState(currentYear - 1); + const prevYearRange = () => setYearRangeStart(prev => prev - 3); + const nextYearRange = () => setYearRangeStart(prev => prev + 3); // 선택된 카테고리 이름 const getSelectedCategoryNames = () => { @@ -341,22 +360,17 @@ function Schedule() { // 정렬된 카테고리 목록 (메모이제이션으로 깜빡임 방지) const sortedCategories = useMemo(() => { return categories - .map(category => { - const count = isSearchMode && searchTerm - ? searchResults.filter(s => s.category_id === category.id).length - : schedules.filter(s => { - const scheduleDate = s.date ? s.date.split('T')[0] : ''; - return scheduleDate.startsWith(currentYearMonth) && s.category_id === category.id; - }).length; - return { ...category, count }; - }) + .map(category => ({ + ...category, + count: categoryCounts.get(category.id) || 0 + })) .filter(category => category.count > 0) .sort((a, b) => { if (a.name === '기타') return 1; if (b.name === '기타') return -1; return b.count - a.count; }); - }, [categories, schedules, searchResults, isSearchMode, searchTerm, currentYearMonth]); + }, [categories, categoryCounts]); return (