mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Merge pull request #1228 from Tria-plc/freight_feature/usermanagement
feat(freight): surface scheduling clock and gate pay during drain
This commit is contained in:
@@ -44,6 +44,27 @@ function formatRelative(iso: string, nowMs: number): string {
|
|||||||
return past ? `${span} ago` : `in ${span}`;
|
return past ? `${span} ago` : `in ${span}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of a window as "1h 30m" / "45m". Null unless both ends are real and
|
||||||
|
* ordered — the pay window is configurable per schedule, so this is read off the
|
||||||
|
* actual stamps rather than assuming any fixed duration.
|
||||||
|
*/
|
||||||
|
function formatDuration(
|
||||||
|
from: string | null | undefined,
|
||||||
|
to: string | null | undefined,
|
||||||
|
): string | null {
|
||||||
|
if (!from || !to) return null;
|
||||||
|
const fromMs = new Date(from).getTime();
|
||||||
|
const toMs = new Date(to).getTime();
|
||||||
|
if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return null;
|
||||||
|
const minutes = Math.round((toMs - fromMs) / 60_000);
|
||||||
|
if (minutes <= 0) return null;
|
||||||
|
const hours = Math.floor(minutes / 60);
|
||||||
|
const rest = minutes % 60;
|
||||||
|
if (!hours) return `${rest}m`;
|
||||||
|
return rest ? `${hours}h ${rest}m` : `${hours}h`;
|
||||||
|
}
|
||||||
|
|
||||||
function Row({
|
function Row({
|
||||||
label,
|
label,
|
||||||
value,
|
value,
|
||||||
@@ -98,8 +119,18 @@ export function BookingSchedulingWindowCard({
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// How long the customer actually had to pay: start → the raw deadline, NOT the
|
||||||
|
// drain end (the drain is settlement grace, not payable time).
|
||||||
|
const windowDuration = formatDuration(
|
||||||
|
booking.selectedForBatchAt,
|
||||||
|
booking.paymentDeadline,
|
||||||
|
);
|
||||||
|
|
||||||
const hasAnything =
|
const hasAnything =
|
||||||
Boolean(schedule) || Boolean(payWindowEndsAt) || Boolean(booking.holdExpiresAt);
|
Boolean(schedule) ||
|
||||||
|
Boolean(payWindowEndsAt) ||
|
||||||
|
Boolean(booking.selectedForBatchAt) ||
|
||||||
|
Boolean(booking.holdExpiresAt);
|
||||||
if (!hasAnything) return null;
|
if (!hasAnything) return null;
|
||||||
|
|
||||||
const payWindowClosed = payWindowEndsAt
|
const payWindowClosed = payWindowEndsAt
|
||||||
@@ -157,6 +188,18 @@ export function BookingSchedulingWindowCard({
|
|||||||
</Group>
|
</Group>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{booking.selectedForBatchAt ? (
|
||||||
|
<Row
|
||||||
|
label="Payment window started"
|
||||||
|
value={formatStamp(booking.selectedForBatchAt) ?? "—"}
|
||||||
|
hint={
|
||||||
|
windowDuration
|
||||||
|
? `${windowDuration} window`
|
||||||
|
: formatRelative(booking.selectedForBatchAt, nowMs)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{payWindowEndsAt ? (
|
{payWindowEndsAt ? (
|
||||||
<Row
|
<Row
|
||||||
label="Payment window ends"
|
label="Payment window ends"
|
||||||
|
|||||||
@@ -206,6 +206,11 @@ export interface BookingDetail {
|
|||||||
trainScheduleStatus?: string | null;
|
trainScheduleStatus?: string | null;
|
||||||
/** The allocated train's identity + clock, attached by the detail endpoint. */
|
/** The allocated train's identity + clock, attached by the detail endpoint. */
|
||||||
trainScheduleSummary?: BookingTrainScheduleSummary | null;
|
trainScheduleSummary?: BookingTrainScheduleSummary | null;
|
||||||
|
/**
|
||||||
|
* When the batch engine picked this booking and opened its pay window — the
|
||||||
|
* start paired with `paymentDeadline` (both are set and cleared together).
|
||||||
|
*/
|
||||||
|
selectedForBatchAt?: string | null;
|
||||||
/** End of this booking's pay window (batch/offer deadline). */
|
/** End of this booking's pay window (batch/offer deadline). */
|
||||||
paymentDeadline?: string | null;
|
paymentDeadline?: string | null;
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user