import { CheckCircle2, AlertTriangle, Minus } from "lucide-react"; /** * One 999 ACK segment status row. The 999 spec labels each transaction * set with a 3-char code: * * "A" = Accepted * "E" = Accepted, but errors are noted (one or more segments had * errors; the transaction set as a whole was accepted) * "R" = Rejected * "P" = Partially accepted (mixed — some segments accepted, some * not; a degraded success the operator must investigate) * * The wire shape's `rawJson` (set by the parser, see backend * `cyclone.parsers.parsers_999`) carries an array of segment rows. * Until that array is parsed into a stable UI shape, we render the * rolled-up counts on the ack row (`acceptedCount` / `rejectedCount`) * and a placeholder explaining how to read it. */ interface SegmentRow { /** Loop / segment reference like "ST*999*0001" or "AK2*HC*0001". */ reference?: string; /** "A" | "E" | "R" | "P". */ status: "A" | "E" | "R" | "P"; /** Free-form note from the parser (e.g. "SVC*HC:9450 missing"). */ note?: string; } interface Props { segments: SegmentRow[]; } /** * Pill for one segment status. Color mirrors the badge palette used on * the Acks page (`Acks.tsx`) so a status reads the same in both * surfaces. */ function StatusPill({ status }: { status: SegmentRow["status"] }) { const cfg = { A: { fg: "hsl(152 64% 30%)", bg: "hsl(152 50% 88%)", border: "hsl(152 64% 38% / 0.30)", label: "Accepted", Icon: CheckCircle2, }, E: { fg: "hsl(36 92% 30%)", bg: "hsl(36 82% 88%)", border: "hsl(36 92% 50% / 0.30)", label: "Accepted w/ errors", Icon: AlertTriangle, }, R: { fg: "hsl(358 70% 36%)", bg: "hsl(358 70% 92%)", border: "hsl(358 70% 50% / 0.30)", label: "Rejected", Icon: AlertTriangle, }, P: { fg: "hsl(36 92% 30%)", bg: "hsl(36 82% 88%)", border: "hsl(36 92% 50% / 0.30)", label: "Partially accepted", Icon: Minus, }, }[status]; const Icon = cfg.Icon; return ( {cfg.label} ); } /** * Per-segment status list inside the AckDrawer body (SP21 Phase 5 * Task 5.2). Renders one row per parsed 999 segment, each with the * segment reference (when present), the parsed status code, and the * parser's note (when present). An empty list renders a small * explanatory note so the drawer doesn't look broken on old acks * without the per-segment slice. */ export function SegmentStatusList({ segments }: Props) { return (
Segment status {segments.length} segment{segments.length === 1 ? "" : "s"}
{segments.length === 0 ? (

No per-segment breakdown for this ack — the rolled-up accepted / rejected counts above are the only signal.

) : ( )}
); }