# T07b Briefing — Frontend Feature Pages ## Project Root /a0/usr/workdir/dev-projects/leocrm ## Frontend Directory /a0/usr/workdir/dev-projects/leocrm/frontend/ ## Task Build all feature pages for the LeoCRM SPA. T07a (shell, auth, routing, i18n, UI library) is complete. ## Tech Stack (already set up by T07a) - React 18 + Vite + TypeScript (strict) - TanStack Query v5 (hooks in src/api/hooks.ts) - Zustand (stores in src/store/) - react-i18next (de/en, src/i18n/) - React Hook Form + Zod - Tailwind CSS with design tokens - Vitest + @testing-library/react ## Existing API Hooks (src/api/hooks.ts) - useCompanies(page, pageSize, search) → { items, total, page, page_size } - useContacts(page, pageSize, search) → { items, total, page, page_size } - useUsers(page, pageSize) → paginated users - useCurrentUser() → current user - useNotifications() → notifications list - usePlugins() → plugins list - useLogin(), useLogout(), useSwitchTenant() - API client: src/api/client.ts (axios, withCredentials, 401→login, 422→validation) ## Backend API Endpoints - GET /api/v1/companies?page=1&page_size=25&search=...&industry=...&sort_by=...&sort_order=... - GET /api/v1/companies/{id} → CompanyDetailResponse (includes contacts[]) - POST /api/v1/companies - PATCH /api/v1/companies/{id} - DELETE /api/v1/companies/{id} - GET /api/v1/companies/export?format=csv&search=...&industry=... - POST /api/v1/companies/import (CSV upload) - GET /api/v1/contacts?page=1&page_size=25&search=... - GET /api/v1/contacts/{id} → ContactDetailResponse (includes companies[]) - POST /api/v1/contacts - PATCH /api/v1/contacts/{id} - DELETE /api/v1/contacts/{id} - GET /api/v1/users?page=1&page_size=25 - GET /api/v1/users/{id} - POST /api/v1/users - PATCH /api/v1/users/{id} - DELETE /api/v1/users/{id} - GET /api/v1/notifications - GET /api/v1/plugins - GET /health Note: No dedicated audit log or global search API endpoint exists yet. For audit log, create a frontend page that calls GET /api/v1/audit (may 404 — handle gracefully with empty state). For global search, call useCompanies and useContacts with search param in parallel. ## Company Schema (from backend) - name: string (required, 1-100) - account_number: string? (max 40) - industry: string? (max 50) - phone: string? (max 30) - email: string? (max 255) - website: string? (max 500) - description: string? - CompanyDetailResponse adds: contacts: list[dict] ## Files to Create/Modify ### New API Hooks (add to src/api/hooks.ts) - useCompany(id), useCreateCompany(), useUpdateCompany(), useDeleteCompany() - useContact(id), useCreateContact(), useUpdateContact(), useDeleteContact() - useCompanyExport(), useCompanyImport() - useAuditLog(page, pageSize, filters) - useGlobalSearch(query, entityTypes) ### New Pages (src/pages/) - CompaniesList.tsx — TanStack Table with search/filter/sort/pagination, empty state - CompanyDetail.tsx — Tabs: overview, contacts, files, activity - CompanyForm.tsx — Create/edit with React Hook Form + Zod - ContactsList.tsx — TanStack Table, loading skeleton - ContactDetail.tsx — Tabs: overview, companies, files, activity - ContactForm.tsx — Create/edit with multi-company assignment - AuditLog.tsx — Filterable table (date, user, action, entity) - GlobalSearchResults.tsx — Filters (entity type, date), highlighting - SettingsProfile.tsx — Update name, email, password, avatar - SettingsRoles.tsx — Role editor: create, assign permissions - SettingsUsers.tsx — User management: list, invite, change role, deactivate ### Modify Existing Pages - Dashboard.tsx — Expand with stat cards + recent activity feed - Settings.tsx — Add tree navigation (Profile, Roles, Users, System) ### New Components (src/components/) - SearchDropdown.tsx — Global search dropdown in topbar - StatCard.tsx — Dashboard stat card - ActivityFeed.tsx — Recent activity feed - Tabs.tsx — Reusable tab component for detail pages - DataGrid.tsx — Wrapper around TanStack Table for list pages - CsvImportDialog.tsx — CSV upload → preview → import - UnsavedChangesGuard.tsx — Warn on navigation away with unsaved changes ### Update Routes (src/routes/index.tsx) Add routes for all new pages under ProtectedRoute children: - /companies, /companies/:id, /companies/new, /companies/:id/edit - /contacts, /contacts/:id, /contacts/new, /contacts/:id/edit - /audit-log - /search?q=... - /settings/profile, /settings/roles, /settings/users ### Tests (src/__tests__/) - companies/CompaniesList.test.tsx, CompanyDetail.test.tsx, CompanyForm.test.tsx - contacts/ContactsList.test.tsx, ContactDetail.test.tsx, ContactForm.test.tsx - settings/SettingsProfile.test.tsx, SettingsRoles.test.tsx, SettingsUsers.test.tsx - dashboard/Dashboard.test.tsx - search/GlobalSearch.test.tsx - AuditLog.test.tsx ## Acceptance Criteria (23 total) 1. Companies list renders with TanStack Table (search, filter, sort, pagination) 2. Company detail renders with tabs (overview, contacts, files, activity) 3. Company form validates required fields (name) with Zod 4. Company import: CSV upload → preview → import → success toast 5. Company export: download CSV with current filters 6. Contacts list renders with TanStack Table 7. Contact detail renders with tabs (overview, companies, files, activity) 8. Contact form validates required fields (first_name, last_name, email) with Zod 9. Contact can be assigned to multiple companies 10. Settings renders with tree navigation (Profile, Roles, Users, System) 11. Profile settings: update name, email, password, avatar 12. Role editor: create role, assign permissions, save 13. User management: list users, invite user, change role, deactivate 14. Audit log renders with filterable table (date, user, action, entity) 15. Dashboard renders with stat cards and recent activity feed 16. Global search bar in topbar returns results dropdown 17. Global search results page renders with filters (entity type, date) 18. Search results highlight matched terms 19. Search works across companies, contacts (v1 scope) 20. Companies list: empty state shows helpful message + create button 21. Contacts list: loading state shows skeleton rows 22. Company form: error state shows inline validation errors 23. Settings: unsaved changes warning when navigating away ## Test Commands ```bash cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx vitest run src/__tests__/companies/ src/__tests__/contacts/ src/__tests__/settings/ src/__tests__/dashboard/ src/__tests__/search/ --reporter=verbose cd /a0/usr/workdir/dev-projects/leocrm/frontend && npm run build cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx tsc --noEmit ``` ## Rules - TypeScript only, no .js files - No Lorem Ipsum — use real German/English content - All interactive elements need ARIA labels - 44px minimum touch targets on mobile - Use existing UI components from T07a (Button, Input, Select, Modal, Toast, Table, Card, Badge, Avatar, Pagination, EmptyState, Skeleton, ConfirmDialog) - Use existing i18n setup — add new keys to de.json and en.json - Use existing API client (src/api/client.ts) — don't create new axios instances - Coverage target: 80% - Keep responses under 50 lines - Use files_create for new files, reference by path ## Deliverables 1. All files created and tests passing 2. npm run build succeeds with 0 errors 3. tsc --noEmit passes with 0 errors 4. Report: test results, AC coverage, files created, bugs encountered