T07b: frontend feature pages — companies + contacts + settings + audit + dashboard + search
- 11 new feature pages (CompaniesList/Detail/Form, ContactsList/Detail/Form, SettingsProfile/Roles/Users, AuditLog, GlobalSearchResults) - 3 page updates (Dashboard with StatCard+ActivityFeed, Settings with tree nav+Outlet, TopBar with SearchDropdown) - 13 new routes in routes/index.tsx - i18n updates (de.json + en.json) with companies/contacts/settings/audit/search keys - 12 new test files + 2 existing test fixes (TopBar, AppShell) - 7 shared components (DataGrid, Tabs, SearchDropdown, CsvImportDialog, StatCard, ActivityFeed, UnsavedChangesGuard) - 16 new API hooks in hooks.ts - Verification: 141 tests pass, build succeeds, tsc --noEmit clean
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user