diff --git a/src/components/collection-confirm/po-card.test.tsx b/src/components/collection-confirm/po-card.test.tsx index d091465..c0bece7 100644 --- a/src/components/collection-confirm/po-card.test.tsx +++ b/src/components/collection-confirm/po-card.test.tsx @@ -659,7 +659,18 @@ describe("PoCard driver-photo marker", () => { describe("PoCard AI-checked marker", () => { const photoRow = { ...baseRows[0], order_item_attachements: ["dn_abc.jpg"] }; - it("turns a photographed card purple and says how many lines the AI checked", () => { + it("turns the card purple when the AI checked every line and all its ticks agree", () => { + render(); + const card = screen.getByTestId("po-card-PO-1"); + expect(card).toHaveAttribute("data-ai-state", "verified"); + expect(card.className).toMatch(/bg-ai\//); + // The white card background must not sit under the tint (it won the clash). + expect(card.className).not.toMatch(/\bbg-card\b/); + expect(card.className).not.toMatch(/emerald-50/); + expect(screen.getByTestId("po-card-ai-checked-PO-1")).toHaveTextContent("AI checked all 1 line"); + }); + + it("goes amber, not purple, when a checked card has a line that needs a look", () => { render( { />, ); const card = screen.getByTestId("po-card-PO-1"); - expect(card).toHaveAttribute("data-ai-checked", "true"); - expect(card.className).toMatch(/bg-ai\//); - expect(card.className).not.toMatch(/emerald-50/); - expect(screen.getByTestId("po-card-ai-checked-PO-1")).toHaveTextContent("AI checked 1 of 2 lines"); + expect(card).toHaveAttribute("data-ai-state", "issues"); + expect(card.className).toMatch(/amber-50/); + expect(card.className).not.toMatch(/bg-ai\//); + expect(screen.getByTestId("po-card-ai-checked-PO-1")).toHaveTextContent("AI checked 1 of 2 lines · 1 needs a look"); }); it("stays green when the AI could not pair the document", () => { @@ -678,7 +689,7 @@ describe("PoCard AI-checked marker", () => { , ); const card = screen.getByTestId("po-card-PO-1"); - expect(card).toHaveAttribute("data-ai-checked", "false"); + expect(card).toHaveAttribute("data-ai-state", "unchecked"); expect(card.className).toMatch(/emerald/); expect(screen.queryByTestId("po-card-ai-checked-PO-1")).not.toBeInTheDocument(); }); @@ -694,6 +705,6 @@ describe("PoCard AI-checked marker", () => { render(); await user.click(screen.getByTestId("po-card-toggle-PO-1")); expect(screen.getByTestId("po-card-PO-1").className).not.toMatch(/bg-ai\//); - expect(screen.getByTestId("po-card-ai-checked-PO-1")).toHaveTextContent("AI checked 1 of 1 line"); + expect(screen.getByTestId("po-card-ai-checked-PO-1")).toHaveTextContent("AI checked all 1 line"); }); }); diff --git a/src/components/collection-confirm/po-card.tsx b/src/components/collection-confirm/po-card.tsx index 2070b6d..6ad0f3e 100644 --- a/src/components/collection-confirm/po-card.tsx +++ b/src/components/collection-confirm/po-card.tsx @@ -19,6 +19,7 @@ import { documentChipLabel, } from "@/lib/collection-ai-card"; import type { CollectionDocLine } from "@/lib/types"; +import { cardAiState } from "@/lib/collection-ai-ticks"; import { AiFindings, DocumentLinesPanel } from "./ai-findings"; import { InvoiceViewer } from "./invoice-viewer"; import { ItemsTable } from "./items-table"; @@ -298,10 +299,8 @@ export function PoCard({ * AI purple, so the operator can tell "driver took a photo" apart * from "the agent has read it and checked the lines". */ - const aiCheckedCount = useMemo( - () => rows.filter((r) => r.ai_check && !r.ai_check.pair_failed).length, - [rows], - ); + const ai = useMemo(() => cardAiState(rows), [rows]); + const aiCheckedCount = ai.checked; /** * When the goods were collected. Customer rows carry an @@ -449,26 +448,33 @@ export function PoCard({ return (
0 - ? "border-ai/40 bg-ai/10" - : photoCount > 0 - ? "border-emerald-300 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950/30" - : "" + ? "bg-card" + : ai.state === "verified" + ? "border-ai/50 bg-ai/15" + : ai.state === "issues" + ? "border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/30" + : photoCount > 0 + ? "border-emerald-300 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950/30" + : "bg-card" }`} data-testid={`po-card-${poNumber}`} data-open={isOpen} data-has-photos={photoCount > 0 ? "true" : "false"} data-photo-count={photoCount} data-ai-checked={aiCheckedCount > 0 ? "true" : "false"} + data-ai-state={ai.state} > {/* The gear is a SIBLING of the expand/collapse button, never a @@ -557,7 +563,9 @@ export function PoCard({ title="Lines the AI checked against the driver's photo" >