diff --git a/frontend/src/pages/History.jsx b/frontend/src/pages/History.jsx index de2b58c..5db64bf 100644 --- a/frontend/src/pages/History.jsx +++ b/frontend/src/pages/History.jsx @@ -1,9 +1,9 @@ -import React, { useState, useEffect, useCallback, useRef } from 'react'; +import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../context/AuthContext'; import { useToast } from '../components/Toast'; import api from '../api/axios'; -import { formatLocalDate, isSunday } from '../utils/dateUtils'; +import { formatDayHeader, formatTimeOnly, getLocalDateKey, isSunday } from '../utils/dateUtils'; import { prefixKey } from '../utils/adminPrefs'; function History() { @@ -150,6 +150,23 @@ function History() { } }; + const groupedSessions = useMemo(() => { + const groups = []; + let currentKey = null; + + sessions.forEach(session => { + const dateKey = getLocalDateKey(session.created_at); + if (dateKey !== currentKey) { + currentKey = dateKey; + groups.push({ dateKey, sessions: [session] }); + } else { + groups[groups.length - 1].sessions.push(session); + } + }); + + return groups; + }, [sessions]); + if (loading) { return (
@@ -220,109 +237,134 @@ function History() {

No sessions found

) : (
- {sessions.map(session => { - const isActive = session.is_active === 1; - const isSelected = selectedIds.has(session.id); - const isSundaySession = isSunday(session.created_at); - const isArchived = session.archived === 1; - const canSelect = selectMode && !isActive; + {groupedSessions.map((group, groupIdx) => { + const isSundayGroup = isSunday(group.sessions[0].created_at); + const isContinued = groupIdx === 0 && page > 1 && prevLastDate && + getLocalDateKey(prevLastDate) === group.dateKey; return ( -
{ - if (longPressFired.current) { - longPressFired.current = false; - return; - } - if (selectMode) { - if (!isActive) toggleSelection(session.id); - } else { - navigate(`/history/${session.id}`); - } - }} - onPointerDown={() => { - if (!isActive) handlePointerDown(session.id); - }} - onPointerUp={handlePointerUp} - onPointerLeave={handlePointerUp} - > -
-
- {selectMode && ( -
- {isSelected && ( - โœ“ - )} -
+
+ {/* Day header bar */} +
+
+ + {formatDayHeader(group.sessions[0].created_at)} + + {isContinued && ( + (continued) )} -
-
-
- - Session #{session.id} - - {isActive && ( - - Active - - )} - {isSundaySession && ( - - ๐ŸŽฒ Game Night - - )} - {isArchived && (filter === 'all' || filter === 'archived') && ( - - Archived - - )} -
- - {session.games_played} game{session.games_played !== 1 ? 's' : ''} - -
-
- {formatLocalDate(session.created_at)} - {isSundaySession && ( - ยท Sunday - )} -
- {session.has_notes && session.notes_preview && ( -
- {session.notes_preview} -
+
+ {!isContinued && ( +
+ + {group.sessions.length} session{group.sessions.length !== 1 ? 's' : ''} + + {isSundayGroup && ( + ๐ŸŽฒ Game Night )}
-
+ )}
- {!selectMode && isAuthenticated && isActive && ( -
- -
- )} + {/* Session cards under this day */} +
+ {group.sessions.map(session => { + const isActive = session.is_active === 1; + const isSelected = selectedIds.has(session.id); + const isArchived = session.archived === 1; + + return ( +
{ + if (longPressFired.current) { + longPressFired.current = false; + return; + } + if (selectMode) { + if (!isActive) toggleSelection(session.id); + } else { + navigate(`/history/${session.id}`); + } + }} + onPointerDown={() => { + if (!isActive) handlePointerDown(session.id); + }} + onPointerUp={handlePointerUp} + onPointerLeave={handlePointerUp} + > +
+
+ {selectMode && ( +
+ {isSelected && ( + โœ“ + )} +
+ )} +
+
+
+ + Session #{session.id} + + {isActive && ( + + Active + + )} + {isArchived && (filter === 'all' || filter === 'archived') && ( + + Archived + + )} +
+ + {session.games_played} game{session.games_played !== 1 ? 's' : ''} + +
+
+ {formatTimeOnly(session.created_at)} +
+ {session.has_notes && session.notes_preview && ( +
+ {session.notes_preview} +
+ )} +
+
+
+ + {!selectMode && isAuthenticated && isActive && ( +
+ +
+ )} +
+ ); + })} +
); })}