mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +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,42 @@
|
||||
"use client";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import {
|
||||
resolveDashboardLayout,
|
||||
type DashboardLayout,
|
||||
} from "@/lib/dashboard-layout";
|
||||
|
||||
/**
|
||||
* v1.4.25 W4 — shared reader for the dashboard-layout payload across
|
||||
* the insights surfaces.
|
||||
*
|
||||
* The mother page and every sub-page need the persisted
|
||||
* `comparisonBaseline` so the dashboard / insights chart-cog stays
|
||||
* in sync. The shape repeats the same `useQuery({ … queryKey:
|
||||
* queryKeys.dashboardWidgets() … })` four-line block that lived inline
|
||||
* on the mother page — extracted here so a new sub-page consumer drops
|
||||
* the boilerplate and so the TanStack-Query cache lookup stays
|
||||
* authoritative for every consumer.
|
||||
*
|
||||
* Returns the resolved `comparisonBaseline` (defaults to `"none"`)
|
||||
* directly so consumers don't have to remember the `resolveDashboardLayout`
|
||||
* fallback dance. `enabled` controls whether the query fires — the
|
||||
* sub-pages gate this on `useAuth().isAuthenticated`.
|
||||
*/
|
||||
export function useInsightsLayoutPrefs(enabled: boolean) {
|
||||
const { data } = useQuery({
|
||||
queryKey: queryKeys.dashboardWidgets(),
|
||||
queryFn: async () => {
|
||||
const res = await fetch("/api/dashboard/widgets");
|
||||
if (!res.ok) throw new Error("Failed to load dashboard layout");
|
||||
const json = await res.json();
|
||||
return json.data as DashboardLayout;
|
||||
},
|
||||
enabled,
|
||||
});
|
||||
const compareBaseline =
|
||||
resolveDashboardLayout(data).comparisonBaseline ?? "none";
|
||||
return { layout: data ?? null, compareBaseline } as const;
|
||||
}
|
||||
Reference in new issue
Block a user