mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 17:38:12 +00:00
add goverment booking
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
Group,
|
||||
Modal,
|
||||
Stack,
|
||||
Text,
|
||||
} from "@mantine/core";
|
||||
import { Landmark } from "lucide-react";
|
||||
|
||||
import type {
|
||||
EligibleContainerBooking,
|
||||
TrainScheduleDetail,
|
||||
} from "@/types/trainScheduling";
|
||||
|
||||
/**
|
||||
* Government-priority switch confirmation: pick the assigned commercial
|
||||
* bookings to take off the train so the government booking can have their
|
||||
* wagons. Mount with key={govBooking.id} so selection resets per booking.
|
||||
*/
|
||||
export function SwitchGovernmentBookingModal({
|
||||
opened,
|
||||
onClose,
|
||||
govBooking,
|
||||
assignedBookings,
|
||||
loading,
|
||||
onConfirm,
|
||||
}: {
|
||||
opened: boolean;
|
||||
onClose: () => void;
|
||||
govBooking: EligibleContainerBooking | null;
|
||||
assignedBookings: TrainScheduleDetail["bookings"];
|
||||
loading?: boolean;
|
||||
onConfirm: (removeBookingIds: string[]) => void;
|
||||
}) {
|
||||
const [selected, setSelected] = useState<string[]>([]);
|
||||
|
||||
const candidates = useMemo(
|
||||
() => assignedBookings.filter((b) => !b.isGovernment && b.wagonAssigned),
|
||||
[assignedBookings],
|
||||
);
|
||||
const freedWagons = candidates
|
||||
.filter((b) => selected.includes(b.id))
|
||||
.reduce((sum, b) => sum + (b.wagonsRequired ?? 0), 0);
|
||||
|
||||
const toggle = (id: string) =>
|
||||
setSelected((ids) =>
|
||||
ids.includes(id) ? ids.filter((x) => x !== id) : [...ids, id],
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
opened={opened}
|
||||
onClose={onClose}
|
||||
title={
|
||||
<Group gap="xs">
|
||||
<Landmark size={18} />
|
||||
<Text fw={600}>Switch in government booking</Text>
|
||||
</Group>
|
||||
}
|
||||
radius="lg"
|
||||
size="lg"
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Alert color="yellow" radius="md" variant="light">
|
||||
Government bookings have priority. Select the booking(s) to switch out —
|
||||
together they must free at least as many wagons as{" "}
|
||||
<Text span fw={600}>
|
||||
{govBooking?.reference}
|
||||
</Text>{" "}
|
||||
needs. Switched-out customers are notified to rebook.
|
||||
</Alert>
|
||||
|
||||
{candidates.length ? (
|
||||
<Stack gap="xs">
|
||||
{candidates.map((b) => (
|
||||
<Group
|
||||
key={b.id}
|
||||
justify="space-between"
|
||||
p="sm"
|
||||
style={{
|
||||
border: "1px solid var(--mantine-color-gray-2)",
|
||||
borderRadius: 12,
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
color="edr-green"
|
||||
checked={selected.includes(b.id)}
|
||||
onChange={() => toggle(b.id)}
|
||||
label={
|
||||
<Group gap="xs">
|
||||
<Text fw={600} size="sm">
|
||||
{b.reference}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
{b.customer}
|
||||
</Text>
|
||||
</Group>
|
||||
}
|
||||
/>
|
||||
<Group gap="xs">
|
||||
<Badge variant="outline" size="xs" color="edr-green">
|
||||
{b.weightTons}T
|
||||
</Badge>
|
||||
<Badge variant="light" size="xs">
|
||||
{b.wagonsRequired ?? "?"} wagon{b.wagonsRequired === 1 ? "" : "s"}
|
||||
</Badge>
|
||||
</Group>
|
||||
</Group>
|
||||
))}
|
||||
</Stack>
|
||||
) : (
|
||||
<Text size="sm" c="dimmed" ta="center" py="md">
|
||||
No commercial bookings with wagons on this train to switch out.
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Group justify="space-between">
|
||||
<Badge variant="light" color={selected.length ? "edr-green" : "gray"}>
|
||||
Frees {freedWagons} wagon{freedWagons === 1 ? "" : "s"}
|
||||
</Badge>
|
||||
<Group gap="sm">
|
||||
<Button variant="default" radius="md" onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
color="edr-green"
|
||||
radius="md"
|
||||
disabled={!selected.length}
|
||||
loading={loading}
|
||||
onClick={() => onConfirm(selected)}
|
||||
>
|
||||
Confirm switch
|
||||
</Button>
|
||||
</Group>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user