Files
edr-platform/apps/edr-freight-web/backoffice/src/features/clearance/requestedCargo.tsx
2026-07-10 23:50:35 +00:00

90 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
}