feat: Schedule 페이지 카테고리 카운트 선택된 날짜 기준으로 변경
- categoryCounts useMemo 맵 추가 - 선택된 날짜가 있으면 해당 날짜의 일정만 카테고리 카운트 - O(1) 조회로 성능 최적화
This commit is contained in:
parent
80fad4d055
commit
71a206da36
1 changed files with 37 additions and 23 deletions
|
|
@ -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 (
|
||||
<div className="py-16">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue