import { useState } from 'react' import type { EncounterDetail, UpdateEncounterInput } from '../types' import { useEvolutions } from '../hooks/useEncounters' interface StatusChangeModalProps { encounter: EncounterDetail onUpdate: (data: { id: number data: UpdateEncounterInput }) => void onClose: () => void isPending: boolean } const typeColors: Record = { normal: 'bg-gray-400', fire: 'bg-red-500', water: 'bg-blue-500', electric: 'bg-yellow-400', grass: 'bg-green-500', ice: 'bg-cyan-300', fighting: 'bg-red-700', poison: 'bg-purple-500', ground: 'bg-amber-600', flying: 'bg-indigo-300', psychic: 'bg-pink-500', bug: 'bg-lime-500', rock: 'bg-amber-700', ghost: 'bg-purple-700', dragon: 'bg-indigo-600', dark: 'bg-gray-700', steel: 'bg-gray-400', fairy: 'bg-pink-300', } function formatEvolutionMethod(evo: { trigger: string; minLevel: number | null; item: string | null; heldItem: string | null; condition: string | null }): string { const parts: string[] = [] if (evo.trigger === 'level-up' && evo.minLevel) { parts.push(`Level ${evo.minLevel}`) } else if (evo.trigger === 'level-up') { parts.push('Level up') } else if (evo.trigger === 'use-item' && evo.item) { parts.push(evo.item.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())) } else if (evo.trigger === 'trade') { parts.push('Trade') } else { parts.push(evo.trigger.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())) } if (evo.heldItem) { parts.push(`holding ${evo.heldItem.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}`) } if (evo.condition) { parts.push(evo.condition) } return parts.join(', ') } export function StatusChangeModal({ encounter, onUpdate, onClose, isPending, }: StatusChangeModalProps) { const { pokemon, currentPokemon, route, nickname, catchLevel, faintLevel, deathCause } = encounter const isDead = faintLevel !== null const displayPokemon = currentPokemon ?? pokemon const [showConfirm, setShowConfirm] = useState(false) const [showEvolve, setShowEvolve] = useState(false) const [deathLevel, setDeathLevel] = useState('') const [cause, setCause] = useState('') const activePokemonId = currentPokemon?.id ?? pokemon.id const { data: evolutions, isLoading: evolutionsLoading } = useEvolutions( showEvolve ? activePokemonId : null ) const handleConfirmDeath = () => { onUpdate({ id: encounter.id, data: { faintLevel: deathLevel ? Number(deathLevel) : undefined, deathCause: cause || undefined, }, }) } const handleEvolve = (toPokemonId: number) => { onUpdate({ id: encounter.id, data: { currentPokemonId: toPokemonId }, }) } return (
{/* Header */}

{isDead ? 'Death Details' : 'Pokemon Status'}

{/* Pokemon info */}
{displayPokemon.spriteUrl ? ( {displayPokemon.name} ) : (
{displayPokemon.name[0].toUpperCase()}
)}
{nickname || displayPokemon.name}
{nickname && (
{displayPokemon.name}
)}
{displayPokemon.types.map((type) => ( {type} ))}
Lv. {catchLevel ?? '?'} · {route.name}
{currentPokemon && (
Originally: {pokemon.name}
)}
{/* Dead pokemon: view-only details */} {isDead && (
Deceased
{faintLevel !== null && (
Level at death: {' '} {faintLevel}
)} {deathCause && (
Cause: {' '} {deathCause}
)}
)} {/* Alive pokemon: actions */} {!isDead && !showConfirm && !showEvolve && (
)} {/* Evolution selection */} {!isDead && showEvolve && (

Evolve into:

{evolutionsLoading && (

Loading evolutions...

)} {!evolutionsLoading && evolutions && evolutions.length === 0 && (

No evolutions available

)} {!evolutionsLoading && evolutions && evolutions.length > 0 && (
{evolutions.map((evo) => ( ))}
)}
)} {/* Confirmation form */} {!isDead && showConfirm && (

This cannot be undone (Nuzlocke rules).

setDeathLevel(e.target.value)} placeholder="Level" className="w-24 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-red-500" />
setCause(e.target.value)} placeholder="e.g. Crit from rival's Charizard" className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-red-500" />
)}
{/* Footer for dead/no-confirm/no-evolve views */} {(isDead || (!isDead && !showConfirm && !showEvolve)) && (
)}
) }