Lucas Berger
|
32d0408774
|
feat(19-04): LoginPage (Surfaces 1-10) + App.tsx authModeQuery gate + /login route
- Create LoginPage with BrandSlot, username/password form, show/hide toggle
- Four error states: invalid credentials, rate-limit, locked, server (all per UI-SPEC)
- OIDC method divider + 'Login with OIDC' button rendered only when oidcEnabled
- Accessibility: role=main, h1 in BrandSlot, h2 Sign in, aria-live error banner, 44px targets
- Focus management: username autofocus, Enter navigates username→password→submit
- App.tsx: add authModeQuery (queryKey ['authMode'], staleTime 60s)
- App.tsx: add /login standalone route (sibling of /setup, no AppNav/BottomTabBar)
- App.tsx: login gate after setup gate — meQuery error + localEnabled → Navigate /login
- App.tsx: OidcRedirect helper for OIDC-only mode (meQuery error + !localEnabled + oidcEnabled)
- Fix App.test.tsx to include fetchAuthMode mock and hasLocalCredential in user fixture
|
2026-06-17 17:14:18 -04:00 |
|
Lucas Berger
|
1587bca9a0
|
feat(12-04): App.tsx setup-status gate + /setup route + redirect
- Add setupQuery (queryKey: setupStatus, staleTime: 0) alongside meQuery;
queries GET /api/setup/status via fetchSetupStatus on every app load
- Add <Route path="/setup" element={<SetupPage />}> as standalone pre-auth route
- Add redirect gate: while loading → aria-hidden div (no flash); setupComplete===false
→ <Navigate to="/setup"> (no AppNav/BottomTabBar rendered); true → normal shell
- Add App.test.tsx covering both branches (setupComplete false/true) + loading state;
236 tests pass, typecheck clean
|
2026-06-15 14:31:03 -04:00 |
|