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]);
|
}, [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 formatDate = (dateStr) => {
|
||||||
const date = new Date(dateStr);
|
const date = new Date(dateStr);
|
||||||
const dayNames = ['일', '월', '화', '수', '목', '금', '토'];
|
const dayNames = ['일', '월', '화', '수', '목', '금', '토'];
|
||||||
|
|
@ -296,25 +318,22 @@ function Schedule() {
|
||||||
if (!schedule.description && schedule.source_url) {
|
if (!schedule.description && schedule.source_url) {
|
||||||
window.open(schedule.source_url, '_blank');
|
window.open(schedule.source_url, '_blank');
|
||||||
} else {
|
} else {
|
||||||
// 상세 페이지로 이동 (추후 구현)
|
// 상세 페이지로 이동
|
||||||
navigate(`/schedule/${schedule.id}`);
|
navigate(`/schedule/${schedule.id}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 년도 범위
|
const currentYear = new Date().getFullYear();
|
||||||
const startYear = Math.floor(year / 10) * 10 - 1;
|
const isCurrentYear = (y) => y === currentYear;
|
||||||
const yearRange = Array.from({ length: 12 }, (_, i) => startYear + i);
|
|
||||||
|
|
||||||
const isCurrentYear = (y) => new Date().getFullYear() === y;
|
|
||||||
const isCurrentMonth = (m) => {
|
const isCurrentMonth = (m) => {
|
||||||
const today = new Date();
|
const now = new Date();
|
||||||
return today.getFullYear() === year && today.getMonth() === m;
|
return year === now.getFullYear() && m === now.getMonth();
|
||||||
};
|
};
|
||||||
|
|
||||||
const monthNames = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'];
|
// 연도 선택 범위
|
||||||
|
const [yearRangeStart, setYearRangeStart] = useState(currentYear - 1);
|
||||||
const prevYearRange = () => setCurrentDate(new Date(year - 10, month, 1));
|
const prevYearRange = () => setYearRangeStart(prev => prev - 3);
|
||||||
const nextYearRange = () => setCurrentDate(new Date(year + 10, month, 1));
|
const nextYearRange = () => setYearRangeStart(prev => prev + 3);
|
||||||
|
|
||||||
// 선택된 카테고리 이름
|
// 선택된 카테고리 이름
|
||||||
const getSelectedCategoryNames = () => {
|
const getSelectedCategoryNames = () => {
|
||||||
|
|
@ -341,22 +360,17 @@ function Schedule() {
|
||||||
// 정렬된 카테고리 목록 (메모이제이션으로 깜빡임 방지)
|
// 정렬된 카테고리 목록 (메모이제이션으로 깜빡임 방지)
|
||||||
const sortedCategories = useMemo(() => {
|
const sortedCategories = useMemo(() => {
|
||||||
return categories
|
return categories
|
||||||
.map(category => {
|
.map(category => ({
|
||||||
const count = isSearchMode && searchTerm
|
...category,
|
||||||
? searchResults.filter(s => s.category_id === category.id).length
|
count: categoryCounts.get(category.id) || 0
|
||||||
: 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 };
|
|
||||||
})
|
|
||||||
.filter(category => category.count > 0)
|
.filter(category => category.count > 0)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.name === '기타') return 1;
|
if (a.name === '기타') return 1;
|
||||||
if (b.name === '기타') return -1;
|
if (b.name === '기타') return -1;
|
||||||
return b.count - a.count;
|
return b.count - a.count;
|
||||||
});
|
});
|
||||||
}, [categories, schedules, searchResults, isSearchMode, searchTerm, currentYearMonth]);
|
}, [categories, categoryCounts]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="py-16">
|
<div className="py-16">
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue