feat(modules): unify Vorsorge, Illness and Labs with the medication pattern

- add a wrench beside each module's add button linking to the module's own
  settings page; rename every add button to a plain "hinzufügen"
- give each module a settings page: view (cards/list) + manual reorder; Labs
  also gets a sort-order choice (by last reading) and biomarker CRUD/reorder
- collapse the Illness "abgeschlossen" list by default
- rebuild the Vorsorge card on the medication card's building blocks: a green
  "Jetzt messen" action, the interval as a chip beside the name, and an
  in-interval progress signal; drop the kebab "anpassen" and stray actions
- persist per-module view/order/sort client-side; add reverse-coverage-clean
  strings across all six locales
This commit is contained in:
Marc-André Bombeck committed 2026-06-18 21:36:58 +02:00
1 parent ae3091df9e
commit 267dcad13d
22 files changed
+1834 -273

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
"use client";
import { Loader2 } from "lucide-react";
import { useAuth } from "@/hooks/use-auth";
import { useMounted } from "@/hooks/use-mounted";
import { useTranslations } from "@/lib/i18n/context";
import { ModuleSettingsFrame } from "@/components/module-list/module-settings-frame";
import { IllnessSettings } from "@/components/illness/illness-settings";
/**
* v1.18.6 (W8 / MOD-03) — the Illness module's own settings page. Dedicated
* static route (wins over `/settings/[section]`); reached from the wrench
* beside the Illness page's "hinzufügen" button.
*/
export default function IllnessSettingsPage() {
const { isLoading } = useAuth();
const mounted = useMounted();
const { t } = useTranslations();
if (!mounted || isLoading) {
return (
<div className="flex min-h-[40vh] items-center justify-center">
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin motion-reduce:animate-none" />
</div>
);
}
return (
<ModuleSettingsFrame
title={t("illness.settings.title")}
description={t("illness.settings.description")}
backHref="/illness"
backLabelKey="illness.settings.back"
>
<IllnessSettings />
</ModuleSettingsFrame>
);
}
+39
View File
@@ -0,0 +1,39 @@
"use client";
import { Loader2 } from "lucide-react";
import { useAuth } from "@/hooks/use-auth";
import { useMounted } from "@/hooks/use-mounted";
import { useTranslations } from "@/lib/i18n/context";
import { ModuleSettingsFrame } from "@/components/module-list/module-settings-frame";
import { LabsSettings } from "@/components/labs/labs-settings";
/**
* v1.18.6 (W8 / MOD-03 + MOD-04) — the Labs module's own settings page.
* Dedicated static route (wins over `/settings/[section]`); reached from the
* wrench beside the Labs page's "hinzufügen" button.
*/
export default function LabsSettingsPage() {
const { isLoading } = useAuth();
const mounted = useMounted();
const { t } = useTranslations();
if (!mounted || isLoading) {
return (
<div className="flex min-h-[40vh] items-center justify-center">
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin motion-reduce:animate-none" />
</div>
);
}
return (
<ModuleSettingsFrame
title={t("labs.settings.title")}
description={t("labs.settings.description")}
backHref="/labs"
backLabelKey="labs.settings.back"
>
<LabsSettings />
</ModuleSettingsFrame>
);
}
+43
View File
@@ -0,0 +1,43 @@
"use client";
import { Loader2 } from "lucide-react";
import { useAuth } from "@/hooks/use-auth";
import { useMounted } from "@/hooks/use-mounted";
import { useTranslations } from "@/lib/i18n/context";
import { ModuleSettingsFrame } from "@/components/module-list/module-settings-frame";
import { VorsorgeSettings } from "@/components/measurement-reminders/vorsorge-settings";
/**
* v1.18.6 (W8 / MOD-03) — the Vorsorge module's own settings page.
*
* A dedicated static route that wins over the dynamic `/settings/[section]`
* router (static segments take precedence in Next.js), so it adds a
* per-module settings surface without touching the parallel-phase-owned
* `section-slugs` registry or `settings-shell`. Reached from the wrench
* beside the Vorsorge page's "hinzufügen" button.
*/
export default function VorsorgeSettingsPage() {
const { isLoading } = useAuth();
const mounted = useMounted();
const { t } = useTranslations();
if (!mounted || isLoading) {
return (
<div className="flex min-h-[40vh] items-center justify-center">
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin motion-reduce:animate-none" />
</div>
);
}
return (
<ModuleSettingsFrame
title={t("measurementReminders.settings.title")}
description={t("measurementReminders.settings.description")}
backHref="/vorsorge"
backLabelKey="measurementReminders.settings.back"
>
<VorsorgeSettings />
</ModuleSettingsFrame>
);
}