diff --git a/src/components/inbox/InboxHeader.tsx b/src/components/inbox/InboxHeader.tsx index f4202e2..2f94a24 100644 --- a/src/components/inbox/InboxHeader.tsx +++ b/src/components/inbox/InboxHeader.tsx @@ -1,16 +1,15 @@ // --------------------------------------------------------------------------- // InboxHeader // -// Compact working-surface header: the day/date, a live clock, and the -// two top-line counts ("N items need eyes" and "N done today") that -// anchor the operator's day. "Need eyes" is computed by the Inbox -// page (sum of actionable lanes) and passed in. -// -// SP14: payer_rejected (277CA) is now part of the actionable lanes — -// it's a working-surface rejection that needs operator follow-up. -// The Inbox page sums it into the needEyes count. +// Editorial dark hero for the Inbox. Larger than the previous 30px title +// so it carries weight against the bright lane surface below. "Inbox." +// is the page's anchor, the day/date sits as a serif italic, and the +// "N items need eyes / N done today" line replaces the small status +// pulse with a more dramatic mono announcement. // --------------------------------------------------------------------------- +import { fmt } from "@/lib/format"; + export function InboxHeader({ needEyesCount, doneTodayCount, @@ -32,66 +31,152 @@ export function InboxHeader({ return (
-
-
-

- Inbox -

- - · {day} {date} - -
- + {/* Ghost "TRIAGE" watermark — a print-shop stamp behind the title. */} +
- {time} - + TRIAGE +
+ +
+
+
+
+ + Inbox · Working surface + +
+

+ Inbox. +

+

+ Five lanes, one queue.{" "} + + {needEyesCount} + {" "} + need eyes; {doneTodayCount} are done today. +

+
+ +
+
+ {day} {date} +
+
+ {time} +
+
+ local +
+
+
+ + {/* Live status row — a horizontal "ticker" of the lane counts so + the operator can read the queue at a glance. */} +
+
+ + Live +
+ · + + + {needEyesCount} + {" "} + need eyes + + · + + + {doneTodayCount} + {" "} + done today + + · + + {fmt.date(new Date().toISOString())} + +
-

- - {needEyesCount} - items need eyes - · - {doneTodayCount} - done today -

); } diff --git a/src/pages/Inbox.tsx b/src/pages/Inbox.tsx index d5c5773..7a59e3d 100644 --- a/src/pages/Inbox.tsx +++ b/src/pages/Inbox.tsx @@ -13,6 +13,7 @@ // --------------------------------------------------------------------------- import { useState } from "react"; +import { cn } from "@/lib/utils"; import { Lane, type LaneRow } from "@/components/inbox/Lane"; import { InboxHeader } from "@/components/inbox/InboxHeader"; import { BulkBar } from "@/components/inbox/BulkBar"; @@ -160,15 +161,21 @@ export default function Inbox() { if (loading) { return (
- - loading inbox… + +
+ + loading inbox… +
); } @@ -176,13 +183,22 @@ export default function Inbox() { if (error) { return (
- - Connection error - - {error.message} + +
+ + Connection error + + {error.message} +
); } @@ -203,7 +219,53 @@ export default function Inbox() { style={{ background: "var(--tt-bg)", color: "var(--tt-ink)" }} > -
+ + {/* Fold — a thin amber rule + italic serif annotation that + transitions the editorial header into the lane grid below. */} +
+
+
+ + ↘ + + + Five lanes · one queue + + + ↙ + +
+
+ +
+ {/* ---------------------------------------------------------------- + PAPER-TONED SUMMARY STRIP + A cream "ledger" panel below the lanes that shows the aggregate + eye-flow across the queue. Mirrors the "Magazine Spread" pattern + used on the Dashboard/Claims/etc pages so the Inbox feels part + of the same document set, not a stand-alone terminal. + ---------------------------------------------------------------- */} +
+
+ {/* Title row */} +
+
+
+ Queue ledger +
+

+ The eye-flow, at a glance. +

+
+
+
+ Need eyes +
+
+ {needEyes} +
+
+
+ + {/* Lane metrics row — paper tiles that mirror each lane's accent */} +
+ + + + + +
+
+
+ {/* Per-lane bulk bars. Each shows when its lane has a selection. */}
@@ -404,3 +563,87 @@ export default function Inbox() {
); } + +// --------------------------------------------------------------------------- +// SummaryTile — paper-toned metric for the queue ledger strip. Mirrors +// the lane accent (oxblood / amber / ink-blue / muted) so the eye-flow +// reads at a glance. +// --------------------------------------------------------------------------- +const SUMMARY_ACCENTS: Record< + "oxblood" | "amber" | "ink" | "muted", + { dot: string; tint: string; text: string } +> = { + oxblood: { + dot: "hsl(358 70% 42%)", + tint: "hsl(358 70% 92%)", + text: "hsl(358 70% 30%)", + }, + amber: { + dot: "hsl(36 92% 50%)", + tint: "hsl(36 82% 88%)", + text: "hsl(36 92% 30%)", + }, + ink: { + dot: "hsl(212 80% 45%)", + tint: "hsl(212 85% 92%)", + text: "hsl(212 80% 30%)", + }, + muted: { + dot: "hsl(30 8% 50%)", + tint: "hsl(36 22% 90%)", + text: "hsl(30 8% 30%)", + }, +}; + +function SummaryTile({ + label, + value, + tone, +}: { + label: string; + value: number; + tone: "oxblood" | "amber" | "ink" | "muted"; +}) { + const a = SUMMARY_ACCENTS[tone]; + return ( +
+
+ + + {label} + +
+
+ {value} +
+
+ {value === 0 ? "Clear" : value === 1 ? "row" : "rows"} +
+
+ ); +}