feat: rewrite History page with controls bar, multi-select, Sunday badge, and update SessionDetail with archive support
Made-with: Cursor
This commit is contained in:
@@ -4,7 +4,7 @@ import Markdown from 'react-markdown';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { useToast } from '../components/Toast';
|
||||
import api from '../api/axios';
|
||||
import { formatLocalDateTime, formatLocalTime } from '../utils/dateUtils';
|
||||
import { formatLocalDateTime, formatLocalTime, isSunday } from '../utils/dateUtils';
|
||||
import PopularityBadge from '../components/PopularityBadge';
|
||||
|
||||
function SessionDetail() {
|
||||
@@ -94,6 +94,17 @@ function SessionDetail() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleArchive = async () => {
|
||||
const action = session.archived === 1 ? 'unarchive' : 'archive';
|
||||
try {
|
||||
await api.post(`/sessions/${id}/${action}`);
|
||||
await loadSession();
|
||||
success(`Session ${action}d`);
|
||||
} catch (err) {
|
||||
showError(err.response?.data?.error || `Failed to ${action} session`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseSession = async (sessionId, notes) => {
|
||||
try {
|
||||
await api.post(`/sessions/${sessionId}/close`, { notes });
|
||||
@@ -155,6 +166,22 @@ function SessionDetail() {
|
||||
← Back to History
|
||||
</Link>
|
||||
|
||||
{session.archived === 1 && (
|
||||
<div className="bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg p-4 mb-4 flex justify-between items-center">
|
||||
<span className="text-gray-600 dark:text-gray-400 text-sm font-medium">
|
||||
This session is archived
|
||||
</span>
|
||||
{isAuthenticated && (
|
||||
<button
|
||||
onClick={handleArchive}
|
||||
className="text-sm bg-green-600 text-white px-3 py-1.5 rounded hover:bg-green-700 transition"
|
||||
>
|
||||
Unarchive
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-6">
|
||||
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-4">
|
||||
<div>
|
||||
@@ -167,9 +194,17 @@ function SessionDetail() {
|
||||
🟢 Active
|
||||
</span>
|
||||
)}
|
||||
{isSunday(session.created_at) && (
|
||||
<span className="bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
☀ Game Night
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-gray-600 dark:text-gray-400">
|
||||
{formatLocalDateTime(session.created_at)}
|
||||
{isSunday(session.created_at) && (
|
||||
<span className="text-gray-400 dark:text-gray-500"> · Sunday</span>
|
||||
)}
|
||||
{' • '}
|
||||
{session.games_played} game{session.games_played !== 1 ? 's' : ''} played
|
||||
</p>
|
||||
@@ -209,12 +244,24 @@ function SessionDetail() {
|
||||
</>
|
||||
)}
|
||||
{isAuthenticated && session.is_active === 0 && (
|
||||
<button
|
||||
onClick={() => setShowDeleteSessionConfirm(true)}
|
||||
className="bg-red-600 dark:bg-red-700 text-white px-4 py-2 rounded-lg hover:bg-red-700 dark:hover:bg-red-800 transition text-sm"
|
||||
>
|
||||
Delete Session
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
onClick={handleArchive}
|
||||
className={`${
|
||||
session.archived === 1
|
||||
? 'bg-green-600 dark:bg-green-700 hover:bg-green-700 dark:hover:bg-green-800'
|
||||
: 'bg-gray-500 dark:bg-gray-600 hover:bg-gray-600 dark:hover:bg-gray-700'
|
||||
} text-white px-4 py-2 rounded-lg transition text-sm`}
|
||||
>
|
||||
{session.archived === 1 ? 'Unarchive' : 'Archive'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowDeleteSessionConfirm(true)}
|
||||
className="bg-red-600 dark:bg-red-700 text-white px-4 py-2 rounded-lg hover:bg-red-700 dark:hover:bg-red-800 transition text-sm"
|
||||
>
|
||||
Delete Session
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user