// ============================================================ // MOORE AI v13 — ACTION REFERENCE TAB // ============================================================ const ActionReferenceView = () => { const { useState } = React; const [testResults, setTestResults] = useState({}); const [testingId, setTestingId] = useState(null); const runTest = async (actionId) => { setTestingId(actionId); setTestResults(prev => ({ ...prev, [actionId]: null })); try { const r = await fetch('/api/actions/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: actionId }) }); const data = await r.json(); setTestResults(prev => ({ ...prev, [actionId]: data })); } catch(e) { setTestResults(prev => ({ ...prev, [actionId]: { ok: false, message: e.message } })); } setTestingId(null); }; const defaultActions = [ { id: 'MAKE_CALL', icon: 'phone-call', label: 'Call a Lead', color: '#3b82f6', desc: 'Dispatch an AI outbound call via Bland AI to any contact in seconds.' }, { id: 'SCHEDULE', icon: 'calendar-check', label: 'Book Appointment', color: '#8b5cf6', desc: 'Create a confirmed GHL calendar appointment for any contact.' }, { id: 'SEND_EMAIL', icon: 'mail', label: 'Send Email', color: '#06b6d4', desc: 'Send a GHL email to a contact — proposals, follow-ups, updates.' }, { id: 'SEND_SMS', icon: 'message-circle', label: 'Send SMS', color: '#10b981', desc: 'Send an SMS via GHL. 98% open rate — fastest re-engagement channel.' }, { id: 'UPDATE_OPP', icon: 'trophy', label: 'Close a Deal', color: '#f59e0b', desc: 'Mark an opportunity won, lost, or open. Keeps pipeline accurate.' }, { id: 'MOVE_STAGE', icon: 'git-merge', label: 'Move Pipeline Stage', color: '#6366f1', desc: 'Push any opportunity to a specific stage in the pipeline.' }, { id: 'CREATE_CONTACT', icon: 'user-plus', label: 'Add Contact', color: '#3b82f6', desc: 'Create a new GHL contact. Every lead captured, none fall through.' }, { id: 'UPDATE_CONTACT', icon: 'pencil', label: 'Update CRM Record', color: '#64748b', desc: 'Update any field on a GHL contact — phone, email, tags, notes.' }, { id: 'ADD_NOTE', icon: 'file-text', label: 'Add Note', color: '#ec4899', desc: 'Attach a note to any contact. Conversation context always on file.' }, { id: 'ADD_TASK', icon: 'check-square', label: 'Create Task', color: '#10b981', desc: 'Add a task to the Tasks board. No next step ever gets forgotten.' }, { id: 'CHAIN', icon: 'zap', label: 'Chain Actions', color: '#f59e0b', desc: 'One command → Jake executes a full multi-step workflow automatically.' }, ]; const useCases = [ { id: 'voice-intake', label: 'AI Voice Intake', icon: 'mic', color: '#3b82f6', tagline: 'New lead calls in — Jake handles it.', description: 'A prospect fills your form or calls your number. Jake dials them within seconds, introduces himself, qualifies the lead, captures their info, and books the appointment — before a competitor can blink.', actions: ['MAKE_CALL', 'CREATE_CONTACT', 'ADD_NOTE', 'SCHEDULE'], stat: '9× faster response', }, { id: 'appt-confirm', label: 'Appointment Confirmation', icon: 'calendar-check', color: '#8b5cf6', tagline: 'No more no-shows.', description: 'Day before and morning of the appointment, Jake texts the client their details, confirms attendance, and reschedules instantly if needed. Show rates go up, wasted trips go to zero.', actions: ['SEND_SMS', 'SCHEDULE'], stat: '−6% no-show rate', }, { id: 'proposal-followup', label: 'Proposal Follow-Up', icon: 'file-text', color: '#06b6d4', tagline: 'Silence never kills a deal again.', description: 'Quote sent, no response. Jake emails a polished follow-up the same day the proposal lands. Three days later — another touch. He never forgets, never feels awkward making the ask.', actions: ['SEND_EMAIL', 'ADD_NOTE', 'ADD_TASK'], stat: '−9% deal ghosting', }, { id: 'client-comms', label: 'Active Job Communication', icon: 'message-circle', color: '#10b981', tagline: 'Every client feels like your most important client.', description: 'Jake handles routine client communications during active jobs — update texts, confirmation emails, quick answers — so no message goes unanswered.', actions: ['SEND_SMS', 'SEND_EMAIL', 'UPDATE_CONTACT'], stat: '−4% churn from silence', }, { id: 'invoice-followup', label: 'Invoice Follow-Up', icon: 'dollar-sign', color: '#f59e0b', tagline: 'Cash collected without the awkwardness.', description: 'Job done, invoice unpaid. Jake sends a friendly reminder the day it goes unpaid, then escalates automatically. No awkwardness, no lost friendship — just cash collected.', actions: ['SEND_EMAIL', 'SEND_SMS', 'UPDATE_OPP'], stat: '−9% revenue delayed', }, { id: 're-engage', label: 'Past Client Re-Engagement', icon: 'refresh-cw', color: '#ec4899', tagline: 'Closed jobs become repeat business.', description: 'Jake keeps a list of closed customers and re-engages them at the right moment — seasonal check-ins, project anniversaries, referral asks. One command turns a closed deal into a repeat customer.', actions: ['MAKE_CALL', 'SEND_SMS', 'CREATE_CONTACT'], stat: '−5% revenue to silence', }, ]; const [actions, setActions] = useState(() => { try { const saved = JSON.parse(localStorage.getItem('moore_action_toggles') || '{}'); return defaultActions.map(a => ({ ...a, enabled: saved[a.id] !== undefined ? saved[a.id] : true })); } catch(e) { return defaultActions.map(a => ({ ...a, enabled: true })); } }); const toggle = (id) => { const updated = actions.map(a => a.id === id ? { ...a, enabled: !a.enabled } : a); setActions(updated); const map = {}; updated.forEach(a => { map[a.id] = a.enabled; }); localStorage.setItem('moore_action_toggles', JSON.stringify(map)); }; const enableAll = () => { const updated = actions.map(a => ({ ...a, enabled: true })); setActions(updated); localStorage.setItem('moore_action_toggles', JSON.stringify(Object.fromEntries(updated.map(a => [a.id, true])))); }; const actionMap = Object.fromEntries(actions.map(a => [a.id, a])); const activeCount = actions.filter(a => a.enabled).length; return (
Toggle which actions Jake AI can execute. Disabled actions are skipped with a notice.