mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-03 13:13:40 +00:00
90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { Badge, Group, Text, Tooltip } from "@mantine/core";
|
||
import { Boxes, Container, Weight } from "lucide-react";
|
||
import type { Freight } from "@edr/types";
|
||
|
||
/**
|
||
* Compact human summary of a shipment request's requested cargo lines — the
|
||
* quantities the customer asked for, before GL enters the real booking cargo.
|
||
* Container contracts read "2 × 20ft, 1 × 40ft"; bulk reads "500 t" or
|
||
* "300 items" depending on the contract's cargo configuration.
|
||
*/
|
||
export function summarizeRequestedCargo(
|
||
lines?: Freight.RequestedShipmentLines | null,
|
||
): string {
|
||
if (!lines) return "—";
|
||
const containers = (lines.containers ?? []).filter((c) => (c.quantity ?? 0) > 0);
|
||
if (containers.length) {
|
||
return containers.map((c) => `${c.quantity} × ${c.containerSize}`).join(", ");
|
||
}
|
||
if (lines.bulk) {
|
||
if (lines.bulk.cargoWeightTons) return `${lines.bulk.cargoWeightTons} t`;
|
||
if (lines.bulk.itemCount) return `${lines.bulk.itemCount} items`;
|
||
}
|
||
return "—";
|
||
}
|
||
|
||
/** Renders the requested cargo as small badges (per container type, or bulk). */
|
||
export function RequestedCargoChips({
|
||
lines,
|
||
size = "sm",
|
||
}: {
|
||
lines?: Freight.RequestedShipmentLines | null;
|
||
size?: "xs" | "sm";
|
||
}) {
|
||
const containers = (lines?.containers ?? []).filter((c) => (c.quantity ?? 0) > 0);
|
||
|
||
if (containers.length) {
|
||
return (
|
||
<Group gap={6} wrap="wrap">
|
||
{containers.map((c, i) => {
|
||
const flags: string[] = [];
|
||
if ((c.hazardousQuantity ?? 0) > 0)
|
||
flags.push(`${c.hazardousQuantity} hazardous`);
|
||
if ((c.reeferQuantity ?? 0) > 0)
|
||
flags.push(`${c.reeferQuantity} reefer`);
|
||
const chip = (
|
||
<Badge
|
||
size={size}
|
||
variant="light"
|
||
color="edr-green"
|
||
radius="sm"
|
||
leftSection={<Container size={12} />}
|
||
>
|
||
{c.quantity} × {c.containerSize}
|
||
</Badge>
|
||
);
|
||
return flags.length ? (
|
||
<Tooltip key={i} label={flags.join(" · ")} withArrow>
|
||
{chip}
|
||
</Tooltip>
|
||
) : (
|
||
<span key={i}>{chip}</span>
|
||
);
|
||
})}
|
||
</Group>
|
||
);
|
||
}
|
||
|
||
if (lines?.bulk && (lines.bulk.cargoWeightTons || lines.bulk.itemCount)) {
|
||
const isWeight = Boolean(lines.bulk.cargoWeightTons);
|
||
const value = lines.bulk.cargoWeightTons ?? lines.bulk.itemCount ?? 0;
|
||
return (
|
||
<Badge
|
||
size={size}
|
||
variant="light"
|
||
color="edr-green"
|
||
radius="sm"
|
||
leftSection={isWeight ? <Weight size={12} /> : <Boxes size={12} />}
|
||
>
|
||
{value} {isWeight ? "t" : "items"}
|
||
</Badge>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<Text size="xs" c="dimmed">
|
||
—
|
||
</Text>
|
||
);
|
||
}
|