From ea9922de001569c4020f97d62a3834653afcfa4a Mon Sep 17 00:00:00 2001 From: caadiq Date: Sat, 24 Jan 2026 18:30:51 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=9D=BC=EC=A0=95=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EB=A1=9C=EC=A7=81=EC=9D=84=20=EB=B0=B1=EC=97=94?= =?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 백엔드에서 특수 일정(기념일, 생일) 우선 정렬 - 프론트엔드의 중복 정렬 로직 제거 - 정렬 순서: 날짜 > 특수 일정 > 시간 Co-Authored-By: Claude Opus 4.5 --- backend/src/services/schedule.js | 29 ++++++++++++- .../src/pages/mobile/schedule/Schedule.jsx | 15 +------ .../src/pages/pc/public/schedule/Schedule.jsx | 43 ++++--------------- 3 files changed, 37 insertions(+), 50 deletions(-) diff --git a/backend/src/services/schedule.js b/backend/src/services/schedule.js index 415b798..a7699b6 100644 --- a/backend/src/services/schedule.js +++ b/backend/src/services/schedule.js @@ -383,8 +383,33 @@ export async function getMonthlySchedules(db, year, month) { } } - // 날짜순 정렬 - schedules.sort((a, b) => a.date.localeCompare(b.date)); + // 날짜순 정렬 (같은 날짜 내에서 특수 일정을 먼저 배치) + schedules.sort((a, b) => { + // 날짜 비교 + const dateCompare = a.date.localeCompare(b.date); + if (dateCompare !== 0) return dateCompare; + + // 같은 날짜면 특수 일정(생일, 기념일)을 먼저 + const aSpecial = a.is_birthday || a.is_debut || a.is_anniversary; + const bSpecial = b.is_birthday || b.is_debut || b.is_anniversary; + if (aSpecial && !bSpecial) return -1; + if (!aSpecial && bSpecial) return 1; + + // 둘 다 특수 일정이면 기념일 > 생일 순서 + if (aSpecial && bSpecial) { + const aDebut = a.is_debut || a.is_anniversary; + const bDebut = b.is_debut || b.is_anniversary; + if (aDebut && !bDebut) return -1; + if (!aDebut && bDebut) return 1; + } + + // 시간순 정렬 + if (a.time && b.time) return a.time.localeCompare(b.time); + if (a.time) return -1; + if (b.time) return 1; + + return 0; + }); return { schedules }; } diff --git a/frontend/src/pages/mobile/schedule/Schedule.jsx b/frontend/src/pages/mobile/schedule/Schedule.jsx index b8b7695..69c0432 100644 --- a/frontend/src/pages/mobile/schedule/Schedule.jsx +++ b/frontend/src/pages/mobile/schedule/Schedule.jsx @@ -336,19 +336,8 @@ function MobileSchedule() { const month = String(selectedDate.getMonth() + 1).padStart(2, '0'); const day = String(selectedDate.getDate()).padStart(2, '0'); const dateStr = `${year}-${month}-${day}`; - return schedules - .filter((s) => s.date.split('T')[0] === dateStr) - .sort((a, b) => { - const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-'); - const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-'); - const aIsDebut = a.is_debut || a.is_anniversary; - const bIsDebut = b.is_debut || b.is_anniversary; - const aIsSpecial = aIsBirthday || aIsDebut; - const bIsSpecial = bIsBirthday || bIsDebut; - if (aIsSpecial && !bIsSpecial) return -1; - if (!aIsSpecial && bIsSpecial) return 1; - return 0; - }); + // 백엔드에서 이미 정렬된 상태로 전달됨 (특수 일정 우선) + return schedules.filter((s) => s.date.split('T')[0] === dateStr); }, [schedules, selectedDate]); // 요일 이름 diff --git a/frontend/src/pages/pc/public/schedule/Schedule.jsx b/frontend/src/pages/pc/public/schedule/Schedule.jsx index 72859bc..ab0276e 100644 --- a/frontend/src/pages/pc/public/schedule/Schedule.jsx +++ b/frontend/src/pages/pc/public/schedule/Schedule.jsx @@ -238,45 +238,18 @@ function PCSchedule() { const currentYearMonth = `${year}-${String(month + 1).padStart(2, '0')}`; const filteredSchedules = useMemo(() => { - const sortWithSpecialFirst = (list) => { - return [...list].sort((a, b) => { - const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-'); - const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-'); - const aIsDebut = a.is_debut || a.is_anniversary; - const bIsDebut = b.is_debut || b.is_anniversary; - const aIsSpecial = aIsBirthday || aIsDebut; - const bIsSpecial = bIsBirthday || bIsDebut; - if (aIsSpecial && !bIsSpecial) return -1; - if (!aIsSpecial && bIsSpecial) return 1; - return 0; - }); - }; - + // 백엔드에서 이미 정렬된 상태로 전달됨 (특수 일정 우선) if (isSearchMode) { if (!searchTerm) return []; - if (selectedCategories.length === 0) return sortWithSpecialFirst(searchResults); - return sortWithSpecialFirst(searchResults.filter((s) => selectedCategories.includes(s.category_id))); + if (selectedCategories.length === 0) return searchResults; + return searchResults.filter((s) => selectedCategories.includes(s.category_id)); } - const filtered = schedules - .filter((s) => { - const matchesDate = selectedDate ? s.date === selectedDate : s.date?.startsWith(currentYearMonth); - const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id); - return matchesDate && matchesCategory; - }) - .sort((a, b) => { - const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-'); - const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-'); - const aIsDebut = a.is_debut || a.is_anniversary; - const bIsDebut = b.is_debut || b.is_anniversary; - const aIsSpecial = aIsBirthday || aIsDebut; - const bIsSpecial = bIsBirthday || bIsDebut; - if (aIsSpecial && !bIsSpecial) return -1; - if (!aIsSpecial && bIsSpecial) return 1; - if (a.date !== b.date) return a.date.localeCompare(b.date); - return (a.time || '00:00:00').localeCompare(b.time || '00:00:00'); - }); - return filtered; + return schedules.filter((s) => { + const matchesDate = selectedDate ? s.date === selectedDate : s.date?.startsWith(currentYearMonth); + const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id); + return matchesDate && matchesCategory; + }); }, [schedules, selectedDate, currentYearMonth, selectedCategories, isSearchMode, searchTerm, searchResults]); // 가상 스크롤