import { Badge, Button, Checkbox, Group, Pagination, Paper, Stack, Table, Text, ThemeIcon, Tooltip, } from "@mantine/core"; import { useQuery } from "@tanstack/react-query"; import { Link2, MapPin, PackageOpen, User } from "lucide-react"; import { useState } from "react"; import { api } from "@/services/api"; interface Props { trainId: string; /** Staff may attach and the train is editable (not out on a run). */ canAttach: boolean; attachPending: boolean; onAttach: (wagonIds: string[]) => void; } /** * "Detached wagons" tab: wagons last detached from THIS train that are still * loose — with when, where and by whom they were detached — so staff can pick * them straight back onto the consist without hunting through the global pool. */ export default function DetachedWagonsPanel({ trainId, canAttach, attachPending, onAttach, }: Props) { const [page, setPage] = useState(1); const query = useQuery( api.trainBuilder.detachedWagons.queryOptions({ input: { id: trainId, page, pageSize: 20 }, enabled: Boolean(trainId), // Keep the previous page on screen while the next one loads. placeholderData: (prev) => prev, }), ); const rows = query.data?.items ?? []; const totalPages = Math.max(1, query.data?.meta.totalPages ?? 1); // Selection is page-scoped in the header checkbox but survives paging, so // staff can gather wagons across pages into one attach. const [selected, setSelected] = useState>(new Set()); const allSelected = rows.length > 0 && rows.every((r) => selected.has(r.wagonId)); const toggle = (wagonId: string, checked: boolean) => setSelected((prev) => { const next = new Set(prev); if (checked) next.add(wagonId); else next.delete(wagonId); return next; }); return ( Detached wagons Wagons that left this train and are still loose — select and attach them back in one click. {canAttach ? ( ) : null} {query.isLoading ? ( Loading detached wagons… ) : rows.length === 0 ? ( No loose wagons were detached from this train — detach history starts being recorded from now on. ) : ( {canAttach ? ( 0 && !allSelected} onChange={(e) => setSelected( e.currentTarget.checked ? new Set(rows.map((r) => r.wagonId)) : new Set(), ) } /> ) : null} Wagon Type Now standing at Last detached {rows.map((r) => ( {canAttach ? ( toggle(r.wagonId, e.currentTarget.checked)} /> ) : null} {r.wagonNumber} {r.wagonTypeCode ?? "—"} {r.currentYardLabel ?? "No yard"} {new Date(r.detachedAt).toLocaleDateString()} {r.detachedYardLabel ? ( at {r.detachedYardLabel} ) : null} {r.detachedBy ? ( by {r.detachedBy} ) : null} ))}
)} {totalPages > 1 ? ( {query.data?.meta.total ?? 0} wagon(s) · selection carries across pages ) : null}
); }