Add account settings page with passkey management

- /settings with profile, security, and account sections
- Profile: edit display name and bio
- Security: list passkeys with device labels, add/delete with
  last-passkey warning
- Account: email change with magic link verification, account
  deletion with username confirmation
- Settings link in nav for authenticated users
- E2E tests: auth guard, profile editing, passkey add/delete,
  last-passkey warning, account deletion, nav visibility
- i18n: full en + de translations for all settings UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-03-29 10:09:06 +02:00
parent 0230d93004
commit be5766fa50
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
12 changed files with 820 additions and 19 deletions

View file

@ -93,14 +93,6 @@ export default {
journal: {
title: "trails.cool",
subtitle: "Dein Outdoor-Aktivitäten-Tagebuch",
nav: {
routes: "Routen",
activities: "Aktivitäten",
login: "Anmelden",
register: "Registrieren",
profile: "Profil",
logout: "Abmelden",
},
welcome: "Willkommen,",
addPasskeyPrompt: "Füge einen Passkey hinzu, um dich schneller auf diesem Gerät anzumelden.",
addPasskey: "Passkey hinzufügen",
@ -130,6 +122,50 @@ export default {
linkToRoute: "Mit Route verknüpfen",
createRouteFromActivity: "Route aus Aktivität erstellen",
},
settings: {
title: "Einstellungen",
profile: {
title: "Profil",
displayName: "Anzeigename",
bio: "Bio",
saved: "Profil gespeichert.",
},
security: {
title: "Sicherheit",
description: "Verwalte deine Passkeys zum Anmelden.",
addPasskey: "Passkey hinzufügen",
passkey: "Passkey",
thisDevice: "Dieses Gerät",
securityKey: "Sicherheitsschlüssel",
bluetooth: "Bluetooth",
phoneOrTablet: "Telefon oder Tablet",
addedOn: "Hinzugefügt am {{date}}",
noPasskeys: "Keine Passkeys registriert. Du kannst dich per Magic Link anmelden.",
deleteConfirm: "Möchtest du diesen Passkey wirklich löschen?",
deleteLastWarning: "Dies ist dein einziger Passkey. Du musst Magic Links zum Anmelden verwenden. Trotzdem löschen?",
},
account: {
title: "Konto",
changeEmail: "Ändern",
newEmailPlaceholder: "Neue E-Mail-Adresse",
sendVerification: "Bestätigen",
verificationSent: "Bestätigungs-E-Mail gesendet. Prüfe deinen Posteingang.",
dangerZone: "Gefahrenzone",
deleteDescription: "Lösche dein Konto und alle zugehörigen Daten unwiderruflich.",
deleteAccount: "Konto löschen",
deleteConfirmPrompt: "Gib \"{{username}}\" ein, um die Löschung zu bestätigen:",
confirmDelete: "Endgültig löschen",
},
},
nav: {
routes: "Routen",
activities: "Aktivitäten",
login: "Anmelden",
register: "Registrieren",
profile: "Profil",
settings: "Einstellungen",
logout: "Abmelden",
},
auth: {
login: "Anmelden",
register: "Registrieren",

View file

@ -93,14 +93,6 @@ export default {
journal: {
title: "trails.cool",
subtitle: "Your outdoor activity journal",
nav: {
routes: "Routes",
activities: "Activities",
login: "Sign In",
register: "Register",
profile: "Profile",
logout: "Log Out",
},
welcome: "Welcome,",
addPasskeyPrompt: "Add a passkey for faster sign-in on this device.",
addPasskey: "Add Passkey",
@ -130,6 +122,50 @@ export default {
linkToRoute: "Link to Route",
createRouteFromActivity: "Create Route from Activity",
},
settings: {
title: "Settings",
profile: {
title: "Profile",
displayName: "Display Name",
bio: "Bio",
saved: "Profile saved.",
},
security: {
title: "Security",
description: "Manage your passkeys for signing in.",
addPasskey: "Add Passkey",
passkey: "Passkey",
thisDevice: "This device",
securityKey: "Security key",
bluetooth: "Bluetooth",
phoneOrTablet: "Phone or tablet",
addedOn: "Added {{date}}",
noPasskeys: "No passkeys registered. You can sign in with magic links.",
deleteConfirm: "Are you sure you want to delete this passkey?",
deleteLastWarning: "This is your only passkey. You will need to use magic links to sign in. Delete anyway?",
},
account: {
title: "Account",
changeEmail: "Change",
newEmailPlaceholder: "New email address",
sendVerification: "Verify",
verificationSent: "Verification email sent. Check your inbox.",
dangerZone: "Danger Zone",
deleteDescription: "Permanently delete your account and all associated data.",
deleteAccount: "Delete Account",
deleteConfirmPrompt: "Type \"{{username}}\" to confirm deletion:",
confirmDelete: "Permanently Delete",
},
},
nav: {
routes: "Routes",
activities: "Activities",
login: "Sign In",
register: "Register",
profile: "Profile",
settings: "Settings",
logout: "Log Out",
},
auth: {
login: "Sign In",
register: "Register",