Files
edr-platform/apps/edr-freight-web/backoffice/src/components/contracts/ClearancePhaseStepper.tsx
2026-07-01 20:55:17 +03:00

113 lines
3.6 KiB
TypeScript

import { Check } from "lucide-react";
import { Box, Group, Stack, Text } from "@mantine/core";
import type { Freight } from "@edr/types";
const BRAND_GREEN = "var(--freight-brand, #0A6F4D)";
const IMPORT_PHASES = [
"CUSTOMER_INTAKE",
"GL_ET_REVIEW",
"GL_ET_OUTPUT",
"CUSTOMER_DUTY",
"GL_ET_POST_CLEARANCE",
"GL_DJ_COLLECTION",
] as const;
const PHASE_LABELS: Record<string, string> = {
CUSTOMER_INTAKE: "Customer docs",
GL_ET_REVIEW: "GL ET review",
GL_DJ_COLLECTION: "GL Djibouti DO",
GL_ET_OUTPUT: "Declaration",
CUSTOMER_DUTY: "Duty / customer pays",
GL_ET_POST_CLEARANCE: "Transit & finalize",
GL_DJ_LOADING: "Loading",
POST_TRANSIT: "Transit",
};
const EXPORT_PHASES = [
"CUSTOMER_INTAKE",
"GL_ET_REVIEW",
"GL_DJ_COLLECTION",
"GL_ET_OUTPUT",
"GL_ET_POST_CLEARANCE",
] as const;
function phaseIndex(phases: readonly string[], current?: string | null): number {
if (!current) return 0;
const idx = phases.indexOf(current);
return idx >= 0 ? idx : 0;
}
export function ClearancePhaseStepper({
clearance,
tradeDirection,
compact = false,
}: {
clearance?: Freight.ContractClearanceView | Freight.ClearanceView | null;
tradeDirection?: string;
compact?: boolean;
}) {
const phases = tradeDirection === "EXPORT" ? EXPORT_PHASES : IMPORT_PHASES;
const current = clearance?.phase ?? phases[0];
const activeIdx = phaseIndex(phases, current);
return (
<Group gap={0} wrap="nowrap" align="flex-start" style={{ overflowX: "auto" }}>
{phases.map((phase, index) => {
const isComplete = index < activeIdx;
const isActive = index === activeIdx;
const isLast = index === phases.length - 1;
return (
<Box key={phase} style={{ flex: isLast ? "0 0 auto" : 1, minWidth: compact ? 72 : 88 }}>
<Group gap={0} wrap="nowrap" align="center">
<Stack gap={4} align="center" style={{ flexShrink: 0 }}>
<Box
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
width: compact ? 28 : 34,
height: compact ? 28 : 34,
borderRadius: "50%",
background: isComplete ? BRAND_GREEN : isActive ? "white" : "var(--mantine-color-gray-1)",
border: isActive
? `2px solid ${BRAND_GREEN}`
: isComplete
? "2px solid transparent"
: "2px solid var(--mantine-color-gray-3)",
color: isComplete ? "white" : isActive ? BRAND_GREEN : "var(--mantine-color-gray-5)",
}}
>
{isComplete ? <Check size={compact ? 14 : 16} strokeWidth={3} /> : null}
</Box>
<Text
size={compact ? "10px" : "xs"}
fw={isActive ? 600 : 500}
c={isActive ? "edr-green.7" : isComplete ? "dark" : "dimmed"}
ta="center"
style={{ whiteSpace: "nowrap" }}
>
{PHASE_LABELS[phase] ?? phase}
</Text>
</Stack>
{!isLast && (
<Box
style={{
flex: 1,
height: 2,
marginInline: 6,
marginBottom: compact ? 16 : 20,
borderRadius: 2,
background: isComplete ? BRAND_GREEN : "var(--mantine-color-gray-2)",
}}
/>
)}
</Group>
</Box>
);
})}
</Group>
);
}