diff --git a/docs/branch-review-records/b56ee4be00d225db51c54f2debc8c43e4fe2b0123f4aaf6c647811c847b94790.record.md b/docs/branch-review-records/b56ee4be00d225db51c54f2debc8c43e4fe2b0123f4aaf6c647811c847b94790.record.md new file mode 100644 index 0000000000..20dffd2071 --- /dev/null +++ b/docs/branch-review-records/b56ee4be00d225db51c54f2debc8c43e4fe2b0123f4aaf6c647811c847b94790.record.md @@ -0,0 +1 @@ +| 2026-08-18 | claude/patient-factsheets-search-regression-8iyvnd | 5c93cffd7e4cfa876e3926d8b40c4ae9bb0a84da | src/components/factsheets/factsheets-home-page.tsx,src/components/factsheets/factsheets-data.ts,src/components/factsheets/factsheets-icons.ts,tests/mode-home-loading-contract.test.ts | approved | verify:pr-local (all 10 checks passed), live Playwright screenshot check at 390x844 | diff --git a/src/components/factsheets/factsheets-data.ts b/src/components/factsheets/factsheets-data.ts index d0c61336ae..170ebace18 100644 --- a/src/components/factsheets/factsheets-data.ts +++ b/src/components/factsheets/factsheets-data.ts @@ -627,7 +627,7 @@ export const factsheets: Factsheet[] = [ const bySlug = new Map(factsheets.map((sheet) => [sheet.slug, sheet])); -/** Sheets shown on the home "Start with a factsheet" grid, in curated order. */ +/** Curated slugs worth promoting elsewhere (e.g. related-content surfaces); kept in order. */ export const featuredFactsheetSlugs = ["sertraline", "depression", "gad", "ssri", "cbt", "lithium-monitoring"]; const relatedMap: Record = { @@ -649,10 +649,6 @@ export function factsheetSlugs(): string[] { return factsheets.map((sheet) => sheet.slug); } -export function featuredFactsheets(): Factsheet[] { - return featuredFactsheetSlugs.map((slug) => bySlug.get(slug)).filter((sheet): sheet is Factsheet => Boolean(sheet)); -} - /** Server-driven filter for the search page: optional query + optional category. */ export function filterFactsheets(query: string, category?: string): Factsheet[] { const q = query.trim().toLowerCase(); @@ -680,11 +676,6 @@ export function sameTopicFactsheets(slug: string): Factsheet[] { return factsheets.filter((entry) => entry.category === sheet.category && entry.slug !== sheet.slug); } -/** Count of sheets per category, for the home browse pills. */ -export function categoryCount(category: FactsheetCategory): number { - return factsheets.filter((sheet) => sheet.category === category).length; -} - // ---- Print + table-of-contents projections ------------------------------------------------- export type PrintBlock = diff --git a/src/components/factsheets/factsheets-home-page.tsx b/src/components/factsheets/factsheets-home-page.tsx index 6758948b8e..295e11f716 100644 --- a/src/components/factsheets/factsheets-home-page.tsx +++ b/src/components/factsheets/factsheets-home-page.tsx @@ -1,140 +1,26 @@ -import Link from "next/link"; -import { ArrowRight, BookOpenText, Clock } from "lucide-react"; +import { BookOpenText } from "lucide-react"; -import { categoryCount, factsheetCategories, featuredFactsheets } from "@/components/factsheets/factsheets-data"; -import { cardAccentEdge, cardInteractive, focusRing } from "@/components/card-recipes"; -import { factsheetCategoryGlyph, factsheetGlyph } from "@/components/factsheets/factsheets-icons"; -import { DesktopComposerPortalSlot } from "@/components/desktop-composer-portal-slot"; -import { ModeHomeHero, ModeHomeVerificationFooter } from "@/components/mode-home-template"; -import { cn, eyebrowText } from "@/components/ui-primitives"; -import { FACTSHEET_CATEGORY_IDENTITY } from "@/lib/category-identity"; +import { ModeHomeMain, ModeHomeTemplate, ModeHomeVerificationFooter } from "@/components/mode-home-template"; import { modeHomeDesktopComposerSlotId } from "@/lib/mode-home-composer"; export function FactsheetsHomePage() { - const featured = featuredFactsheets(); - return ( -
-
- - - {/* The universal composer portals itself into this slot on the mode home (hero placement). */} - - -
-

Browse by topic

-
- {factsheetCategories.map((category) => { - return ( - - - {factsheetCategoryGlyph(category, "size-icon-sm")} - - {category} - - {categoryCount(category)} - - - ); - })} -
-
- -
-
-
- -

- Dated demonstration content, written in plain language. -

-
- - View all sheets -
- -
- {featured.map((sheet) => { - return ( - -
- - {factsheetGlyph(sheet.icon, "size-icon-lg")} - - - {sheet.category} - -
-

- {sheet.title} - {sheet.brand ? ( - {sheet.brand} - ) : null} -

-

- {sheet.summary} -

-
- - - {sheet.readTime} -
- - ); - })} -
-
- -
+ + -
-
-
+ } + /> + ); } diff --git a/src/components/factsheets/factsheets-icons.ts b/src/components/factsheets/factsheets-icons.ts index 447f97d269..60c20b8587 100644 --- a/src/components/factsheets/factsheets-icons.ts +++ b/src/components/factsheets/factsheets-icons.ts @@ -1,7 +1,5 @@ import { Activity, - BrainCircuit, - ClipboardList, CloudRain, Droplet, HeartPulse, @@ -15,7 +13,7 @@ import { } from "lucide-react"; import { createElement } from "react"; -import type { FactsheetCategory, FactsheetIconKey } from "@/components/factsheets/factsheets-data"; +import type { FactsheetIconKey } from "@/components/factsheets/factsheets-data"; /** Stable icon-key → Lucide component map for per-sheet icons. */ const factsheetIcons: Record = { @@ -32,14 +30,6 @@ const factsheetIcons: Record = { droplet: Droplet, }; -/** Category browse icons for the home topic pills. */ -const factsheetCategoryIcons: Record = { - Medications: Pill, - Conditions: BrainCircuit, - Therapies: MessagesSquare, - "Tests & procedures": ClipboardList, -}; - /** * Render a Lucide glyph without binding a capitalised component to a render-body * local (which `react-hooks/static-components` forbids). @@ -47,7 +37,3 @@ const factsheetCategoryIcons: Record = { export function factsheetGlyph(icon: FactsheetIconKey, className: string) { return createElement(factsheetIcons[icon], { className, "aria-hidden": "true" }); } - -export function factsheetCategoryGlyph(category: FactsheetCategory, className: string) { - return createElement(factsheetCategoryIcons[category], { className, "aria-hidden": "true" }); -} diff --git a/tests/mode-home-loading-contract.test.ts b/tests/mode-home-loading-contract.test.ts index c636184579..ba95eb94e5 100644 --- a/tests/mode-home-loading-contract.test.ts +++ b/tests/mode-home-loading-contract.test.ts @@ -93,6 +93,22 @@ describe("mode-home loading contract", () => { expect(source).toContain("pathname === THERAPY_HOME"); }); + it("routes Factsheets' mode home body through the shared ModeHomeTemplate composer host", () => { + // A hand-rolled composer slot (as Factsheets briefly had) omits the SSR + // data-composer-reserve/min-h reserve that ModeHomeTemplate provides, which + // regresses the shared "one composer host" contract — see + // docs/search-chrome-behaviour.md Invariant 15. + const factsheetsSource = readFileSync( + join(process.cwd(), "src/components/factsheets/factsheets-home-page.tsx"), + "utf8", + ); + expect(factsheetsSource).toMatch( + /import\s*\{[^}]*ModeHomeTemplate[^}]*\}\s*from\s*"@\/components\/mode-home-template"/, + ); + expect(factsheetsSource).toMatch(/ { const skeletonSource = readFileSync(join(process.cwd(), "src/components/mode-home-page-skeleton.tsx"), "utf8"); expect(skeletonSource).toContain("items-start");