- DynamicTable component: wraps Table for dynamic/unknown columns with headerRenderer support
- Import wizard preview now uses DynamicTable instead of plain HTML table
- Fixed modal height (80vh) to prevent jitter between wizard steps
- Campaign card shows actual linked lead count, not marketing metric
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ColumnToggle component with checkbox dropdown for column visibility
- useColumnVisibility hook for state management
- Campaign/Ad/FirstContact/Spam/Dups hidden by default (mostly empty)
- ResizableTableContainer wrapping Table for column resize support
- Column defaultWidth/minWidth props
- Removed non-functional Filter and Sort buttons
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Missed call queue with FIFO auto-assignment, dedup, SLA tracking
- Status sub-tabs (Pending/Attempted/Completed/Invalid) in worklist
- missedCallId passed through disposition flow for callback tracking
- Login page redesigned: centered white card on blue background
- Disposition button changed to content-width
- NavAccountCard popover close fix on menu item click
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced all bare `FC<{ className?: string }>` and `FC<HTMLAttributes<...>>`
wrappers that only forwarded `className` with `faIcon()` from
`src/lib/icon-wrapper.ts`, ensuring props like `data-icon` needed by the
Button component's CSS selector `*:data-icon:size-5` are correctly forwarded.
Also widened `NavItemBaseProps.icon` and `NavItemType.icon` prop types to
`FC<Record<string, any>>` to stay compatible with `faIcon()` return type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all @untitledui/icons imports across 55 files with equivalent
@fortawesome/pro-duotone-svg-icons icons, using FontAwesomeIcon wrappers
(FC<{ className?: string }>) for prop-based usage and inline replacements
for direct JSX usage. Drops unsupported Untitled UI-specific props
(strokeWidth, numeric size). TypeScript compiles clean with no errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CC Agent:
- Call transfer (CONFERENCE + KICK_CALL) with inline transfer dialog
- Recording pause/resume during active calls
- Missed calls API (Ozonetel abandonCalls)
- Call history API (Ozonetel fetchCDRDetails)
Live Call Assist:
- Deepgram Nova STT via raw WebSocket
- OpenAI suggestions every 10s with lead context
- LiveTranscript component in sidebar during calls
- Browser audio capture from remote WebRTC stream
Worklist:
- Redesigned table: clickable phones, context menu (Call/SMS/WhatsApp)
- Last interaction sub-line, source column, improved SLA
- Filtered out rows without phone numbers
- New missed call notifications
Brand:
- Logo on login page
- Blue scale rebuilt from logo blue rgb(32, 96, 160)
- FontAwesome duotone CSS variables set globally
- Profile menu icons switched to duotone
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Telephony:
- Track UCID from SIP headers and ManualDial response
- Submit disposition to Ozonetel via Set Disposition API (ends ACW)
- Fix outboundPending flag lifecycle to prevent inbound poisoning
- Fix render order: post-call UI takes priority over active state
- Pre-select disposition when appointment booked during call
Appointment form:
- Convert from slideout to inline collapsible below call card
- Fetch real doctors from platform, filter by department
- Show time slot availability grid (booked slots greyed + strikethrough)
- Double-check availability before booking
- Support edit and cancel existing appointments
UI:
- Add Force Ready button to profile menu (logout+login to clear ACW)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Collapsible sidebar with Jotai atom (icon-only mode, persisted to localStorage)
- 2-panel call desk: worklist (60%) + context panel (40%) with AI + Lead 360 tabs
- Inline AI call prep card — known lead summary or unknown caller script
- Active call card with compact Answer/Decline buttons
- Worklist panel with human-readable labels, priority badges, click-to-select
- Context panel auto-switches to Lead 360 when lead selected or call incoming
- Browser ringtone via Web Audio API on incoming calls
- Sonner + Untitled UI IconNotification for toast system
- apiClient pattern: centralized post/get/graphql with auto-toast on errors
- Remove duplicate avatar from top bar, hide floating widget on call desk
- Fix Link routing in collapsed sidebar (was using <a> causing full page reload)
- Fix GraphQL field names: adStatus→status, platformUrl needs subfield selection
- Silent mode for DataProvider queries to prevent toast spam
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace mock DataProvider with real GraphQL queries through sidecar
- Add queries.ts and transforms.ts for platform field name mapping
- Migrate SIP state from React Context to Jotai atoms (React 19 compat)
- Add singleton SIP manager to survive StrictMode remounts
- Remove hardcoded Olivia/Sienna accounts from nav menu
- Add password eye toggle, remember me checkbox, forgot password link
- Fix worklist hook to transform platform field names
- Add seed scripts for clinics, health packages, lab tests
- Update test harness for new doctor→clinic relation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Sidebar: use useAuth() for isAdmin and pass auth user to NavAccountCard
- NavAccountCard: fix bug where items prop was ignored (used placeholderAccounts)
- TopBar: replace hardcoded "SM" initials with user.initials from auth
- All Leads: add "My Leads" tab filtering by assignedAgent matching user
- Lead Card: add role-aware action buttons (Call/Disposition for assigned leads)
- Lead Workspace: pass onLogCall/onUpdateStatus handlers to LeadCard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>