165 lines
7.3 KiB
Markdown
165 lines
7.3 KiB
Markdown
|
|
# 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
|