feat(settings): nine groups, module pages and one switch per state

Settings now reads as nine groups: Account, Tracking, Arrangement,
Notifications, Health profile, AI, Connections, Data and System. On a
phone one button names the current section and opens the grouped list,
replacing the strip of every section.

What moved, every old address still working:
- Sessions, trusted devices and security activity sit under Security;
  the privacy page anchors forward there.
- Notifications holds every reminder kind: the Coach nudges and the
  checkup reminder switches joined, and a card names the reminders set
  where their subject lives (dose times, cycle reminders).
- Arrangement holds order and view only. Mood tags, the labs biomarker
  catalog and on-device text recognition, and the injection sites live on
  module pages under /settings/modules/<id>, linked from each Modules row
  and from the module's own wrench. /settings/layout/mood redirects.
- The timezone saves on change in the Display card, with a one-tap offer
  of the device zone.
- Screening hints sit beside the life circumstances they come from.
- System gains Preview features with the Topics switch.

Duplicates: the Coach and MCP pages show their state and link to the one
switch in Modules (turning MCP off keeps tokens), the Coach overlay shows
the provider and model with a link to Settings > AI instead of a second
set of selects, and the privacy page drops its copy of the export links.

A guard walks every historical /settings address through the redirects
and every forwarded anchor to a page that renders.
This commit is contained in:
Marc-André Bombeck committed 2026-10-21 19:43:02 +02:00
1 parent 3ebef19ac3
commit 71dbef1742
76 files changed
+2517 -1806

No files matched your search

@@ -48,6 +48,7 @@ import { NAV_DESTINATIONS } from "@/components/layout/nav-model";
import { CAPTURE_KIND_ORDER } from "@/components/layout/capture-picker";
import { SETTINGS_SECTIONS } from "@/components/settings/settings-shell";
import { LAYOUT_GROUP_IDS } from "@/components/settings/layout-groups";
import { MODULE_SETTINGS_PAGE_IDS } from "@/components/settings/module-settings-page-ids";
import {
DASHBOARD_WIDGET_CATALOGUE_IDS,
SCORE_RING_IDS,
@@ -160,6 +161,13 @@ describe("every surface id names a surface that exists", () => {
}
});
it("settings-module: a module page under Settings > Modules", () => {
const ids = new Set<string>(MODULE_SETTINGS_PAGE_IDS);
for (const id of localIds("settings-module")) {
expect(ids.has(id), id).toBe(true);
}
});
it("day-section: a section the day view renders", () => {
const keys = new Set<string>(DAY_SECTION_KEYS);
for (const id of localIds("day-section")) {
+7 -1
View File
@@ -46,6 +46,7 @@ import type { ModuleKey } from "@/lib/modules/registry";
* - `derived`: a derived score, by its `DerivedMetricId`.
* - `settings`: a Settings section, by its slug.
* - `settings-layout`: a Settings, Layout group, by its id.
* - `settings-module`: a module's own Settings page under Modules, by its id.
* - `correlation`: a correlation-discovery channel, by its channel key.
* - `score-ring`: a dashboard hero score ring, by its `ScoreRingId`.
* - `day-section`: a section of the day view, by its `DaySectionKey`. The
@@ -66,6 +67,7 @@ export const SURFACE_KINDS = [
"derived",
"settings",
"settings-layout",
"settings-module",
"correlation",
"score-ring",
"day-section",
@@ -200,11 +202,15 @@ const STATIC_SURFACE_MODULE = {
// ── Settings, Layout groups ──
"settings-layout:medications": "medications",
"settings-layout:mood": "mood",
"settings-layout:labs": "labs",
"settings-layout:illness": "illness",
"settings-layout:documents": "inboundDocuments",
// ── Settings, a module's own page under Modules ──
"settings-module:medications": "medications",
"settings-module:mood": "mood",
"settings-module:labs": "labs",
// ── Correlation channels ──
// Rated mood factors (`FACTOR:<key>`) are mood's too; see
// `correlationChannelSurfaceId`.