import { Badge, Group, Pagination, Paper, Stack, Text, ThemeIcon, Timeline } from "@mantine/core"; import { useQuery } from "@tanstack/react-query"; import { ArrowLeftRight, History, MapPin, MessageSquare, Minus, Plus, TrainFront, User, } from "lucide-react"; import { useState } from "react"; import { api } from "@/services/api"; import type { TrainHistoryEntry } from "@/services/trainBuilder.service"; const PAGE_SIZE = 20; const ACTION_META: Record< TrainHistoryEntry["action"], { label: string; color: string; icon: typeof Plus } > = { ADD: { label: "Wagon attached", color: "edr-green", icon: Plus }, REMOVE: { label: "Wagon detached", color: "red", icon: Minus }, SWITCH: { label: "Wagon switched", color: "blue", icon: ArrowLeftRight }, }; /** * "History" tab of the train-builder detail page: every wagon ever attached, * detached or switched on this built train — builder edits and trip events * (real cuts, mid-route couples, consist adjustments) alike, newest first. */ export default function TrainHistoryPanel({ trainId }: { trainId: string }) { const [page, setPage] = useState(1); const historyQuery = useQuery( api.trainBuilder.history.queryOptions({ input: { id: trainId, page, pageSize: PAGE_SIZE }, enabled: Boolean(trainId), // Keep the previous page on screen while the next one loads. placeholderData: (prev) => prev, }), ); const entries = historyQuery.data?.items ?? []; const totalPages = Math.max(1, historyQuery.data?.meta.totalPages ?? 1); const total = historyQuery.data?.meta.total ?? 0; return ( Wagon history Who attached, detached or switched which wagon on this train — from the builder and from its trips — newest first, with the reason given for detaching off a scheduled run. {historyQuery.isLoading ? ( Loading history… ) : entries.length === 0 ? ( No wagon changes recorded yet for this train. ) : ( {entries.map((entry) => { const meta = ACTION_META[entry.action] ?? ACTION_META.ADD; const Icon = meta.icon; return ( } color={meta.color} title={ {meta.label} {entry.subject ? ( {entry.subject} ) : null} {entry.scheduleReference ? ( } > {entry.scheduleReference} ) : ( Builder )} } > {new Date(entry.occurredAt).toLocaleString()} {entry.yardLabel ? ( at {entry.yardLabel} ) : null} {entry.actor ? ( {entry.actor} ) : null} {entry.reason ? ( {entry.reason} ) : null} ); })} )} {totalPages > 1 ? ( {total} change(s) ) : null} ); }