Merge pull request #588 from Tria-plc/freight_feature/usermanagement

fix issues
This commit is contained in:
marshal
2026-07-09 23:27:02 +03:00
committed by GitHub
29 changed files with 1143 additions and 147 deletions

View File

@@ -83,7 +83,7 @@ export function ContractClearanceAction({
centered
overlayProps={{ blur: 2, backgroundOpacity: 0.55 }}
>
<ContractClearancePanel contractId={contractId} bare />
<ContractClearancePanel contractId={contractId} bare onSubmitted={close} />
</Modal>
</ModalSafeWrapper>
);

View File

@@ -142,7 +142,7 @@ function ProgressTracker({
const activeRing = tone === "ink" ? "#D9E0E7" : "#BFE8D4";
return (
/* Scrollable on mobile so 5 stages never overflow */
/* Scrollable on mobile so the stages never overflow */
<Box
className="overflow-x-auto pt-2"
style={
@@ -152,7 +152,7 @@ function ProgressTracker({
} as React.CSSProperties
}
>
<div className="flex items-start" style={{ minWidth: 520 }}>
<div className="flex items-start" style={{ minWidth: 640 }}>
{PROGRESS_STAGES.map((stage, idx) => {
const state =
idx < current ? "done" : idx === current ? "active" : "idle";

View File

@@ -3,6 +3,7 @@ import {
FileText,
MapPin,
PackageCheck,
PackageOpen,
ShieldCheck,
Ship,
Train,
@@ -54,12 +55,22 @@ export const PROGRESS_STAGES = [
statuses: ["EXPIRED", "IN_TRANSIT"],
},
{
// ARRIVED: cargo unloaded at the booking's own destination yard (segment
// corridor journeys). Legacy bookings stay IN_TRANSIT until delivery, so
// this stage also lights up from the assigned train's own status
// (trainScheduleStatus === "ARRIVED") — see resolveStage.
// The train reached the booking's destination yard — cargo may still be
// on board. No booking status of its own: it lights up from the assigned
// train's status (trainScheduleStatus === "ARRIVED") while the booking is
// still IN_TRANSIT — see resolveStage. Bookings unloaded mid-corridor (or
// auto-unloaded on a checkpoint) jump straight past it to Unloading.
label: "Arrival",
icon: MapPin,
statuses: [],
},
{
// ARRIVED: cargo unloaded off the train at the booking's own destination
// yard. Unloading is automatic — the API alights the booking the moment a
// checkpoint is recorded at its destination yard (or, as a fallback, when
// the train's final arrival is logged).
label: "Unloading",
icon: PackageOpen,
statuses: ["ARRIVED"],
},
{
@@ -69,17 +80,17 @@ export const PROGRESS_STAGES = [
},
];
/** Stage index of the Arrival step (train ARRIVED, cargo not yet delivered). */
/** Stage index of the Arrival step (train ARRIVED, cargo not yet unloaded). */
export const ARRIVAL_STAGE = PROGRESS_STAGES.findIndex(
(s) => s.label === "Arrival",
);
/**
* Stage for a booking, factoring in the assigned train's operational status:
* a booking with per-booking journey data reaches ARRIVED when it is unloaded
* at its own destination yard; a legacy booking is stuck at IN_TRANSIT between
* dispatch and delivery, so once its train has ARRIVED the tracker advances to
* the Arrival stage.
* a booking with per-booking journey data reaches ARRIVED (the Unloading
* stage) when it is unloaded at its own destination yard; a legacy booking is
* stuck at IN_TRANSIT between dispatch and delivery, so once its train has
* ARRIVED the tracker advances to the Arrival stage.
*/
export function resolveStage(booking: {
status: string;
@@ -181,10 +192,10 @@ export const STATUS_MAP: Record<
stage: 6,
},
ARRIVED: {
title: "Arrived at destination",
title: "Unloaded at destination",
description:
"Your cargo has been unloaded at its destination yard and is being prepared for release.",
stage: 7,
stage: 8,
},
OPERATION_REQUEST_PENDING: {
title: "Operation request under review",
@@ -251,7 +262,7 @@ export const STATUS_MAP: Record<
title: "Contract closed",
description:
"This general contract is closed — its reserved quantity has been used or its window has elapsed.",
stage: 8,
stage: 9,
},
PRICE_CHANGED_PENDING_CONFIRM: {
title: "Price changed — confirm to proceed",
@@ -277,12 +288,12 @@ export const STATUS_MAP: Record<
COMPLETED: {
title: "Service complete",
description: "Cargo delivered and service successfully terminated.",
stage: 8,
stage: 9,
},
DELIVERED: {
title: "Service complete",
description: "Cargo delivered and service successfully terminated.",
stage: 8,
stage: 9,
},
REJECTED: {
title: "Booking rejected",

View File

@@ -42,7 +42,7 @@ function BookingActionModalBody({
const flow = useClearanceFlow(booking);
const reference = booking.reference;
const handleSubmit = () => flow.submitDocuments();
const handleSubmit = () => flow.submitDocuments({ onSuccess: onClose });
const handleProceed = () => flow.proceedToOperation({ onSuccess: onClose });
return (

View File

@@ -39,6 +39,8 @@ export interface ContractClearancePanelProps {
tradeDirection?: string;
/** Show the loading state without the surrounding Paper (e.g. inside a modal). */
bare?: boolean;
/** Called after a successful document submission (e.g. to close the host modal). */
onSubmitted?: () => void;
}
/**
@@ -52,6 +54,7 @@ export function ContractClearancePanel({
contractId,
tradeDirection = "IMPORT",
bare,
onSubmitted,
}: ContractClearancePanelProps) {
const queryClient = useQueryClient();
const [pending, setPending] = useState<Record<string, File>>({});
@@ -77,6 +80,13 @@ export function ContractClearancePanel({
queryClient.invalidateQueries({
queryKey: api.contracts.get.queryKey({ id: contractId }),
});
// Submitting moves the contract to CLEARANCE_UNDER_REVIEW — refresh every
// contracts-list query (prefix key) so the /contracts table row and its
// action button update without a page reload.
queryClient.invalidateQueries({
queryKey: api.contracts.list.queryKey(),
});
onSubmitted?.();
},
});