import { useMemo, useState } from 'react' import { useNavigate } from 'react-router-dom' import { GameGrid, RulesConfiguration, StepIndicator } from '../components' import { useGames, useGameRoutes } from '../hooks/useGames' import { useCreateRun, useRuns } from '../hooks/useRuns' import type { Game, NuzlockeRules } from '../types' import { DEFAULT_RULES } from '../types' import { RULE_DEFINITIONS } from '../types/rules' const DEFAULT_COLOR = '#6366f1' export function NewRun() { const navigate = useNavigate() const { data: games, isLoading, error } = useGames() const { data: runs } = useRuns() const createRun = useCreateRun() const [step, setStep] = useState(1) const [selectedGame, setSelectedGame] = useState(null) const [rules, setRules] = useState(DEFAULT_RULES) const [runName, setRunName] = useState('') const { data: routes } = useGameRoutes(selectedGame?.id ?? null) const hiddenRules = useMemo(() => { const hidden = new Set() const hasPinwheelZones = routes?.some((r) => r.pinwheelZone != null) if (!hasPinwheelZones) { hidden.add('pinwheelClause') } return hidden.size > 0 ? hidden : undefined }, [routes]) const handleGameSelect = (game: Game) => { if (selectedGame?.id === game.id) { setSelectedGame(null) return } setSelectedGame(game) if (!runName || runName === `${selectedGame?.name} Nuzlocke`) { setRunName(`${game.name} Nuzlocke`) } } const handleCreate = () => { if (!selectedGame) return createRun.mutate( { gameId: selectedGame.id, name: runName, rules }, { onSuccess: (data) => navigate(`/runs/${data.id}`) }, ) } const visibleRuleKeys = RULE_DEFINITIONS .filter((r) => !hiddenRules?.has(r.key)) .map((r) => r.key) const enabledRuleCount = visibleRuleKeys.filter((k) => rules[k]).length const totalRuleCount = visibleRuleKeys.length return (

New Nuzlocke Run

Set up your run in a few steps.

{step === 1 && (

Choose a Game

{selectedGame ? (

{selectedGame.name}

{selectedGame.region.charAt(0).toUpperCase() + selectedGame.region.slice(1)}

) : (

Select a game to continue

)}
{isLoading && (
)} {error && (
Failed to load games. Please try again.
)} {games && ( )}
)} {step === 2 && (
)} {step === 3 && (

Name Your Run

setRunName(e.target.value)} 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-blue-500 focus:border-transparent" placeholder="My Nuzlocke Run" />

Summary

Game
{selectedGame?.name}
Region
{selectedGame && (selectedGame.region.charAt(0).toUpperCase() + selectedGame.region.slice(1))}
Rules
{enabledRuleCount} of {totalRuleCount} enabled
{createRun.error && (
Failed to create run. Please try again.
)}
)}
) } function SelectedGameThumb({ game }: { game: Game }) { const [imgIdx, setImgIdx] = useState(0) const backgroundColor = game.color ?? DEFAULT_COLOR const boxArtSrcs = [`/boxart/${game.slug}.png`, `/boxart/${game.slug}.jpg`] if (imgIdx >= boxArtSrcs.length) { return (
{game.name.replace('Pokemon ', '').slice(0, 3)}
) } return ( {game.name} setImgIdx((i) => i + 1)} /> ) }