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 { RouteFormModal } from '../../components/admin/RouteFormModal' import { DeleteConfirmModal } from '../../components/admin/DeleteConfirmModal' import { useGame, useRoutePokemon } from '../../hooks/useGames' import { useAddRouteEncounter, useUpdateRouteEncounter, useRemoveRouteEncounter, useCreateRoute, useDeleteRoute, } from '../../hooks/useAdmin' import type { Route, RouteEncounterDetail, CreateRouteEncounterInput, UpdateRouteEncounterInput, CreateRouteInput, } from '../../types' 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) const addEncounter = useAddRouteEncounter(rId) const updateEncounter = useUpdateRouteEncounter(rId) const removeEncounter = useRemoveRouteEncounter(rId) const createRoute = useCreateRoute(gId) const deleteRoute = useDeleteRoute(gId) const [showCreate, setShowCreate] = useState(false) const [editing, setEditing] = useState(null) const [showCreateChild, setShowCreateChild] = useState(false) const [deletingChild, setDeletingChild] = useState(null) 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 childRoutes = useMemo( () => (game?.routes ?? []).filter((r) => r.parentRouteId === rId).sort((a, b) => a.order - b.order), [game?.routes, rId] ) const nextChildOrder = childRoutes.length > 0 ? Math.max(...childRoutes.map((r) => r.order)) + 1 : (route?.order ?? 0) * 10 + 1 const hasConditions = encounters.some((e) => e.condition !== '') const columns: Column[] = [ { header: 'Pokemon', accessor: (e) => (
{e.pokemon.spriteUrl ? ( {e.pokemon.name} ) : null} #{e.pokemon.nationalDex} {e.pokemon.name}
), }, { header: 'Method', accessor: (e) => e.encounterMethod }, { header: 'Rate', accessor: (e) => `${e.encounterRate}%` }, ...(hasConditions ? [ { header: 'Condition', accessor: (e: RouteEncounterDetail) => e.condition || '\u2014', } as Column, ] : []), { header: 'Levels', accessor: (e) => e.minLevel === e.maxLevel ? `Lv ${e.minLevel}` : `Lv ${e.minLevel}-${e.maxLevel}`, }, ] return (

{route?.name ?? 'Route'} - Pokemon ({encounters.length})

{prevRoute ? ( ← Prev ) : ( ← Prev )} {nextRoute ? ( Next → ) : ( Next → )}
e.id} onRowClick={(e) => setEditing(e)} /> {showCreate && ( addEncounter.mutate({ ...data, gameId: gId } as CreateRouteEncounterInput, { onSuccess: () => setShowCreate(false), }) } onClose={() => setShowCreate(false)} isSubmitting={addEncounter.isPending} /> )} {editing && ( updateEncounter.mutate( { encounterId: editing.id, data: data as UpdateRouteEncounterInput, }, { onSuccess: () => setEditing(null) } ) } onClose={() => setEditing(null)} isSubmitting={updateEncounter.isPending} onDelete={() => removeEncounter.mutate(editing.id, { onSuccess: () => setEditing(null), }) } isDeleting={removeEncounter.isPending} /> )} {/* Sub-areas */}

Sub-areas ({childRoutes.length})

{childRoutes.length === 0 ? (

No sub-areas for this route.

) : (
{childRoutes.map((child) => (
{child.name}
))}
)}
{showCreateChild && ( createRoute.mutate({ ...data, parentRouteId: rId } as CreateRouteInput, { onSuccess: () => setShowCreateChild(false), }) } onClose={() => setShowCreateChild(false)} isSubmitting={createRoute.isPending} /> )} {deletingChild && ( deleteRoute.mutate(deletingChild.id, { onSuccess: () => setDeletingChild(null), }) } onCancel={() => setDeletingChild(null)} isDeleting={deleteRoute.isPending} /> )}
) }