feat(insights): open the briefing card on the day's signals

The recall/forward-look block read as a second briefing paragraph
above the structured list and pulled the card down — the card now
starts straight at 'signals of the day'. The section titles read in
the regular foreground, and the card's Ask-the-Coach corner entry is
gone; the Coach keeps its own surfaces.
This commit is contained in:
Marc-André Bombeck committed 2026-07-05 15:03:22 +02:00
1 parent a20aa845d9
commit ba17ca34eb
2 files changed
+13 -62

No files matched your search

+6 -11
View File
@@ -303,19 +303,18 @@ export default function InsightsPage() {
const analyticsQuery = useAnalyticsQuery();
const analytics = analyticsQuery.data as AnalyticsData | undefined;
// v1.21.2 (A4 / A5 / A6) — the dashboard snapshot is the single server source
// for the ambient narrative the hero + briefing surface: the Tension Verdict
// and return-to-baseline ride its `healthScore`, the briefing recall +
// forward-look rides `briefingMemory`. The hero score number itself stays on
// the analytics payload (unchanged); only these three additive, server-
// resolved DTO fields are lifted from the snapshot. Reads the same shared
// v1.21.2 (A5 / A6) — the dashboard snapshot is the single server source
// for the ambient narrative the hero surfaces: the Tension Verdict and
// return-to-baseline ride its `healthScore`. The hero score number itself
// stays on the analytics payload (unchanged). Reads the same shared
// `queryKeys.dashboardSnapshot()` cell the dashboard warms, so the insights
// visit pays at most one extra round-trip and usually a warm cache hit.
// (The A4 recall/forward-look block left the briefing card — the card now
// opens straight on the day's signals.)
const snapshotQuery = useDashboardSnapshot(isAuthenticated);
const snapshotHealthScore = snapshotQuery.data?.healthScore ?? null;
const heroTension = snapshotHealthScore?.tension ?? null;
const heroReturnToBand = snapshotHealthScore?.returnToBand ?? null;
const briefingMemory = snapshotQuery.data?.briefingMemory ?? null;
// v1.12.6 — the page owns the ONE overview derived batch. The wellness
// strip (above the briefing) and the vitals grid (below it) both read this
@@ -483,10 +482,6 @@ export default function InsightsPage() {
// v1.25.3 — failure class points the empty-state hint at the right
// lever (raise the response timeout vs re-check the provider).
generationFailureClass={advisor.generationFailureClass}
// v1.21.2 (A4) — server-resolved recall + forward-look off the dashboard
// snapshot. Both strings are already localised; null leaves the card's
// memory block unrendered.
memory={briefingMemory}
/>
) : null,
vitals: <VitalsDashboard batch={dashboardDerived} layout={layout} />,
+7 -51
View File
@@ -25,7 +25,6 @@ import { EmptyState } from "@/components/ui/empty-state";
import { ListRow } from "@/components/ui/list-row";
import { Skeleton } from "@/components/ui/skeleton";
import { SectionHeading } from "@/components/insights/section-heading";
import { AskCoachAction } from "@/components/insights/ask-coach-action";
import { useTranslations, useFormatters } from "@/lib/i18n/context";
import { formatUpdatedLabel } from "@/lib/i18n/relative-time";
import { stripChartTokens } from "@/lib/insights/chart-tokens";
@@ -140,20 +139,6 @@ interface DailyBriefingProps {
* comparison toggle migrates here from the hero in commit 5.
*/
metaSlot?: React.ReactNode;
/**
* v1.21.2 (A4) — server-resolved callback + forward-look. The briefing
* recalls the prior period and points ahead ("as I noted Monday, your sleep
* was short; it's recovered since — worth watching tonight"). Both strings
* are already localised and figure-anchored by the resolver; the card only
* renders them. One callback per surface — absent (the common case) when no
* prior narrative recall is on file.
*/
memory?: {
/** The recall of the prior-period read, anchored to a figure. */
recall: string;
/** The forward-look pointing ahead. */
forward: string;
} | null;
}
const METRIC_ICON: Record<
@@ -368,7 +353,6 @@ export function DailyBriefing({
generationFailed = false,
generationFailureClass = null,
metaSlot,
memory = null,
}: DailyBriefingProps) {
const { t } = useTranslations();
const fmt = useFormatters();
@@ -424,33 +408,11 @@ export function DailyBriefing({
// looser `space-y-4`, which read as taller than its neighbours on
// the overview. One token, no new spacing scale.
<div className="space-y-3">
{/* v1.21.2 (A4) — callback + forward-look. Recalls the prior
period and points ahead, both server-resolved and
figure-anchored. Leads the card so the briefing opens by
closing the loop on what it noted last, then looks forward. */}
{memory && (
<div
data-slot="daily-briefing-memory"
className="border-border/60 bg-card/40 space-y-1 rounded-md border px-3 py-2"
>
<p
data-slot="daily-briefing-memory-recall"
className="text-muted-foreground text-xs leading-snug"
>
{t("insights.briefing.memory.recall", {
text: memory.recall,
})}
</p>
<p
data-slot="daily-briefing-memory-forward"
className="text-foreground/80 text-xs leading-snug"
>
{t("insights.briefing.memory.forward", {
text: memory.forward,
})}
</p>
</div>
)}
{/* The v1.21.2 recall/forward-look block is gone: the card
opens straight on "signals of the day". The narrative
memory read as a second briefing paragraph above the
structured list and pulled the card down; the server
still resolves `briefingMemory` for other consumers. */}
{/* v1.4.27 B1 — the leading narrative paragraph dropped.
The hero strip subtitle on `/insights` already renders
the same `briefing.paragraph` text directly above this
@@ -465,7 +427,7 @@ export function DailyBriefing({
<div className="space-y-2">
<p
data-slot="daily-briefing-signals-title"
className="text-muted-foreground text-xs font-semibold tracking-wide uppercase"
className="text-foreground text-xs font-semibold tracking-wide uppercase"
>
{t("insights.dailyBriefing.signalsTitle")}
</p>
@@ -483,7 +445,7 @@ export function DailyBriefing({
<div className="space-y-2">
<p
data-slot="daily-briefing-findings-title"
className="text-muted-foreground text-xs font-semibold tracking-wide uppercase"
className="text-foreground text-xs font-semibold tracking-wide uppercase"
>
{t("insights.dailyBriefing.keyFindingsTitle")}
</p>
@@ -565,12 +527,6 @@ export function DailyBriefing({
)}
</div>
)}
{/* v1.21.0 (C4 H2) — hand off to the Coach for the whole
picture. The briefing spans every metric, so no scope: the
default all-source snapshot reads best here. */}
<div className="flex justify-end">
<AskCoachAction question={t("insights.coach.seed.briefing")} />
</div>
</div>
) : noProvider ? (
// v1.15.20 — no provider configured anywhere: a regenerate CTA