mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 17:10:56 +00:00
187 lines
6.1 KiB
TypeScript
187 lines
6.1 KiB
TypeScript
import {
|
|
Badge,
|
|
Button,
|
|
Group,
|
|
Paper,
|
|
Stack,
|
|
Tabs,
|
|
Text,
|
|
} from "@mantine/core";
|
|
import { ArrowRight, FileText, Landmark, MapPin, Package, Train } from "lucide-react";
|
|
|
|
import type { EligibleContainerBooking, FreightType } from "@/types/trainScheduling";
|
|
|
|
import { EligibleBookingsPanel } from "./EligibleBookingsPanel";
|
|
|
|
export type AssignedBookingRow = {
|
|
id: string;
|
|
reference: string;
|
|
weightTons?: number;
|
|
isGovernment?: boolean;
|
|
wagonsRequired?: number | null;
|
|
contractReference?: string | null;
|
|
origin?: string | null;
|
|
destination?: string | null;
|
|
};
|
|
|
|
export function ScheduleBookingsStep({
|
|
assignedBookings,
|
|
eligibleItems,
|
|
eligibleLoading,
|
|
selectedIds,
|
|
onSelectionChange,
|
|
assignedIds,
|
|
freightType,
|
|
canRemove,
|
|
onRemove,
|
|
onSwitch,
|
|
}: {
|
|
assignedBookings: AssignedBookingRow[];
|
|
eligibleItems: EligibleContainerBooking[];
|
|
eligibleLoading?: boolean;
|
|
selectedIds: string[];
|
|
onSelectionChange: (ids: string[]) => void;
|
|
assignedIds?: string[];
|
|
freightType?: FreightType;
|
|
canRemove?: boolean;
|
|
onRemove?: (bookingId: string) => void;
|
|
onSwitch?: (booking: EligibleContainerBooking) => void;
|
|
}) {
|
|
return (
|
|
<Paper p="md" radius="lg" withBorder style={{ borderColor: "var(--mantine-color-gray-2)" }}>
|
|
<Tabs
|
|
defaultValue={assignedBookings.length ? "on-train" : "add"}
|
|
radius="md"
|
|
variant="pills"
|
|
color="edr-green"
|
|
>
|
|
<Tabs.List mb="md">
|
|
<Tabs.Tab
|
|
value="on-train"
|
|
leftSection={<Train size={14} />}
|
|
rightSection={
|
|
assignedBookings.length ? (
|
|
<Badge size="xs" variant="light" color="edr-green" circle>
|
|
{assignedBookings.length}
|
|
</Badge>
|
|
) : undefined
|
|
}
|
|
>
|
|
On this train
|
|
</Tabs.Tab>
|
|
<Tabs.Tab value="add" leftSection={<Package size={14} />}>
|
|
Add bookings
|
|
</Tabs.Tab>
|
|
</Tabs.List>
|
|
|
|
<Tabs.Panel value="on-train">
|
|
{assignedBookings.length ? (
|
|
<Stack gap="sm">
|
|
{assignedBookings.map((booking) => (
|
|
<Group
|
|
key={booking.id}
|
|
justify="space-between"
|
|
p="sm"
|
|
style={{
|
|
border: "1px solid var(--mantine-color-edr-green-2)",
|
|
borderRadius: 12,
|
|
background: "var(--mantine-color-edr-green-0)",
|
|
}}
|
|
>
|
|
<Stack gap={4}>
|
|
<Group gap="xs">
|
|
<Text fw={600} size="sm">
|
|
{booking.reference}
|
|
</Text>
|
|
{booking.weightTons != null ? (
|
|
<Badge variant="outline" size="xs" color="edr-green">
|
|
{booking.weightTons}T
|
|
</Badge>
|
|
) : null}
|
|
{booking.wagonsRequired != null ? (
|
|
<Badge
|
|
variant="outline"
|
|
size="xs"
|
|
color="gray"
|
|
leftSection={<Train size={10} />}
|
|
>
|
|
{booking.wagonsRequired} wagon{booking.wagonsRequired === 1 ? "" : "s"}
|
|
</Badge>
|
|
) : null}
|
|
{booking.isGovernment ? (
|
|
<Badge
|
|
variant="light"
|
|
size="xs"
|
|
color="yellow"
|
|
leftSection={<Landmark size={10} />}
|
|
>
|
|
Government
|
|
</Badge>
|
|
) : null}
|
|
</Group>
|
|
{booking.contractReference || booking.origin || booking.destination ? (
|
|
<Group gap="xs">
|
|
{booking.contractReference ? (
|
|
<Group gap={4}>
|
|
<FileText size={12} />
|
|
<Text size="xs" c="dimmed">
|
|
{booking.contractReference}
|
|
</Text>
|
|
</Group>
|
|
) : null}
|
|
{booking.origin || booking.destination ? (
|
|
<Group gap={4}>
|
|
<MapPin size={12} />
|
|
<Text size="xs" c="dimmed">
|
|
{booking.origin ?? "?"} → {booking.destination ?? "?"}
|
|
</Text>
|
|
</Group>
|
|
) : null}
|
|
</Group>
|
|
) : null}
|
|
<Group gap={6}>
|
|
<Text size="xs" c="dimmed">
|
|
Assigned to this consist
|
|
</Text>
|
|
<ArrowRight size={12} />
|
|
<Text size="xs" c="edr-green.7" fw={500}>
|
|
Ready for wagon plan
|
|
</Text>
|
|
</Group>
|
|
</Stack>
|
|
{canRemove && onRemove ? (
|
|
<Button
|
|
variant="subtle"
|
|
color="red"
|
|
size="compact-xs"
|
|
onClick={() => onRemove(booking.id)}
|
|
>
|
|
Remove
|
|
</Button>
|
|
) : null}
|
|
</Group>
|
|
))}
|
|
</Stack>
|
|
) : (
|
|
<Text size="sm" c="dimmed" ta="center" py="lg">
|
|
No bookings on this train yet. Use the Add bookings tab to select eligible cargo.
|
|
</Text>
|
|
)}
|
|
</Tabs.Panel>
|
|
|
|
<Tabs.Panel value="add">
|
|
<EligibleBookingsPanel
|
|
items={eligibleItems}
|
|
isLoading={eligibleLoading}
|
|
selectedIds={selectedIds}
|
|
onSelectionChange={onSelectionChange}
|
|
assignedIds={assignedIds}
|
|
freightType={freightType}
|
|
onSwitch={onSwitch}
|
|
/>
|
|
</Tabs.Panel>
|
|
</Tabs>
|
|
</Paper>
|
|
);
|
|
}
|