# T07b Continuation — Frontend Feature Pages (Part 2) ## Project Root /a0/usr/workdir/dev-projects/leocrm ## Frontend Directory /a0/usr/workdir/dev-projects/leocrm/frontend/ ## What's Already Done (DO NOT recreate) ### API Hooks (src/api/hooks.ts — 432 lines, modified) 16 new hooks already added: useCompany, useCreateCompany, useUpdateCompany, useDeleteCompany, useContact, useCreateContact, useUpdateContact, useDeleteContact, useCompanyExport, useCompanyImport, useAuditLog, useGlobalSearch, plus CRUD for users. ### Shared Components (src/components/shared/ — all exist) - `Tabs.tsx` (2055 bytes) — Tab navigation component - `StatCard.tsx` (1107 bytes) — Dashboard stat card - `ActivityFeed.tsx` (1372 bytes) — Activity feed list - `DataGrid.tsx` (6067 bytes) — TanStack Table wrapper with search/sort/pagination - `SearchDropdown.tsx` (6275 bytes) — Debounced search dropdown with highlighting - `CsvImportDialog.tsx` (5429 bytes) — CSV upload + preview dialog - `UnsavedChangesGuard.tsx` (821 bytes) — useBlocker-based unsaved changes warning ### Dependencies - @tanstack/react-table@8.21.3 installed ## What Remains (ALL of this must be created) ### 1. Feature Pages (src/pages/) **Companies:** - `CompaniesList.tsx` — Use DataGrid component, search/filter/sort/pagination, CSV import (CsvImportDialog) + export buttons, empty state with create button (AC 1, 4, 5, 20) - `CompanyDetail.tsx` — Tabs: overview, contacts, files, activity (AC 2) - `CompanyForm.tsx` — RHF + Zod, validate name required, unsaved changes guard (AC 3, 22) **Contacts:** - `ContactsList.tsx` — Use DataGrid, loading skeleton rows, empty state (AC 6, 21) - `ContactDetail.tsx` — Tabs: overview, companies, files, activity (AC 7) - `ContactForm.tsx` — RHF + Zod, validate first_name/last_name/email, multi-company assignment (AC 8, 9) **Settings:** - `SettingsProfile.tsx` — Update name, email, password, avatar (AC 11) - `SettingsRoles.tsx` — Create role, assign permissions, save (AC 12) - `SettingsUsers.tsx` — List users, invite user, change role, deactivate (AC 13) **Other:** - `AuditLog.tsx` — Filterable table (date, user, action, entity). Call useAuditLog hook. Handle 404 gracefully with empty state (AC 14) - `GlobalSearchResults.tsx` — Filters (entity type, date), highlight matched terms. Call useGlobalSearch hook (AC 17, 18) ### 2. Page Updates - `Dashboard.tsx` — Replace placeholder with stat cards (StatCard component) + recent activity feed (ActivityFeed component) (AC 15) - `Settings.tsx` — Add tree navigation (Profile, Roles, Users, System). Render child routes (AC 10) - `TopBar.tsx` — Add SearchDropdown in topbar for global search (AC 16) ### 3. Routes (src/routes/index.tsx) Add these routes: ``` /companies → CompaniesList /companies/:id → CompanyDetail /companies/new → CompanyForm /companies/:id/edit → CompanyForm /contacts → ContactsList /contacts/:id → ContactDetail /contacts/new → ContactForm /contacts/:id/edit → ContactForm /audit-log → AuditLog /search → GlobalSearchResults /settings/profile → SettingsProfile /settings/roles → SettingsRoles /settings/users → SettingsUsers ``` ### 4. i18n Updates (src/i18n/locales/de.json + en.json) Add translation keys for all new pages: companies, contacts, settings, audit_log, search, dashboard sections. ### 5. Tests (src/__tests__/) Create test files: - `companies/CompaniesList.test.tsx` - `companies/CompanyDetail.test.tsx` - `companies/CompanyForm.test.tsx` - `contacts/ContactsList.test.tsx` - `contacts/ContactDetail.test.tsx` - `contacts/ContactForm.test.tsx` - `settings/SettingsProfile.test.tsx` - `settings/SettingsRoles.test.tsx` - `settings/SettingsUsers.test.tsx` - `dashboard/Dashboard.test.tsx` - `search/GlobalSearch.test.tsx` - `AuditLog.test.tsx` ### 6. Verification Run these commands and report results: ```bash cd /a0/usr/workdir/dev-projects/leocrm/frontend npx vitest run src/__tests__/ --reporter=verbose npm run build npx tsc --noEmit ``` ## Tech Stack - React 18 + Vite + TypeScript - TanStack Query v5 (hooks in src/api/hooks.ts) - Zustand (stores in src/store/) - react-i18next (de/en locales) - React Hook Form + Zod - Tailwind CSS - Vitest + @testing-library/react - @tanstack/react-table v8 ## Existing UI Components (src/components/ui/) Avatar, Badge, Button, Card, ConfirmDialog, EmptyState, Input, Modal, Pagination, Select, Skeleton, Table, Toast ## Existing Layout (src/components/layout/) AppShell, Sidebar, TopBar ## API Client (src/api/client.ts) Axios instance with interceptors. Base URL: http://localhost:8000. Auth via session cookie. ## Backend API Endpoints ``` GET/POST/PATCH/DELETE /api/v1/companies GET /api/v1/companies/{id} # includes contacts[] GET /api/v1/companies/export?format=csv POST /api/v1/companies/import # CSV upload GET/POST/PATCH/DELETE /api/v1/contacts GET /api/v1/contacts/{id} # includes companies[] GET/POST/PATCH/DELETE /api/v1/users GET /api/v1/users/{id} GET /api/v1/notifications GET /api/v1/plugins GET /health ``` Note: No /api/v1/audit endpoint exists yet. useAuditLog hook may 404 — handle gracefully. Note: No dedicated search endpoint. useGlobalSearch calls useCompanies + useContacts with search param. ## Company Schema ```python name: str (required, 1-100 chars) account_number: str | None (max 40) industry: str | None (max 50) phone: str | None (max 30) email: str | None (max 255) website: str | None (max 500) description: str | None ``` ## Rules - TypeScript only, no .js files - No Lorem Ipsum — use real German/English content - Reuse existing UI components, don't recreate them - Keep responses under 50 lines — reference files by path - Use real content, not placeholder text - All 23 acceptance criteria must be covered - Test files must use @testing-library/react with vitest