fix(settings): keep moved checkup and session cards reachable in context

The checkups page links to the checkup reminders under Notifications
and the screening hints under the health profile, the two cards that
left its settings in this release. Data & privacy gets a row pointing
at sessions and devices under Security.
This commit is contained in:
Marc-André Bombeck committed 2026-10-21 21:50:13 +02:00
1 parent 90c9a4e2d0
commit b25ee09f7d
12 files changed
+104 -1

No files matched your search

+5
View File
@@ -7239,6 +7239,11 @@
"title": "Datenschutz-Einstellung",
"description": "Steuere, wie viele deiner Daten an KI-Funktionen weitergegeben werden.",
"openAi": "KI-Datenschutzmodus"
},
"sessions": {
"title": "Sitzungen und Geräte",
"description": "Wo du angemeldet bist, welche Geräte den zweiten Faktor überspringen, und die Sicherheitsaktivität deines Kontos.",
"open": "Sicherheit öffnen"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Privacy posture",
"description": "Control how much of your data is shared with AI features.",
"openAi": "AI privacy mode"
},
"sessions": {
"title": "Sessions and devices",
"description": "Where you are signed in, the devices that skip the second factor, and the security activity of your account.",
"open": "Open security"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Configuración de privacidad",
"description": "Controla cuántos de tus datos se comparten con las funciones de IA.",
"openAi": "Modo de privacidad de IA"
},
"sessions": {
"title": "Sesiones y dispositivos",
"description": "Dónde tienes la sesión iniciada, qué dispositivos omiten el segundo factor y la actividad de seguridad de tu cuenta.",
"open": "Abrir seguridad"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Posture de confidentialité",
"description": "Contrôlez la quantité de données partagées avec les fonctions d'IA.",
"openAi": "Mode confidentialité IA"
},
"sessions": {
"title": "Sessions et appareils",
"description": "Où tu es connecté, les appareils qui sautent le second facteur et l'activité de sécurité de ton compte.",
"open": "Ouvrir la sécurité"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Impostazione privacy",
"description": "Controlla quanti dei tuoi dati vengono condivisi con le funzioni di IA.",
"openAi": "Modalità privacy IA"
},
"sessions": {
"title": "Sessioni e dispositivi",
"description": "Dove hai effettuato l'accesso, i dispositivi che saltano il secondo fattore e l'attività di sicurezza del tuo account.",
"open": "Apri sicurezza"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "개인정보 보호 수준",
"description": "AI 기능에 데이터를 어디까지 공유할지 정해요.",
"openAi": "AI 개인정보 모드"
},
"sessions": {
"title": "세션 및 기기",
"description": "로그인된 위치, 2단계 인증을 건너뛰는 기기, 계정의 보안 활동을 확인해요.",
"open": "보안 열기"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Privacyniveau",
"description": "Bepaal hoeveel van je gegevens met AI-functies wordt gedeeld.",
"openAi": "AI-privacymodus"
},
"sessions": {
"title": "Sessies en apparaten",
"description": "Waar je bent ingelogd, welke apparaten de tweede factor overslaan en de beveiligingsactiviteit van je account.",
"open": "Beveiliging openen"
}
},
"mcp": {
+5
View File
@@ -7239,6 +7239,11 @@
"title": "Ustawienia prywatności",
"description": "Kontroluj, ile Twoich danych jest udostępnianych funkcjom AI.",
"openAi": "Tryb prywatności AI"
},
"sessions": {
"title": "Sesje i urządzenia",
"description": "Gdzie jesteś zalogowany, które urządzenia pomijają drugi składnik i aktywność zabezpieczeń twojego konta.",
"open": "Otwórz zabezpieczenia"
}
},
"mcp": {
@@ -114,6 +114,16 @@ describe("<VorsorgeSection> loading + empty", () => {
expect(html).not.toContain('data-slot="vorsorge-loading"');
});
it("links the checkups page to the reminder and screening settings that moved", () => {
remindersMock.mockReturnValue({ data: [], isLoading: false });
const page = render(<VorsorgeSection variant="page" />);
expect(page).toContain('href="/settings/notifications#vorsorge-reminders"');
expect(page).toContain('href="/settings/anamnesis#screening-hints"');
// The embedded settings card is already in Settings and carries no links.
const embedded = render(<VorsorgeSection />);
expect(embedded).not.toContain('data-slot="vorsorge-settings-links"');
});
it("renders reminder cards once data lands", () => {
const reminder: MeasurementReminder = {
id: "r1",
@@ -465,7 +465,38 @@ export function VorsorgeSection({
</>
}
/>
) : (
) : null}
{variant === "page" && !inSharedRecord ? (
// The reminder switches and the screening hints moved out of the
// checkups settings in v1.44 (Notifications, Health profile); both
// stay one tap away from the page they are about.
<div
className="flex flex-wrap gap-2"
data-slot="vorsorge-settings-links"
>
<Button
asChild
variant="outline"
size="sm"
className="min-h-11 sm:min-h-9"
>
<Link href="/settings/notifications#vorsorge-reminders">
{t("notifications.checkupReminders.title")}
</Link>
</Button>
<Button
asChild
variant="outline"
size="sm"
className="min-h-11 sm:min-h-9"
>
<Link href="/settings/anamnesis#screening-hints">
{t("records.life.screening.cardTitle")}
</Link>
</Button>
</div>
) : null}
{variant === "page" ? null : (
<SettingsCardHeader
icon={CalendarClock}
titleId="vorsorge-section-title"
@@ -71,6 +71,8 @@ describe("<PrivacySection> — assembled Data & Privacy dashboard", () => {
expect(html).not.toContain("settings-security-sessions-card");
expect(html).not.toContain("settings-trusted-devices-card");
expect(html).not.toContain('href="/settings/export"');
// ...but stay one tap away from here, where people looked for them.
expect(html).toContain('href="/settings/security#sessions"');
});
it("shows a loading placeholder for the retention block before the summary resolves", () => {
@@ -23,6 +23,7 @@ import {
Clock,
Sparkles,
Info,
MonitorSmartphone,
} from "lucide-react";
import { Button } from "@/components/ui/button";
@@ -180,6 +181,25 @@ export function PrivacySection() {
)}
</SettingsCard>
{/* Sessions, trusted devices and the security activity live under
Security since v1.44; the row keeps them reachable from here, where
people looked for them before. */}
<SettingsCard>
<SettingsCardHeader
anchor="sessions-link"
icon={MonitorSmartphone}
title={t("settings.privacy.sessions.title")}
description={t("settings.privacy.sessions.description")}
/>
<SettingsCardActions align="start">
<Button asChild variant="outline" size="sm">
<Link href="/settings/security#sessions">
{t("settings.privacy.sessions.open")}
</Link>
</Button>
</SettingsCardActions>
</SettingsCard>
{/* Delete / reset — with the honest backup lag disclosure */}
<SettingsCard>
<SettingsCardHeader