diff --git a/messages/de.json b/messages/de.json index 5c5a46b7b..1047b2c5b 100644 --- a/messages/de.json +++ b/messages/de.json @@ -340,8 +340,7 @@ "logMeasurement": "Messung erfassen" }, "briefing": { - "title": "Tagesbriefing", - "viewAll": "Insights öffnen" + "title": "Tagesbriefing" } }, "greetingSalutation": "Hallo, {name}", diff --git a/messages/en.json b/messages/en.json index f5e419f74..39de8b24b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -340,8 +340,7 @@ "logMeasurement": "Log measurement" }, "briefing": { - "title": "Today’s briefing", - "viewAll": "Open Insights" + "title": "Today’s briefing" } }, "greetingSalutation": "Hi, {name}", diff --git a/messages/es.json b/messages/es.json index 3f42877e9..ae92a339a 100644 --- a/messages/es.json +++ b/messages/es.json @@ -340,8 +340,7 @@ "logMeasurement": "Registrar medición" }, "briefing": { - "title": "Resumen de hoy", - "viewAll": "Abrir Insights" + "title": "Resumen de hoy" } }, "greetingSalutation": "Hola, {name}", diff --git a/messages/fr.json b/messages/fr.json index 82c8922ef..23645cb90 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -340,8 +340,7 @@ "logMeasurement": "Saisir une mesure" }, "briefing": { - "title": "Briefing du jour", - "viewAll": "Ouvrir Insights" + "title": "Briefing du jour" } }, "greetingSalutation": "Bonjour, {name}", diff --git a/messages/it.json b/messages/it.json index 0c572fa4c..04c1c0381 100644 --- a/messages/it.json +++ b/messages/it.json @@ -340,8 +340,7 @@ "logMeasurement": "Registra misurazione" }, "briefing": { - "title": "Briefing di oggi", - "viewAll": "Apri Insights" + "title": "Briefing di oggi" } }, "greetingSalutation": "Ciao, {name}", diff --git a/messages/pl.json b/messages/pl.json index eec36bce2..914bbd61b 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -340,8 +340,7 @@ "logMeasurement": "Zapisz pomiar" }, "briefing": { - "title": "Briefing dnia", - "viewAll": "Otwórz Insights" + "title": "Briefing dnia" } }, "greetingSalutation": "Cześć, {name}", diff --git a/src/components/dashboard/hero/__tests__/briefing-spotlight.test.tsx b/src/components/dashboard/hero/__tests__/briefing-spotlight.test.tsx index 8c72401be..2d6a6eb34 100644 --- a/src/components/dashboard/hero/__tests__/briefing-spotlight.test.tsx +++ b/src/components/dashboard/hero/__tests__/briefing-spotlight.test.tsx @@ -117,7 +117,10 @@ describe("", () => { }); expect(html).toContain('data-slot="dashboard-briefing-spotlight"'); expect(html).toContain("Short on sleep this week"); - expect(html).toContain('href="/insights"'); + // The heading itself links to the briefing card anchor; the former + // separate "view all" text link is gone. + expect(html).toContain('href="/insights#daily-briefing"'); + expect(html).not.toContain('data-slot="dashboard-briefing-spotlight-link"'); expect(html).toContain("-1.2 h"); // Signals win over key findings when present. expect(html).not.toContain("should not appear when signals exist"); diff --git a/src/components/dashboard/hero/briefing-spotlight.tsx b/src/components/dashboard/hero/briefing-spotlight.tsx index dcdc6f95a..5954030a8 100644 --- a/src/components/dashboard/hero/briefing-spotlight.tsx +++ b/src/components/dashboard/hero/briefing-spotlight.tsx @@ -152,18 +152,17 @@ export function BriefingSpotlight({ return (
-
-

- {t("dashboard.hero.briefing.title")} -

- - {t("dashboard.hero.briefing.viewAll")} - -
+ {/* The heading itself routes to the briefing card on /insights — + quiet (no underline, hover lift only). The former separate + "open Insights" text link is gone: it thickened the card while + every signal row below already deep-links. */} + + {t("dashboard.hero.briefing.title")} +
{rows.map((row, index) => { const Icon = METRIC_ICON[row.sourceMetric]; diff --git a/src/components/dashboard/hero/dashboard-hero.tsx b/src/components/dashboard/hero/dashboard-hero.tsx index ed226a59d..08133cb84 100644 --- a/src/components/dashboard/hero/dashboard-hero.tsx +++ b/src/components/dashboard/hero/dashboard-hero.tsx @@ -53,6 +53,7 @@ import { ScoreRing } from "@/components/insights/derived/score-ring"; import type { RingHue } from "@/components/insights/derived/ring-hues"; import { RestModeBanner } from "@/components/insights/rest-mode-banner"; import { BriefingSpotlight } from "@/components/dashboard/hero/briefing-spotlight"; +import { METRIC_HREF } from "@/components/insights/daily-briefing"; import { resolveDashboardVerdict, type DashboardVerdictVariant, @@ -199,6 +200,23 @@ export function DashboardHero({ const cta = verdict.cta; const ctaLabelKey = CTA_LABEL_KEY[verdict.variant]; + // Link-CTA verdicts WITHOUT a button label (scoreDrop, briefing) make + // the sentence itself the link — after the broad "open Insights" + // button was dropped the sentence was a dead end. The briefing + // sentence deep-links to the picked finding's metric sub-page (the + // METRIC_HREF map the briefing rows use); metrics without a routed + // sub-page fall back to the resolver's `/insights` href. Verdicts + // with their own action (take dose, view BP, …) keep the button. + const sentenceHref = + cta !== null && cta.kind === "link" && !ctaLabelKey + ? verdict.variant === "briefing" && + typeof verdict.values.sourceMetric === "string" + ? (METRIC_HREF[ + verdict.values.sourceMetric as keyof typeof METRIC_HREF + ] ?? cta.href) + : cta.href + : null; + // ── Provisional score copy ────────────────────────────────────────── // The score's four pillars are weight, BP, mood, and medication // compliance. When ANY of them already carries data, a null score is @@ -250,13 +268,24 @@ export function DashboardHero({ {welcomeText}

-

- {sentence} -

+ {sentenceHref ? ( + + {sentence} + + ) : ( +

+ {sentence} +

+ )} {cta !== null && ctaLabelKey ? ( cta.kind === "link" ? (