Files
HealthLog/src/components/settings/layout-groups.ts
T
Marc-André Bombeck f17819f1c2 fix(settings): English addresses for the health record and checkups pages
Two Settings pages had German words in their address in every
language: /settings/gesundheitsakte and /settings/layout/vorsorge.
They are /settings/health-record and /settings/layout/checkups now,
and the old addresses (and the older /settings/sharing and
/settings/vorsorge) redirect permanently, so bookmarks and links in
old reports keep working; the report range a since-last-visit link
carries in its query passes through. The in-app links, the tour, the
command palette, the anchor forwards and the e2e specs use the new
addresses, and the two message groups follow the new slugs.
2026-11-11 22:47:40 +01:00

118 lines
4.6 KiB
TypeScript

import type { JSX } from "react";
import type { ModuleKey } from "@/lib/modules/registry";
import { surfaceModule } from "@/lib/modules/surface";
import { DashboardSection } from "./dashboard-section";
import { InsightsSection } from "./insights-section";
import { MedicationsSection } from "./medications-section";
import { LabsSection } from "./labs-section";
import { IllnessSection } from "./illness-section";
import { DocumentsSection } from "./documents-section";
import { VorsorgeSection } from "./vorsorge-section";
/**
* v1.25.11 (#148) — single source of truth for the "Layout" (slug
* `layout`) hub + its per-module subpages.
*
* "How my app looks and is arranged" was scattered across several unrelated
* settings sections. The `layout` slug is the one front door. v1.25.7 stacked
* every module's view/sort surface inline on a single page; #148 splits that
* back into a HUB → SUBPAGE model: `/settings/layout` lists the modules as
* clickable rows, and each row opens `/settings/layout/<id>`, which renders
* ONLY that module's section (the same existing section component, verbatim)
* with a "← Layout" back-link.
*
* This module is intentionally NOT `"use client"`: the client hub
* (`layout-section.tsx`) AND the server subpage route
* (`app/settings/layout/[module]/page.tsx`, which reads `LAYOUT_GROUP_IDS` in
* `generateStaticParams()`) both consume it, so its array values must stay
* usable on the server. It holds references to the `"use client"` section
* components, which a server component renders as ordinary client boundaries.
*
* v1.44 — the hub holds order and view only ("Arrangement"). The mood tag
* management, the labs biomarker catalog and text recognition, and the
* injection sites moved to the module pages under Settings > Modules
* (`module-settings-pages.tsx`); `/settings/layout/mood` redirects there.
*
* Each module section keeps its module-gate: a disabled module's row / subpage
* does not render, read from the resolved `useAuth().user.modules` map (the
* same map the nav, the Modules hub, and the Insights pills gate off). The gate
* fails OPEN (`!== false`) so a stale `/me` payload never blanks an entry.
* Vorsorge (preventive-care reminders) is not a toggleable module, so it always
* shows.
*/
export interface LayoutGroup {
/** Stable id — the subpage path segment (`/settings/layout/<id>`). */
id: string;
/** i18n key under `settings.sections.layout.<slug>.title`. */
titleKey: string;
/** i18n key under `settings.sections.layout.<slug>.description`. */
descriptionKey: string;
Body: () => JSX.Element | null;
}
/**
* The module a layout group belongs to, from the one surface map
* (`settings-layout:<id>`), or `undefined` for a group that is always shown.
* The row and its sub-page render only while that module is on (fail-open,
* `!== false`).
*/
export function layoutGroupModule(id: string): ModuleKey | undefined {
return surfaceModule(`settings-layout:${id}`);
}
export const LAYOUT_GROUPS: ReadonlyArray<LayoutGroup> = [
{
id: "dashboard",
titleKey: "settings.sections.layout.dashboard.title",
descriptionKey: "settings.sections.layout.dashboard.description",
Body: DashboardSection,
},
{
id: "insights",
titleKey: "settings.sections.layout.insights.title",
descriptionKey: "settings.sections.layout.insights.description",
Body: InsightsSection,
},
{
id: "medications",
titleKey: "settings.sections.layout.medications.title",
descriptionKey: "settings.sections.layout.medications.description",
Body: MedicationsSection,
},
{
id: "labs",
titleKey: "settings.sections.layout.labs.title",
descriptionKey: "settings.sections.layout.labs.description",
Body: LabsSection,
},
{
id: "illness",
titleKey: "settings.sections.layout.illness.title",
descriptionKey: "settings.sections.layout.illness.description",
Body: IllnessSection,
},
{
id: "documents",
titleKey: "settings.sections.layout.documents.title",
descriptionKey: "settings.sections.layout.documents.description",
Body: DocumentsSection,
},
{
// The address read `vorsorge` in every language; that one redirects.
id: "checkups",
titleKey: "settings.sections.layout.checkups.title",
descriptionKey: "settings.sections.layout.checkups.description",
Body: VorsorgeSection,
},
];
/** Ordered list of the subpage path segments — server-safe for `generateStaticParams()`. */
export const LAYOUT_GROUP_IDS: readonly string[] = LAYOUT_GROUPS.map(
(group) => group.id,
);
export function isLayoutGroupId(value: string): boolean {
return LAYOUT_GROUP_IDS.includes(value);
}