# 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 } /> } /> } /> } /> ``` ## 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)