Add prev/next and dropdown route navigation to route detail page
Reduces navigation depth when working with route encounters by adding prev/next buttons and a route dropdown selector to AdminRouteDetail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { useParams, Link } from 'react-router-dom'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useParams, Link, useNavigate } from 'react-router-dom'
|
||||
import { AdminTable, type Column } from '../../components/admin/AdminTable'
|
||||
import { RouteEncounterFormModal } from '../../components/admin/RouteEncounterFormModal'
|
||||
import { useGame, useRoutePokemon } from '../../hooks/useGames'
|
||||
@@ -18,6 +18,7 @@ export function AdminRouteDetail() {
|
||||
const { gameId, routeId } = useParams<{ gameId: string; routeId: string }>()
|
||||
const gId = Number(gameId)
|
||||
const rId = Number(routeId)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { data: game } = useGame(gId)
|
||||
const { data: encounters = [], isLoading } = useRoutePokemon(rId, gId)
|
||||
@@ -29,7 +30,17 @@ export function AdminRouteDetail() {
|
||||
const [showCreate, setShowCreate] = useState(false)
|
||||
const [editing, setEditing] = useState<RouteEncounterDetail | null>(null)
|
||||
|
||||
const route = game?.routes?.find((r) => r.id === rId)
|
||||
const sortedRoutes = useMemo(
|
||||
() => [...(game?.routes ?? [])].sort((a, b) => a.order - b.order),
|
||||
[game?.routes],
|
||||
)
|
||||
const currentIndex = sortedRoutes.findIndex((r) => r.id === rId)
|
||||
const route = currentIndex >= 0 ? sortedRoutes[currentIndex] : undefined
|
||||
const prevRoute = currentIndex > 0 ? sortedRoutes[currentIndex - 1] : undefined
|
||||
const nextRoute =
|
||||
currentIndex >= 0 && currentIndex < sortedRoutes.length - 1
|
||||
? sortedRoutes[currentIndex + 1]
|
||||
: undefined
|
||||
|
||||
const columns: Column<RouteEncounterDetail>[] = [
|
||||
{
|
||||
@@ -65,15 +76,53 @@ export function AdminRouteDetail() {
|
||||
{game?.name ?? '...'}
|
||||
</Link>
|
||||
{' / '}
|
||||
<span className="text-gray-900 dark:text-gray-100">
|
||||
{route?.name ?? '...'}
|
||||
</span>
|
||||
<select
|
||||
className="text-gray-900 dark:text-gray-100 bg-transparent font-medium cursor-pointer hover:underline border-none p-0 text-sm"
|
||||
value={rId}
|
||||
onChange={(e) => navigate(`/admin/games/${gId}/routes/${e.target.value}`)}
|
||||
>
|
||||
{sortedRoutes.map((r) => (
|
||||
<option key={r.id} value={r.id}>
|
||||
{r.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</nav>
|
||||
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-xl font-semibold">
|
||||
{route?.name ?? 'Route'} - Pokemon ({encounters.length})
|
||||
</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
<h2 className="text-xl font-semibold">
|
||||
{route?.name ?? 'Route'} - Pokemon ({encounters.length})
|
||||
</h2>
|
||||
<div className="flex items-center gap-1 ml-2">
|
||||
{prevRoute ? (
|
||||
<Link
|
||||
to={`/admin/games/${gId}/routes/${prevRoute.id}`}
|
||||
className="px-2 py-1 text-sm rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
title={prevRoute.name}
|
||||
>
|
||||
← Prev
|
||||
</Link>
|
||||
) : (
|
||||
<span className="px-2 py-1 text-sm rounded border border-gray-200 dark:border-gray-700 text-gray-300 dark:text-gray-600 cursor-not-allowed">
|
||||
← Prev
|
||||
</span>
|
||||
)}
|
||||
{nextRoute ? (
|
||||
<Link
|
||||
to={`/admin/games/${gId}/routes/${nextRoute.id}`}
|
||||
className="px-2 py-1 text-sm rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
title={nextRoute.name}
|
||||
>
|
||||
Next →
|
||||
</Link>
|
||||
) : (
|
||||
<span className="px-2 py-1 text-sm rounded border border-gray-200 dark:border-gray-700 text-gray-300 dark:text-gray-600 cursor-not-allowed">
|
||||
Next →
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowCreate(true)}
|
||||
className="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700"
|
||||
|
||||
Reference in New Issue
Block a user