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} + +
+ +

+ {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 ( +
+

+ INBOX{" "} + + · {day} {time} + +

+

+ {needEyesCount} items need eyes ·{" "} + {doneTodayCount} done today +

+
+ ); +}