--- phase: 3 title: Service Catalog & Quote Builder — UI Design Contract status: approved date: 2026-05-17 source: land-book.com aesthetic + existing admin brand --- # UI-SPEC: Phase 3 — Service Catalog & Quote Builder ## Design Direction **Reference:** land-book.com — clean minimal white, card grid, dark typography, generous whitespace, subtle borders. **Brand accent:** #1A463C (green), #DEF168 (yellow) — used sparingly for CTAs and active states. **Base:** white backgrounds, #1a1a1a text, #e5e7eb borders, #f9f9f9 surface. ## Pages ### /admin/catalog — Service Catalog **Layout:** - Full-width table layout (same pattern as admin clients list) - Header row: "Catalogo Servizi" h1 + "+ Aggiungi servizio" button (primary green) - Table: bg-white, rounded-xl, border border-[#e5e7eb] - Columns: Nome | Descrizione | Prezzo | Stato | Azioni **Row design:** - Hover: bg-[#f9f9f9] transition - Inactive rows: opacity-50 - Status badge: pill "Attivo" (bg-[#1A463C]/10 text-[#1A463C]) / "Disattivato" (bg-[#f4f4f5] text-[#71717a]) - Inline edit: click → row expands into editable inputs, save/cancel buttons - Actions: "Disattiva" / "Riattiva" text button, no icons **Add service form:** - Slide-in panel (right side) OR inline row at top of table - Fields: Nome (text), Descrizione (textarea, optional), Prezzo unitario (number, EUR) - CTA: "+ Aggiungi" button primary ### /admin/clients/[id] — Tab "Preventivo" **Tab navigation:** - Added as 5th tab after Documenti: Fasi | Pagamenti | Documenti | Note | Preventivo **Preventivo tab layout — two sections stacked:** **Section 1: Aggiungi voci** - Compact add-row UI: dropdown "Seleziona dal catalogo" + qty input + "Aggiungi" OR "Voce libera" toggle → text input + price + qty - Dropdown shows only active catalog items, sorted by name **Section 2: Voci preventivo** (card with border) - Table: Voce | Qty | Prezzo unitario | Subtotale | Rimuovi - Footer row: "Totale calcolato" bold right-aligned - Below table: separator + "Totale accettato dal cliente" label + editable EUR input + "Salva" button (primary) - Small helper text: "Il cliente vede solo questo importo, non le singole voci." **Empty state:** - Centered text: "Nessuna voce aggiunta. Seleziona dal catalogo per iniziare." ## Components | Component | Type | Location | |-----------|------|---------| | ServiceTable | Server+Client | `components/admin/catalog/ServiceTable.tsx` | | ServiceForm | Client | `components/admin/catalog/ServiceForm.tsx` | | QuoteTab | Client | `components/admin/tabs/QuoteTab.tsx` | | CatalogSelector | Client (inside QuoteTab) | inline | ## Interaction Rules - Add service: inline form row at top OR slide panel — no full page redirect - Edit service: inline row expansion, save with Server Action - Disable/enable: single click, optimistic toggle, Server Action confirm - Add quote item: instant append to list, no page reload - Remove quote item: instant remove, no confirmation (items not locked) - "Salva totale accettato": saves `accepted_total` via Server Action, shows success state (green border flash) ## Typography & Spacing - Section headings: `text-xs font-bold text-[#71717a] uppercase tracking-wider` (same as existing admin) - Table headers: `text-sm font-medium text-[#71717a]` - Prices: `tabular-nums` monospace-aligned - Whitespace: `gap-6` between sections, `py-3 px-4` for table cells - All cards: `rounded-xl border border-[#e5e7eb] bg-white` ## What NOT to do - No modals/dialogs — prefer inline editing - No full-page forms for simple CRUD — stay in context - No icon-heavy buttons — text labels only (consistent with existing admin) - No complex animations — only `transition-colors` on hover