ff0985d244
InboxHeader: - Editorial dark hero replaces the 30px sticky header - Massive 'Inbox.' (clamp 48-80px) with ghost amber 'TRIAGE' watermark - Italic subtitle: 'Five lanes, one queue. N need eyes; N done today.' - Right column: SUN JUN 21 / 14:15 / local - Live status row: amber pulse + counts + date Inbox page: - Amber fold with '↘ FIVE LANES · ONE QUEUE ↙' between header and lanes - Lanes stay dark (working surface preserved) - New paper-toned Queue ledger panel below lanes: - Title block: 'The eye-flow, at a glance.' with need-eyes total - 5 paper tiles (Rejected / Payer rejected / Candidates / Unmatched / Done today) - Each tile shows lane accent dot + count + 'Clear'/'rows' chip - Loading and error states now also use the new InboxHeader for consistency - SummaryTile helper with paper-toned metric cards
183 lines
5.5 KiB
TypeScript
183 lines
5.5 KiB
TypeScript
// ---------------------------------------------------------------------------
|
|
// InboxHeader
|
|
//
|
|
// 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,
|
|
}: {
|
|
needEyesCount: number;
|
|
doneTodayCount: number;
|
|
}) {
|
|
const now = new Date();
|
|
const day = now.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase();
|
|
const date = now.toLocaleDateString("en-US", {
|
|
month: "short",
|
|
day: "2-digit",
|
|
});
|
|
const time = now.toLocaleTimeString("en-US", {
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
hour12: false,
|
|
});
|
|
|
|
return (
|
|
<header
|
|
className="sticky top-0 z-10 px-6 lg:px-10 pt-6 pb-5"
|
|
style={{
|
|
background: "var(--tt-bg)",
|
|
borderBottom: "1px solid var(--tt-bg-elev)",
|
|
}}
|
|
>
|
|
<div className="relative">
|
|
{/* Ghost "TRIAGE" watermark — a print-shop stamp behind the title. */}
|
|
<div
|
|
aria-hidden
|
|
className="pointer-events-none select-none absolute inset-x-0 top-1/2 -translate-y-1/2 whitespace-nowrap display text-center"
|
|
style={{
|
|
fontSize: "clamp(120px, 18vw, 260px)",
|
|
letterSpacing: "-0.05em",
|
|
opacity: 0.05,
|
|
lineHeight: 1,
|
|
color: "var(--tt-amber)",
|
|
}}
|
|
>
|
|
TRIAGE
|
|
</div>
|
|
|
|
<div className="relative flex items-end justify-between gap-6 flex-wrap">
|
|
<div className="min-w-0 max-w-3xl">
|
|
<div className="flex items-center gap-3 mb-3">
|
|
<div
|
|
className="h-px w-14"
|
|
style={{ backgroundColor: "var(--tt-amber)" }}
|
|
/>
|
|
<span
|
|
className="mono uppercase"
|
|
style={{
|
|
color: "var(--tt-amber)",
|
|
fontSize: 11,
|
|
letterSpacing: "0.22em",
|
|
fontWeight: 600,
|
|
}}
|
|
>
|
|
Inbox · Working surface
|
|
</span>
|
|
</div>
|
|
<h1
|
|
className="display tracking-[-0.04em]"
|
|
style={{
|
|
color: "var(--tt-ink)",
|
|
fontSize: "clamp(48px, 6vw, 80px)",
|
|
lineHeight: 0.92,
|
|
fontWeight: 400,
|
|
}}
|
|
>
|
|
Inbox.
|
|
</h1>
|
|
<p
|
|
className="display italic mt-3"
|
|
style={{
|
|
color: "var(--tt-ink-dim)",
|
|
fontSize: "clamp(15px, 1.4vw, 19px)",
|
|
lineHeight: 1.4,
|
|
maxWidth: "44ch",
|
|
}}
|
|
>
|
|
Five lanes, one queue.{" "}
|
|
<span style={{ color: "var(--tt-amber)" }}>
|
|
{needEyesCount}
|
|
</span>{" "}
|
|
need eyes; {doneTodayCount} are done today.
|
|
</p>
|
|
</div>
|
|
|
|
<div
|
|
className="flex flex-col items-start lg:items-end gap-2"
|
|
aria-label="Day and time"
|
|
>
|
|
<div
|
|
className="mono uppercase"
|
|
style={{
|
|
color: "var(--tt-ink-dim)",
|
|
fontSize: 11,
|
|
letterSpacing: "0.22em",
|
|
fontWeight: 500,
|
|
}}
|
|
>
|
|
{day} {date}
|
|
</div>
|
|
<div
|
|
className="display tabular-nums"
|
|
style={{
|
|
color: "var(--tt-ink)",
|
|
fontSize: 26,
|
|
lineHeight: 1,
|
|
fontWeight: 400,
|
|
}}
|
|
>
|
|
{time}
|
|
</div>
|
|
<div
|
|
className="mono uppercase"
|
|
style={{
|
|
color: "var(--tt-ink-dim)",
|
|
fontSize: 10,
|
|
letterSpacing: "0.20em",
|
|
}}
|
|
>
|
|
local
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Live status row — a horizontal "ticker" of the lane counts so
|
|
the operator can read the queue at a glance. */}
|
|
<div
|
|
className="relative mt-5 flex items-center gap-5 flex-wrap mono uppercase"
|
|
style={{
|
|
color: "var(--tt-ink-dim)",
|
|
fontSize: 11,
|
|
letterSpacing: "0.14em",
|
|
}}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<span
|
|
aria-hidden
|
|
className="inline-block w-1.5 h-1.5 rounded-full animate-pulse-dot"
|
|
style={{ background: "var(--tt-amber)" }}
|
|
/>
|
|
<span>Live</span>
|
|
</div>
|
|
<span className="opacity-50">·</span>
|
|
<span>
|
|
<span style={{ color: "var(--tt-amber)", fontWeight: 600 }}>
|
|
{needEyesCount}
|
|
</span>{" "}
|
|
need eyes
|
|
</span>
|
|
<span className="opacity-50">·</span>
|
|
<span>
|
|
<span style={{ color: "var(--tt-ink)", fontWeight: 600 }}>
|
|
{doneTodayCount}
|
|
</span>{" "}
|
|
done today
|
|
</span>
|
|
<span className="opacity-50 hidden sm:inline">·</span>
|
|
<span className="hidden sm:inline">
|
|
{fmt.date(new Date().toISOString())}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|