Add click-to-edit pattern across all admin tables

Replace Actions columns with clickable rows that open edit modals
directly. Delete is now an inline two-step confirm button in the
edit modal footer. Games modal links to routes/bosses detail,
route modal links to encounters, and boss modal has an Edit Team button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 13:44:38 +01:00
parent 76d69dfaf1
commit f09b8213fd
14 changed files with 145 additions and 228 deletions

View File

@@ -2,7 +2,6 @@ import { useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import { AdminTable, type Column } from '../../components/admin/AdminTable'
import { RouteEncounterFormModal } from '../../components/admin/RouteEncounterFormModal'
import { DeleteConfirmModal } from '../../components/admin/DeleteConfirmModal'
import { useGame, useRoutePokemon } from '../../hooks/useGames'
import {
useAddRouteEncounter,
@@ -29,7 +28,6 @@ export function AdminRouteDetail() {
const [showCreate, setShowCreate] = useState(false)
const [editing, setEditing] = useState<RouteEncounterDetail | null>(null)
const [deleting, setDeleting] = useState<RouteEncounterDetail | null>(null)
const route = game?.routes?.find((r) => r.id === rId)
@@ -54,25 +52,6 @@ export function AdminRouteDetail() {
accessor: (e) =>
e.minLevel === e.maxLevel ? `Lv ${e.minLevel}` : `Lv ${e.minLevel}-${e.maxLevel}`,
},
{
header: 'Actions',
accessor: (e) => (
<div className="flex gap-2">
<button
onClick={() => setEditing(e)}
className="text-blue-600 hover:text-blue-800 dark:text-blue-400 text-sm"
>
Edit
</button>
<button
onClick={() => setDeleting(e)}
className="text-red-600 hover:text-red-800 dark:text-red-400 text-sm"
>
Remove
</button>
</div>
),
},
]
return (
@@ -109,6 +88,7 @@ export function AdminRouteDetail() {
isLoading={isLoading}
emptyMessage="No pokemon assigned to this route yet."
keyFn={(e) => e.id}
onRowClick={(e) => setEditing(e)}
/>
{showCreate && (
@@ -134,19 +114,11 @@ export function AdminRouteDetail() {
}
onClose={() => setEditing(null)}
isSubmitting={updateEncounter.isPending}
/>
)}
{deleting && (
<DeleteConfirmModal
title={`Remove ${deleting.pokemon.name}?`}
message="This will remove this pokemon from the route's encounter table."
onConfirm={() =>
removeEncounter.mutate(deleting.id, {
onSuccess: () => setDeleting(null),
onDelete={() =>
removeEncounter.mutate(editing.id, {
onSuccess: () => setEditing(null),
})
}
onCancel={() => setDeleting(null)}
isDeleting={removeEncounter.isPending}
/>
)}