Merge branch 'dev' into freight/feat/fixes-v1

This commit is contained in:
Nathnael
2026-07-10 12:22:41 +00:00
41 changed files with 3067 additions and 677 deletions

View File

@@ -38,6 +38,7 @@ import {
MapPin,
Package,
Receipt,
Repeat,
X,
} from "lucide-react";
import type { Freight } from "@edr/types";
@@ -192,9 +193,19 @@ export default function GlCreateBookingForm() {
const [notes, setNotes] = useState("");
const [containerLines, setContainerLines] = useState<ContainerLineDraft[]>([]);
const [bulkLines, setBulkLines] = useState<BulkLineDraft[]>([]);
const [withReturn, setWithReturn] = useState(false);
const [prefilled, setPrefilled] = useState(false);
const [priceOpen, setPriceOpen] = useState(false);
const seededRef = useRef(false);
const returnSeededRef = useRef(false);
// Seed the equipment-return toggle from the contract exactly once (also when
// the form is prefilled from a shipment request); GL can flip it per shipment.
useEffect(() => {
if (!contract || returnSeededRef.current) return;
returnSeededRef.current = true;
setWithReturn(contract.equipmentReturn === "WITH_RETURN");
}, [contract]);
const isContainer = contract?.freightType === "CONTAINER";
const routes = useMemo(
@@ -527,6 +538,10 @@ export default function GlCreateBookingForm() {
scheduledDate,
...(contractRouteId ? { contractRouteId } : {}),
...(notes.trim() ? { notes: notes.trim() } : {}),
// Equipment return is a container concern — bulk keeps the contract default.
...(isContainer
? { equipmentReturn: withReturn ? "WITH_RETURN" : "WITHOUT_RETURN" }
: {}),
};
if (isContainer) {
@@ -1091,6 +1106,67 @@ export default function GlCreateBookingForm() {
</StepCard>
)}
{isContainer ? (
<StepCard>
<StepHeader
icon={<Repeat size={22} />}
title="Equipment Return"
description="Choose whether the empty container(s) come back to EDR after unloading."
/>
<Paper
withBorder
radius="md"
p="md"
style={{
borderColor: withReturn ? "#CDEBDD" : "#E6ECF2",
background: withReturn ? "#F6FBF8" : "white",
cursor: "pointer",
transition: "border-color 150ms ease, background 150ms ease",
}}
onClick={() => setWithReturn((v) => !v)}
>
<Group justify="space-between" wrap="nowrap" gap="md">
<Group gap={13} wrap="nowrap" align="flex-start">
<Box
style={{
width: 38,
height: 38,
flexShrink: 0,
borderRadius: 11,
display: "flex",
alignItems: "center",
justifyContent: "center",
background: withReturn ? "#ECF6F1" : "#F1F4F7",
color: withReturn ? "#0A6F4D" : "#6B7C8E",
}}
>
<Repeat size={18} />
</Box>
<Box>
<Text fz={14} fw={700}>
With return
</Text>
<Text fz={12} c="dimmed" style={{ lineHeight: 1.4 }}>
{withReturn
? "Container(s) returned to EDR after unloading."
: "Container(s) retained by the customer after delivery."}
</Text>
</Box>
</Group>
<Switch
size="md"
color="edr-green"
aria-label="With return"
checked={withReturn}
onChange={(e) => setWithReturn(e.currentTarget.checked)}
onClick={(e) => e.stopPropagation()}
style={{ flexShrink: 0 }}
/>
</Group>
</Paper>
</StepCard>
) : null}
<StepCard>
<StepHeader
icon={<CalendarDays size={22} />}