Files
edr-platform/apps/edr-freight-web/backoffice/src/components/trainScheduling/ScheduleWarningsAlert.tsx
Marshal 0dead281ce add per-container handling options for hazardous, reefer, and return services
- Introduced new boolean fields (isHazardous, isReefer, isReturn) in UnitDraft and related interfaces to allow individual container handling options.
- Updated emptyUnit function to initialize these new fields.
- Modified GlCreateBookingForm to handle and display these options for each container.
- Adjusted calculations for hazardous, reefer, and return quantities based on the new handling options.
- Updated the schema for container units and booking container lines to include handling options.
- Added migration to support the new return flag in the database.
- Enhanced various components to reflect gross weight calculations, ensuring consistency across the application.
2026-07-18 19:20:45 +00:00

80 lines
2.2 KiB
TypeScript

import { Alert, List, Paper, SimpleGrid, Stack, Text } from "@mantine/core";
import { AlertTriangle, XCircle } from "lucide-react";
export function ScheduleWarningsAlert({
violations = [],
warnings = [],
}: {
violations?: string[];
warnings?: string[];
}) {
if (!violations.length && !warnings.length) return null;
return (
<Stack gap="sm">
{violations.length > 0 ? (
<Alert color="red" radius="xl" icon={<XCircle size={16} />} title="Violations">
<List size="sm" spacing={4}>
{violations.map((v) => (
<List.Item key={v}>{v}</List.Item>
))}
</List>
</Alert>
) : null}
{warnings.length > 0 ? (
<Alert color="yellow" radius="xl" icon={<AlertTriangle size={16} />} title="Warnings">
<List size="sm" spacing={4}>
{warnings.map((w) => (
<List.Item key={w}>{w}</List.Item>
))}
</List>
</Alert>
) : null}
</Stack>
);
}
export function PreviewSummary({
summary,
}: {
summary?: {
totalBookings: number;
totalWeightTons: number;
grossWeightTons?: number;
totalTareTons?: number;
wagonType: string;
wagonsNeeded: number;
totalLengthMeters: number;
};
}) {
if (!summary) return null;
// GROSS — the axis every train limit is spent against.
const gross = summary.grossWeightTons ?? summary.totalWeightTons;
const stats = [
{ label: "Bookings", value: String(summary.totalBookings) },
{ label: "Wagons", value: String(summary.wagonsNeeded) },
{ label: "Wagon type", value: summary.wagonType },
{ label: "Gross weight", value: `${gross}T` },
{ label: "Train length", value: `${summary.totalLengthMeters}m` },
];
return (
<Paper p="md" radius="xl" withBorder bg="edr-green.0">
<Text size="sm" fw={600} mb="sm">
Plan summary
</Text>
<SimpleGrid cols={{ base: 2, sm: 3, md: 5 }} spacing="sm">
{stats.map((stat) => (
<Stack key={stat.label} gap={2}>
<Text size="xs" c="dimmed" tt="uppercase">
{stat.label}
</Text>
<Text size="sm" fw={600}>
{stat.value}
</Text>
</Stack>
))}
</SimpleGrid>
</Paper>
);
}