mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 02:58:11 +00:00
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Badge, Box, Button, Group, SegmentedControl, Text } from "@mantine/core";
|
|
import { ShieldAlert } from "lucide-react";
|
|
import type { Freight } from "@edr/types";
|
|
|
|
import { useAssignRisk } from "@/hooks/contracts/useContracts";
|
|
import { ActionShell } from "./ActionShell";
|
|
|
|
const RISK_COLOR: Record<Freight.CustomsRiskLevel, string> = {
|
|
GREEN: "green",
|
|
YELLOW: "yellow",
|
|
RED: "red",
|
|
};
|
|
|
|
export function AssignRiskCard({
|
|
bookingId,
|
|
milestone,
|
|
locked = false,
|
|
}: {
|
|
bookingId: string;
|
|
milestone: Freight.IClearanceMilestone;
|
|
/**
|
|
* Duty has already been advised off this risk level, so the decision is now
|
|
* final. Until then a mis-assigned level must stay correctable — the server
|
|
* accepts reassignment and overwrites the milestone metadata.
|
|
*/
|
|
locked?: boolean;
|
|
}) {
|
|
const assign = useAssignRisk(bookingId);
|
|
|
|
const assigned = milestone.status === "COMPLETED";
|
|
const current = milestone.metadata?.riskLevel;
|
|
const [level, setLevel] = useState<Freight.CustomsRiskLevel>(
|
|
current ?? "GREEN",
|
|
);
|
|
|
|
// The milestone loads (and refetches after a reassignment) after first render,
|
|
// so mirror the persisted level onto the control whenever it changes.
|
|
useEffect(() => {
|
|
if (current) setLevel(current);
|
|
}, [current]);
|
|
|
|
return (
|
|
<ActionShell
|
|
icon={ShieldAlert}
|
|
title="Customs risk"
|
|
subtitle={
|
|
assigned && !locked
|
|
? "Reassign the customs examination risk level."
|
|
: "Assign the customs examination risk level."
|
|
}
|
|
done={assigned}
|
|
keepChildrenWhenDone={!locked}
|
|
doneLabel={
|
|
current ? (
|
|
<Badge color={RISK_COLOR[current]} variant="filled" radius="sm">
|
|
{current}
|
|
</Badge>
|
|
) : (
|
|
"Assigned"
|
|
)
|
|
}
|
|
>
|
|
<Box>
|
|
<SegmentedControl
|
|
fullWidth
|
|
value={level}
|
|
onChange={(v) => setLevel(v as Freight.CustomsRiskLevel)}
|
|
data={[
|
|
{ label: "Green", value: "GREEN" },
|
|
{ label: "Yellow", value: "YELLOW" },
|
|
{ label: "Red", value: "RED" },
|
|
]}
|
|
/>
|
|
<Group justify="space-between" mt="sm">
|
|
<Text size="xs" c="dimmed">
|
|
Customer is notified of the assigned risk.
|
|
</Text>
|
|
<Button
|
|
size="compact-sm"
|
|
color="edr-green"
|
|
loading={assign.isPending}
|
|
disabled={assigned && level === current}
|
|
onClick={() => assign.mutate({ riskLevel: level })}
|
|
>
|
|
{assigned ? "Reassign risk" : "Assign risk"}
|
|
</Button>
|
|
</Group>
|
|
</Box>
|
|
</ActionShell>
|
|
);
|
|
}
|