From 5cc025bfd314e789830d43db0c5ad4b0658c11bb Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Mon, 11 May 2026 22:49:00 -0700 Subject: [PATCH] Move registry calls from component to loader in admin.sports.$id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SIMULATOR_TYPES and getSimulatorInfo were used directly in the component body to build the simulator type dropdown. This dragged registry.ts — which imports every simulator implementation — into the client bundle, causing a TDZ ReferenceError that broke any route co-loaded with it (observed as "Error loading route module" on admin events pages). Fix: pre-build simulatorOptions in the loader and pass them as plain serializable data. The registry imports remain for the action's validator but are now only reachable from server-only code. Co-Authored-By: Claude Sonnet 4.6 --- app/routes/admin.sports.$id.tsx | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/routes/admin.sports.$id.tsx b/app/routes/admin.sports.$id.tsx index e98813a..e029541 100644 --- a/app/routes/admin.sports.$id.tsx +++ b/app/routes/admin.sports.$id.tsx @@ -34,8 +34,17 @@ export async function loader({ params }: Route.LoaderArgs) { const sports = await findAllSports(); + const simulatorOptions = [...SIMULATOR_TYPES] + .toSorted((a, b) => { + const nameA = getSimulatorInfo(a)?.name ?? a; + const nameB = getSimulatorInfo(b)?.name ?? b; + return nameA.localeCompare(nameB); + }) + .map((type) => ({ value: type, label: getSimulatorInfo(type)?.name ?? type })); + return { sport, + simulatorOptions, existingIconOptions: sports .filter((option) => option.id !== sport.id && Boolean(option.iconUrl)) .map((option) => ({ id: option.id, name: option.name, iconUrl: option.iconUrl as string })), @@ -116,7 +125,7 @@ export async function action({ request, params }: Route.ActionArgs) { } export default function EditSport({ loaderData, actionData }: Route.ComponentProps) { - const { sport, existingIconOptions } = loaderData; + const { sport, simulatorOptions, existingIconOptions } = loaderData; return (
@@ -185,17 +194,11 @@ export default function EditSport({ loaderData, actionData }: Route.ComponentPro className={SELECT_CLASS} > - {[...SIMULATOR_TYPES] - .toSorted((a, b) => { - const nameA = getSimulatorInfo(a)?.name ?? a; - const nameB = getSimulatorInfo(b)?.name ?? b; - return nameA.localeCompare(nameB); - }) - .map((type) => ( - - ))} + {simulatorOptions.map((option) => ( + + ))}

Algorithm used when running EV simulations for this sport