update: Major Overhaul to all subsystems
This commit is contained in:
84
.claude/crm-step-06.md
Normal file
84
.claude/crm-step-06.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# CRM Step 06 — Frontend: Customers List + Detail Page
|
||||
|
||||
## Context
|
||||
Read `.claude/crm-build-plan.md` for full context, data models, and IMPORTANT NOTES.
|
||||
Backend Steps 01–04 and Frontend Step 05 must be complete.
|
||||
|
||||
## Task
|
||||
Build the Customers section — the core of the CRM.
|
||||
|
||||
## Files to create
|
||||
|
||||
### `frontend/src/crm/customers/CustomerList.jsx`
|
||||
- Fetch `GET /api/crm/customers` (query: search, tag)
|
||||
- Show cards or table rows: Name, Organization, Location, Tags, primary contact
|
||||
- Search input → query param `search`
|
||||
- "New Customer" button → `/crm/customers/new`
|
||||
- Row/card click → `/crm/customers/:id`
|
||||
|
||||
### `frontend/src/crm/customers/CustomerForm.jsx`
|
||||
Create/edit form. Receives `customerId` prop (null = create).
|
||||
|
||||
**Sections:**
|
||||
1. **Basic Info** — name, organization, language, tags (pill input), nextcloud_folder
|
||||
2. **Location** — city, country, region
|
||||
3. **Contacts** — dynamic list of `{ type, label, value, primary }` entries. Add/remove rows. Radio to set primary per type group.
|
||||
4. **Notes** — dynamic list of `{ text, by, at }`. Add new note button. Existing notes shown as read-only with author/date. `by` auto-filled from current user name.
|
||||
5. **Owned Items** — dynamic list with type selector:
|
||||
- `console_device`: device_id text input + label
|
||||
- `product`: product selector (fetch `/api/crm/products` for dropdown) + quantity + serial_numbers (comma-separated input)
|
||||
- `freetext`: description + serial_number + notes
|
||||
Add/remove rows.
|
||||
6. **Linked App Accounts** — list of Firebase UIDs (simple text inputs, add/remove). Label: "Linked App User IDs"
|
||||
|
||||
Save: POST or PUT. Delete with confirmation.
|
||||
|
||||
### `frontend/src/crm/customers/CustomerDetail.jsx`
|
||||
The main customer page. Fetches customer by ID. Tab layout:
|
||||
|
||||
**Tab 1: Overview**
|
||||
- Show all info from CustomerForm fields in read-only view
|
||||
- "Edit" button → opens CustomerForm in a modal or navigates to edit route
|
||||
|
||||
**Tab 2: Orders**
|
||||
- Fetch `GET /api/crm/orders?customer_id=:id`
|
||||
- List orders: order_number, status badge, total_price, date
|
||||
- "New Order" button → navigate to `/crm/orders/new?customer_id=:id`
|
||||
- Row click → `/crm/orders/:id`
|
||||
|
||||
**Tab 3: Comms**
|
||||
- Fetch `GET /api/crm/comms?customer_id=:id`
|
||||
- Timeline view sorted by occurred_at descending
|
||||
- Each entry shows: type icon, direction indicator, subject/body preview, date
|
||||
- "Log Entry" button → inline form to create a new comms entry (type, direction, subject, body, occurred_at)
|
||||
|
||||
**Tab 4: Media**
|
||||
- Fetch `GET /api/crm/media?customer_id=:id`
|
||||
- Grid of files: filename, direction badge (Received/Sent/Internal), date
|
||||
- "Add Media Record" button → form with filename, nextcloud_path, direction, tags (manual entry for now — Nextcloud integration comes in Step 9)
|
||||
|
||||
**Tab 5: Devices** (read-only summary)
|
||||
- Display `owned_items` grouped by type
|
||||
- For console_device items: link to `/devices/:device_id` in a new tab
|
||||
|
||||
### `frontend/src/crm/customers/index.js`
|
||||
Export all components.
|
||||
|
||||
## Routing in `frontend/src/App.jsx`
|
||||
```jsx
|
||||
<Route path="/crm/customers" element={<CustomerList />} />
|
||||
<Route path="/crm/customers/new" element={<CustomerForm />} />
|
||||
<Route path="/crm/customers/:id" element={<CustomerDetail />} />
|
||||
<Route path="/crm/customers/:id/edit" element={<CustomerForm />} />
|
||||
```
|
||||
|
||||
## Sidebar update
|
||||
Add to CRM section:
|
||||
- Customers → `/crm/customers`
|
||||
|
||||
## Notes
|
||||
- ALL hooks in CustomerDetail must be before any early returns (loading/error states)
|
||||
- Tag input: comma or enter to add, click pill to remove
|
||||
- Contact type icons: use simple text labels or emoji (📧 📞 💬) — keep it simple
|
||||
- Comms type icons: simple colored badges per type (email=blue, whatsapp=green, call=yellow, note=grey)
|
||||
- No file upload UI yet in Media tab — just nextcloud_path text field for now (Step 9 adds real upload)
|
||||
Reference in New Issue
Block a user