diff --git a/frontend/src/pages/pirocheck/attendance/Attendance.js b/frontend/src/pages/pirocheck/attendance/Attendance.js index 92a53cd..77968ae 100644 --- a/frontend/src/pages/pirocheck/attendance/Attendance.js +++ b/frontend/src/pages/pirocheck/attendance/Attendance.js @@ -15,19 +15,9 @@ function cloverForSlot(status) { return 미정; } -// 세션 1회 출석 결과 → 코인/화남 아이콘 -// status: true(출석성공) / false(결석) / null(미정) -// successCount: 해당 세션에서 출석 성공한 횟수 (AM/PM 등 슬롯 수) -function sessionIcon(slot) { - if (slot.status === true) return 출석; - if (slot.status === false) return 결석; - return 미정; -} - -// 주차 전체 슬롯(3개) → 코인 합산 -function weekCoinIcon(slots) { +function historyIcon(slots) { const successCount = slots.filter(s => s.status === true).length; - if (successCount >= 3) return 3회 출석; + if (successCount === 3) return 3회 출석; if (successCount === 2) return 2회 출석; if (successCount === 1) return 1회 출석; return 결석; @@ -114,34 +104,54 @@ function MemberView() { const [history, setHistory] = useState([]); useEffect(() => { - const defaultHistory = [1, 2, 3, 4, 5].map(week => ({ - week, - slots: [ - { status: null }, - { status: null }, - { status: null }, - ] - })); - - // 오늘 출석 현황 초기 fetch (새로고침 시 유지) - const today = new Date().toISOString().split('T')[0]; - authFetch(`/api/attendance/user/date?date=${today}`) - .then(r => r.json()) - .then(d => setTodaySlots(d.data || [])) - .catch(() => {}); - - authFetch('/api/attendance/user') - .then(r => r.json()) - .then(data => { - const apiData = data.data || []; - const merged = defaultHistory.map(def => { - const found = apiData.find(d => d.week === def.week); - return found || def; - }); - setHistory(merged); - }) - .catch(() => setHistory(defaultHistory)); - }, []); + const today = new Date().toISOString().split('T')[0]; + + authFetch(`/api/attendance/user/date?date=${today}`) + .then(r => r.json()) + .then(d => setTodaySlots(d.data || [])) + .catch(() => setTodaySlots([])); + + const dayOrder = ['TUESDAY', 'THURSDAY', 'SATURDAY']; + + const defaultHistory = [1, 2, 3, 4, 5].map(week => ({ + week, + days: dayOrder.map(day => ({ + day, + slots: [] + })) + })); + + authFetch('/api/attendance/user') + .then(r => r.json()) + .then(data => { + const apiData = data.data || []; + + const merged = defaultHistory.map(def => { + const foundWeek = apiData.find( + item => Number(item.week) === Number(def.week) + ); + + if (!foundWeek) return def; + + return { + week: def.week, + days: dayOrder.map(dayName => { + const foundDay = foundWeek.days?.find( + day => day.day === dayName + ); + + return { + day: dayName, + slots: foundDay?.slots || [] + }; + }) + }; + }); + + setHistory(merged); + }) + .catch(() => setHistory(defaultHistory)); +}, []); const handleSubmit = async () => { if (!inputCode.trim()) return; @@ -162,7 +172,7 @@ function MemberView() { } else if (result.statusCode === 'INVALID_CODE') { setMessage('출석 코드를 확인해주세요.'); } else { - setMessage(result.message); + setMessage(result.message); } setInputCode(''); @@ -188,22 +198,21 @@ function MemberView() { {message &&
{message}
} - {/* 오늘 출석 현황 클로버 */}
{displaySlots.map((slot, i) => (
{cloverForSlot(slot.status)}
))}
- {/* 주차별 출석 히스토리 */}
{history.map((row, i) => (
{row.week}주차
- {/* 슬롯 3개 각각 코인/화남으로 표시 */} - {row.slots.map((slot, j) => ( -
{sessionIcon(slot)}
+ {row.days.map((day) => ( +
+ {historyIcon(day.slots)} +
))}
@@ -224,4 +233,4 @@ function Attendance() { ); } -export default Attendance; \ No newline at end of file +export default Attendance;