mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 01:48:12 +00:00
fix
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
|||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
|
|
||||||
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
|
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
|
||||||
|
import { LastMileStepper, type LastMileStepState } from "@/components/operations/LastMileSteps";
|
||||||
import { ReceiveInventoryModal } from "@/components/warehouses/ReceiveInventoryModal";
|
import { ReceiveInventoryModal } from "@/components/warehouses/ReceiveInventoryModal";
|
||||||
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
|
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
@@ -121,6 +122,50 @@ const bookingContainerNumbers = (record: FirstMileRecord): string[] =>
|
|||||||
.map((c) => c.containerNumber)
|
.map((c) => c.containerNumber)
|
||||||
.filter((n): n is string => Boolean(n));
|
.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.
|
// Paid = record flag set OR its invoice reached PAID.
|
||||||
const isPaidRecord = (r: FirstMileRecord) =>
|
const isPaidRecord = (r: FirstMileRecord) =>
|
||||||
Boolean((r as { paid?: boolean }).paid) ||
|
Boolean((r as { paid?: boolean }).paid) ||
|
||||||
@@ -1320,6 +1365,37 @@ const FirstMilePage = () => {
|
|||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
{activeRecord && <BookingInfo record={activeRecord} />}
|
{activeRecord && <BookingInfo record={activeRecord} />}
|
||||||
|
{activeRecord && (activeRecord.vehicleAssignments?.length ?? 0) > 0 && (
|
||||||
|
<Card withBorder padding="md" radius="md">
|
||||||
|
<Text fw={600} size="sm" mb="sm">Assigned vehicles</Text>
|
||||||
|
<Stack gap="xs">
|
||||||
|
{activeRecord.vehicleAssignments!.map((a) => {
|
||||||
|
const v = a.vehicle;
|
||||||
|
const label = v
|
||||||
|
? [v.code, v.plateNumber].filter(Boolean).join(" · ")
|
||||||
|
: a.vehicleId;
|
||||||
|
return (
|
||||||
|
<Group key={a.id} justify="space-between" wrap="nowrap">
|
||||||
|
<Text size="sm">{label}</Text>
|
||||||
|
{a.containerNumber ? (
|
||||||
|
<Badge size="sm" variant="light" color="blue">
|
||||||
|
{a.containerNumber}
|
||||||
|
</Badge>
|
||||||
|
) : (
|
||||||
|
<Text size="xs" c="dimmed">No container no.</Text>
|
||||||
|
)}
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
{activeRecord && (
|
||||||
|
<Card withBorder padding="md" radius="md">
|
||||||
|
<Text fw={600} size="sm" mb="sm">Pickup steps</Text>
|
||||||
|
<LastMileStepper steps={computeFirstMileSteps(activeRecord)} />
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
<Group justify="flex-end">
|
<Group justify="flex-end">
|
||||||
<Button variant="default" onClick={() => { setDetailOpen(false); setActiveId(null); }}>Close</Button>
|
<Button variant="default" onClick={() => { setDetailOpen(false); setActiveId(null); }}>Close</Button>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
Reference in New Issue
Block a user