- Sidebar: expanded 256->200px, collapsed 80->64px; collapsed state now
renders icon-only (label removed from flow) so icons are centered, not
pushed left by an invisible text span
- Kanban cards: add StatusBadge + email line to match design reference
- Lead table: add "Mostrando N lead" footer and center/right-align
Stato/Tag/Azioni headers per reference
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Design system foundations: Plus Jakarta Sans font, shadow-card/radius
tokens in @theme, design-reference/DESIGN-SYSTEM.md with component inventory
- Collapsible admin shell (AdminShell): smooth w-64<->w-20 sidebar, new top
header with "Admin" + avatar placeholder, localStorage-persisted state
- Rename route /admin/leads -> /admin/pipeline (redirect stubs preserved),
nav label Lead -> Pipeline; DB table unchanged
- Reusable primitives: StatusBadge, SearchInput, SegmentedToggle (dual-theme)
- Luxury restyle of lead table, kanban (6 stages + @dnd-kit intact), PageHeader
- Tokenize editable-cell / option-multi-select for dark-mode legibility
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Blocco A+B (milestone v2.3). Migration 0011 is additive (ADD COLUMN only):
clients.email, clients.phone, leads.archived.
- createClientCore() extracted from createClient and reused by conversion
- clients.email/phone added to create + edit forms and shown on client header
(never exposed on the public /client/[token] page)
- convertLeadToClient(): reuses core, carries over lead transcripts
(client_transcripts.client_id), links project.created_from_lead_id,
archives the lead while keeping its "won" status; idempotent
- "Converti in cliente" button on won leads; "Convertito → Apri cliente"
once converted (clientId resolved via created_from_lead_id)
- archived leads hidden from list/kanban; detail page fetches by id incl. archived
Migration must be applied to the prod DB BEFORE this is deployed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- LeadsViewToggle: client wrapper with useState<list|kanban>, useMemo filtered
- Search input (left) + pill toggle Lista/Kanban (right) on single row
- Filters leads by name/email/company/status/tags across both views
- Search state preserved when switching between Lista and Kanban
- LeadsSearch.tsx: replaced with re-export of LeadsViewToggle (backward compat)
assignQuoteToLead's generate_new check was unreachable since
SendQuoteModal always passed false. Removes the field from both
the server schema and the modal's local schema/defaultValues/call site.
- New LeadsSearch.tsx: client-side instant filter across name/email/
company/status/tags (mirrors CatalogSearch.tsx)
- page.tsx: fetch via getLeadsWithTags()/getLeadFieldOptions(), render
LeadsSearch + CreateLeadModal, revalidate=0
- [id]/page.tsx: fetch getLeadsWithTags()/getLeadFieldOptions(), find
lead by id, pass tags/tagOptions to LeadDetail
- LeadDetail.tsx: add OptionMultiSelect for lead tags in the "Profilo"
card, wired to addLeadTag/removeLeadTag/renameLeadTag with error display
Replace shadcn Table-based read-only LeadTable with an Attio-style raw
table database view (1:1 structural port of ServiceTable.tsx):
- EditableCell for name/email/phone/company/next_action, persisted via
updateLeadField
- Local StatusCell: closed click-to-open dropdown over the 6 fixed
LEAD_STAGES values, preserving semantic STAGE_COLOR badges (won=green,
lost=red, etc.) without modifying shared option-select.tsx
- OptionMultiSelect for lead tags, wired to addLeadTag/removeLeadTag/
renameLeadTag
- Per-row error display and "Nessun lead trovato" empty state
- Remove unreachable if (tab === "new") branch in onSubmit - the new-tab button has its own onClick navigation and never triggers form submit
- Escape unescaped double quotes in JSX text (react/no-unescaped-entities)
- generate_new field left as-is per plan (optional cleanup, out of scope)
- Log pre-existing useForm<any>/onSubmit(data: any) no-explicit-any lint errors to deferred-items.md (out of scope: fixing requires resolving a zodResolver/Resolver generic incompatibility with assignQuoteSchema's optional/default fields)
- CreateLeadModal and EditLeadModal use useForm<CreateLeadInput>() instead of useForm<any>()
- Import CreateLeadInput from lead-validators, remove local z.infer redeclaration
- Narrow EditLeadModal status default value to CreateLeadInput["status"], remove 'as any'
- Fix FormField generic signature in shared ui/form.tsx (was ControllerProps<any, any>, broke Control<T> assignability once useForm<T> became concrete) - Rule 3 blocking issue
Stage C of staged Phase 10 redo. Restores dangling phase10-wip work:
- schema.ts: leads expansion + activities/reminders tables + relations
- lead-service.ts / lead-validators.ts service layer
- /admin/leads list + detail + actions, LeadTable/LeadDetail/LeadForm
- LogActivityModal, SendQuoteModal, FollowUpWidget on dashboard
- migration 0005 (applied to prod DB in Stage B, along with
previously-missing 0001/0003/0004 — root cause of all post-deploy
500s: prod DB had no migrations applied since 0000)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>