Files
edr-platform/apps/edr-freight-web/backoffice/src/components/contracts/gl-actions/GlActionsPanel.tsx

68 lines
2.2 KiB
TypeScript

import { useMemo } from "react";
import { Stack, Text } from "@mantine/core";
import type { Freight } from "@edr/types";
import { SectionCard } from "@/components/bookings/detail/SectionCard";
import { Flag } from "lucide-react";
import { AssignStationCard } from "./AssignStationCard";
import { AssignRiskCard } from "./AssignRiskCard";
import { AdviseDutyCard } from "./AdviseDutyCard";
import { GlDocumentUploadCard } from "./GlDocumentUploadCard";
import { IncidentReportCard } from "./IncidentReportCard";
export interface GlActionsPanelProps {
bookingId: string;
milestones: Freight.IClearanceMilestone[];
}
/** Find a milestone by code (post-booking milestones live on the booking). */
function findMilestone(
milestones: Freight.IClearanceMilestone[],
code: string,
): Freight.IClearanceMilestone | undefined {
return milestones.find((m) => m.milestoneCode === code);
}
/**
* Global Logistics action surface for a shipment. Each card is gated by whether
* its milestone exists on this shipment (import vs export differ) and renders the
* structured action (risk level, duty advice, document upload, incident report,
* station routing) that the plain "Complete" button can't capture.
*/
export function GlActionsPanel({ bookingId, milestones }: GlActionsPanelProps) {
const riskMs = useMemo(
() => findMilestone(milestones, "RISK_ASSIGNED"),
[milestones],
);
const dutyMs = useMemo(
() => findMilestone(milestones, "DUTY_TAXES_ADVISED"),
[milestones],
);
return (
<SectionCard icon={Flag} title="Global Logistics actions" accent="edr-green">
<Stack gap="md">
<Text size="xs" c="dimmed">
Structured GL operations for this shipment. Uploading a document
advances its milestone automatically.
</Text>
<AssignStationCard bookingId={bookingId} />
{dutyMs ? (
<AdviseDutyCard bookingId={bookingId} milestone={dutyMs} />
) : null}
<GlDocumentUploadCard bookingId={bookingId} />
{riskMs ? (
<AssignRiskCard bookingId={bookingId} milestone={riskMs} />
) : null}
<IncidentReportCard bookingId={bookingId} />
</Stack>
</SectionCard>
);
}