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.