💾 Your data saves automatically to this browser.
Never exported
⬇ Export Backup
⬆ Import
Dashboard
What you're working on right now
🔍
+ Add
Recent Processes
GHL Snapshots
Open Tasks
Voice & Chat Widgets
Add
×
Cancel
Save
// ─────────────────────────────────────────── // STATE // ─────────────────────────────────────────── const SK = 'opshub_v3'; function loadState() { try { const saved = JSON.parse(localStorage.getItem(SK)); if (!saved) return seed(); // Migrate: if brands array is missing, inject it from seed if (!saved.brands || !saved.brands.length) { saved.brands = seed().brands; } else { saved.brands.forEach(b => { ['processes','snapshots','gpttools','sops','components','widgets','tools','snippets'].forEach(k => { if (!b[k]) b[k] = []; }); }); } if (!saved.tools) saved.tools = seed().tools; if (!saved.snippets) saved.snippets = seed().snippets; // Migrate clients (saved.clients||[]).forEach(cl => { if (!cl.brands) cl.brands = cl.brand ? [] : []; if (!cl.assetLinks) cl.assetLinks = {}; if (!cl.assetLinks.tools) cl.assetLinks.tools = []; if (!cl.assetLinks.snippets) cl.assetLinks.snippets = []; if (cl.stackNotes === undefined) cl.stackNotes = ''; }); // Migrate SOPs to have url/pdf fields (saved.sops||[]).forEach(o => { if (o.url === undefined) o.url = ''; if (o.pdf === undefined) o.pdf = null; if (o.pdfName === undefined) o.pdfName = ''; }); return saved; } catch { return seed(); } } async function persist() { try { localStorage.setItem(SK, JSON.stringify(S)); const now = new Date(); const t = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); const d = now.toLocaleDateString([], { month: 'short', day: 'numeric' }); const el = document.getElementById('last-saved'); if (el) el.textContent = `Auto-saved ${d} at ${t}`; const { error } = await supabase .from('ops_data') .upsert( { key: 'ops_hub', value: S }, { onConflict: 'key' } ); if (error) { console.error('Supabase save error:', error); } } catch (err) { console.error('Persist error:', err); } } function seed() { return { brands: [ { id: 'br1', name: 'Chic AI Receptionist', icon: '🎙', color: '#C9A84C', processes: ['p1'], snapshots: ['s2'], gpttools: ['g2'], sops: ['o1'], components: ['c1'], widgets: ['w1'], tools: ['tl1','tl3'], snippets: ['sn1'] }, { id: 'br2', name: 'PerksPro+', icon: '💎', color: '#A8C5A0', processes: ['p2'], snapshots: ['s1'], gpttools: [], sops: [], components: ['c2'], widgets: [], tools: ['tl1'], snippets: [] }, { id: 'br3', name: 'The Fountain Church', icon: '⛪', color: '#7EB8C9', processes: ['p3'], snapshots: ['s3'], gpttools: ['g1'], sops: ['o2'], components: [], widgets: [], tools: ['tl1','tl2'], snippets: ['sn2'] }, { id: 'br4', name: 'Business Automation Hub', icon: '⚙️', color: '#1A2340', processes: [], snapshots: [], gpttools: [], sops: [], components: [], widgets: [], tools: [], snippets: [] } ], clients: [ { id: 'cl1', name: 'Setchfield Audio', contact: 'Husband\'s business', email: '', phone: '', brand: 'Chic AI Receptionist', status: 'active', color: '#C9A84C', industry: 'AV Integration', notes: 'Internal client — AV integration business. Uses voice receptionist and loyalty program.', assetLinks: { widgets:['w1'], snapshots:['s2'], processes:['p1'], gpttools:[], sops:['o1'], components:[], tools:['tl1','tl3'] }, brands: ['br1'], stackNotes: 'Also uses their own booking software.' }, { id: 'cl2', name: 'The Fountain Church', contact: 'Internal', email: '', phone: '', brand: 'The Fountain Church', status: 'active', color: '#7EB8C9', industry: 'Church / Nonprofit', notes: 'Primary church client. Full digital stack: SEO, GHL automations, YouTube pipeline, Easter campaign.', assetLinks: { widgets:[], snapshots:['s3'], processes:['p3'], gpttools:['g1'], sops:['o2'], components:[], tools:['tl1','tl2'] }, brands: ['br3'], stackNotes: 'Also uses Planning Center, YouTube Studio.' } ], widgets: [ { id: 'w1', name: 'Chic AI Voice Receptionist — Setchfield Audio', brand: 'Chic AI Receptionist', type: 'voice', status: 'live', color: '#C9A84C', client: 'Setchfield Audio', industry: 'AV Integration', purpose: 'Handles inbound calls after hours and during busy periods. Books consultations, answers FAQs about AV services, and routes urgent calls to the right person.', platform: 'Aminos + GHL', languages: ['English'], embedCode: '