feat(unit-2-auth): Implement authentication pages and guards
Completes Unit 2 Code Generation (Steps 1-21 of 24): - SetupPage: First Owner account creation with language preference - InviteCompletePage: User invitation completion with token validation - InitGuard: System initialization status checking - RoleGuard: Role-based access control for protected routes - API hooks: useSetup, useValidateInvitation, useCompleteInvitation - Shared password validation schema via Zod - Error display components: FormErrorBanner, FieldError - MSW mock handlers for setup and invitation flows - i18n translations (en/nl) for auth screens - Router updates: public routes (/setup, /invite/complete) + role guards - Unit/integration tests: 25/29 passing (86% pass rate) - Build: ✅ PASSED, Lint: ✅ PASSED, Tests: 86% PASSED Stories: US-01, US-02, US-03, US-04, US-05, US-06, US-07, US-13, US-14 Remaining: Step 22 (README), Step 23 (final verification), Step 24 (commit) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,46 +31,25 @@
|
||||
},
|
||||
"setup": {
|
||||
"title": "System Setup",
|
||||
"subtitle": "Create the first Owner account to get started.",
|
||||
"fields": {
|
||||
"name": "Full name",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"confirmPassword": "Confirm password",
|
||||
"locale": "Language"
|
||||
},
|
||||
"localeOptions": {
|
||||
"en": "English",
|
||||
"nl": "Dutch"
|
||||
},
|
||||
"submit": "Create account",
|
||||
"submitting": "Creating account…",
|
||||
"success": "Account created. You can now sign in.",
|
||||
"errors": {
|
||||
"alreadyInitialized": "This system has already been set up.",
|
||||
"generic": "Something went wrong. Please try again."
|
||||
}
|
||||
"nameLabel": "Full name",
|
||||
"emailLabel": "Email",
|
||||
"passwordLabel": "Password",
|
||||
"confirmPasswordLabel": "Confirm password",
|
||||
"languageLabel": "Language preference",
|
||||
"submitButton": "Create owner account",
|
||||
"successMessage": "Account created. You can now sign in."
|
||||
},
|
||||
"inviteComplete": {
|
||||
"title": "Complete your account",
|
||||
"subtitle": "You have been invited to {{appName}}.",
|
||||
"loading": "Validating your invitation…",
|
||||
"fields": {
|
||||
"email": "Email",
|
||||
"name": "Full name",
|
||||
"password": "Password",
|
||||
"confirmPassword": "Confirm password"
|
||||
},
|
||||
"submit": "Complete setup",
|
||||
"submitting": "Completing setup…",
|
||||
"success": "Account setup complete. You can now sign in.",
|
||||
"errors": {
|
||||
"expired": "This invitation link has expired. Please request a new one.",
|
||||
"used": "This invitation link has already been used.",
|
||||
"notFound": "This invitation link is not valid.",
|
||||
"noToken": "Invalid invitation link.",
|
||||
"generic": "Something went wrong. Please try again."
|
||||
}
|
||||
"emailLabel": "Email",
|
||||
"nameLabel": "Full name",
|
||||
"passwordLabel": "Password",
|
||||
"confirmPasswordLabel": "Confirm password",
|
||||
"submitButton": "Complete setup",
|
||||
"loadingMessage": "Validating your invitation…",
|
||||
"invalidTokenMessage": "This invitation link has expired or is invalid.",
|
||||
"requestNewInvitationLink": "Request a new invitation link",
|
||||
"successMessage": "Account setup complete. You can now sign in."
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Dashboard",
|
||||
@@ -83,8 +62,9 @@
|
||||
},
|
||||
"errors": {
|
||||
"network": "Unable to reach the server. Check your connection and try again.",
|
||||
"accessDenied": "You do not have permission to view this page.",
|
||||
"accessDeniedDetail": "This section requires the {{roles}} role.",
|
||||
"sessionExpired": "Your session has expired. Please sign in again."
|
||||
"generic": "Something went wrong. Please try again.",
|
||||
"accessDenied": "You do not have permission to access this page.",
|
||||
"setupRequired": "System setup required. Please initialize the system first.",
|
||||
"invalidInvitationToken": "Invalid or expired invitation token."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,46 +31,25 @@
|
||||
},
|
||||
"setup": {
|
||||
"title": "Systeeminstallatie",
|
||||
"subtitle": "Maak het eerste Owner-account aan om te beginnen.",
|
||||
"fields": {
|
||||
"name": "Volledige naam",
|
||||
"email": "E-mail",
|
||||
"password": "Wachtwoord",
|
||||
"confirmPassword": "Wachtwoord bevestigen",
|
||||
"locale": "Taal"
|
||||
},
|
||||
"localeOptions": {
|
||||
"en": "Engels",
|
||||
"nl": "Nederlands"
|
||||
},
|
||||
"submit": "Account aanmaken",
|
||||
"submitting": "Account aanmaken…",
|
||||
"success": "Account aangemaakt. Je kunt nu inloggen.",
|
||||
"errors": {
|
||||
"alreadyInitialized": "Dit systeem is al ingesteld.",
|
||||
"generic": "Er is iets misgegaan. Probeer het opnieuw."
|
||||
}
|
||||
"nameLabel": "Volledige naam",
|
||||
"emailLabel": "E-mail",
|
||||
"passwordLabel": "Wachtwoord",
|
||||
"confirmPasswordLabel": "Wachtwoord bevestigen",
|
||||
"languageLabel": "Taalkeuze",
|
||||
"submitButton": "Owner-account aanmaken",
|
||||
"successMessage": "Account aangemaakt. Je kunt nu inloggen."
|
||||
},
|
||||
"inviteComplete": {
|
||||
"title": "Account voltooien",
|
||||
"subtitle": "Je bent uitgenodigd voor {{appName}}.",
|
||||
"loading": "Uitnodiging valideren…",
|
||||
"fields": {
|
||||
"email": "E-mail",
|
||||
"name": "Volledige naam",
|
||||
"password": "Wachtwoord",
|
||||
"confirmPassword": "Wachtwoord bevestigen"
|
||||
},
|
||||
"submit": "Setup voltooien",
|
||||
"submitting": "Setup voltooien…",
|
||||
"success": "Account-setup voltooid. Je kunt nu inloggen.",
|
||||
"errors": {
|
||||
"expired": "Deze uitnodigingslink is verlopen. Vraag een nieuwe aan.",
|
||||
"used": "Deze uitnodigingslink is al gebruikt.",
|
||||
"notFound": "Deze uitnodigingslink is niet geldig.",
|
||||
"noToken": "Ongeldige uitnodigingslink.",
|
||||
"generic": "Er is iets misgegaan. Probeer het opnieuw."
|
||||
}
|
||||
"emailLabel": "E-mail",
|
||||
"nameLabel": "Volledige naam",
|
||||
"passwordLabel": "Wachtwoord",
|
||||
"confirmPasswordLabel": "Wachtwoord bevestigen",
|
||||
"submitButton": "Setup voltooien",
|
||||
"loadingMessage": "Uitnodiging valideren…",
|
||||
"invalidTokenMessage": "Deze uitnodigingslink is verlopen of ongeldig.",
|
||||
"requestNewInvitationLink": "Vraag een nieuwe uitnodigingslink aan",
|
||||
"successMessage": "Account-setup voltooid. Je kunt nu inloggen."
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Dashboard",
|
||||
@@ -83,8 +62,9 @@
|
||||
},
|
||||
"errors": {
|
||||
"network": "Kan de server niet bereiken. Controleer je verbinding en probeer opnieuw.",
|
||||
"generic": "Er is iets misgegaan. Probeer het opnieuw.",
|
||||
"accessDenied": "Je hebt geen toestemming om deze pagina te bekijken.",
|
||||
"accessDeniedDetail": "Dit gedeelte vereist de rol {{roles}}.",
|
||||
"sessionExpired": "Je sessie is verlopen. Meld je opnieuw aan."
|
||||
"setupRequired": "Systeeminstallatie vereist. Initialiseer eerst het systeem.",
|
||||
"invalidInvitationToken": "Ongeldig of verlopen uitnodigingstoken."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user