mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
feat(insights): scaffold 6 metric sub-pages with shared layout shell
Carves the v1.4.24 monolithic /insights page into routed sub-pages
under /insights/{blutdruck,gewicht,puls,stimmung,medikamente,bmi}.
Each sub-page renders its metric chart with the per-chart cog
(chartKey from CHART_OVERLAY_KEYS) and the existing AI status card;
empty states surface a CTA where the chart can't compute (BMI without
height, mood with zero entries, medication adherence without a tracked
medication).
The sticky tab strip moves into src/app/insights/layout.tsx via the
new <InsightsLayoutShell>, which also owns the advisor query so the
regenerate affordance stays reachable from every Insights surface.
The tab strip itself is now route-aware (<Link> + usePathname()) and
exposes an "Overview" pill for the mother page. The CoachDrawer stays
in the mother-page body only — per Marc's directive, navigating to a
sub-page must unmount the drawer.
Shared infrastructure:
- src/lib/insights/sub-page-metric.ts: slug → MeasurementType[] map
+ SUB_PAGE_SLUGS canonical order.
- src/hooks/use-insights-layout-prefs.ts: reader for the dashboard-
layout payload so every sub-page picks up the comparisonBaseline
without re-fetching.
- src/components/insights/sub-page-shell.tsx: title + optional badge
+ focusable h1 (a11y — screen-reader focus restoration on tab
navigation).
- src/components/insights/insights-layout-shell.tsx: the layout's
client shell that mounts the strip + threads the regenerate handler.
The 7th sub-page (/insights/schlaf) ships in the follow-up W4c commit
together with its sleep-stage chart components.
This commit is contained in:
1 parent
2668020d92
commit
38bbba110a
13 files changed
+1187
-109
No files matched your search
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* v1.4.25 W4 — slug → metric mapping for the routed insights sub-pages.
|
||||
*
|
||||
* The mother page (`/insights`) hosts the overview (hero + briefing +
|
||||
* trends + advisor). Each named slug below is a sub-route that focuses
|
||||
* one metric. Charts on the sub-pages still use the dashboard chart-cog
|
||||
* surface — see `chartKey` strings in `src/lib/dashboard-layout.ts`
|
||||
* (`CHART_OVERLAY_KEYS`). The slugs themselves are German because the
|
||||
* product surface is bilingual and German is the primary author voice.
|
||||
*
|
||||
* `medikamente` carries no `MeasurementType[]` because medication
|
||||
* compliance is event-driven (`MedicationIntakeEvent` rows) rather than
|
||||
* time-series `Measurement` rows; the page fetches that data via the
|
||||
* existing `/api/insights/comprehensive` consumer.
|
||||
*
|
||||
* `bmi` lists both `WEIGHT` + `BODY_HEIGHT` because BMI is derived
|
||||
* client-side — `WEIGHT / (heightCm/100)^2` — and the chart sets
|
||||
* `valueMode="bmi"` on `<HealthChart>`. `BODY_HEIGHT` is informational
|
||||
* only (we don't fetch a height series; the user's height lives on the
|
||||
* profile).
|
||||
*/
|
||||
export type SubPageSlug =
|
||||
| "blutdruck"
|
||||
| "gewicht"
|
||||
| "puls"
|
||||
| "stimmung"
|
||||
| "medikamente"
|
||||
| "bmi"
|
||||
| "schlaf";
|
||||
|
||||
export const SUB_PAGE_SLUGS = [
|
||||
"blutdruck",
|
||||
"gewicht",
|
||||
"puls",
|
||||
"stimmung",
|
||||
"medikamente",
|
||||
"bmi",
|
||||
"schlaf",
|
||||
] as const satisfies readonly SubPageSlug[];
|
||||
|
||||
export const SUB_PAGE_METRIC: Record<SubPageSlug, string[]> = {
|
||||
blutdruck: ["BLOOD_PRESSURE_SYS", "BLOOD_PRESSURE_DIA", "PULSE"],
|
||||
gewicht: ["WEIGHT"],
|
||||
puls: ["PULSE"],
|
||||
stimmung: ["MOOD"],
|
||||
// medication adherence is event-driven; no measurement series.
|
||||
medikamente: [],
|
||||
// BMI is derived from WEIGHT + profile height (no separate series).
|
||||
bmi: ["WEIGHT"],
|
||||
schlaf: ["SLEEP_DURATION"],
|
||||
};
|
||||
|
||||
/**
|
||||
* Mother-page route. Kept here as a named constant so call sites
|
||||
* never have to hard-code the string.
|
||||
*/
|
||||
export const INSIGHTS_OVERVIEW_PATH = "/insights" as const;
|
||||
|
||||
export function isSubPageSlug(value: string): value is SubPageSlug {
|
||||
return (SUB_PAGE_SLUGS as readonly string[]).includes(value);
|
||||
}
|
||||
Reference in new issue
Block a user