diff --git a/src/components/inbox/CandidateBreakdown.test.tsx b/src/components/inbox/CandidateBreakdown.test.tsx
new file mode 100644
index 0000000..134bb5c
--- /dev/null
+++ b/src/components/inbox/CandidateBreakdown.test.tsx
@@ -0,0 +1,23 @@
+// @vitest-environment happy-dom
+import { afterEach, describe, expect, it } from "vitest";
+import { cleanup, render } from "@testing-library/react";
+import { CandidateBreakdown } from "./CandidateBreakdown";
+
+afterEach(() => cleanup());
+
+describe("CandidateBreakdown", () => {
+ it("renders per-field scores", () => {
+ const { container } = render(
+ ,
+ );
+ expect(container.textContent).toMatch(/patient/i);
+ expect(container.textContent).toMatch(/date/i);
+ expect(container.textContent).toMatch(/amount/i);
+ expect(container.textContent).toMatch(/provider/i);
+ expect(container.textContent).toContain("92");
+ });
+});
diff --git a/src/components/inbox/CandidateBreakdown.tsx b/src/components/inbox/CandidateBreakdown.tsx
new file mode 100644
index 0000000..abdf8ec
--- /dev/null
+++ b/src/components/inbox/CandidateBreakdown.tsx
@@ -0,0 +1,56 @@
+import type { ScoreBreakdown, ScoreTier } from "@/lib/inbox-api";
+
+const FIELDS: Array<{ key: keyof ScoreBreakdown; label: string; weight: number }> = [
+ { key: "patient", label: "Patient", weight: 40 },
+ { key: "date", label: "Date", weight: 25 },
+ { key: "amount", label: "Amount", weight: 20 },
+ { key: "provider", label: "Provider", weight: 15 },
+];
+
+export function CandidateBreakdown({
+ score,
+ breakdown,
+ tier,
+}: {
+ score: number;
+ breakdown: ScoreBreakdown;
+ tier: ScoreTier;
+}) {
+ return (
+
+
+
+ Score
+
+
+ {score}
+
+
+
+ {FIELDS.map((f) => (
+ -
+ {f.label}
+
+ {Math.round(breakdown[f.key] * f.weight)} / {f.weight}
+
+
+ ))}
+
+
+ {tier}
+
+
+ );
+}
diff --git a/src/components/inbox/InboxHeader.test.tsx b/src/components/inbox/InboxHeader.test.tsx
new file mode 100644
index 0000000..b109844
--- /dev/null
+++ b/src/components/inbox/InboxHeader.test.tsx
@@ -0,0 +1,14 @@
+// @vitest-environment happy-dom
+import { afterEach, describe, expect, it } from "vitest";
+import { cleanup, render } from "@testing-library/react";
+import { InboxHeader } from "./InboxHeader";
+
+afterEach(() => cleanup());
+
+describe("InboxHeader", () => {
+ it("renders the date and counts", () => {
+ const { container } = render();
+ expect(container.textContent).toMatch(/6.*items need eyes/);
+ expect(container.textContent).toMatch(/23.*done today/);
+ });
+});
diff --git a/src/components/inbox/InboxHeader.tsx b/src/components/inbox/InboxHeader.tsx
new file mode 100644
index 0000000..02f9690
--- /dev/null
+++ b/src/components/inbox/InboxHeader.tsx
@@ -0,0 +1,50 @@
+export function InboxHeader({
+ needEyesCount,
+ doneTodayCount,
+}: {
+ needEyesCount: number;
+ doneTodayCount: number;
+}) {
+ const now = new Date();
+ const day = now.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase();
+ const time = now.toLocaleTimeString("en-US", {
+ hour: "2-digit",
+ minute: "2-digit",
+ hour12: false,
+ });
+
+ return (
+
+ );
+}