This commit is contained in:
natib21
2026-07-03 16:34:06 +00:00
parent 8661586301
commit e02cb52e19
2 changed files with 164 additions and 0 deletions

View File

@@ -49,6 +49,7 @@ import { driversService, type Driver } from "@/services/drivers.service";
import { ratesService } from "@/services/rates.service";
import { LastMileContainerAllocationTable, type LastMileContainerRow } from "@/components/LastMileContainerAllocationTable";
import { ReleaseOrderModal, type ReleaseOrderTruckPrefill } from "@/components/warehouses/ReleaseOrderModal";
import { LastMileStepBar, LastMileStepper, type LastMileStepState } from "@/components/operations/LastMileSteps";
import { api } from "@/auth/http";
const formatPrice = (amount: number) =>
@@ -92,6 +93,50 @@ const vehicleLabel = (record: LastMileRecord) => {
const isAssigned = (record: LastMileRecord) => Boolean(record.vehicleId);
const fmtStamp = (iso?: string | null) => {
if (!iso) return null;
const d = new Date(iso);
return Number.isNaN(d.getTime()) ? null : d.toLocaleString();
};
/**
* Derive the 6-step last-mile workflow state for a record. Step completion is
* read from the record + its pickup-ready (warehouse release) row:
* assign→vehicleId, arrived→release order issued, leave→releaseDate,
* in-transit/delivered→status, distance→exactKm.
*/
const computeLastMileSteps = (
record: LastMileRecord,
releaseRow?: ImportUnloadedItem,
): LastMileStepState[] => {
const exactKm = (record as { exactKm?: number | null }).exactKm;
const flags = [
Boolean(record.vehicleId),
Boolean(releaseRow?.releaseOrderReference),
Boolean(releaseRow?.releaseDate),
record.status === "IN_TRANSIT" || record.status === "DELIVERED",
exactKm != null,
record.status === "DELIVERED",
];
// Current step = earliest incomplete one.
const activeIdx = flags.findIndex((f) => !f);
const labels = ["Assign vehicle", "Truck arrived", "Truck leave", "In transit", "Add distance", "Delivered"];
const details: (string | null)[] = [
record.vehicle?.plateNumber ?? null,
releaseRow?.releaseOrderReference ?? null,
fmtStamp(releaseRow?.releaseDate),
null,
exactKm != null ? `${exactKm} KM` : null,
fmtStamp(releaseRow?.deliveredAt),
];
return labels.map((label, i) => ({
label,
done: flags[i],
active: i === activeIdx,
detail: details[i],
}));
};
const bookingRef = (r: LastMileRecord) => r.booking?.reference ?? r.bookingId;
const customerName = (r: LastMileRecord) => r.booking?.company?.name ?? "—";
const deliveryLocation = (r: LastMileRecord) => r.booking?.lastMileDeliveryAddress ?? "—";
@@ -943,6 +988,20 @@ const LastMilePage = () => {
</Badge>
),
},
{
id: "progress",
header: "Progress",
meta: { headerClassName, cellClassName },
cell: ({ row }) => (
<LastMileStepBar
steps={computeLastMileSteps(
row.original,
pickupReadyByBooking.get(row.original.bookingId) ??
pickupReadyByBooking.get(bookingRef(row.original)),
)}
/>
),
},
{
id: "actions",
header: "Actions",
@@ -1324,6 +1383,18 @@ const LastMilePage = () => {
>
<Stack gap="md">
{activeRecord && <BookingInfo record={activeRecord} />}
{activeRecord && (
<Card withBorder padding="md" radius="md">
<Text fw={600} size="sm" mb="sm">Delivery steps</Text>
<LastMileStepper
steps={computeLastMileSteps(
activeRecord,
pickupReadyByBooking.get(activeRecord.bookingId) ??
pickupReadyByBooking.get(bookingRef(activeRecord)),
)}
/>
</Card>
)}
<Group justify="flex-end">
<Button variant="default" onClick={() => { setDetailOpen(false); setActiveId(null); }}>Close</Button>
</Group>