import { Center, Loader, Modal, Text, Timeline } from "@mantine/core"; import { useQuery } from "@tanstack/react-query"; import { Activity, CircleDot, Route, Truck, UserCheck, UserMinus, UserPlus, } from "lucide-react"; import { fleetHistoryService, type FleetHistoryEvent, } from "@/services/fleet-history.service"; import type { FleetRecord } from "@/services/fleet/fleet.service"; export interface FleetHistoryModalProps { opened: boolean; onClose: () => void; entity: "driver" | "vehicle"; record: FleetRecord | null; } const asObj = (r: FleetRecord | null) => (r ?? {}) as Record; const titleFor = (entity: "driver" | "vehicle", record: FleetRecord | null) => { const r = asObj(record); if (entity === "vehicle") { return `Vehicle history — ${r.plateNumber ?? r.code ?? ""}`.trim(); } return `Driver history — ${[r.firstName, r.lastName] .filter(Boolean) .join(" ")}`.trim(); }; const mileLabel = (e: FleetHistoryEvent) => e.metadata?.mile === "LAST" ? "Last-mile" : "First-mile"; const arrow = (from?: string | null, to?: string | null) => `${from ?? "—"} → ${to ?? "—"}`; const metaStr = (e: FleetHistoryEvent, key: string) => { const v = e.metadata?.[key]; return typeof v === "string" && v ? v : null; }; function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") { const vehiclePlate = metaStr(e, "vehiclePlate"); const driverName = metaStr(e, "driverName") ?? (e.label || null); const bookingRef = metaStr(e, "bookingRef"); // Compose the detail line with whatever the current view doesn't already // know: on a driver's timeline show which vehicle; always show the booking. const detail = (extra?: string) => [ entity === "driver" && vehiclePlate ? `Vehicle ${vehiclePlate}` : "", bookingRef ? `Booking ${bookingRef}` : "", extra ?? "", ] .filter(Boolean) .join(" · "); switch (e.eventType) { case "DRIVER_REGISTERED": return { icon: , title: "Driver registered", text: e.toValue ? `Status: ${e.toValue}` : "", }; case "VEHICLE_REGISTERED": return { icon: , title: "Vehicle registered", text: e.toValue ? `Availability: ${e.toValue}` : "", }; case "DRIVER_ASSIGNED": return { icon: , title: entity === "vehicle" ? "Driver assigned" : "Assigned to vehicle", text: entity === "vehicle" ? driverName ? `Driver ${driverName}` : "" : vehiclePlate ? `Vehicle ${vehiclePlate}` : "", }; case "DRIVER_UNASSIGNED": return { icon: , title: entity === "vehicle" ? "Driver unassigned" : "Unassigned from vehicle", text: entity === "vehicle" ? driverName ? `Driver ${driverName}` : "" : vehiclePlate ? `Vehicle ${vehiclePlate}` : "", }; case "VEHICLE_STATUS_CHANGED": return { icon: , title: "Status changed", text: arrow(e.fromValue, e.toValue), }; case "VEHICLE_AVAILABILITY_CHANGED": return { icon: , title: `Marked ${e.toValue ?? ""}`.trim(), text: e.fromValue ? arrow(e.fromValue, e.toValue) : "", }; case "MILE_VEHICLE_ASSIGNED": return { icon: , title: `${mileLabel(e)}: vehicle assigned`, text: detail(e.label ? `Status: ${e.label}` : ""), }; case "MILE_VEHICLE_RELEASED": return { icon: , title: `${mileLabel(e)}: vehicle released`, text: detail(), }; case "MILE_STATUS_CHANGED": return { icon: , title: `${mileLabel(e)} status`, text: detail(arrow(e.fromValue, e.toValue)), }; default: return { icon: , title: e.eventType, text: "" }; } } const fmt = (iso: string) => { const d = new Date(iso); return Number.isNaN(d.getTime()) ? iso : d.toLocaleString(); }; const FleetHistoryModal = ({ opened, onClose, entity, record, }: FleetHistoryModalProps) => { const id = asObj(record).id ? String(asObj(record).id) : ""; const { data, isLoading } = useQuery({ queryKey: ["fleet-history", entity, id], queryFn: () => entity === "vehicle" ? fleetHistoryService.vehicle(id) : fleetHistoryService.driver(id), enabled: opened && Boolean(id), }); const events = data ?? []; return ( {titleFor(entity, record)}} radius="lg" size="lg" centered > {isLoading ? (
) : events.length === 0 ? ( No history recorded yet. Activity appears here as this{" "} {entity} is assigned, reassigned, or its status changes. ) : ( {events.map((e) => { const d = describe(e, entity); return ( {d.text && ( {d.text} )} {fmt(e.createdAt)} ); })} )}
); }; export default FleetHistoryModal;