import { useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; import { api } from "@/services/api"; /** Dropdown-settings code holding the admin-managed IMPORT run numbers. */ export const IMPORT_TRAIN_NUMBERS_CODE = "import_train_numbers"; export interface ImportTrainNumberOption { value: string; label: string; disabled?: boolean; } /** * Selectable IMPORT run numbers for the Train Builder, sourced solely from the * admin-managed `import_train_numbers` dropdown setting — admins add and remove * runs from /dashboard/dropdown-settings and the pickers follow. There is no * hardcoded fallback on purpose: a missing setting must be visible (see * `settingMissing`) rather than masked by stale defaults. * * Numbers already claimed by an existing train are kept in the list but * disabled and tagged "in use". Pass `currentNumber` when editing a train so * its own number stays pickable, and so a legacy number that was removed from * the setting still renders. */ export function useImportTrainNumberOptions(currentNumber?: string | null) { const settingQuery = useQuery( api.dropdownSettings.getByCode.queryOptions({ input: { code: IMPORT_TRAIN_NUMBERS_CODE }, staleTime: 5 * 60_000, retry: false, }), ); const usedQuery = useQuery( api.trainBuilder.usedTrainNumbers.queryOptions({ staleTime: 30_000 }), ); const options = useMemo(() => { const base = [...(settingQuery.data?.children ?? [])] .filter((option) => !option.disabled) .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) .map((option) => ({ value: option.value, label: option.label || option.value, })); const used = new Set(usedQuery.data?.importTrainNumbers ?? []); if (currentNumber) used.delete(currentNumber); const items: ImportTrainNumberOption[] = base.map((option) => used.has(option.value) ? { ...option, label: `${option.label} — in use`, disabled: true } : option, ); if (currentNumber && !items.some((option) => option.value === currentNumber)) { items.unshift({ value: currentNumber, label: currentNumber }); } return items; }, [settingQuery.data, usedQuery.data, currentNumber]); const settingMissing = settingQuery.isError; return { options, isLoading: settingQuery.isLoading || usedQuery.isLoading, /** True when the dropdown setting is absent — surfaced instead of silently * falling back, so a broken config is visible rather than looking normal. */ settingMissing, emptyMessage: settingMissing ? `Dropdown setting "${IMPORT_TRAIN_NUMBERS_CODE}" is missing — create it in Dropdown Settings` : "No free run numbers — add more in Dropdown Settings", }; }