import { Form, Link, useActionData, useNavigation, useSearchParams } from "react-router"; import type { Route } from "./+types/admin.simulators"; import { Badge } from "~/components/ui/badge"; import { Button } from "~/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "~/components/ui/table"; import { listSportsSeasonSimulatorSummaries } from "~/models/simulator"; import { runSportsSeasonSimulation } from "~/services/simulations/runner"; import { Activity, CheckCircle2, Loader2, Play, SlidersHorizontal, XCircle } from "lucide-react"; export function meta(): Route.MetaDescriptors { return [{ title: "Simulators - Brackt Admin" }]; } export async function loader() { const simulators = (await listSportsSeasonSimulatorSummaries()) .filter((simulator) => simulator.seasonStatus !== "completed"); const sports = [...new Set(simulators.map((sim) => sim.sportName))].toSorted(); const simulatorTypes = [...new Set(simulators.map((sim) => sim.simulatorType))].toSorted(); return { simulators, sports, simulatorTypes }; } interface ActionData { success?: boolean; message: string; results?: Array<{ sportsSeasonId: string; ok: boolean; message: string }>; } export async function action({ request }: Route.ActionArgs): Promise { const formData = await request.formData(); const intent = formData.get("intent"); const ids = intent === "run-selected" ? formData.getAll("sportsSeasonId").filter((id): id is string => typeof id === "string") : [formData.get("sportsSeasonId")].filter((id): id is string => typeof id === "string"); if (ids.length === 0) { return { success: false, message: "Select at least one simulator to run." }; } const results: ActionData["results"] = []; for (const sportsSeasonId of ids) { try { const result = await runSportsSeasonSimulation(sportsSeasonId); results.push({ sportsSeasonId, ok: true, message: `Simulated ${result.simulatedParticipants} participant(s).`, }); } catch (error) { results.push({ sportsSeasonId, ok: false, message: error instanceof Error ? error.message : "Simulation failed.", }); } } const succeeded = results.filter((result) => result.ok).length; return { success: succeeded > 0 && succeeded === results.length, message: `Simulation run complete: ${succeeded}/${results.length} succeeded.`, results, }; } function statusBadge(status: string) { if (status === "ready") return Ready; return Needs setup; } export default function AdminSimulators({ loaderData }: Route.ComponentProps) { const { simulators, sports, simulatorTypes } = loaderData; const actionData = useActionData(); const navigation = useNavigation(); const [searchParams, setSearchParams] = useSearchParams(); const selectedSport = searchParams.get("sport") ?? "all"; const selectedType = searchParams.get("type") ?? "all"; const selectedReadiness = searchParams.get("readiness") ?? "all"; const selectedStatus = searchParams.get("status") ?? "all"; const isSubmitting = navigation.state === "submitting"; const filtered = simulators.filter((sim) => { if (selectedSport !== "all" && sim.sportName !== selectedSport) return false; if (selectedType !== "all" && sim.simulatorType !== selectedType) return false; if (selectedReadiness !== "all" && sim.readiness.status !== selectedReadiness) return false; if (selectedStatus !== "all" && sim.seasonStatus !== selectedStatus) return false; return true; }); function updateFilter(key: string, value: string) { const next = new URLSearchParams(searchParams); if (value === "all") next.delete(key); else next.set(key, value); setSearchParams(next); } return (

Simulators

Inventory, validate, and run every sports-season EV simulator from one place.

{actionData && ( {actionData.message} {actionData.results && ( {actionData.results.map((result) => (
{result.sportsSeasonId}: {result.message}
))}
)}
)} Filters {filtered.length} of {simulators.length} simulator seasons shown
Sports-Season Simulators Bulk runs execute sequentially and skip nothing silently: failures are reported per season.
Season Simulator Status Readiness Inputs Last Run Actions {filtered.map((sim) => { const canRun = sim.readiness.canRun && sim.simulationStatus !== "running"; return (
{sim.sportName} {sim.year}
{sim.seasonName}
{sim.leagueName && (
League: {sim.leagueName}
)}
{sim.simulatorName}
{sim.simulatorType}
{sim.seasonStatus} {sim.simulationStatus}
{statusBadge(sim.readiness.status)} {sim.readiness.missingInputs.length > 0 && (
Missing {sim.readiness.missingInputs.join(", ")}
)} {sim.readiness.warnings.some((warning) => warning.includes("Derived") || warning.includes("fallback")) && (
{sim.readiness.warnings .filter((warning) => warning.includes("Derived") || warning.includes("fallback")) .join(" ")}
)}
{sim.participantInputCount}/{sim.participantCount} {sim.lastSimulatedDate ?? "Never"}
); })}
); }