134 lines
6.6 KiB
Markdown
134 lines
6.6 KiB
Markdown
|
|
# T07a — Frontend Core SPA — Shell, Auth, Routing, i18n, UI Library, Accessibility
|
||
|
|
|
||
|
|
## Project Root
|
||
|
|
/a0/usr/workdir/dev-projects/leocrm
|
||
|
|
|
||
|
|
## Frontend Directory
|
||
|
|
/a0/usr/workdir/dev-projects/leocrm/frontend/
|
||
|
|
|
||
|
|
## Tech Stack (CONFIRMED from architecture.md)
|
||
|
|
- React 18 + Vite + TypeScript
|
||
|
|
- React Router v6
|
||
|
|
- TanStack Query (React Query v5) for server state
|
||
|
|
- Zustand for client state
|
||
|
|
- react-i18next for i18n (de/en)
|
||
|
|
- React Hook Form + Zod for forms
|
||
|
|
- Tailwind CSS with design tokens from prototype
|
||
|
|
- Vitest for testing
|
||
|
|
|
||
|
|
## Backend API (already running, T01-T03 complete)
|
||
|
|
- Base URL: http://localhost:8000
|
||
|
|
- Auth: session cookie (leocrm_session), SameSite=strict
|
||
|
|
- CORS: http://localhost:5173 (Vite dev) allowed
|
||
|
|
- Endpoints available: /api/v1/auth/login, /api/v1/auth/logout, /api/v1/auth/me, /api/v1/auth/password-reset/request, /api/v1/auth/password-reset/confirm, /api/v1/users, /api/v1/companies, /api/v1/contacts, /api/v1/notifications, /api/v1/plugins, /health
|
||
|
|
|
||
|
|
## Requirements (23)
|
||
|
|
F-AUTH-01, F-AUTH-02, F-AUTH-03, F-AUTH-05, F-AUTH-07, F-CORE-06, F-CORE-07, F-CORE-08, F-CORE-09, F-CORE-13, F-A11Y-01, F-A11Y-02, F-A11Y-03, F-INT-01, F-NAV-01, F-UI-01 through F-UI-06, F-UI-08, F-TEST-01
|
||
|
|
|
||
|
|
## Acceptance Criteria (27)
|
||
|
|
1. Login page renders with email+password form
|
||
|
|
2. Login with valid credentials → redirect to Dashboard
|
||
|
|
3. Login with invalid credentials → error toast shown
|
||
|
|
4. Password reset request page renders and submits
|
||
|
|
5. Password reset confirm page renders with token validation
|
||
|
|
6. App shell renders with sidebar (plugin menu), topbar (tenant switcher, search, notifications, user menu), content area
|
||
|
|
7. Router navigates between routes without page reload (SPA)
|
||
|
|
8. Protected routes redirect to /login when not authenticated
|
||
|
|
9. Tenant switcher shows current tenant and allows switching
|
||
|
|
10. API client sends session cookie automatically via axios interceptor
|
||
|
|
11. API client handles 401 → redirect to login
|
||
|
|
12. API client handles 422 → display validation errors
|
||
|
|
13. i18n: German locale loads by default
|
||
|
|
14. i18n: English locale switchable via settings
|
||
|
|
15. UI Library: Button renders with variants (primary, secondary, danger, ghost)
|
||
|
|
16. UI Library: Input renders with label, error, helper text
|
||
|
|
17. UI Library: Modal opens/closes with backdrop click and ESC
|
||
|
|
18. UI Library: Toast notifications appear and auto-dismiss
|
||
|
|
19. UI Library: Table renders with sortable headers
|
||
|
|
20. UI Library: Card, Badge, Avatar, Pagination, EmptyState, Skeleton, ConfirmDialog render correctly
|
||
|
|
21. Accessibility: All interactive elements have ARIA labels
|
||
|
|
22. Accessibility: Keyboard navigation works (Tab, Enter, Escape, Arrow keys)
|
||
|
|
23. Accessibility: 44px minimum touch targets on mobile
|
||
|
|
24. Accessibility: prefers-reduced-motion respected
|
||
|
|
25. Vite dev server starts without errors
|
||
|
|
26. Production build (npm run build) succeeds with 0 errors
|
||
|
|
27. TypeScript: tsc --noEmit passes with 0 errors
|
||
|
|
|
||
|
|
## Files to Create
|
||
|
|
- frontend/package.json (React 18, Vite, TanStack Query, Zustand, react-i18next, React Hook Form, Zod, Tailwind CSS, Vitest, axios)
|
||
|
|
- frontend/vite.config.ts
|
||
|
|
- frontend/tsconfig.json, tsconfig.node.json
|
||
|
|
- frontend/tailwind.config.js, postcss.config.js
|
||
|
|
- frontend/index.html
|
||
|
|
- frontend/src/main.tsx — React entry point with providers
|
||
|
|
- frontend/src/App.tsx — Router + providers setup
|
||
|
|
- frontend/src/api/client.ts — axios instance with interceptors (cookie, 401, 422)
|
||
|
|
- frontend/src/api/hooks.ts — TanStack Query hooks for auth, users, companies, contacts, notifications
|
||
|
|
- frontend/src/store/authStore.ts — Zustand auth store
|
||
|
|
- frontend/src/store/uiStore.ts — Zustand UI store (theme, sidebar, locale)
|
||
|
|
- frontend/src/i18n/index.ts — react-i18next setup
|
||
|
|
- frontend/src/i18n/locales/de.json, en.json
|
||
|
|
- frontend/src/components/ui/Button.tsx
|
||
|
|
- frontend/src/components/ui/Input.tsx
|
||
|
|
- frontend/src/components/ui/Select.tsx
|
||
|
|
- frontend/src/components/ui/Modal.tsx
|
||
|
|
- frontend/src/components/ui/Toast.tsx (ToastContainer + useToast)
|
||
|
|
- frontend/src/components/ui/Table.tsx
|
||
|
|
- frontend/src/components/ui/Card.tsx
|
||
|
|
- frontend/src/components/ui/Badge.tsx
|
||
|
|
- frontend/src/components/ui/Avatar.tsx
|
||
|
|
- frontend/src/components/ui/Pagination.tsx
|
||
|
|
- frontend/src/components/ui/EmptyState.tsx
|
||
|
|
- frontend/src/components/ui/Skeleton.tsx
|
||
|
|
- frontend/src/components/ui/ConfirmDialog.tsx
|
||
|
|
- frontend/src/components/layout/AppShell.tsx — Sidebar + TopBar + ContentArea
|
||
|
|
- frontend/src/components/layout/Sidebar.tsx — Plugin menu, navigation
|
||
|
|
- frontend/src/components/layout/TopBar.tsx — Tenant switcher, search, notifications, user menu
|
||
|
|
- frontend/src/pages/Login.tsx
|
||
|
|
- frontend/src/pages/PasswordResetRequest.tsx
|
||
|
|
- frontend/src/pages/PasswordResetConfirm.tsx
|
||
|
|
- frontend/src/pages/Dashboard.tsx (placeholder)
|
||
|
|
- frontend/src/pages/Settings.tsx (locale switch, theme)
|
||
|
|
- frontend/src/routes/index.tsx — Route definitions with guards
|
||
|
|
- frontend/src/routes/ProtectedRoute.tsx — Auth guard
|
||
|
|
- frontend/src/hooks/useAuth.ts
|
||
|
|
- frontend/src/hooks/useTenant.ts
|
||
|
|
- frontend/src/index.css — Tailwind directives + design tokens
|
||
|
|
- frontend/src/__tests__/shell/ (AppShell, Router, Sidebar, TopBar tests)
|
||
|
|
- frontend/src/__tests__/auth/ (Login, PasswordReset tests)
|
||
|
|
- frontend/src/__tests__/ui/ (Button, Input, Modal, Toast, Table, etc. tests)
|
||
|
|
- frontend/vitest.config.ts (or merge into vite.config.ts)
|
||
|
|
- frontend/src/test/setup.ts — Vitest setup (jsdom, i18n, mocks)
|
||
|
|
|
||
|
|
## Design Tokens (from prototype)
|
||
|
|
- Reference: https://webspace.media-on.de/leocrm-prototype-x7k2p9/
|
||
|
|
- Primary color, secondary, accent, danger, warning, success
|
||
|
|
- Spacing scale, border radius, shadows
|
||
|
|
- Typography: font families, sizes, weights
|
||
|
|
- Define as CSS custom properties in index.css + Tailwind config
|
||
|
|
|
||
|
|
## Critical Rules
|
||
|
|
- Use TypeScript strict mode
|
||
|
|
- All components must have ARIA labels for interactive elements
|
||
|
|
- 44px minimum touch targets on mobile (Tailwind min-h-[44px] min-w-[44px])
|
||
|
|
- prefers-reduced-motion: use Tailwind motion-safe/motion-reduce variants
|
||
|
|
- Session cookie: axios with withCredentials: true
|
||
|
|
- 401 handler: redirect to /login, clear auth store
|
||
|
|
- 422 handler: extract validation errors, display in form
|
||
|
|
- i18n: German default, English switchable
|
||
|
|
- No Lorem Ipsum — use real German/English content
|
||
|
|
- Test with Vitest + jsdom + @testing-library/react
|
||
|
|
- Coverage target: 80%
|
||
|
|
|
||
|
|
## Test Commands
|
||
|
|
cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx vitest run src/__tests__/ --reporter=verbose
|
||
|
|
cd /a0/usr/workdir/dev-projects/leocrm/frontend && npm run build
|
||
|
|
cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx tsc --noEmit
|
||
|
|
|
||
|
|
## Deliverables
|
||
|
|
1. Complete frontend/ directory with all files listed above
|
||
|
|
2. All 27 ACs covered by tests
|
||
|
|
3. npm run build succeeds with 0 errors
|
||
|
|
4. tsc --noEmit passes with 0 errors
|
||
|
|
5. Report: test results, AC coverage, files, bugs
|