From 28ad9363d1ad6e0ccae68c9416ca181c79cf58e4 Mon Sep 17 00:00:00 2001 From: Marshal Date: Mon, 15 Jun 2026 12:01:44 +0000 Subject: [PATCH] tracking ui --- .../TrainScheduleTrackPage.tsx | 292 +++++++++++------- .../backoffice/user-management | 1 - 2 files changed, 180 insertions(+), 113 deletions(-) delete mode 160000 apps/edr-freight-web/backoffice/user-management diff --git a/apps/edr-freight-web/backoffice/src/pages/trainScheduling/TrainScheduleTrackPage.tsx b/apps/edr-freight-web/backoffice/src/pages/trainScheduling/TrainScheduleTrackPage.tsx index 2091d091c..6f85b82d6 100644 --- a/apps/edr-freight-web/backoffice/src/pages/trainScheduling/TrainScheduleTrackPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/trainScheduling/TrainScheduleTrackPage.tsx @@ -16,7 +16,7 @@ import { Group, Loader, Paper, - SimpleGrid, + Progress, Stack, Text, ThemeIcon, @@ -25,12 +25,8 @@ import { } from "@mantine/core"; import { RouteCorridorTrack } from "@/components/trainScheduling/RouteCorridorTrack"; -import { - RouteCorridor, - StatTile, - StatusPill, - scheduleBrand, -} from "@/components/trainScheduling/scheduleVisuals"; +import { RouteCorridor, StatusPill } from "@/components/trainScheduling/scheduleVisuals"; +import { freightBrand } from "@/theme/freight-brand"; import { useTrainTrack, useScheduleMutations } from "@/hooks/trainScheduling/useTrainScheduling"; import { useToast } from "@/hooks/use-toast"; @@ -54,6 +50,33 @@ function formatDateTime(iso?: string | null) { }); } +/** Compact icon + label + value cell used in the header meta strip. */ +function MetaStat({ + icon, + label, + value, +}: { + icon: React.ReactNode; + label: string; + value: string; +}) { + return ( + + + {icon} + + + + {label} + + + {value} + + + + ); +} + export default function TrainScheduleTrackPage() { const { scheduleId } = useParams<{ scheduleId: string }>(); const { toast } = useToast(); @@ -63,7 +86,7 @@ export default function TrainScheduleTrackPage() { if (trackQuery.isLoading) { return ( - + ); } @@ -80,7 +103,9 @@ export default function TrainScheduleTrackPage() { const canLog = track.status === "DISPATCHED"; const totalStations = track.stations.length; const reached = Math.min(track.currentSequenceNo + 1, totalStations); - const progressLabel = `${reached} / ${totalStations}`; + const progressPct = totalStations > 1 ? (track.currentSequenceNo / (totalStations - 1)) * 100 : 0; + const clampedPct = Math.min(100, Math.max(0, progressPct)); + const currentStation = track.stations[Math.max(0, track.currentSequenceNo)]?.label ?? "—"; const handleLog = (sequenceNo: number) => { const isFinal = sequenceNo === track.stations[totalStations - 1]?.sequenceNo; @@ -105,7 +130,7 @@ export default function TrainScheduleTrackPage() { }; return ( - +