mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 12:18:11 +00:00
add contract clearance detail page and enhance contract requests filtering and ui fix
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
type KeyboardEvent,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
@@ -37,10 +38,12 @@ import {
|
||||
FileDown,
|
||||
FileText,
|
||||
FileUp,
|
||||
Flame,
|
||||
MapPin,
|
||||
Package,
|
||||
Receipt,
|
||||
Repeat,
|
||||
Snowflake,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import type { Freight } from "@edr/types";
|
||||
@@ -302,13 +305,34 @@ export default function GlCreateBookingForm() {
|
||||
*/
|
||||
const handlingColumns = (
|
||||
[
|
||||
contract?.isHazardous && { key: "isHazardous", label: "Hazardous" },
|
||||
contract?.isReefer && { key: "isReefer", label: "Refrigerated" },
|
||||
contractWithReturn && { key: "isReturn", label: "With return" },
|
||||
] as Array<false | undefined | { key: keyof UnitDraft; label: string }>
|
||||
contract?.isHazardous && {
|
||||
key: "isHazardous",
|
||||
label: "Hazardous",
|
||||
icon: <Flame size={14} />,
|
||||
color: "#C0392B",
|
||||
},
|
||||
contract?.isReefer && {
|
||||
key: "isReefer",
|
||||
label: "Refrigerated",
|
||||
icon: <Snowflake size={14} />,
|
||||
color: "#2E5B96",
|
||||
},
|
||||
contractWithReturn && {
|
||||
key: "isReturn",
|
||||
label: "With return",
|
||||
icon: <Repeat size={14} />,
|
||||
color: "#0A6F4D",
|
||||
},
|
||||
] as Array<
|
||||
| false
|
||||
| undefined
|
||||
| { key: keyof UnitDraft; label: string; icon: ReactNode; color: string }
|
||||
>
|
||||
).filter(Boolean) as Array<{
|
||||
key: "isHazardous" | "isReefer" | "isReturn";
|
||||
label: string;
|
||||
icon: ReactNode;
|
||||
color: string;
|
||||
}>;
|
||||
// Intercity shipments ride a passing import/export train staff pick at
|
||||
// finalize time — no shipment day is chosen and no window gate applies.
|
||||
@@ -1246,10 +1270,41 @@ export default function GlCreateBookingForm() {
|
||||
</Text>
|
||||
) : null}
|
||||
<Stack gap={10} mt={8}>
|
||||
{/* Header row — input labels + handling-service labels,
|
||||
one aligned grid shared by every unit row below.
|
||||
Same layout as the portal shipment form. */}
|
||||
{line.units.length > 0 && (
|
||||
<Group gap={10} wrap="nowrap" align="flex-end">
|
||||
<Text fz={12} fw={600} c="#10202F" style={{ flex: 1 }}>
|
||||
Container number *
|
||||
</Text>
|
||||
<Text fz={12} fw={600} c="#10202F" style={{ flex: 1 }}>
|
||||
Seal number
|
||||
</Text>
|
||||
<Text fz={12} fw={600} c="#10202F" style={{ flex: 1 }}>
|
||||
VGM (tons) *
|
||||
</Text>
|
||||
{handlingColumns.map((col) => (
|
||||
<Group
|
||||
key={col.key}
|
||||
gap={4}
|
||||
wrap="nowrap"
|
||||
justify="center"
|
||||
style={{ width: 96, flexShrink: 0 }}
|
||||
>
|
||||
<span style={{ color: col.color, display: "flex" }}>
|
||||
{col.icon}
|
||||
</span>
|
||||
<Text fz={12} fw={600} c="#10202F">
|
||||
{col.label}
|
||||
</Text>
|
||||
</Group>
|
||||
))}
|
||||
</Group>
|
||||
)}
|
||||
{line.units.map((unit, unitIdx) => (
|
||||
<Group key={unitIdx} gap={10} grow align="flex-start">
|
||||
<Group key={unitIdx} gap={10} wrap="nowrap" align="flex-start">
|
||||
<TextInput
|
||||
label={unitIdx === 0 ? "Container number *" : undefined}
|
||||
placeholder="e.g. MSCU1234567"
|
||||
value={unit.containerNumber}
|
||||
error={
|
||||
@@ -1265,9 +1320,9 @@ export default function GlCreateBookingForm() {
|
||||
}
|
||||
radius={10}
|
||||
styles={fieldStyles}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<TextInput
|
||||
label={unitIdx === 0 ? "Seal number" : undefined}
|
||||
placeholder="Optional"
|
||||
value={unit.sealNumber}
|
||||
onChange={(e) =>
|
||||
@@ -1277,11 +1332,11 @@ export default function GlCreateBookingForm() {
|
||||
}
|
||||
radius={10}
|
||||
styles={fieldStyles}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<TextInput
|
||||
type="number"
|
||||
onKeyDown={blockNegative}
|
||||
label={unitIdx === 0 ? "VGM (tons) *" : undefined}
|
||||
placeholder="e.g. 24.5"
|
||||
min={0}
|
||||
step={0.01}
|
||||
@@ -1298,22 +1353,31 @@ export default function GlCreateBookingForm() {
|
||||
}
|
||||
radius={10}
|
||||
styles={fieldStyles}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
{handlingColumns.map((col) => (
|
||||
<Switch
|
||||
<Box
|
||||
key={col.key}
|
||||
checked={Boolean(unit[col.key])}
|
||||
aria-label={`${col.label} — container ${unitIdx + 1}`}
|
||||
onChange={(e) =>
|
||||
patchUnit(lineIdx, unitIdx, {
|
||||
[col.key]: e.currentTarget.checked,
|
||||
})
|
||||
}
|
||||
label={unitIdx === 0 ? col.label : undefined}
|
||||
labelPosition="right"
|
||||
size="sm"
|
||||
mt={unitIdx === 0 ? 26 : 6}
|
||||
/>
|
||||
style={{
|
||||
width: 96,
|
||||
flexShrink: 0,
|
||||
height: 42,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<Switch
|
||||
checked={Boolean(unit[col.key])}
|
||||
aria-label={`${col.label} — container ${unitIdx + 1}`}
|
||||
onChange={(e) =>
|
||||
patchUnit(lineIdx, unitIdx, {
|
||||
[col.key]: e.currentTarget.checked,
|
||||
})
|
||||
}
|
||||
size="sm"
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Group>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user