From 3b87397432e9d6c15801b4add945eeaee2864604 Mon Sep 17 00:00:00 2001 From: Julian Tabel Date: Sun, 8 Feb 2026 10:54:47 +0100 Subject: [PATCH] Add run management screen to admin panel Co-Authored-By: Claude Opus 4.6 --- ...5wsn--add-run-management-to-admin-panel.md | 11 +++ ...le62--add-run-management-to-admin-panel.md | 5 +- ...ker-w7o6--improve-run-creation-workflow.md | 5 +- frontend/src/App.tsx | 2 + frontend/src/components/admin/AdminLayout.tsx | 1 + frontend/src/pages/admin/AdminRuns.tsx | 93 +++++++++++++++++++ frontend/src/pages/admin/index.ts | 1 + 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 .beans/nuzlocke-tracker-5wsn--add-run-management-to-admin-panel.md create mode 100644 frontend/src/pages/admin/AdminRuns.tsx diff --git a/.beans/nuzlocke-tracker-5wsn--add-run-management-to-admin-panel.md b/.beans/nuzlocke-tracker-5wsn--add-run-management-to-admin-panel.md new file mode 100644 index 0000000..e2c5a9a --- /dev/null +++ b/.beans/nuzlocke-tracker-5wsn--add-run-management-to-admin-panel.md @@ -0,0 +1,11 @@ +--- +# nuzlocke-tracker-5wsn +title: Add run management to admin panel +status: completed +type: feature +priority: normal +created_at: 2026-02-08T09:53:01Z +updated_at: 2026-02-08T09:53:25Z +--- + +Create AdminRuns page with table listing all runs (name, game, status, started date) with delete functionality. Wire it into routing and admin navigation. \ No newline at end of file diff --git a/.beans/nuzlocke-tracker-le62--add-run-management-to-admin-panel.md b/.beans/nuzlocke-tracker-le62--add-run-management-to-admin-panel.md index 0ffae0b..13d4e3f 100644 --- a/.beans/nuzlocke-tracker-le62--add-run-management-to-admin-panel.md +++ b/.beans/nuzlocke-tracker-le62--add-run-management-to-admin-panel.md @@ -1,10 +1,11 @@ --- # nuzlocke-tracker-le62 title: Add run management to admin panel -status: todo +status: completed type: feature +priority: normal created_at: 2026-02-07T21:09:13Z -updated_at: 2026-02-07T21:09:13Z +updated_at: 2026-02-08T09:54:13Z --- Add a runs screen to the admin panel that lists all runs and allows deletion. This provides a way to clean up test runs or remove unwanted runs without needing direct database access. \ No newline at end of file diff --git a/.beans/nuzlocke-tracker-w7o6--improve-run-creation-workflow.md b/.beans/nuzlocke-tracker-w7o6--improve-run-creation-workflow.md index cd9d4d3..3b067df 100644 --- a/.beans/nuzlocke-tracker-w7o6--improve-run-creation-workflow.md +++ b/.beans/nuzlocke-tracker-w7o6--improve-run-creation-workflow.md @@ -1,10 +1,11 @@ --- # nuzlocke-tracker-w7o6 title: Improve Run Creation Workflow -status: draft +status: completed type: feature +priority: normal created_at: 2026-02-07T20:20:51Z -updated_at: 2026-02-07T20:20:51Z +updated_at: 2026-02-08T09:54:24Z --- Improve the run creation flow with better game filtering, box art display, and UX fixes. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b1fe61e..bb0c4bc 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -8,6 +8,7 @@ import { AdminPokemon, AdminRouteDetail, AdminEvolutions, + AdminRuns, } from './pages/admin' function App() { @@ -27,6 +28,7 @@ function App() { } /> } /> } /> + } /> diff --git a/frontend/src/components/admin/AdminLayout.tsx b/frontend/src/components/admin/AdminLayout.tsx index af99ee5..0c55532 100644 --- a/frontend/src/components/admin/AdminLayout.tsx +++ b/frontend/src/components/admin/AdminLayout.tsx @@ -4,6 +4,7 @@ const navItems = [ { to: '/admin/games', label: 'Games' }, { to: '/admin/pokemon', label: 'Pokemon' }, { to: '/admin/evolutions', label: 'Evolutions' }, + { to: '/admin/runs', label: 'Runs' }, ] export function AdminLayout() { diff --git a/frontend/src/pages/admin/AdminRuns.tsx b/frontend/src/pages/admin/AdminRuns.tsx new file mode 100644 index 0000000..c9fc4ab --- /dev/null +++ b/frontend/src/pages/admin/AdminRuns.tsx @@ -0,0 +1,93 @@ +import { useState, useMemo } from 'react' +import { AdminTable, type Column } from '../../components/admin/AdminTable' +import { DeleteConfirmModal } from '../../components/admin/DeleteConfirmModal' +import { useRuns, useDeleteRun } from '../../hooks/useRuns' +import { useGames } from '../../hooks/useGames' +import type { NuzlockeRun } from '../../types/game' + +export function AdminRuns() { + const { data: runs = [], isLoading: runsLoading } = useRuns() + const { data: games = [], isLoading: gamesLoading } = useGames() + const deleteRun = useDeleteRun() + + const [deleting, setDeleting] = useState(null) + + const gameMap = useMemo( + () => new Map(games.map((g) => [g.id, g.name])), + [games], + ) + + const columns: Column[] = [ + { header: 'Run Name', accessor: (r) => r.name, sortKey: (r) => r.name }, + { + header: 'Game', + accessor: (r) => gameMap.get(r.gameId) ?? `Game #${r.gameId}`, + sortKey: (r) => gameMap.get(r.gameId) ?? '', + }, + { + header: 'Status', + accessor: (r) => ( + + {r.status} + + ), + sortKey: (r) => r.status, + }, + { + header: 'Started', + accessor: (r) => new Date(r.startedAt).toLocaleDateString(), + sortKey: (r) => r.startedAt, + }, + { + header: 'Actions', + accessor: (r) => ( +
e.stopPropagation()}> + +
+ ), + }, + ] + + return ( +
+
+

Runs

+
+ + r.id} + /> + + {deleting && ( + + deleteRun.mutate(deleting.id, { + onSuccess: () => setDeleting(null), + }) + } + onCancel={() => setDeleting(null)} + isDeleting={deleteRun.isPending} + /> + )} +
+ ) +} diff --git a/frontend/src/pages/admin/index.ts b/frontend/src/pages/admin/index.ts index 952af14..6779596 100644 --- a/frontend/src/pages/admin/index.ts +++ b/frontend/src/pages/admin/index.ts @@ -3,3 +3,4 @@ export { AdminGameDetail } from './AdminGameDetail' export { AdminPokemon } from './AdminPokemon' export { AdminRouteDetail } from './AdminRouteDetail' export { AdminEvolutions } from './AdminEvolutions' +export { AdminRuns } from './AdminRuns'