import { Button, Group, Modal, Select, Stack, Text, TextInput } from "@mantine/core"; import { useMutation } from "@tanstack/react-query"; import { Pencil } from "lucide-react"; import { useEffect, useState } from "react"; import { exportRunFor } from "@/constants/trainRuns"; import { useToast } from "@/hooks/use-toast"; import { useImportTrainNumberOptions } from "@/hooks/useImportTrainNumberOptions"; import { api } from "@/services/api"; import type { BuiltTrainSummary } from "@/services/trainBuilder.service"; export interface EditTrainDetailsModalProps { /** Train being edited; null closes the modal. */ train: BuiltTrainSummary | null; onClose: () => void; } /** * Edit a built train's display identity from the list: its name and its fixed * import/export run numbers. The import number comes from the admin-managed * dropdown setting (numbers on other trains are disabled; this train's own * number stays pickable) and the export number follows it. Composition (yard, * locomotives, wagons) is edited on the detail page. Number collisions come * back as a 409 with the owning train's code and surface verbatim. */ const EditTrainDetailsModal = ({ train, onClose }: EditTrainDetailsModalProps) => { const { toast } = useToast(); const [name, setName] = useState(""); const [importNo, setImportNo] = useState(""); const [exportNo, setExportNo] = useState(""); const importNumbers = useImportTrainNumberOptions(train?.importTrainNumber); useEffect(() => { if (train) { setName(train.trainName ?? ""); setImportNo(train.importTrainNumber ?? ""); setExportNo(train.exportTrainNumber ?? ""); } }, [train]); const update = useMutation(api.trainBuilder.updateDetails.mutationOptions()); const handleSave = async () => { if (!train) return; try { await update.mutateAsync({ id: train.id, payload: { trainName: name.trim(), // Numbers cannot be cleared — only replaced; empty inputs keep the // current value (legacy trains may have none yet). ...(importNo.trim() ? { importTrainNumber: importNo.trim() } : {}), ...(exportNo.trim() ? { exportTrainNumber: exportNo.trim() } : {}), }, }); toast({ title: `Train ${train.code} updated` }); onClose(); } catch (err) { const message = (err as { response?: { data?: { message?: string } } })?.response?.data ?.message ?? "Update failed"; toast({ title: "Could not update train", description: String(message), variant: "destructive", }); } }; return ( Edit train {train?.code ?? ""} } centered size="md" radius="lg" > setName(e.currentTarget.value)} maxLength={100} radius="md" />