fix(frontend): 멤버 표시 오류 수정 및 생일 우선 정렬 추가

수정:
- AdminSchedule.jsx 1306번 라인 멤버 처리 오류 수정
- getMemberList 헬퍼 함수 사용으로 통일

생일 우선 정렬:
- PC 공개 일정 페이지: filteredSchedules에 생일 우선 정렬 추가
- PC 관리 페이지: filteredSchedules에 생일 우선 정렬 추가
- 모바일 공개 페이지: groupedSchedules, selectedDateSchedules에 생일 우선 정렬 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-01-21 16:26:17 +09:00
parent b4c393c20a
commit 9d365dcadb
3 changed files with 76 additions and 26 deletions

View file

@ -440,7 +440,7 @@ function MobileSchedule() {
return category?.color || '#6b7280'; return category?.color || '#6b7280';
}; };
// // ( )
const groupedSchedules = useMemo(() => { const groupedSchedules = useMemo(() => {
const groups = {}; const groups = {};
schedules.forEach(schedule => { schedules.forEach(schedule => {
@ -448,6 +448,16 @@ function MobileSchedule() {
if (!groups[date]) groups[date] = []; if (!groups[date]) groups[date] = [];
groups[date].push(schedule); groups[date].push(schedule);
}); });
//
Object.values(groups).forEach(group => {
group.sort((a, b) => {
const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-');
const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-');
if (aIsBirthday && !bIsBirthday) return -1;
if (!aIsBirthday && bIsBirthday) return 1;
return 0;
});
});
return Object.entries(groups).sort((a, b) => a[0].localeCompare(b[0])); return Object.entries(groups).sort((a, b) => a[0].localeCompare(b[0]));
}, [schedules]); }, [schedules]);
@ -463,7 +473,7 @@ function MobileSchedule() {
return days; return days;
}, [selectedDate]); }, [selectedDate]);
// // ( )
const selectedDateSchedules = useMemo(() => { const selectedDateSchedules = useMemo(() => {
// KST // KST
const year = selectedDate.getFullYear(); const year = selectedDate.getFullYear();
@ -471,7 +481,15 @@ function MobileSchedule() {
const day = String(selectedDate.getDate()).padStart(2, '0'); const day = String(selectedDate.getDate()).padStart(2, '0');
const dateStr = `${year}-${month}-${day}`; const dateStr = `${year}-${month}-${day}`;
// API date ISO T // API date ISO T
return schedules.filter(s => s.date.split('T')[0] === dateStr); 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-');
if (aIsBirthday && !bIsBirthday) return -1;
if (!aIsBirthday && bIsBirthday) return 1;
return 0;
});
}, [schedules, selectedDate]); }, [schedules, selectedDate]);
// //

View file

@ -575,18 +575,31 @@ function AdminSchedule() {
// ( searchResults, ) - useMemo // ( searchResults, ) - useMemo
const filteredSchedules = useMemo(() => { const filteredSchedules = useMemo(() => {
let result;
if (isSearchMode) { if (isSearchMode) {
if (!searchTerm) return []; if (!searchTerm) return [];
// //
if (selectedCategories.length === 0) return searchResults; if (selectedCategories.length === 0) {
return searchResults.filter(s => selectedCategories.includes(s.category_id)); result = [...searchResults];
} else {
result = searchResults.filter(s => selectedCategories.includes(s.category_id));
}
} else {
// :
result = schedules.filter(schedule => {
const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(schedule.category_id);
const scheduleDate = formatDate(schedule.date);
const matchesDate = !selectedDate || scheduleDate === selectedDate;
return matchesCategory && matchesDate;
});
} }
// : //
return schedules.filter(schedule => { return result.sort((a, b) => {
const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(schedule.category_id); const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-');
const scheduleDate = formatDate(schedule.date); const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-');
const matchesDate = !selectedDate || scheduleDate === selectedDate; if (aIsBirthday && !bIsBirthday) return -1;
return matchesCategory && matchesDate; if (!aIsBirthday && bIsBirthday) return 1;
return 0;
}); });
}, [isSearchMode, searchTerm, searchResults, schedules, selectedCategories, selectedDate]); }, [isSearchMode, searchTerm, searchResults, schedules, selectedCategories, selectedDate]);
@ -1300,18 +1313,19 @@ function AdminSchedule() {
</span> </span>
)} )}
</div> </div>
{(schedule.members?.length > 0 || schedule.member_names) && ( {(() => {
<div className="flex flex-wrap gap-1.5 mt-2"> const memberList = getMemberList(schedule);
{(() => { if (memberList.length === 0) return null;
const memberList = schedule.members?.map(m => m.name) || schedule.member_names?.split(',') || []; return (
return memberList.map((name, i) => ( <div className="flex flex-wrap gap-1.5 mt-2">
{memberList.map((name, i) => (
<span key={i} className="px-2 py-0.5 bg-primary/10 text-primary text-xs font-medium rounded-full"> <span key={i} className="px-2 py-0.5 bg-primary/10 text-primary text-xs font-medium rounded-full">
{name.trim()} {name}
</span> </span>
)); ))}
})()} </div>
</div> );
)} })()}
</div> </div>
<div className="flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity"> <div className="flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity">

View file

@ -483,27 +483,44 @@ function Schedule() {
const currentYearMonth = `${year}-${String(month + 1).padStart(2, '0')}`; const currentYearMonth = `${year}-${String(month + 1).padStart(2, '0')}`;
const filteredSchedules = useMemo(() => { const filteredSchedules = useMemo(() => {
//
const sortWithBirthdayFirst = (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-');
if (aIsBirthday && !bIsBirthday) return -1;
if (!aIsBirthday && bIsBirthday) return 1;
return 0;
});
};
// //
if (isSearchMode) { if (isSearchMode) {
// , API (Meilisearch ) // , API (Meilisearch )
if (!searchTerm) return []; if (!searchTerm) return [];
// //
if (selectedCategories.length === 0) return searchResults; if (selectedCategories.length === 0) return sortWithBirthdayFirst(searchResults);
return searchResults.filter(s => selectedCategories.includes(s.category_id)); return sortWithBirthdayFirst(searchResults.filter(s => selectedCategories.includes(s.category_id)));
} }
// : // :
return schedules const filtered = schedules
.filter(s => { .filter(s => {
const scheduleDate = s.date ? s.date.split('T')[0] : ''; const scheduleDate = s.date ? s.date.split('T')[0] : '';
const matchesDate = selectedDate const matchesDate = selectedDate
? scheduleDate === selectedDate ? scheduleDate === selectedDate
: scheduleDate.startsWith(currentYearMonth); : scheduleDate.startsWith(currentYearMonth);
const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id); const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id);
return matchesDate && matchesCategory; return matchesDate && matchesCategory;
}) })
.sort((a, b) => { .sort((a, b) => {
//
const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-');
const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-');
if (aIsBirthday && !bIsBirthday) return -1;
if (!aIsBirthday && bIsBirthday) return 1;
// /
const dateA = a.date ? a.date.split('T')[0] : ''; const dateA = a.date ? a.date.split('T')[0] : '';
const dateB = b.date ? b.date.split('T')[0] : ''; const dateB = b.date ? b.date.split('T')[0] : '';
if (dateA !== dateB) return dateA.localeCompare(dateB); if (dateA !== dateB) return dateA.localeCompare(dateB);
@ -511,6 +528,7 @@ function Schedule() {
const timeB = b.time || '00:00:00'; const timeB = b.time || '00:00:00';
return timeA.localeCompare(timeB); return timeA.localeCompare(timeB);
}); });
return filtered;
}, [schedules, selectedDate, currentYearMonth, selectedCategories, isSearchMode, searchTerm, searchResults]); }, [schedules, selectedDate, currentYearMonth, selectedCategories, isSearchMode, searchTerm, searchResults]);
// ( , ) // ( , )