'; }
function renderMappings(){ var box=$('#mappingList'); if(!box) return; box.innerHTML = app.integrations.mappings.map(function(m,i){return '
'+m.crm+' ➜ '+m.app+'
'}).join(''); }
function renderMail(){ var box=$('#mailList'); if(!box) return; box.innerHTML = app.integrations.mailboxes.map(function(m,i){return '
'+m.provider+' • '+m.user+''+m.status+'
'}).join('') || '
No mailboxes
'; }
function renderLeadImports(){ var p=$('#leadImportPanels'); if(!p) return; p.innerHTML = '\n
\n
\n \n \n \n
\n
\n
\n
\n \n \n \n \n
\n
\n
\n \n \n
';
}
function switchLeadImport(tab){
var panels = $all('#leadImportPanels > div');
panels.forEach(function(p){ p.classList.add('hidden'); });
var activePanel = $('#panel-' + tab);
if (activePanel) activePanel.classList.remove('hidden');
}
function renderLeads(){ var t=$('#leadTable'); if(!t) return; var lc=$('#leadCount'); if(lc) lc.textContent = app.leads.length+' total'; var header = '
Name
Email
Company
Title
Country
Score
Status
'; var tpl=$('#tpl-lead-row'); var tbody=document.createElement('tbody'); app.leads.slice(0,300).forEach(function(l){ var row=tpl.content.cloneNode(true); row.querySelector('.fn').textContent = (l.first_name||'')+' '+(l.last_name||''); row.querySelector('.em').textContent = l.email||''; row.querySelector('.co').textContent = l.company||''; row.querySelector('.jt').textContent = l.job_title||''; row.querySelector('.ct').textContent = l.country||''; row.querySelector('.sc').textContent = (l.score!=null? l.score : '-'); row.querySelector('.st').textContent = l.status||'new'; tbody.appendChild(row); }); t.innerHTML = header; t.appendChild(tbody); }
function renderSegments(){ var list=$('#segmentList'); if(!list) return; list.innerHTML = app.segments.map(function(s){ var count=app.leads.filter(function(l){ return matchRule(l, s.rule); }).length; return '
'+s.name+''+count+' leads'+s.rule+'
'; }).join('') || '
No segments yet.
'; var sel=$('#revSegment'); if(sel) sel.innerHTML = app.segments.map(function(s){return ''}).join(''); }
function renderExecution(){ var kActive = app.campaigns.filter(function(c){return c.status==='active'}).length; var kA=$('#kActive'); if(kA) kA.textContent = kActive; var ac=$('#activeC'); if(ac) ac.textContent = kActive; var t=$('#liveCampaigns'); if(!t) return; t.innerHTML = '
Name
Segment
Status
Progress
' + app.campaigns.map(function(c,i){ var sg=(app.segments.filter(function(s){return s.id===c.segmentId})[0]||{}).name||'-'; return '
'+c.name+'
'+sg+'
'+c.status+'
'; }).join('') + ''; renderActivity(); }
function renderActivity(){ var box=$('#activityFeed'); if(!box) return; box.innerHTML = app.inbox.slice(0,30).map(function(m){ return '
'; }
function renderAnalytics(){ var s=computeStats(); var aSent=$('#aSent'); if(aSent) aSent.textContent=s.sent; var aOp=$('#aOpens'); if(aOp) aOp.textContent=s.opens; var aCl=$('#aClicks'); if(aCl) aCl.textContent=s.clicks; var aRp=$('#aReplies'); if(aRp) aRp.textContent=s.replies; var kO=$('#kOpen'); if(kO) kO.textContent=fmtPct(s.openRate||0); var kR=$('#kReply'); if(kR) kR.textContent=fmtPct(s.replyRate||0); var pO=$('#pOpen'); if(pO) pO.style.width=(s.openRate*100)+'%'; var pR=$('#pReply'); if(pR) pR.style.width=(s.replyRate*100)+'%'; var ab='
"); });
el=$('#btnInvite'); if(el) el.addEventListener('click', function(){ var email=$('#inviteEmail').value.trim(); var role=$('#inviteRole').value; if(!email) return toast('Enter email'); app.team.push({email:email, role:role, status:'invited'}); save(); renderTeam(); toast('Invite sent'); audit({action:'Invited member', actor:email}); });
el=$('#teamTable'); if(el) el.addEventListener('click', function(e){ var btn=e.target.closest('[data-rm-member]'); if(!btn) return; var i=+btn.getAttribute('data-rm-member'); var m=app.team[i]; app.team.splice(i,1); save(); renderTeam(); toast('Removed '+m.email); audit({action:'Removed member', actor:m.email}); });
el=$('#btnConnectCRM'); if(el) el.addEventListener('click', function(){ var provider=$('#crmProvider').value; var auth=$('#crmAuth').value; var key=$('#crmKey').value; app.integrations.crm.push({provider:provider, auth:auth, key:key, connected:true}); save(); renderCRM(); renderLeadImports(); toast(provider+' connected'); audit({action:'Connected CRM: '+provider}); });
el=$('#crmList'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('[data-disconnect-crm]'); if(!b) return; var i=+b.getAttribute('data-disconnect-crm'); var c=app.integrations.crm[i]; app.integrations.crm.splice(i,1); save(); renderCRM(); renderLeadImports(); toast('Disconnected '+c.provider); audit({action:'Disconnected CRM: '+c.provider}); });
el=$('#btnAddMapping'); if(el) el.addEventListener('click', function(){ var crm=$('#mapCrmField').value.trim(); var appf=$('#mapAppField').value; if(!crm) return toast('Enter CRM field'); app.integrations.mappings.push({crm:crm, app:appf}); save(); renderMappings(); toast('Mapping added'); });
el=$('#mappingList'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('[data-del-mapping]'); if(!b) return; var i=+b.getAttribute('data-del-mapping'); app.integrations.mappings.splice(i,1); save(); renderMappings(); });
el=$('#btnSaveApollo'); if(el) el.addEventListener('click', function(){ app.integrations.apolloKey=$('#apolloKey').value; save(); toast('Apollo key saved'); });
el=$('#btnConnectMailbox'); if(el) el.addEventListener('click', function(){ var provider=$('#mailProvider').value; var user=$('#mailUser').value; if(!user) return toast('Enter mailbox user'); app.integrations.mailboxes.push({provider:provider,user:user,status:'connected'}); save(); renderMail(); toast('Mailbox connected'); audit({action:'Mailbox connected', actor:user}); });
el=$('#mailList'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('[data-del-mail]'); if(!b) return; var i=+b.getAttribute('data-del-mail'); var m=app.integrations.mailboxes[i]; app.integrations.mailboxes.splice(i,1); save(); renderMail(); toast('Removed '+m.user); });
}
/*****************
* Leads
*****************/
function bindLeads(){
var el;
el=$('#leadImportTabs'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('button[data-t]'); if(!b) return; $all('#leadImportTabs button').forEach(function(x){ x.classList.toggle('active', x===b); }); switchLeadImport(b.getAttribute('data-t')); });
el=$('#leadImportPanels'); if(el) el.addEventListener('click', function(e){ var id=(e.target && e.target.id)||''; if(id==='btnSyncCRMLeads') return syncCRMLeads(); if(id==='btnApolloSearch') return apolloSearch(); if(id==='btnParseCSV') return parseCSV(); });
el=$('#btnSmartApollo'); if(el) el.addEventListener('click', openModalApolloSearch);
el=$('#btnDedupe'); if(el) el.addEventListener('click', dedupeLeads);
el=$('#btnEnrich'); if(el) el.addEventListener('click', enrichLeads);
el=$('#btnExportLeads'); if(el) el.addEventListener('click', exportLeads);
}
function syncCRMLeads(){ var prov=($('#syncCRM') && $('#syncCRM').value)||'HubSpot'; var sample=[{first_name:'Sara',last_name:'Owen',email:'sara.owen@fintexy.co',company:'Fintexy',job_title:'VP Sales',country:'UK',source:'CRM:'+prov},{first_name:'Amir',last_name:'Khan',email:'amir.khan@paylynk.io',company:'PayLynk',job_title:'Head of Growth',country:'UK',source:'CRM:'+prov}]; sample.forEach(function(l){ app.leads.push(Object.assign({id:uid('lead'), status:'new'}, l)); }); save(); renderLeads(); toast('Synced '+sample.length+' leads from '+prov); audit({action:'Synced CRM leads', actor:prov}); }
function openModalApolloSearch(){ openModal('Smart Apollo Search', '\n
\n \n \n \n
\n
\n \n AI expands your query, dedupes and enriches before import.\n
',[{label:'Close', cls:'ghost'}]); var m=$('#modal'); if(m) m.addEventListener('click', function(e){ if((e.target&&e.target.id)==='modalApolloRun') modalApolloRun(); }); }
function modalApolloRun(){ var results=[{first_name:'Linda',last_name:'Price',email:'linda.price@novapay.com',company:'NovaPay',job_title:'VP Sales',country:'UK',source:'Apollo'},{first_name:'Hussam',last_name:'Nasser',email:'hussam@innovafin.com',company:'InnovaFin',job_title:'Head of Sales',country:'UAE',source:'Apollo'}]; results.forEach(function(l){ app.leads.push(Object.assign({id:uid('lead'), status:'new'}, l)); }); save(); renderLeads(); toast('Imported '+results.length+' leads'); audit({action:'Apollo import'}); }
function apolloSearch(){ var loc=($('#apLoc')&&$('#apLoc').value)||'UK'; var add=[{first_name:'Chloe',last_name:'Ng',email:'chloe.ng@ledgerly.io',company:'Ledgerly',job_title:'VP Sales',country:(loc.split(';')[0]||'UK'),source:'Apollo'}]; add.forEach(function(l){ app.leads.push(Object.assign({id:uid('lead'), status:'new'}, l)); }); save(); renderLeads(); toast('Apollo search added '+add.length+' leads'); }
function parseCSV(){ var text=($('#csvArea')&&$('#csvArea').value||'').trim(); if(!text) return toast('Paste CSV'); var rows=text.split(/\n+/).map(function(r){return r.split(/,\s*/)}); var hdr=rows.shift(); function idx(k){ return hdr.indexOf(k) } rows.forEach(function(r){ var l={id:uid('lead'), first_name:r[idx('first_name')]||'', last_name:r[idx('last_name')]||'', email:r[idx('email')]||'', company:r[idx('company')]||'', job_title:r[idx('job_title')]||'', country:r[idx('country')]||'', source:'CSV', status:'new'}; if(l.email) app.leads.push(l); }); save(); renderLeads(); toast('CSV imported '+rows.length+' rows'); }
function dedupeLeads(){ var before=app.leads.length; var map={}; app.leads = app.leads.filter(function(l){ if(!l.email) return true; if(map[l.email]) return false; map[l.email]=true; return true; }); var after=app.leads.length; save(); renderLeads(); var log=$('#cleanseLog'); if(log) log.innerHTML = '
Removed '+(before-after)+' dups
'; audit({action:'Deduplicated leads'}); }
function enrichLeads(){ var count=0; app.leads.forEach(function(l){ if(!l.job_title){ l.job_title=pick(['VP Sales','Head of Growth','Marketing Director','Head of RevOps']); count++; } if(!l.country){ l.country=pick(['UK','UAE','USA','DE','FR']); count++; } }); save(); renderLeads(); var log=$('#cleanseLog'); if(log) log.innerHTML += '
Enriched '+count+' fields
'; toast('AI enrichment complete'); audit({action:'Enriched leads'}); }
function exportLeads(){ var hdr=['first_name','last_name','email','company','job_title','country','status']; var rows=app.leads.map(function(l){ return hdr.map(function(k){return l[k]||''}).join(',') }); var csv=[hdr.join(',')].concat(rows).join('\n'); var blob=new Blob([csv],{type:'text/csv'}); var a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='leads.csv'; a.click(); }
/*****************
* Segments & Scoring
*****************/
function matchRule(lead, rule){ if(!rule) return true; var pairs=rule.split(';').map(function(s){return s.trim()}).filter(Boolean).map(function(s){return s.split(':')}); return pairs.every(function(p){ var k=(p[0]||'').trim(); var v=(p[1]||'').trim().toLowerCase(); return ((lead[k]||'')+'').toLowerCase().indexOf(v)>-1; }); }
function bindSegments(){ var el; el=$('#btnCreateSegment'); if(el) el.addEventListener('click', function(){ var name=$('#segName').value.trim(); var rule=$('#segRule').value.trim(); if(!name||!rule) return toast('Enter name & rule'); app.segments.push({id:uid('seg'), name:name, rule:rule}); save(); renderSegments(); toast('Segment created'); }); el=$('#btnRefreshSegments'); if(el) el.addEventListener('click', function(){ renderSegments(); toast('Segments refreshed') }); el=$('#btnScoreAll'); if(el) el.addEventListener('click', function(){ var wFit=+$('#wFit').value||60; var wEng=+$('#wEng').value||40; app.leads.forEach(function(l){ l.score = scoreLead(l, wFit, wEng); }); save(); renderLeads(); var sl=$('#scoreLog'); if(sl) sl.innerHTML = '
Scored '+app.leads.length+' leads (weights: fit '+wFit+' / eng '+wEng+')
'; audit({action:'Lead scoring run'}); }); }
function scoreLead(l, wFit, wEng){ if(wFit==null) wFit=60; if(wEng==null) wEng=40; var fit=((['VP','Head','Director'].some(function(t){ return (l.job_title||'').indexOf(t)>-1; })?0.8:0.4) + (['UK','UAE'].indexOf(l.country)>-1?0.1:0)); var eng=(l.opens||0)*0.02 + (l.clicks||0)*0.05 + (l.replies?0.2:0); var score=Math.round(clamp(fit,0,1)*wFit + clamp(eng,0,1)*wEng); return clamp(score,0,100); }
/*****************
* Campaign Studio
*****************/
var currentVariant='A';
var variants={ A:{subject:'', body:''}, B:{subject:'', body:''} };
function bindStudio(){
var el;
el=$('#btnDemoGoal'); if(el) el.addEventListener('click', function(){ $('#campGoal').value='Book 20 meetings with VPs of Sales in UK fintech to sell our analytics platform.'; });
el=$('#btnGenStrategies'); if(el) el.addEventListener('click', function(){ var goal=($('#campGoal')&&$('#campGoal').value.trim())||'Book meetings in UK fintech'; var deck=$('#strategyDeck'); if(deck) deck.innerHTML=''; var cards=[]; var i=0; function gen(){ if(i>=3){ deck.innerHTML = cards.map(function(c,idx){ return '
Target Persona'+c.channels+'
'+c.target+'
Pains
'+c.pains.map(function(p){return '
'+p+'
'}).join('')+'
Value Proposition
'+c.value+'
Cadence: '+c.cadence+'
'; }).join(''); deck.setAttribute('data-cards', JSON.stringify(cards)); toast('AI generated strategies'); return; } awaitAI('STRATEGY',{goal:goal}).then(function(s){ cards.push(Object.assign({id:uid('str')}, s)); i++; gen(); }); } gen(); });
el=$('#strategyDeck'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('[data-use-strategy]'); if(!b) return; var cards=JSON.parse(($('#strategyDeck')&&$('#strategyDeck').getAttribute('data-cards'))||'[]'); var c=cards[+b.getAttribute('data-use-strategy')]; pickStrategy(c); });
el=$('#btnBuildPersona'); if(el) el.addEventListener('click', function(){ awaitAI('PERSONA',{}).then(function(p){ $('#personaHint').value=p; toast('Persona drafted'); }); });
el=$('#btnPersonaToGoal'); if(el) el.addEventListener('click', function(){ var t=$('#personaHint').value; $('#campGoal').value += '\n\n'+t; toast('Persona appended to goal'); });
el=$('#btnOpenContentStudio'); if(el) el.addEventListener('click', function(){ var cs=$('#contentStudio'); if(cs) cs.hidden=false; });
el=$('#abTabs'); if(el) el.addEventListener('click', function(e){ var b=e.target.closest('button[data-v]'); if(!b) return; currentVariant=b.getAttribute('data-v'); $all('#abTabs button').forEach(function(x){ x.classList.toggle('active', x.getAttribute('data-v')===currentVariant); }); loadVariantIntoEditor(); });
el=$('#contentStudio'); if(el) el.addEventListener('click', function(e){ var btn=e.target.closest('[data-token]'); if(!btn) return; insertToken(btn.getAttribute('data-token')); });
el=$('#btnWriteSeq'); if(el) el.addEventListener('click', function(){ var persona=($('#stPersona')&&$('#stPersona').value)||'target leaders'; awaitAI('COPY',{persona:persona}).then(function(c){ variants[currentVariant].subject=c.subject; variants[currentVariant].body=c.body; loadVariantIntoEditor(); toast('AI wrote sequence for variant '+currentVariant); }); });
el=$('#btnCompliance'); if(el) el.addEventListener('click', function(){ var text = (($('#editor')&&$('#editor').innerText)||'')+' '+(($('#subj')&&$('#subj').value)||''); awaitAI('COMPLIANCE',{text:text}).then(function(issues){ openModal('Compliance Review', issues.length? issues.map(function(i){return '
⚠️'+i+'
'}).join('') : '
No issues found
'); }); });
el=$('#btnTranslate'); if(el) el.addEventListener('click', function(){ var sel=$('#langSelect'); var langs=[]; if(sel){ $all('option:checked', sel).forEach(function(o){ langs.push(o.value); }); } var text='Subject: '+(($('#subj')&&$('#subj').value)||'')+'\n\n'+(($('#editor')&&$('#editor').innerText)||''); var out=[]; function step(i){ if(i>=langs.length){ var t=$('#translations'); if(t) t.innerHTML = out.join('') || '
Select languages to translate.
'; return; } var lang=langs[i]; awaitAI('TRANSLATE',{text:text, lang:lang}).then(function(r){ out.push('
'+lang+'
'+r.replace(/
'); step(i+1); }); } step(0); });
el=$('#btnFinalReview'); if(el) el.addEventListener('click', function(){ var fr=$('#finalReview'); if(fr) fr.hidden=false; renderSegments(); });
el=$('#btnLaunch'); if(el) el.addEventListener('click', function(){ var segId=($('#revSegment')&&$('#revSegment').value)||''; var name='Campaign '+(app.campaigns.length+1); var camp={id:uid('camp'), name:name, segmentId:segId, status:'active', progress:0, startedAt:nowISO(), variantA:Object.assign({},variants.A), variantB:Object.assign({},variants.B)}; app.campaigns.push(camp); save(); renderExecution(); routeTo('execution'); toast('Campaign launched'); audit({action:'Launched campaign', actor:'system'}); simulateSends(camp.id); });
el=$('#btnSaveDraft'); if(el) el.addEventListener('click', function(){ var segId=($('#revSegment')&&$('#revSegment').value)||''; var name='Draft '+(app.campaigns.length+1); var camp={id:uid('camp'), name:name, segmentId:segId, status:'draft', progress:0}; app.campaigns.push(camp); save(); toast('Draft saved'); renderExecution(); });
}
function pickStrategy(c){ var se=$('#strategyEditor'); if(se) se.hidden=false; if($('#stRegion')) $('#stRegion').value='UK'; if($('#stLang')) $('#stLang').value='English'; if($('#stRoles')) $('#stRoles').value=c.target; if($('#stChannels')) $('#stChannels').value=c.channels; if($('#stCadence')) $('#stCadence').value=c.cadence; if($('#stPersona')) $('#stPersona').value=c.target; window.__pickedStrategy=c; }
function loadVariantIntoEditor(){ if($('#subj')) $('#subj').value = variants[currentVariant].subject||''; if($('#editor')) $('#editor').innerText = variants[currentVariant].body||''; }
function insertToken(tok){ var ed=$('#editor'); if(!ed) return; ed.focus(); try{ document.execCommand('insertText', false, tok); }catch(e){} }
/*****************
* Execution & Inbox Simulation
*****************/
function simulateSends(campId){ var camp=app.campaigns.filter(function(c){return c.id===campId})[0]; if(!camp) return; var ticks=0; var int=setInterval(function(){ try{ ticks++; camp.progress = clamp((camp.progress||0)+Math.random()*18, 0, 100); if(camp.progress>=100){ camp.progress=100; camp.status='completed'; clearInterval(int); toast('Campaign "'+camp.name+'" completed'); } var lead=pick(app.leads)||{first_name:'Alex', last_name:'Demo', email:'alex@demo.com', company:'DemoCo'}; var opened=Math.random()<0.6; var clicked= opened && Math.random()<0.25; var replied= opened && Math.random()<0.15; if(opened){ app.inbox.unshift({id:uid('msg'), box:'events', type:'open', preview:lead.first_name+' opened', at: nowISO()}); } if(clicked){ app.inbox.unshift({id:uid('msg'), box:'events', type:'click', preview:lead.first_name+' clicked', at: nowISO()}); } if(replied){ var text=pick(["Yes, let's talk","Not interested, thanks","Price?","Out of office until tomorrow","Forwarded to my colleague","Maybe later, follow up next month"]); awaitAI('CLASSIFY',{text:text}).then(function(cls){ app.inbox.unshift({ id: uid('msg'), box:'inbox', class: cls, from: (lead.first_name+' '+lead.last_name), email:lead.email, subject: 'Re: '+(variants.A.subject || 'your email'), preview:text, body: text+'\n\n— '+lead.first_name, at: nowISO() }); renderInbox(); }); }
save(); renderExecution(); renderAnalytics(); if(ticks>12) clearInterval(int); }catch(err){ console.error('simulate error', err); } }, 1500); }
function bindInbox(){ var list=$('#inboxList'); if(!list) return; list.addEventListener('click', function(e){ var item=e.target.closest('[data-open-msg]'); if(!item) return; openMsg(item.getAttribute('data-open-msg')); }); }
function openMsg(id){ var m=app.inbox.filter(function(x){return String(x.id)===String(id)})[0]; if(!m) return; var fromFirst=(m.from||'').split(' ')[0]||'there'; $('#reading').innerHTML = '
'+m.subject+''+new Date(m.at).toLocaleString()+'
From: '+(m.from||'')+' • '+(m.email||'')+'
'+(m.body||m.preview)+'
'; var reading=$('#reading'); if(!reading) return; reading.addEventListener('click', function(e){ if(e.target.id==='btnAIDraftReply'){ var draft = 'Hi '+fromFirst+',\n\nThanks for getting back to us. Happy to share pricing and a quick demo. Does '+new Date().toLocaleDateString()+' at 10:00 work?\n\n— '+((app.team[0]&&app.team[0].email)||'me'); openModal('AI Draft Reply', '
'+draft.replace(/', [{label:'Insert to CRM', cls:'acc', on:function(){ toast('Synced to CRM (simulated)') }},{label:'Close', cls:'ghost'}]); } if(e.target.id==='btnHandled'){ var i=app.inbox.findIndex? app.inbox.findIndex(function(x){return String(x.id)===String(e.target.getAttribute('data-done'))}) : -1; if(i>-1){ app.inbox.splice(i,1); save(); renderInbox(); $('#reading').innerHTML = '
Select a message
'; } } }); }
/*****************
* Analytics
*****************/
function computeStats(){ var sent = Math.floor(app.campaigns.length*200 + app.leads.length*0.2); var opens = Math.floor(sent*0.45); var clicks = Math.floor(opens*0.25); var replies = Math.floor(opens*0.15); var openRateA = 0.38 + Math.random()*0.05; var openRateB = 0.42 + Math.random()*0.05; var replyRateA = 0.11 + Math.random()*0.03; var replyRateB = 0.13 + Math.random()*0.04; var openRate = opens/(sent||1); var replyRate = replies/(sent||1); var leadPick = pick(app.leads); var leadCompany = (leadPick && leadPick.company) || 'Acme'; var revenue = app.campaigns.filter(function(c){return c.status==='completed'}).slice(0,5).map(function(c,i){return {campaign:c.name, lead: leadCompany, amount: 2000 + i*1500, stage: pick(['Won','Closed‑Won','Closed'])}}); return {sent:sent, opens:opens, clicks:clicks, replies:replies, openRate:openRate, replyRate:replyRate, openRateA:openRateA, openRateB:openRateB, replyRateA:replyRateA, replyRateB:replyRateB, revenue:revenue}; }
/*****************
* Settings & Global
*****************/
function bindSettings(){
var el;
el=$('#btnSaveState'); if(el) el.addEventListener('click', function(){ save(); toast('State saved') });
el=$('#btnResetDemo'); if(el) el.addEventListener('click', function(){ localStorage.removeItem(stateKey); window.location.reload(); });
el=$('#btnExportState'); if(el) el.addEventListener('click', exportState);
el=$('#btnAddSuppression'); if(el) el.addEventListener('click', function(){ var v=($('#suppInput')&&$('#suppInput').value.trim())||''; if(!v) return; app.suppressions.push(v); save(); renderSupp(); $('#suppInput').value=''; });
el=$('#btnSaveWebhook'); if(el) el.addEventListener('click', function(){ app.settings.webhook=(($('#webhookUrl')&&$('#webhookUrl').value)||'').trim(); save(); var hs=$('#hookStatus'); if(hs) hs.textContent='Saved ✓'; toast('Webhook saved'); });
var suppList = $('#suppList'); if(suppList){ suppList.addEventListener('click', function(e){ var btn=e.target.closest('[data-del-supp]'); if(!btn) return; var i=+btn.getAttribute('data-del-supp'); if(app.suppressions[i]!==undefined){app.suppressions.splice(i,1); save(); renderSupp(); toast('Suppression removed.'); } }); }
}
function renderSupp(){ var box=$('#suppList'); if(!box) return; box.innerHTML = app.suppressions.map(function(s,i){return ''+s+' '}).join(' '); }
function exportState(){ var blob=new Blob([JSON.stringify(app,null,2)],{type:'application/json'}); var a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='alex_state.json'; a.click(); }
function bindGlobal(){
function openCmd(){ openModal('Command', '', [{label:'Close',cls:'ghost'}]); }
var cp=$('#cmdPaletteBtn'); if(cp) cp.addEventListener('click', openCmd);
var oc=$('#btnOpenCmd'); if(oc) oc.addEventListener('click', openCmd);
var ncb=$('#newCampaignBtn'); if(ncb) ncb.addEventListener('click', function(){ routeTo('studio'); });
document.addEventListener('keydown', function(e){ var k=(e.key||'').toLowerCase(); if((e.ctrlKey||e.metaKey) && k==='k'){ e.preventDefault(); openCmd(); }});
var ql=$('#btnQuickLead'); if(ql) ql.addEventListener('click', function(){ var l={id:uid('lead'), first_name:'Alex', last_name:'Quick', email:'alex.quick+'+Date.now()+'@demo.test', company:'DemoCo', job_title:'VP Sales', country:'UK', status:'new'}; app.leads.unshift(l); save(); renderLeads(); toast('Quick lead added') });
var gs=$('#globalSearch'); if(gs) gs.addEventListener('keydown', function(e){ if(e.key==='Enter'){ var q=(e.target.value||'').toLowerCase(); if(q.indexOf('campaign')>-1) routeTo('execution'); else if(q.indexOf('lead')>-1) routeTo('leads'); else if(q.indexOf('inbox')>-1) routeTo('inbox'); else if(q.indexOf('analytics')>-1) routeTo('analytics'); else routeTo('foundation'); }});
var mb=$('#modalRoot'); if(mb) mb.addEventListener('click', function(e){ if((e.target&&e.target.id)==='modalRoot') closeModal(); });
window.addEventListener('error', function(e){ console.error('Global error:', e.error||e.message); toast('Error: '+(e.error&&e.error.message || e.message)); });
}
/*****************
* Bootstrap
*****************/
function seedIfEmpty(){ if(app.leads.length===0){ app.leads.push({id:uid('lead'), first_name:'Sara', last_name:'Owen', email:'sara@fintexy.co', company:'Fintexy', job_title:'VP Sales', country:'UK', status:'new'},{id:uid('lead'), first_name:'Amir', last_name:'Khan', email:'amir@paylynk.io', company:'PayLynk', job_title:'Head of Growth', country:'UK', status:'new'}); } if(app.inbox.length===0){ app.inbox.push({id:uid('msg'), box:'inbox', class:'Interested', from:'Linda Price', email:'linda.price@novapay.com', subject:'Re: Quick question', preview:'Yes, happy to chat', body:'Yes, happy to chat next week.', at: nowISO()}); } }
function init(){
seedIfEmpty();
mountRouter();
bindFoundation();
bindLeads();
bindSegments();
bindStudio();
bindInbox();
bindSettings();
bindGlobal();
refreshAll();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}