From cac6e4eaa1da19ddd4a5c52ec8838b3a475be1fc Mon Sep 17 00:00:00 2001 From: natib21 Date: Sat, 4 Jul 2026 02:07:31 +0000 Subject: [PATCH] fix --- .../src/pages/operations/FirstMilePage.tsx | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx b/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx index efc3af7ca..c3dac97d8 100644 --- a/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx @@ -40,6 +40,7 @@ import { } from "@mantine/core"; import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles"; +import { LastMileStepper, type LastMileStepState } from "@/components/operations/LastMileSteps"; import { ReceiveInventoryModal } from "@/components/warehouses/ReceiveInventoryModal"; import { QUERY_KEYS } from "@/constants/QUERY_KEYS"; import { useToast } from "@/hooks/use-toast"; @@ -121,6 +122,50 @@ const bookingContainerNumbers = (record: FirstMileRecord): string[] => .map((c) => c.containerNumber) .filter((n): n is string => Boolean(n)); +/** Progress stages of the first-mile pickup workflow, for the detail stepper. */ +const computeFirstMileSteps = (record: FirstMileRecord): LastMileStepState[] => { + const exactKm = record.exactKm; + const inTransitOrPast = + record.status === "IN_TRANSIT" || record.status === "RECEIVED_TO_PORT"; + const flags = [ + record.status !== "PAYMENT_PENDING", // Ready to Transit + isAssigned(record), // Assign vehicle + inTransitOrPast, // In transit + exactKm != null, // Add distance + Boolean(record.invoice), // Generate Invoice + record.status === "RECEIVED_TO_PORT",// Received to port + ]; + // Current step = earliest incomplete one. + const activeIdx = flags.findIndex((f) => !f); + const labels = [ + "Ready to Transit", + "Assign vehicle", + "In transit", + "Add distance", + "Generate Invoice", + "Received to port", + ]; + const vehCount = record.vehicleAssignments?.length ?? (record.vehicleId ? 1 : 0); + const primaryPlate = + record.vehicle?.plateNumber ?? + record.vehicleAssignments?.[0]?.vehicle?.plateNumber ?? + null; + const details: (string | null)[] = [ + null, + vehCount > 1 ? `${vehCount} vehicles` : primaryPlate, + null, + exactKm != null ? `${exactKm} KM` : null, + record.invoice?.number ?? null, + null, + ]; + return labels.map((label, i) => ({ + label, + done: flags[i], + active: i === activeIdx, + detail: details[i], + })); +}; + // Paid = record flag set OR its invoice reached PAID. const isPaidRecord = (r: FirstMileRecord) => Boolean((r as { paid?: boolean }).paid) || @@ -1320,6 +1365,37 @@ const FirstMilePage = () => { > {activeRecord && } + {activeRecord && (activeRecord.vehicleAssignments?.length ?? 0) > 0 && ( + + Assigned vehicles + + {activeRecord.vehicleAssignments!.map((a) => { + const v = a.vehicle; + const label = v + ? [v.code, v.plateNumber].filter(Boolean).join(" ยท ") + : a.vehicleId; + return ( + + {label} + {a.containerNumber ? ( + + {a.containerNumber} + + ) : ( + No container no. + )} + + ); + })} + + + )} + {activeRecord && ( + + Pickup steps + + + )}