PageSourceSearch

https://supafone.ai/assets/CampaignBuilderPage-BCDXymCh.js

js supafone.ai collected 2026-10-05 12:43:23 UTC 101,306 bytes, 4 lines download raw bytes

1import{j as e,r}from"./react-vendor-B84ySind.js";import{toast as o}from"./index-DJ9vMMmN.js";import{A as Dt}from"./AppShell-Czw89rrj.js";import{B as mn}from"./BrandIcons-Bl2Va15g.js";import{C as un,F as Ft,a as pn,b as xn,c as hn,d as bn}from"./SalesPage-CrRviLmE.js";import{Q as gn}from"./QuickCreateAgentModal-CW1BRt9n.js";import{U as pt,A as fn,E as Ks,a as vn}from"./ConnectionStatus-Nvun7Rhr.js";import{campaignsApi as u,agentsApi as Js}from"./api-C_8UOW6Y.js";import{c as Wt,q as H,v as ne,a4 as ca,J as ee,L as Zs,f as te,o as yn}from"./App-D2lF-mjJ.js";import{C as Ot}from"./chevron-right-QzEFr3mX.js";import{t as kn}from"./toastError-DVfZ5s9a.js";import{ba as jn,b5 as wn,bf as Nn,a8 as It}from"./chunk-62JRHF6Z-DOE63XKs.js";import{L as N}from"./loader-circle-B4-zOoTw.js";import{A as _n}from"./arrow-left-CqA9rHXa.js";import{P as ea}from"./pause-BJPOai6p.js";import{R as ta}from"./rocket-Cep-5JVt.js";import{T as se}from"./triangle-alert-DD6EjXG6.js";import{T as Cn}from"./table-2-CA1dmKkj.js";import{T as me}from"./trash-2-DH_G0B5L.js";import{R as sa}from"./refresh-cw-D6lR8Cqw.js";import{M as Bt}from"./mail-Bpls0SuW.js";import{T as ma}from"./target-DSK3WS_2.js";import{C as Sn}from"./copy-CKU5uACq.js";import{D as Pn}from"./download-CD1cqq98.js";import{C as zn}from"./clock-DqGrdGGC.js";import"./auth-BLGehRGb.js";import"./index-BD4QB2Lb.js";import"./phone-call-BeFO-e-U.js";import"./send-Cy0j9QuL.js";import"./palette-Buy9I3x_.js";import"./circle-check-B8j2x77-.js";import"./save-DebQib_d.js";import"./connections-VSfiVSAL.js";import"./arrow-right-C23lXerh.js";import"./external-link-CHYqV81b.js";import"./agentSetup-CsG4uq5R.js";const Ln=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],ua=Wt("chevron-left",Ln);const $n=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M8 13h2",key:"yr2amv"}],["path",{d:"M14 13h2",key:"un5t4a"}],["path",{d:"M8 17h2",key:"2yhykz"}],["path",{d:"M14 17h2",key:"10kma7"}]],Ut=Wt("file-spreadsheet",$n);const qn=[["path",{d:"M13 21h8",key:"1jsn5i"}],["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]],ue=Wt("pen-line",qn),An={queued:{label:"Queued",color:"bg-slate-400"},in_progress:{label:"In progress",color:"bg-brand-500"},awaiting_result:{label:"Awaiting result",color:"bg-sky-500"},completed:{label:"Completed",color:"bg-emerald-500"},needs_human:{label:"Needs review",color:"bg-amber-500"},needs_consent:{label:"Needs consent",color:"bg-amber-500"},needs_twilio:{label:"Finish calling setup",color:"bg-rose-500"},needs_provider:{label:"Finish calling setup",color:"bg-rose-500"},no_credits:{label:"Out of credits",color:"bg-rose-500"},opted_out:{label:"Opted out",color:"bg-slate-500"}};function ae({label:a,value:l,sub:m}){return e.jsxs("div",{className:"card",children:[e.jsx("div",{className:"text-2xl font-semibold text-ink",children:l}),e.jsx("div",{className:"mt-0.5 text-xs font-medium text-slate-500 dark:text-slate-400",children:a}),m?e.jsx("div",{className:"mt-1 text-[11px] text-slate-400 dark:text-slate-500",children:m}):null]})}function Rn({recipients:a,stats:l}){const m=l?.total??a.length,i=l?.by_state??{},g=a.filter(S=>S.last_touch_at).length,p=i.completed??0,f=(i.queued??0)+(i.in_progress??0)+(i.awaiting_result??0),v=a.reduce((S,A)=>S+(A.attempts||0),0),w=m?Math.round(g/m*100):0,y=a.filter(S=>S.last_channel==="voice").length,R=a.filter(S=>S.last_channel==="email").length,q=Object.entries(i).sort((S,A)=>A[1]-S[1]),E=Math.max(1,...q.map(([,S])=>S));return m===0?e.jsx("div",{className:"card text-sm text-slate-500 dark:text-slate-400",children:"No recipients yet — add some under “Who to call”, and analytics will show up here as the campaign runs."}):e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:[e.jsx(ae,{label:"Recipients",value:m}),e.jsx(ae,{label:"Reached",value:g,sub:`${w}% of the list`}),e.jsx(ae,{label:"Completed",value:p}),e.jsx(ae,{label:"Still to go",value:f})]}),e.jsxs("div",{className:"card",children:[e.jsx("div",{className:"text-sm font-semibold text-ink",children:"Where every recipient stands"}),e.jsx("div",{className:"mt-3 space-y-2.5",children:q.map(([S,A])=>{const j=An[S]||{label:S,color:"bg-slate-400"},O=Math.round(A/m*100);return e.jsxs("div",{className:"flex items-center gap-3 text-xs",children:[e.jsx("div",{className:"w-28 shrink-0 text-slate-600 dar
1k:text-slate-300",children:j.label}),e.jsx("div",{className:"h-2.5 flex-1 overflow-hidden rounded-full bg-slate-100 dark:bg-white/5",children:e.jsx("div",{className:`h-full rounded-full ${j.color}`,style:{width:`${Math.max(3,A/E*100)}%`}})}),e.jsxs("div",{className:"w-16 shrink-0 text-right tabular-nums text-slate-500 dark:text-slate-400",children:[A," · ",O,"%"]})]},S)})})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-3",children:[e.jsx(ae,{label:"Total touches",value:v,sub:"calls + emails placed"}),e.jsx(ae,{label:"Voice-first replies",value:y,sub:"last touch was a call"}),e.jsx(ae,{label:"Email-first replies",value:R,sub:"last touch was an email"})]})]})}const xt=612,Pe=792,aa=[{id:"fit",label:"Fit",width:480},{id:"work",label:"Work",width:620},{id:"xl",label:"XL",width:760}];function pa(a){return a==="date"?{width:62,height:18}:a==="initials"?{width:44,height:18}:a==="text"?{width:84,height:20}:{width:92,height:26}}function Vt(a){return{...a,page:Math.max(0,Math.floor(a.page||0)),x:Math.max(0,Math.min(a.x,xt-a.width)),y:Math.max(0,Math.min(a.y,Pe-a.height))}}function Tn(a,l){const m=pa(String(a.type||"signature"));return Vt({...l,width:m.width,height:m.height})}function En(a){return a==="date"?"border-sky-500 bg-sky-200/40 ring-sky-500/30 text-sky-700 dark:text-sky-300":a==="initials"?"border-amber-500 bg-amber-200/40 ring-amber-500/30 text-amber-700 dark:text-amber-300":a==="text"?"border-violet-500 bg-violet-200/40 ring-violet-500/30 text-violet-700 dark:text-violet-300":"border-emerald-500 bg-emerald-200/40 ring-emerald-500/30 text-emerald-700 dark:text-emerald-300"}function Dn({pdfUrl:a,fields:l,activeFieldKey:m,onActiveFieldKeyChange:i,onFieldsChange:g}){const p=r.useRef(null),[f,v]=r.useState(0),[w,y]=r.useState(0),[R,q]=r.useState(0),[E,S]=r.useState("work"),A=r.useRef(null),j=r.useMemo(()=>l.length?l:[{key:"client_signature",type:"signature",label:"Signature",required:!0,placement:null}],[l]),O=m||j[0]?.key||"client_signature";r.useEffect(()=>{j.length&&(j.some(c=>c.key===O)||i?.(j[0].key))},[i,O,j]),r.useEffect(()=>{const c=()=>q(k=>k+1);return window.addEventListener("resize",c),()=>window.removeEventListener("resize",c)},[]),r.useEffect(()=>{let c=!1;if(y(0),v(0),!!a)return(async()=>{try{const x=await(await fetch(a)).arrayBuffer(),b=new TextDecoder("latin1").decode(new Uint8Array(x)),h=[...b.matchAll(/\/Count\s+(\d+)/g)].map(I=>Number(I[1])).filter(I=>I>0),_=(b.match(/\/Type\s*\/Page(?![s])/g)||[]).length,Q=Math.max(h.length?Math.max(...h):0,_);!c&&Q>0&&y(Q)}catch{}})(),()=>{c=!0}},[a]),r.useEffect(()=>{w>0&&f>w-1&&v(w-1)},[w,f]);const B=(c,k)=>{g(j.map(x=>x.key===c?{...x,placement:k?Tn(x,k):null}:x))},Le=(c,k)=>{const x=p.current;if(!x)return null;const b=x.getBoundingClientRect();if(b.width===0||b.height===0)return null;const h=c.clientX-b.left,_=c.clientY-b.top,Q=xt/b.width,I=Pe/b.height,J=h*Q,Ae=Pe-_*I,Z=pa(String(k.type||"signature"));return Vt({page:f,x:J-Z.width/2,y:Ae-Z.height/2,width:Z.width,height:Z.height})},ht=c=>{const k=j.find(b=>b.key===O)||j[0];if(!k)return;const x=Le(c,k);x&&(B(k.key,x),i?.(k.key),q(b=>b+1))};r.useEffect(()=>{const c=x=>{const b=A.current,h=p.current;if(!b||!h)return;x.preventDefault();const _=h.getBoundingClientRect();if(!_.width||!_.height)return;const Q=(x.clientX-b.startClientX)*(xt/_.width),I=-(x.clientY-b.startClientY)*(Pe/_.height);B(b.key,Vt({...b.startPlacement,x:b.startPlacement.x+Q,y:b.startPlacement.y+I})),q(J=>J+1)},k=()=>{A.current=null};return window.addEventListener("pointermove",c),window.addEventListener("pointerup",k),window.addEventListener("pointercancel",k),()=>{window.removeEventListener("pointermove",c),window.removeEventListener("pointerup",k),window.removeEventListener("pointercancel",k)}},[j]);const xe=`${a}#page=${f+1}&toolbar=0&view=FitH`,$e=(()=>{const c=p.current;if(!c)return[];const k=c.getBoundingClientRect();if(k.width===0||k.height===0)return[];const x=k.width/xt,b=k.height/Pe;return j.filter(h=>h.placement&&h.placement.page===f).map(h=>({field:h,rect:{left:h.placement.x*x,top:k.height-(h.placement.y+h.placement.height)*b,width:h.placement.width*x,height:h.placement.height*b}}))})(),qe=aa.find(c=>c.id===E)?.width||620;return e.jsxs("div",{className:"w-full max-w-none space-y-3",children:[e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("p",{className:"text-xs font-medium text-slate-600 dar
1k:text-slate-300",children:"Click to place the selected field, or drag a placed field to move it"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 sm:justify-end",children:[e.jsx("div",{className:"inline-flex rounded-md border border-slate-200 bg-white p-0.5 dark:border-white/10 dark:bg-slate-900",children:aa.map(c=>e.jsx("button",{type:"button",onClick:()=>S(c.id),className:`min-w-10 rounded px-2 py-1 text-[11px] font-semibold ${E===c.id?"bg-brand-600 text-white":"text-slate-600 hover:bg-slate-50 dark:text-slate-300 dark:hover:bg-white/5"}`,children:c.label},c.id))}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("button",{type:"button",onClick:()=>v(c=>Math.max(0,c-1)),className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 disabled:opacity-30 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300 dark:hover:bg-white/5",disabled:f===0,"aria-label":"Previous page",children:e.jsx(ua,{size:14})}),e.jsxs("span",{className:"text-[11px] font-medium text-slate-600 dark:text-slate-300",children:["Page ",f+1,w?` of ${w}`:""]}),e.jsx("button",{type:"button",onClick:()=>v(c=>w?Math.min(c+1,w-1):c+1),className:"inline-flex h-7 w-7 items-center justify-center rounded-md border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 disabled:opacity-30 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300 dark:hover:bg-white/5",disabled:w?f>=w-1:!1,"aria-label":"Next page",children:e.jsx(Ot,{size:14})})]})]})]}),e.jsx("div",{className:"overflow-x-auto rounded-xl bg-slate-100/70 p-2 dark:bg-white/5",children:e.jsxs("div",{ref:p,onClick:ht,className:"relative mx-auto aspect-[612/792] cursor-crosshair overflow-hidden rounded-xl border-2 border-dashed border-brand-300 bg-slate-50 shadow-inner transition hover:border-brand-400 dark:border-brand-500/40 dark:bg-slate-900",style:{width:`${qe}px`,maxWidth:"100%"},children:[e.jsx("object",{data:xe,type:"application/pdf",className:"pointer-events-none absolute inset-0 h-full w-full","aria-label":"Signing document preview",children:e.jsxs("div",{className:"flex h-full items-center justify-center p-4 text-center text-xs text-slate-500 dark:text-slate-400",children:["Your browser couldn't render the PDF inline. The placement still works —",e.jsx("a",{href:a,target:"_blank",rel:"noreferrer",className:"ml-1 font-medium text-brand-600 underline dark:text-brand-300",children:"open the PDF in a new tab"})," ","and use the page number to navigate."]})}),$e.map(({field:c,rect:k})=>{const x=c.key===O;return e.jsx("button",{type:"button",onClick:b=>{b.stopPropagation(),i?.(c.key)},onPointerDown:b=>{if(b.stopPropagation(),i?.(c.key),!!c.placement){try{b.currentTarget.setPointerCapture(b.pointerId)}catch{}A.current={key:c.key,startClientX:b.clientX,startClientY:b.clientY,startPlacement:c.placement}}},className:`absolute border-2 text-left ring-2 ${En(String(c.type||"signature"))} ${x?"ring-offset-2":""}`,style:{left:k.left,top:k.top,width:k.width,height:k.height},title:`Drag ${c.label||c.key}`,children:e.jsx("span",{className:"absolute -top-5 left-0 rounded bg-white px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide shadow-sm dark:bg-slate-800",children:c.label||c.type||"Field"})},c.key)})]})}),e.jsxs("div",{className:"flex items-center justify-between gap-2 text-[11px]",children:[e.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:`${j.filter(c=>c.placement).length}/${j.length} fields placed`}),e.jsxs("button",{type:"button",onClick:()=>B(O,null),className:"inline-flex items-center gap-1 text-brand-600 hover:underline dark:text-brand-300",children:[e.jsx(ue,{size:12}),"Clear selected field"]})]})]})}const xa=[{value:"byo_twilio",label:"Twilio",brand:"twilio"},{value:"byo_telnyx",label:"Telnyx",brand:"telnyx"},{value:"byo_plivo",label:"Plivo",brand:"plivo"},{value:"byo_sip",label:"SIP trunk",brand:"sip"}],Mt={native:"Supafone native",byo_twilio:"Twilio",byo_telnyx:"Telnyx",byo_plivo:"Plivo",byo_sip:"SIP trunk"};function na(a){return xa.some(l=>l.value===a)?a:"native"}function ia(a,l){return a?l==="native"?!!a.native_twilio?.configured:l==="byo_twilio"?!!(a.twilio.connected&&a.twilio.from_number&&!a.twilio.needs_reauth):l==="b
1yo_telnyx"?!!(a.telnyx.connected&&a.telnyx.from_number&&!a.telnyx.needs_reauth):l==="byo_plivo"?!!(a.plivo.connected&&a.plivo.from_number&&!a.plivo.needs_reauth):!!(a.sip.connected&&a.sip.from_number&&!a.sip.needs_reauth):!1}function Se(a,l){const m=String(l||"").trim();m&&!a.includes(m)&&a.push(m)}function In(a,l,m){const i=[];if(!a)return i;if(l==="native")return(a.native_twilio?.from_numbers||[]).forEach(p=>Se(i,p)),Se(i,a.native_twilio?.from_number),m.forEach(p=>Se(i,p.phone_number)),i;const g=l==="byo_twilio"?a.twilio:l==="byo_telnyx"?a.telnyx:l==="byo_plivo"?a.plivo:a.sip;return(g.from_numbers||[]).forEach(p=>Se(i,p)),Se(i,g.from_number),i}function ra(a){return a==="recorded"||a==="skip"?a:"agent"}function la(a){const l=a?.outbound_prompts;return!l||typeof l!="object"||Array.isArray(l)?"":String(l.voicemail||"")}const Ht=[{id:"script",label:"Script",icon:ma},{id:"audience",label:"Leads",icon:ca},{id:"message",label:"Agent",icon:Bt},{id:"document",label:"Document",icon:ue},{id:"delivery",label:"Delivery",icon:ne},{id:"cadence",label:"Timing",icon:zn},{id:"analytics",label:"Reports",icon:xn},{id:"config",label:"Advanced",icon:Ft}],Mn=a=>!!(a&&Ht.some(l=>l.id===a)),pe=["script","audience","message","document","delivery","cadence"],Fn=Ht.filter(a=>pe.includes(a.id)),On=Ht.filter(a=>!pe.includes(a.id)),Bn={script:"Script",audience:"Leads",message:"Agent",document:"Document",delivery:"Delivery",cadence:"Timing"},Un={script:"Pick what the agent should accomplish.",audience:"Add warm leads with consent.",message:"Choose the agent and email follow-up.",document:"Optional: upload a PDF to send for e-signature.",delivery:"Use Supafone delivery or your own carrier.",cadence:"Set the touch order, then launch."},Vn=[{id:"opening",label:"Opening",hint:"How the agent opens the call"},{id:"qualification",label:"Qualification",hint:"How the agent works through the qualifying questions"},{id:"closing",label:"Closing",hint:"What happens with qualified vs disqualified leads"},{id:"voicemail",label:"Voicemail",hint:"The one short message left when nobody answers"}],Yn={book:"book a time",transfer:"live transfer",callback:"team callback"},Wn={polite_exit:"polite exit",remove:"remove from outreach"},oa={queued:"bg-slate-100 text-slate-600 dark:bg-white/5 dark:text-slate-300",in_progress:"bg-brand-50 text-brand-700 dark:bg-brand-500/15 dark:text-brand-300",completed:"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",replied:"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",booked:"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",qualified:"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",disqualified:"bg-slate-100 text-slate-400 dark:bg-white/5 dark:text-slate-400",needs_human:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",needs_consent:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",needs_twilio:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",needs_provider:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",no_credits:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",paused:"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300",processing:"bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300",awaiting_result:"bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300",daily_limit:"bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300",opted_out:"bg-slate-100 text-slate-400 dark:bg-white/5 dark:text-slate-400",failed:"bg-rose-50 text-rose-700 dark:bg-rose-500/15 dark:text-rose-300",stopped:"bg-slate-100 text-slate-400 dark:bg-white/5 dark:text-slate-400"},Hn={queued:"Queued",in_progress:"In progress",completed:"Completed",booked:"Booked",qualified:"Qualified",disqualified:"Disqualified",needs_human:"Needs review",needs_consent:"Needs consent",needs_twilio:"Finish calling setup",needs_provider:"Finish calling setup",no_credits:"Out of credits",paused:"Paused",processing:"Dialing",awaiting_result:"Call in flight",daily_limit:"Daily limit",opted_out:"Opted out",failed:"Failed"};function Qn(a){const l=[];for(const m of a.split(/\r?\n/)){const i=m.trim();if(!i)continue;const g=i.split(/[\t,;]+/).map(y=>
1y.trim()).filter(Boolean);let p="",f="";const v={},w=[];for(const y of g){const R=y.indexOf("=");if(R>0&&!y.slice(0,R).includes("@")){const q=y.slice(0,R).trim().toLowerCase().replace(/\s+/g,"_"),E=y.slice(R+1).trim();if(q&&E){v[q]=E;continue}}!p&&y.includes("@")?p=y:!f&&/^\+?[\d().\-\s]{7,}$/.test(y)?f=y.replace(/[^\d+]/g,""):w.push(y)}(p||f)&&l.push({name:w.join(" "),phone:f,email:p,...v})}return l}function ze(a){let l=a.trim().replace(/[^\d+]/g,"");return l.startsWith("00")&&(l=`+${l.slice(2)}`),l.includes("+")&&(l=`+${l.replace(/\+/g,"")}`),l.startsWith("+")||(l.length===10?l=`+1${l}`:l.length===11&&l.startsWith("1")&&(l=`+${l}`)),l}const Yt=/^\+?\d{7,15}$/,ha=/^\S+@\S+\.\S+$/,Xn=["outreach_consent","consent","consented","opted_in","opt_in","marketing_consent","phone_consent","sms_consent","can_contact","permission_to_contact","permission"],Gn=new Set(["1","true","yes","y","x","ok","okay","consent","consented","opted in","opt-in"]),Kn=["phone","phone_number","mobile","cell","number","tel"],Jn=["email","email_address","e-mail","mail"];function ba(a){return a.trim().toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")}function da(a,l){const m={};for(const i of Object.keys(a))m[i.trim().toLowerCase()]=a[i]??"",m[ba(i)]=a[i]??"";for(const i of l){const g=(m[i]??"").trim();if(g)return g}return""}function Zn(a){const l={};for(const m of Object.keys(a))l[m.trim().toLowerCase()]=a[m]??"",l[ba(m)]=a[m]??"";for(const m of Xn){const i=(l[m]??"").trim().toLowerCase();if(i)return i}return""}function ei(a){const l=[];let m=[],i="",g=!1;for(let f=0;f<a.length;f++){const v=a[f];g?v==='"'?a[f+1]==='"'?(i+='"',f++):g=!1:i+=v:v==='"'?g=!0:v===","?(m.push(i),i=""):v===`
2`||v==="\r"?(v==="\r"&&a[f+1]===`
3`&&f++,m.push(i),i="",l.push(m),m=[]):i+=v}(i!==""||m.length)&&(m.push(i),l.push(m));const p=(l.shift()||[]).map(f=>f.replace(/^\uFEFF/,"").trim());return l.filter(f=>f.some(v=>v.trim()!=="")).map(f=>{const v={};return p.forEach((w,y)=>{w&&(v[w]=(f[y]??"").trim())}),v})}function ti(a,l){const m=new Set(l.map(p=>p.phone||"").filter(Boolean)),i=new Set(l.map(p=>(p.email||"").toLowerCase()).filter(Boolean)),g={total:a.length,importable:0,validPhones:0,invalid:[],duplicates:0,consentFound:!1,consented:0};return a.forEach((p,f)=>{const v=f+1,w=da(p,Kn),y=da(p,Jn),R=ze(w),q=!!w&&Yt.test(R),E=ha.test(y),S=Zn(p);if(S&&(g.consentFound=!0,Gn.has(S)&&(g.consented+=1)),!w&&!y){g.invalid.push({line:v,reason:"no phone or email — row will be skipped"});return}w&&!q&&g.invalid.push({line:v,reason:`invalid phone “${w}”${E?" — email only":" — not callable"}`}),y&&!E&&g.invalid.push({line:v,reason:`invalid email “${y}”`}),q&&(g.validPhones+=1);const A=w?R:"",j=y.toLowerCase();if(A&&m.has(A)||j&&i.has(j)){g.duplicates+=1;return}A&&m.add(A),j&&i.add(j),g.importable+=1}),g}const mt=()=>({name:"",phone:"",email:"",company:"",consent:!1}),si=[{id:"rows",label:"Enter manually",icon:Cn},{id:"paste",label:"Paste",icon:ca},{id:"csv",label:"Upload CSV",icon:pt},{id:"sheet",label:"Google Sheet",icon:Ut}];function ut(a){if(!a)return"—";try{return new Date(a).toLocaleString(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}catch{return"—"}}function Mi(){const{campaignId:a}=jn(),l=wn(),[m]=Nn(),[i,g]=r.useState(null),[p,f]=r.useState([]),[v,w]=r.useState(null),[y,R]=r.useState(null),[q,E]=r.useState([]),[S,A]=r.useState([]),[j,O]=r.useState(null),[B,Le]=r.useState(null),[ht,xe]=r.useState([]),[$e,qe]=r.useState(null),[c,k]=r.useState(!0),[x,b]=r.useState(()=>{const t=m.get("tab");return Mn(t)?t:"script"}),[h,_]=r.useState(!1),[Q,I]=r.useState(!1),[J,Ae]=r.useState(!1),[Z,Qt]=r.useState(!1),Re=r.useRef(null),Te=r.useRef(null),[bt,Xt]=r.useState(""),[Ee,gt]=r.useState(""),[De,ft]=r.useState(""),[Ie,vt]=r.useState(""),[ga,yt]=r.useState(!1),[Gt,Kt]=r.useState(!1),[ie,Me]=r.useState([]),[P,he]=r.useState("native"),[be,Jt]=r.useState(""),[Fe,Zt]=r.useState(100),[Oe,es]=r.useState(500),[kt,ts]=r.useState(3),[re,ss]=r.useState("agent"),[ge,as]=r.useState(""),[Be,ns]=r.useState(""),[jt,is]=r.useState(""),[fe,wt]=r.useState(""),[D,fa
3]=r.useState("rows"),[Nt,Ue]=r.useState([mt()]),[Ve,rs]=r.useState(""),[ve,_t]=r.useState([]),[Ye,Ct]=r.useState(""),[We,va]=r.useState(""),[ls,os]=r.useState(!1),[ds,cs]=r.useState(!1),[V,ye]=r.useState(null),[ya,ka]=r.useState(""),[ms,us]=r.useState(!1),[ps,ja]=r.useState([]),[z,He]=r.useState(null),[Y,xs]=r.useState(""),[Qe,ke]=r.useState([]),[X,hs]=r.useState({}),[bs,wa]=r.useState(!1),[gs,fs]=r.useState(!1),[St,Xe]=r.useState([]),[Ge,vs]=r.useState(null),[Na,ys]=r.useState(!1),[Ke,ks]=r.useState(""),[js,ws]=r.useState(""),[Ns,_s]=r.useState(!1),[Cs,Ss]=r.useState(!1),W=r.useRef(!1),[Je,Ze]=r.useState("idle"),[F,Ps]=r.useState(null),[zs,je]=r.useState("client_signature"),[le,et]=r.useState([]),[Ls,$s]=r.useState(!1),[qs,As]=r.useState(!1),we=r.useRef(!1),[tt,st]=r.useState("idle"),at=r.useRef(null),U=t=>{const s=t.settings||{};g(t),Xt(t.name),gt(t.email_subject),ft(t.email_body),vt(t.agent_id||""),Me(t.cadence?.length?t.cadence:[]),he(na(s.delivery_provider)),Jt(String(s.caller_id_number||"")),Zt(Number(s.native_daily_limit??100)||100),es(Number(s.byo_daily_limit??500)||500),ts(Number(s.max_calls_per_tick??3)||3),ss(ra(s.voicemail_mode)),as(String(s.voicemail_recording_url||"")),ns(la(s)),is(String(s.campaign_voice||"")),wt(s.campaign_temperature===void 0||s.campaign_temperature===null||s.campaign_temperature===""?"":String(s.campaign_temperature)),Ps(s.native_signing||null)};r.useEffect(()=>{a&&(Promise.all([u.get(a),u.recipients(a),Js.list(),Js.catalog()]).then(([t,s,n,d])=>{U(t.campaign),f(s.recipients),E(n.agents),A(d.voices)}).catch(t=>o.error(t.message)).finally(()=>k(!1)),u.connections().then(({connections:t})=>O(t)).catch(()=>{}),u.consent().then(t=>{Le(t)}).catch(()=>{}),u.signLinks(a).then(({links:t})=>xe(t)).catch(()=>{}))},[a]);const Ne=async()=>{if(!a)return;const[t,s]=await Promise.all([u.recipients(a),u.get(a)]);f(t.recipients),g(s.campaign),u.signLinks(a).then(({links:n})=>xe(n)).catch(()=>{})},Rs=t=>{const s=ht.filter(n=>n.recipient_id===t);return s.find(n=>n.status==="completed")||s[0]},Ts=async(t,s)=>{try{await navigator.clipboard.writeText(t.mobile_url),o.success(`Signing link copied — text or email it to ${s.name||s.email||s.phone||"your lead"}.`)}catch{o.info(t.mobile_url,{duration:15e3})}},_a=async t=>{if(!a)return;const s=Rs(t.id);if(s&&s.status!=="completed"){await Ts(s,t);return}qe(t.id);try{const{link:n}=await u.createSignLink(a,t.id,{title:`Review & sign — ${i?.name||"your documents"}`});xe(d=>[n,...d]),await Ts(n,t)}catch(n){o.error(n.message)}finally{qe(null)}};r.useEffect(()=>{if(!a||i?.status!=="active")return;const t=window.setInterval(()=>{Ne().catch(()=>{})},15e3);return()=>window.clearInterval(t)},[a,i?.status]),r.useEffect(()=>{x!=="config"||!a||V!==null||ms||(us(!0),u.exportConfig(a).then(t=>{ye(t.config),ka(t.slug)}).catch(t=>o.error(t.message)).finally(()=>us(!1)))},[x,a,V]);const oe=t=>{He(t),xs(t.preset_id||""),ke(t.qualification_criteria.map(s=>({...s}))),hs({opening:t.stages.opening.override||"",qualification:t.stages.qualification.override||"",closing:t.stages.closing.override||"",voicemail:t.stages.voicemail.override||"",system_prompt_override:t.system_prompt_override||""})};r.useEffect(()=>{x!=="script"||!a||z!==null||gs||(fs(!0),Promise.all([u.outboundPresets(),u.outboundPrompts(a)]).then(([t,s])=>{ja(t.presets),oe(s)}).catch(t=>o.error(t.message)).finally(()=>fs(!1)),u.customPresets().then(({presets:t})=>Xe(t)).catch(()=>{}))},[x,a,z]);const Es=async t=>{if(a){if(Y===t.id){xs(""),ke([]),W.current=!0;return}vs(t.id);try{const{campaign:s}=await u.applyPreset(a,t.id);U(s),oe(await u.outboundPrompts(a)),ye(null),o.success(`Applied "${t.label}" — saved`)}catch(s){o.error(s.message)}finally{vs(null)}}},nt=(t,s)=>{W.current=!0,ke(n=>n.map((d,C)=>C===t?{...d,...s}:d))},Ca=t=>{W.current=!0,ke(s=>s.filter((n,d)=>d!==t))},Sa=()=>{W.current=!0,ke(t=>[...t,{question:"",field:""}])},Ds=(t,s)=>{W.current=!0,hs(n=>({...n,[t]:s}))},it=()=>{const t={};for(const s of["opening","qualification","closing","voicemail","system_prompt_override"]){const n=(X[s]||"").trim();n&&(t[s]=n)}return t},rt=()=>Qe.filter(t=>t.question.trim()).map(t=>({question:t.question.trim(),field:t.field.trim(),...t.disqualifies_when?.trim()?{disqualifies_when:t.disqualifies_when.trim()}:{}}));r.useEffect(()=>{if(!W.current||!a||!i||z===null)return;const t=window.setTimeout(async()=>{W.current=!1,Ze("saving");try{const{campaign:s}=await u.update(a,{settings:{...i.settings||{},outbound_preset_id:Y,outbound_prompts:it(),qualification_criteria:rt()}});g(s),He(await u.outboundPrompts(a)),ye(null),Ze("saved")}catch{W.current=!0,Ze("error")}},900);return()=>window.clearTimeout(t)},[Qe,X,Y]);const Pa=async()=>
3{if(!(!a||!i||!Ke.trim())){_s(!0);try{const t={label:Ke.trim(),description:js.trim(),goal:i.goal||"",objective:String(i.settings?.campaign_objective||z?.objective||""),opening_style:String(i.settings?.opening_style||""),voicemail_style:String(i.settings?.voicemail_style||""),qualification_criteria:rt(),qualified_action:z?.qualified_action||"",disqualified_action:z?.disqualified_action||"",outbound_prompts:it(),email_subject:Ee,email_body:De,native_signing:F},{preset:s}=await u.createCustomPreset(t);Xe(n=>[...n,s]),ys(!1),ks(""),ws(""),o.success(`Preset "${s.label}" saved — reusable on every campaign`)}catch(t){o.error(t.message)}finally{_s(!1)}}},za=async()=>{if(!(!a||!i)){Ss(!0);try{const s={label:`${(i.name||"Campaign").slice(0,56)} — saved script`,description:"One-click restore point for this campaign’s exact script.",goal:i.goal||"",objective:String(i.settings?.campaign_objective||z?.objective||""),opening_style:String(i.settings?.opening_style||""),voicemail_style:String(i.settings?.voicemail_style||""),qualification_criteria:rt(),qualified_action:z?.qualified_action||"",disqualified_action:z?.disqualified_action||"",outbound_prompts:it(),email_subject:Ee,email_body:De,native_signing:F},{preset:n}=await u.createCustomPreset(s);Xe(C=>[...C,n]);const{campaign:d}=await u.applyPreset(a,n.id);U(d),oe(await u.outboundPrompts(a)),ye(null),o.success(`Saved & locked "${n.label}" — restore it anytime from your presets`)}catch(t){o.error(t.message)}finally{Ss(!1)}}},La=async t=>{try{await u.deleteCustomPreset(t.id),Xe(s=>s.filter(n=>n.id!==t.id)),o.success(`Deleted preset "${t.label}"`)}catch(s){o.error(s.message)}},de=F?.fields||[],Pt=t=>{we.current=!0,Ps(s=>t(s||{enabled:!0,mode:"native_pdf",fields:[]}))},zt=t=>Pt(s=>({...s,fields:t}));r.useEffect(()=>{if(!we.current||!a||!i)return;const t=window.setTimeout(async()=>{we.current=!1,st("saving");try{const{campaign:s}=await u.update(a,{settings:{...i.settings||{},native_signing:F||{}}});g(s),st("saved")}catch(s){we.current=!0,st("error"),o.error(s.message)}},800);return()=>window.clearTimeout(t)},[F]);const $a=async t=>{if(a){$s(!0);try{const{campaign:s,asset:n,detected_fields:d}=await u.uploadSigningDocument(a,t);we.current=!1,U(s),et(d),je("client_signature"),st("saved"),o.success(d.length?`${n.filename} uploaded — ${d.length} field${d.length===1?"":"s"} auto-detected`:`${n.filename} uploaded — click the page to place the signature`)}catch(s){o.error(s.message)}finally{$s(!1),at.current&&(at.current.value="")}}},qa=async()=>{if(a){As(!0);try{const{fields:t,detected:s}=await u.detectSigningFields(a);et(t),o[s?"success":"info"](s?`${t.length} field${t.length===1?"":"s"} detected — apply below or place by hand`:"Nothing confidently detected (scanned PDF?) — click the page to place fields")}catch(t){o.error(t.message)}finally{As(!1)}}},Aa=()=>{if(!le.length)return;const t=new Set,s=le.map((n,d)=>{const C=n.type==="signature"?"client_signature":n.type==="date"?"date_signed":n.type==="initials"?"initials":`field_${d+1}`;let $=C,T=2;for(;t.has($);)$=`${C}_${T++}`;return t.add($),{key:$,type:n.type,label:n.label||n.type.charAt(0).toUpperCase()+n.type.slice(1),required:n.type==="signature",placement:{page:n.page,x:n.x,y:n.y,width:n.width,height:n.height}}});Pt(n=>({...n,enabled:!0,fields:s})),je(s[0]?.key||"client_signature"),et([]),o.success("Detected fields applied — drag any box to fine-tune")},Ra=t=>{const s=t==="signature"?"client_signature":t==="date"?"date_signed":t,n=new Set(de.map(T=>T.key));let d=s,C=2;for(;n.has(d);)d=`${s}_${C++}`;const $=t==="signature"?"Client signature":t==="date"?"Date":t==="initials"?"Initials":"Text";zt([...de,{key:d,type:t,label:$,required:t==="signature",placement:null}]),je(d)},Ta=t=>{zt(de.filter(s=>s.key!==t))},Is=async()=>{if(!(!a||!i)){_(!0);try{const t=ps.find(n=>n.id===Y);W.current=!1;const{campaign:s}=await u.update(a,{...t?{goal:t.goal}:{},settings:{...i.settings||{},outbound_preset_id:Y,outbound_prompts:it(),qualification_criteria:rt()}});U(s),oe(await u.outboundPrompts(a)),ye(null),Ze("saved"),o.success("Script & qualification saved")}catch(t){o.error(t.message)}finally{_(!1)}}},Ea=async()=>
3{if(V)try{await navigator.clipboard.writeText(V),o.success("Config copied to clipboard")}catch{o.error("Could not copy — select the text and copy manually")}},Da=()=>{if(!V)return;const t=new Blob([V],{type:"text/yaml"}),s=URL.createObjectURL(t),n=document.createElement("a");n.href=s,n.download=`${ya||"campaign"}.yaml`,n.click(),URL.revokeObjectURL(s)},Ia=async()=>{if(!(!a||!i||bt===i.name))try{const{campaign:t}=await u.update(a,{name:bt.trim()||"New campaign"});g(t),o.success("Saved")}catch(t){o.error(t.message)}},Ma=async()=>{if(a){_(!0);try{const{campaign:t}=await u.update(a,{email_subject:Ee,email_body:De,agent_id:Ie||null});U(t),o.success("Saved")}catch(t){o.error(t.message)}finally{_(!1)}}},Fa=async()=>{if(a){_(!0);try{const{campaign:t}=await u.update(a,{cadence:ie});U(t),o.success("Cadence saved")}catch(t){o.error(t.message)}finally{_(!1)}}},Oa=async()=>{if(!(!a||!i)){_(!0);try{const t=i.settings?.outbound_prompts&&typeof i.settings.outbound_prompts=="object"?{...i.settings.outbound_prompts}:{};re==="skip"||!Be.trim()?delete t.voicemail:t.voicemail=Be.trim();const{campaign:s}=await u.update(a,{settings:{...i.settings||{},delivery_provider:P,caller_id_number:be.trim(),native_daily_limit:Fe,byo_daily_limit:Oe,max_calls_per_tick:kt,warm_consent_required:!0,native_consent_required:!0,native_outreach_type:"warm",voicemail_mode:re,voicemail_recording_url:ge.trim(),campaign_voice:jt.trim(),campaign_temperature:fe.trim()===""?"":Number(fe),outbound_prompts:t}});U(s),z&&oe(await u.outboundPrompts(a)),o.success("Delivery workflow saved")}catch(t){o.error(t.message)}finally{_(!1)}}},Ba=async t=>{if(a){Qt(!0);try{const{campaign:s,asset:n}=await u.uploadVoicemail(a,t);U(s),z&&oe(await u.outboundPrompts(a)),o.success(`Voicemail recording uploaded: ${n.filename}`)}catch(s){o.error(s.message)}finally{Qt(!1),Te.current&&(Te.current.value="")}}},Ua=async()=>{if(!(!a||i?.status!=="active"))try{const{campaign:t}=await u.launch(a);g(t)}catch{}},Lt=r.useMemo(()=>D==="rows"?Nt.filter(t=>t.name.trim()||t.phone.trim()||t.email.trim()||t.company.trim()).map(t=>({name:t.name.trim(),phone:t.phone.trim()?ze(t.phone):"",email:t.email.trim(),...t.company.trim()?{company:t.company.trim()}:{},...t.consent?{outreach_consent:"yes",outreach_consent_source:t.attested?"manual_attestation":"manual"}:{}})):D==="paste"?Qn(Ve):ve,[D,Nt,Ve,ve]),M=r.useMemo(()=>ds&&D!=="rows"?Lt.map(t=>({...t,outreach_consent:"yes",outreach_consent_source:"manual_attestation"})):Lt,[Lt,ds,D]),L=r.useMemo(()=>ti(M,p),[M,p]),_e=M.length>0&&L.consented<L.total,Ce=na(i?.settings?.delivery_provider),Va=ra(i?.settings?.voicemail_mode),Ya=la(i?.settings),Wa=i?.settings?.campaign_temperature===void 0||i?.settings?.campaign_temperature===null||i?.settings?.campaign_temperature===""?"":String(i.settings.campaign_temperature),Ha=Ce==="native",Ms=P==="native",lt=P!==Ce||be.trim()!==String(i?.settings?.caller_id_number||"")||Number(Fe)!==Number(i?.settings?.native_daily_limit??100)||Number(Oe)!==Number(i?.settings?.byo_daily_limit??500)||Number(kt)!==Number(i?.settings?.max_calls_per_tick??3)||re!==Va||ge.trim()!==String(i?.settings?.voicemail_recording_url||"")||Be.trim()!==Ya.trim()||jt.trim()!==String(i?.settings?.campaign_voice||"")||fe.trim()!==Wa,Qa=ia(j,Ce),$t=Number(Oe||i?.settings?.byo_daily_limit||500)||500,qt=Number(Fe||i?.settings?.native_daily_limit||100)||100,Xa=Ms&&M.length>qt,Ga=!Ms&&M.length>$t,At=r.useMemo(()=>In(j,P,q),[j,P,q]),Fs=!!(be.trim()&&At.length>0&&!At.includes(be.trim())),G=q.find(t=>t.id===Ie)||null,Os=fe.trim()===""?String(G?.temperature??.4):fe,Bs=i?.agent_id||"",Rt=Ie!==Bs,Us=ie.length?ie:i?.cadence||[],ot=Us.length===0||Us.some(t=>(t.channel||"voice")==="voice");r.useEffect(()=>{cs(!1)},[D,Ve,ve]);const ce=(t,s)=>Ue(n=>n.map((d,C)=>C===t?{...d,...s}:d)),Ka=t=>Ue(s=>s.length>1?s.filter((n,d)=>d!==t):[mt()]),Ja=async t=>{try{const s=ei(await t.text());if(!s.length){o.error("No rows found in that CSV");return}_t(s),Ct(`${t.name} · ${s.length} row${s.length===1?"":"s"}`)}catch{o.error("Could not read that file")}finally{Re.current&&(Re.current.value="")}},Za=async()=>
3{if(!(!a||!We.trim())){os(!0);try{const s=((await u.importSheet(a,We.trim(),!0)).rows||[]).map(n=>({...Object.fromEntries(Object.entries(n.data||{}).map(([d,C])=>[d,String(C)])),name:n.name,phone:n.phone,email:n.email}));if(!s.length){o.error("No usable rows found in the sheet");return}_t(s),Ct(`Google Sheet · ${s.length} row${s.length===1?"":"s"}`),o.success(`Fetched ${s.length} rows — review the checks below, then add`)}catch(t){o.error(t.message)}finally{os(!1)}}},en=async(t=!1)=>{if(!(!a||!M.length)){_(!0);try{const n=(t?M.map($=>({...$,outreach_consent:"yes",outreach_consent_source:"manual_attestation"})):M).map($=>{const T=($.phone??"").trim();if(!T)return $;const Gs=ze(T);return Yt.test(Gs)?{...$,phone:Gs}:$}),d=await u.addRecipients(a,n),C=M.length-d.added;o.success(`Added ${d.added} lead${d.added===1?"":"s"}${C>0?` — ${C} duplicate/empty skipped`:""}`),D==="rows"&&Ue([mt()]),D==="paste"&&rs(""),_t([]),Ct(""),cs(!1),await Ua(),await Ne()}catch(s){o.error(s.message)}finally{_(!1)}}},tn=async()=>B?.accepted?!0:(I(!0),!1),Vs=async()=>{if(!a)return;_(!0);const t=o.loading("Activating campaign…");try{const{campaign:s}=await u.launch(a),n=hn(s),d=bn(s);d==="error"?o.error(n,{id:t,duration:9e3,action:{label:"Billing",onClick:()=>l("/app/billing")}}):d==="warning"?o.warning(n,{id:t,duration:8e3}):o.success(n,{id:t}),g(s),await Ne()}catch(s){o.dismiss(t),kn(s,"Could not launch campaign")}finally{_(!1)}},Ys=async()=>{!a||!await tn()||await Vs()},sn=async()=>{if(a){Ae(!0);try{const t=await u.acceptConsent({accepted:!0});Le(t),I(!1),o.success("Campaign consent saved"),await Vs()}catch(t){o.error(t.message)}finally{Ae(!1)}}},an=async()=>{if(a){_(!0);try{const{campaign:t}=await u.pause(a);g(t),o.success("Campaign paused")}catch(t){o.error(t.message)}finally{_(!1)}}},Ws=(t,s)=>Me(n=>n.map((d,C)=>C===t?{...d,...s}:d)),nn=()=>Me(t=>[...t,{channel:"email",delay_hours:24}]),rn=t=>Me(s=>s.filter((n,d)=>d!==t));if(c)return e.jsx(Dt,{children:e.jsx("div",{className:"flex min-h-[60vh] items-center justify-center",children:e.jsx(N,{className:"animate-spin text-slate-400 dark:text-slate-600"})})});if(!i)return e.jsx(Dt,{children:e.jsx("div",{className:"mx-auto max-w-3xl px-4 py-10 text-center text-slate-500 dark:text-slate-400",children:"Campaign not found."})});const dt=i.status==="active",ln=i.stats?.total??p.length,Tt=t=>{const s=t.data||{},n=t.captured||{},d=C=>["1","true","yes","y","x","ok","okay","consent","consented","opted in","opt-in"].includes(String(C??"").trim().toLowerCase());for(const C of[s,n]){for(const $ of["do_not_contact","dnc","opted_out","opt_out","unsubscribe"])if(d(C[$]))return!1;for(const $ of["outreach_consent","consent","consented","opted_in","opt_in","marketing_consent","phone_consent","sms_consent","can_contact","permission_to_contact","permission"])if(d(C[$]))return!0}return!1},Hs=p.filter(Tt).length,K={message:!ot||!!Bs&&!Rt,delivery:!ot||!lt&&Qa,audience:p.length>0&&Hs>0},on=async t=>{if(a){w(t.id);try{await u.removeRecipient(a,t.id),f(s=>s.filter(n=>n.id!==t.id)),o.success("Recipient removed")}catch(s){o.error(s.message)}finally{w(null)}}},Et=(t,s)=>{f(n=>n.map(d=>d.id===t.id?t:d)),s&&g(n=>n&&{...n,stats:s})},dn=async t=>{if(a){R(`pause:${t.id}`);try{const s=await u.pauseRecipient(a,t.id);Et(s.recipient,s.stats),o.success("Recipient paused")}catch(s){o.error(s.message)}finally{R(null)}}},cn=async t=>{if(!a)return;const s=t.state==="needs_consent";R(`resume:${t.id}`);try{const n=await u.resumeRecipient(a,t.id,s);Et(n.recipient,n.stats),o.success(s?"Consent saved and recipient resumed":"Recipient resumed")}catch(n){o.error(n.message)}finally{R(null)}},Qs=async(t,s)=>{if(a){R(`${s}:${t.id}`);try{const n=await u.manualTouchpoint(a,t.id,{channel:t.last_channel==="email"?"email":"voice",outcome:s});Et(n.recipient,n.stats),o.success(s==="completed"?"Recipient marked done":"Recipient sent to human review")}catch(n){o.error(n.message)}finally{R(null)}}},Xs=!!(K.message&&K.delivery&&K.audience),ct=K.message?K.delivery?K.audience?"":p.length>0?"Add consent for at least one lead":"Add at least one lead":lt?"Save the Delivery step before launch":`Connect ${Mt[Ce]} before launch`:Rt?"Save the Message step so this agent is attached before launch":"Pick a Supafone agent under “Message” first";return e.jsxs(Dt,{children:[e.jsxs("header",{className:"sticky top-0 z-30 overflow-x-hidden border-b border-slate-100 bg-white/90 backdrop-blur dark:border-white/10 dark:bg-slate-900/80",children:[e.jsxs("div",{className:"mx-auto flex w-full max-w-5xl items-center gap-2 px-3 py-3 sm:gap-3 sm:px-6",children:[e.jsx(It,{to:"/app/sales",className:"shrink-0 rounded-full p-2 text-slate-500 hover:bg-slate-100 dar
3k:text-slate-400 dark:hover:bg-white/5",children:e.jsx(_n,{size:18})}),e.jsx("input",{value:bt,onChange:t=>Xt(t.target.value),onBlur:Ia,className:"min-w-0 flex-1 bg-transparent text-lg font-semibold text-ink outline-none"}),e.jsxs("span",{className:"hidden text-xs text-slate-500 sm:inline dark:text-slate-500",children:[ln," recipients"]}),dt?e.jsxs("button",{className:"btn-secondary h-10 shrink-0 justify-center px-3 text-xs sm:text-sm",onClick:an,disabled:h,children:[e.jsx(ea,{size:14})," Pause"]}):e.jsxs("button",{className:"btn-primary h-10 shrink-0 justify-center gap-1.5 px-3 text-xs shadow-lg shadow-brand-500/30 sm:px-5 sm:text-sm",onClick:Ys,disabled:h||!Xs,title:ct||"Launch this campaign",children:[h?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(H,{size:14})," Launch"]})]}),e.jsxs("div",{className:"mx-auto flex w-full max-w-5xl gap-1.5 overflow-x-auto px-3 pb-2 sm:gap-2 sm:px-6",children:[Fn.map((t,s)=>e.jsxs("button",{onClick:()=>b(t.id),className:`flex h-9 items-center gap-1.5 rounded-full px-2.5 text-[11px] font-semibold whitespace-nowrap transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 sm:px-3.5 sm:text-xs ${x===t.id?"bg-brand-600 text-white shadow-md shadow-brand-600/25":K[t.id]?"border border-brand-300 bg-brand-50 text-brand-700 dark:border-brand-500/40 dark:bg-brand-500/10 dark:text-brand-300":"border border-slate-200 bg-white text-slate-600 hover:border-brand-300 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300"}`,children:[e.jsx("span",{className:"flex h-4 w-4 items-center justify-center rounded-full bg-current/10 text-[10px]",children:s+1}),e.jsx(t.icon,{size:13})," ",t.label,K[t.id]&&x!==t.id&&e.jsx("span",{className:"ml-0.5 flex h-3.5 w-3.5 items-center justify-center rounded-full bg-brand-500 text-[9px] text-white",children:"✓"})]},t.id)),e.jsx("div",{className:"mx-1 h-7 w-px shrink-0 bg-slate-200 dark:bg-white/10"}),On.map(t=>e.jsxs("button",{onClick:()=>b(t.id),className:`flex h-9 items-center gap-1.5 rounded-full px-2.5 text-[11px] font-semibold whitespace-nowrap transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 sm:px-3 sm:text-xs ${x===t.id?"bg-slate-900 text-white shadow-md shadow-slate-900/15 dark:bg-white dark:text-slate-950":"border border-slate-200 bg-white text-slate-500 hover:border-brand-300 dark:border-white/10 dark:bg-slate-900 dark:text-slate-400"}`,children:[e.jsx(t.icon,{size:13})," ",t.label]},t.id))]})]}),Q&&!B?.accepted&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-slate-950/60 p-4 backdrop-blur-sm sm:items-center",onClick:()=>I(!1),children:e.jsxs("div",{className:"w-full max-w-2xl rounded-3xl bg-white shadow-2xl dark:bg-slate-900",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 border-b border-slate-100 px-5 py-4 dark:border-white/10",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 text-base font-semibold text-ink",children:[e.jsx(ne,{size:17,className:"text-brand-600"}),"Campaign consent"]}),e.jsx("p",{className:"mt-1 text-sm leading-6 text-slate-500 dark:text-slate-400",children:"Accept once before Supafone starts calling or emailing campaign leads."})]}),B?.terms.version&&e.jsxs("span",{className:"shrink-0 rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-600 dark:bg-white/10 dark:text-slate-300",children:["v",B.terms.version]})]}),e.jsxs("div",{className:"space-y-4 p-5",children:[e.jsx("div",{className:"rounded-2xl border border-brand-200 bg-brand-50 p-4 text-sm leading-6 text-brand-950 dark:border-brand-500/30 dark:bg-brand-500/10 dark:text-brand-100",children:"By continuing, you confirm this campaign only contacts people you are allowed to call or email, and that you will honor opt-outs and recording rules."}),B?.terms.text&&e.jsxs("details",{className:"rounded-2xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-300",children:[e.jsx("summary",{className:"cursor-pointer font-semibold text-ink",children:"View consent terms"}),e.jsx("div",{className:"mt-3 max-h-44 overflow-y-auto leading-6 whitespace-pre-line",children:B.terms.text})]}),e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",children:[e.jsx("button",{type:"button",className:"btn-secondary justify-center",onClick:()=>I(!1),disabled:J||h,children:"Cancel"}),e.jsxs("button",{type:"button",className:"btn-primary justify-center",onClick:()=>{sn()},disabled:J||h,children:[J||h?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(ta,{size:14}),"Consent & launch"]})]})]})]})}),e.jsxs("main",{className:"mx-auto w-full max-w-5xl overflow-x-hidden px-3 py-4 sm:px-6 sm:py-6",children:[!dt&&ct&&e.jsx("div",{className:"mb-5 rounded-2xl border border-amber-200 bg-amber-50/80 p-3 text-sm text-amber-900 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(se,{size:16,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Not ready to launch"}),e.jsxs("p",{className:"mt-0.5 text-xs leading-5",children:[ct,"."]})]})]})}),x==="audience"&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"card",children:[e.jsx("div",{className:"font-semibold text-ink",children:"Add leads"}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"Type, paste, upload, or import leads. If your file has no consent field, use Consent & add to mark this batch with your manual attestation."}),e.jsx("div",{className:"mt-3 flex gap-2 overflow-x-auto pb-1",children:si.map(t=>e.jsxs("button",{type:"button",onClick:()=>fa(t.id),className:`flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-semibold whitespace-nowrap transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 ${D===t.id?"bg-brand-600 text-white shadow-md shadow-brand-600/25":"border border-slate-200 bg-white text-slate-600 hover:border-brand-300 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300"}`,children:[e.jsx(t.icon,{size:13})," ",t.label]},t.id))}),D==="rows"&&e.jsxs("div",{className:"mt-4",children:[e.jsxs("div",{className:"hidden gap-2 px-1 text-[11px] font-semibold uppercase tracking-wide text-slate-400 md:grid md:grid-cols-[1fr_1fr_1.2fr_1fr_5.5rem_1.75rem] dark:text-slate-500",children:[e.jsx("span",{children:"Name"}),e.jsx("span",{children:"Phone"}),e.jsx("span",{children:"Email"}),e.jsx("span",{children:"Company"}),e.jsx("span",{children:"Consent"}),e.jsx("span",{})]}),e.jsx("p",{className:"mt-1 px-1 text-[11px] leading-5 text-slate-500 dark:text-slate-400",children:"Add the lead details. Consent & add can attest the batch before it is saved."}),e.jsx("div",{className:"mt-1 max-h-80 space-y-2 overflow-y-auto pr-1",children:Nt.map((t,s)=>{const n=t.phone.trim()!==""&&!Yt.test(ze(t.phone)),d=t.email.trim()!==""&&!ha.test(t.email.trim()),$=!!(t.name.trim()||t.phone.trim()||t.email.trim()||t.company.trim())&&!t.phone.trim()&&!t.email.trim();return e.jsxs("div",{className:`grid min-w-0 grid-cols-1 gap-2 rounded-xl border p-2 sm:grid-cols-2 md:grid-cols-[1fr_1fr_1.2fr_1fr_5.5rem_1.75rem] md:items-center ${$?"border-rose-300 bg-rose-50/50 dark:border-rose-500/40 dark:bg-rose-500/5":"border-slate-100 bg-slate-50/50 dark:border-white/10 dark:bg-white/5"}`,children:[e.jsx("input",{className:"input min-w-0",placeholder:"Name",value:t.name,onChange:T=>ce(s,{name:T.target.value})}),e.jsx("input",{className:`input min-w-0 ${n?"border-rose-400 focus:border-rose-400 dark:border-rose-500/60":""}`,placeholder:"Phone",inputMode:"tel",title:n?"Invalid phone — 
310-digit US numbers get +1 automatically":void 0,value:t.phone,onChange:T=>ce(s,{phone:T.target.value}),onBlur:()=>t.phone.trim()&&ce(s,{phone:ze(t.phone)})}),e.jsx("input",{className:`input min-w-0 ${d?"border-rose-400 focus:border-rose-400 dark:border-rose-500/60":""}`,placeholder:"Email",inputMode:"email",value:t.email,onChange:T=>ce(s,{email:T.target.value})}),e.jsx("input",{className:"input min-w-0",placeholder:"Company (optional)",value:t.company,onChange:T=>ce(s,{company:T.target.value})}),e.jsxs("label",{className:"flex cursor-pointer items-center gap-1.5 text-xs font-medium text-slate-600 dark:text-slate-300 sm:col-span-1",children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4 rounded border-slate-300 text-brand-600 focus:ring-brand-500 dark:border-white/20",checked:t.consent,onChange:T=>ce(s,{consent:T.target.checked,attested:!1})}),"Consent"]}),e.jsx("button",{type:"button",className:"justify-self-start text-slate-400 transition hover:text-rose-500 sm:justify-self-end dark:text-slate-600",onClick:()=>Ka(s),"aria-label":"Remove row",children:e.jsx(me,{size:15})})]},s)})}),e.jsxs("button",{type:"button",className:"btn-secondary mt-2",onClick:()=>Ue(t=>[...t,mt()]),children:[e.jsx(ee,{size:14})," Add row"]})]}),D==="paste"&&e.jsxs("div",{className:"mt-4",children:[e.jsx("textarea",{className:"input h-28 w-full",placeholder:`Jane Doe, +14155550123, [email protected], outreach_consent=yes
4John Smith, +14155550124, [email protected], outreach_consent=no`,value:Ve,onChange:t=>rs(t.target.value)}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"One lead per line — name, phone, email in any order; key=value tokens (e.g. outreach_consent=yes) become extra fields."})]}),D==="csv"&&e.jsxs("div",{className:"mt-4",children:[e.jsx("input",{ref:Re,type:"file",accept:".csv,text/csv",className:"hidden",onChange:t=>t.target.files?.[0]&&Ja(t.target.files[0])}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("button",{className:"btn-secondary",onClick:()=>Re.current?.click(),disabled:h,children:[e.jsx(pt,{size:14})," Choose CSV"]}),Ye&&ve.length>0&&e.jsx("span",{className:"text-xs font-medium text-slate-600 dark:text-slate-300",children:Ye})]}),e.jsx("p",{className:"mt-2 text-xs text-slate-500 dark:text-slate-400",children:"Columns like name, phone, email, company. Consent columns accepted: outreach_consent, consent, consented, opted_in, opt_in, marketing_consent, phone_consent, can_contact, permission_to_contact."})]}),D==="sheet"&&e.jsxs("div",{className:"mt-4",children:[e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{className:"input w-full",placeholder:"https://docs.google.com/spreadsheets/d/…",value:We,onChange:t=>va(t.target.value)}),e.jsxs("button",{className:"btn-secondary w-full justify-center sm:w-auto",onClick:Za,disabled:ls||!We.trim(),children:[ls?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(Ut,{size:14})," Import"]})]}),e.jsx("p",{className:"mt-2 text-xs text-slate-500 dark:text-slate-400",children:"The sheet must be viewable: 
4Share > Anyone with the link > Viewer. First row is the header (name, phone, email, consent…)."}),Ye&&ve.length>0&&e.jsx("p",{className:"mt-1 text-xs font-medium text-slate-600 dark:text-slate-300",children:Ye})]}),M.length>0&&e.jsxs("div",{className:"mt-4 rounded-2xl border border-slate-200 bg-slate-50 p-3 text-xs text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-300",children:[e.jsxs("div",{className:"flex items-center gap-1.5 font-semibold text-ink",children:[e.jsx(Zs,{size:14,className:"text-brand-500"})," Pre-flight check"]}),e.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-x-4 gap-y-1.5 sm:grid-cols-3",children:[e.jsxs("span",{children:["Rows: ",e.jsx("span",{className:"font-semibold text-ink",children:L.total})]}),e.jsxs("span",{children:["Valid phones: ",e.jsx("span",{className:"font-semibold text-ink",children:L.validPhones})]}),e.jsxs("span",{children:["Duplicates removed:"," ",e.jsx("span",{className:`font-semibold ${L.duplicates?"text-amber-600 dark:text-amber-300":"text-ink"}`,children:L.duplicates})]}),e.jsxs("span",{children:["Invalid rows:"," ",e.jsx("span",{className:`font-semibold ${L.invalid.length?"text-rose-600 dar
4k:text-rose-300":"text-ink"}`,children:L.invalid.length})]}),e.jsxs("span",{children:["Consent:"," ",e.jsx("span",{className:`font-semibold ${L.consentFound?"text-emerald-600 dark:text-emerald-300":"text-amber-600 dark:text-amber-300"}`,children:_e?`${L.consented} ready`:"ready"})]}),e.jsxs("span",{children:["Leads:"," ",e.jsx("span",{className:"font-semibold text-ink",children:L.total})]})]}),L.invalid.length>0&&e.jsxs("ul",{className:"mt-2 list-inside list-disc space-y-0.5 text-rose-600 dark:text-rose-300",children:[L.invalid.slice(0,5).map(t=>e.jsxs("li",{children:["Row ",t.line,": ",t.reason]},`${t.line}-${t.reason}`)),L.invalid.length>5&&e.jsxs("li",{children:["…and ",L.invalid.length-5," more"]})]})]}),_e&&e.jsxs("div",{className:"mt-3 flex items-start gap-2 rounded-2xl border border-amber-200 bg-amber-50 p-3 text-xs leading-5 text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:[e.jsx(ne,{size:15,className:"mt-0.5 shrink-0"}),e.jsx("span",{children:"Consent & add marks this pending batch as manually attested, then adds the leads."})]}),Xa&&e.jsx("div",{className:"mt-3 rounded-2xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(te,{size:15,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-semibold",children:["Native calling paces at ",qt," calls/day — for more calls connect your own telephony (Twilio, Telnyx, Plivo or SIP)."]}),e.jsxs("p",{className:"mt-1 leading-5",children:["You can still add all ",M.length," leads — native delivery simply works them ",qt," per day. Connect your own provider to go faster."]}),e.jsxs("button",{type:"button",className:"btn-secondary mt-2",onClick:()=>l("/app/sales?connect=1"),children:[e.jsx(te,{size:13})," Connect your telephony"]})]})]})}),Ga&&e.jsxs("div",{className:"mt-3 rounded-2xl border border-slate-200 bg-slate-50 p-3 text-xs text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-300",children:["Your telephony is capped at ",$t," calls/day on this campaign — this list will take about ",Math.ceil(M.length/$t)," days to work through. You can raise the limit in campaign settings."]}),e.jsx("div",{className:"sticky bottom-3 z-10 mt-4 sm:static",children:e.jsxs("button",{className:"btn-primary w-full justify-center shadow-lg shadow-brand-500/25 sm:w-auto",onClick:()=>{en(_e)},disabled:h||L.importable===0,children:[h?e.jsx(N,{size:14,className:"animate-spin"}):_e?e.jsx(ne,{size:14}):e.jsx(ee,{size:14}),_e?"Consent & add":"Add"," ",L.importable>0?L.importable:""," lead",L.importable===1?"":"s"]})})]}),e.jsxs("div",{className:"card p-0",children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-3",children:[e.jsxs("div",{className:"font-semibold text-ink",children:["Recipients (",p.length,")"]}),e.jsx("button",{className:"text-slate-500 hover:text-ink dark:text-slate-400 dark:hover:text-white",onClick:Ne,title:"Refresh",children:e.jsx(sa,{size:15})})]}),p.length===0?e.jsx("div",{className:"px-5 pb-5 text-sm text-slate-500 dark:text-slate-500",children:"No recipients yet."}):e.jsx("div",{className:"max-h-[26rem] divide-y divide-slate-50 overflow-y-auto dark:divide-white/10",children:p.map(t=>e.jsxs("div",{className:"flex flex-col items-start justify-between gap-2 px-5 py-3 text-sm sm:flex-row sm:items-center",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate font-medium text-ink",children:t.name||t.phone||t.email}),e.jsx("div",{className:"truncate text-xs text-slate-500 dark:text-slate-500",children:[t.phone,t.email].filter(Boolean).join(" · ")})]}),e.jsxs("div",{className:"flex w-full flex-wrap items-center justify-between gap-2 text-xs text-slate-500 sm:w-auto sm:justify-end dark:text-slate-500",children:[(()=>{const s=Rs(t.id);return s?.status==="completed"?s.signed_pdf_url?e.jsxs("a",{href:s.signed_pdf_url,target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2 py-0.5 text-[11px] font-semibold text-emerald-700 underline-offset-2 hover:underline dark:bg-emerald-500/15 dark:text-emerald-300",title:`${s.completed_at?`Signed ${ut(s.completed_at)} — `:""}open the stamped signed PDF`,children:[e.jsx(ue,{size:11})," Signed · PDF"]}):e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2 py-0.5 text-[11px] font-semibold text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",title:s.completed_at?`Signed ${ut(s.completed_at)}`:"Signed",children:[e.jsx(ue,{size:11})," Signed"]}):e.jsxs("button",{type:"button",onClick:()=>{_a(t)},disabled:$e===t.id,className:"inline-flex items-center gap-1 rounded-full border border-slate-200 bg-white px-2 py-0.5 text-[11px] font-semibold text-slate-600 transition hover:border-brand-300 hover:text-brand-700 disabled:opacity-50 dark:border-white/15 dark:bg-transparent dark:text-slate-300 dark:hover:border-brand-500/50 dark:hover:text-brand-300",title:"Copy a secure tap-to-sign page for this lead — works on any phone, no app needed",children:[$e===t.id?e.jsx(N,{size:11,className:"animate-spin"}):e.jsx(ue,{size:11}),s?s.status==="opened"?"Opened · copy link":"Copy sign link":"Sign link"]})})(),Ha&&e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[11px] font-semibold ${Tt(t)?"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300":"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300"}`,children:Tt(t)?"Consented":"No consent"}),t.last_channel&&(t.last_call_id?e.jsxs(It,{to:`/app/calls?call=${encodeURIComponent(t.last_call_id)}`,className:"hidden items-center gap-1 underline-offset-2 hover:text-brand-600 hover:underline sm:flex dar
4k:hover:text-brand-300",title:"View call record",children:[t.last_channel==="voice"?e.jsx(te,{size:12}):e.jsx(Bt,{size:12}),ut(t.last_touch_at)]}):e.jsxs("span",{className:"hidden items-center gap-1 sm:flex",children:[t.last_channel==="voice"?e.jsx(te,{size:12}):e.jsx(Bt,{size:12}),ut(t.last_touch_at)]})),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[11px] font-semibold ${oa[t.state]||oa.queued}`,children:Hn[t.state]||t.state}),(()=>{const s=["completed","opted_out"].includes(t.state),n=["paused","needs_human","needs_consent","needs_twilio","needs_provider","no_credits"].includes(t.state),d=!!y?.endsWith(`:${t.id}`);return e.jsxs("span",{className:"inline-flex items-center gap-1",children:[!s&&!n&&e.jsx("button",{type:"button",onClick:()=>{dn(t)},disabled:d,className:"rounded-full border border-slate-200 bg-white p-1 text-slate-400 transition hover:border-amber-300 hover:text-amber-600 disabled:opacity-50 dark:border-white/15 dark:bg-transparent dark:text-slate-500",title:"Pause this recipient only",children:y===`pause:${t.id}`?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(ea,{size:12})}),!s&&n&&e.jsx("button",{type:"button",onClick:()=>{cn(t)},disabled:d,className:"rounded-full border border-slate-200 bg-white p-1 text-slate-400 transition hover:border-brand-300 hover:text-brand-600 disabled:opacity-50 dark:border-white/15 dark:bg-transparent dark:text-slate-500",title:t.state==="needs_consent"?"Mark consent and resume":"Resume this recipient",children:y===`resume:${t.id}`?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(sa,{size:12})}),!s&&e.jsx("button",{type:"button",onClick:()=>{Qs(t,"completed")},disabled:d,className:"rounded-full border border-slate-200 bg-white p-1 text-slate-400 transition hover:border-emerald-300 hover:text-emerald-600 disabled:opacity-50 dark:border-white/15 dark:bg-transparent dark:text-slate-500",title:"Mark this recipient done",children:y===`completed:${t.id}`?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(ne,{size:12})}),!s&&t.state!=="needs_human"&&e.jsx("button",{type:"button",onClick:()=>{Qs(t,"needs_human")},disabled:d,className:"rounded-full border border-slate-200 bg-white p-1 text-slate-400 transition hover:border-rose-300 hover:text-rose-600 disabled:opacity-50 dark:border-white/15 dark:bg-transparent dark:text-slate-500",title:"Send to human review",children:y===`needs_human:${t.id}`?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(se,{size:12})})]})})(),e.jsx("button",{type:"button",onClick:()=>{on(t)},disabled:v===t.id,className:"rounded-full p-1 text-slate-400 transition hover:text-rose-500 disabled:opacity-50 dark:text-slate-600",title:"Remove from campaign",children:v===t.id?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(me,{size:12})})]})]},t.id))})]})]}),x==="delivery"&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("button",{type:"button",onClick:()=>he("native"),className:`rounded-3xl border p-5 text-left transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 ${P==="native"?"border-brand-400 bg-brand-50 shadow-lg shadow-brand-500/10 dark:border-brand-500/60 dark:bg-brand-500/10":"border-slate-200 bg-white hover:border-brand-300 dark:border-white/10 dark:bg-slate-900"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(ne,{size:17,className:"text-brand-500"})," Supafone infrastructure"]}),e.jsx("span",{className:"rounded-full bg-emerald-50 px-2 py-0.5 text-[11px] font-semibold text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300",children:"Default"})]}),e.jsx("p",{className:"mt-2 text-sm text-slate-600 dark:text-slate-300",children:"Easiest path. Supafone places the calls, tracks results, and keeps outreach limited to consented leads."}),e.jsxs("div",{className:"mt-4 grid gap-2 text-xs text-slate-500 dark:text-slate-400",children:[e.jsx("span",{children:"Native cap: 100 voice touches per account per day."}),e.jsxs("span",{children:["Allowed rows now: ",Hs," of ",p.length||0," recipients."]}),e.jsx("span",{children:"Rows without consent park as Needs consent."})]})]}),e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>{P==="native"&&he("byo_twilio")},onKeyDown:t=>{(t.key==="Enter"||t.key===" ")&&P==="native"&&(t.preventDefault(),he("byo_twilio"))}
4,className:`cursor-pointer rounded-3xl border p-5 text-left transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 ${P!=="native"?"border-brand-400 bg-brand-50 shadow-lg shadow-brand-500/10 dark:border-brand-500/60 dark:bg-brand-500/10":"border-slate-200 bg-white hover:border-brand-300 dark:border-white/10 dark:bg-slate-900"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(te,{size:17,className:"text-brand-500"})," Use your own telephony"]}),e.jsx("p",{className:"mt-2 text-sm text-slate-600 dark:text-slate-300",children:"Use your own carrier only when you already manage one. Supafone still runs the agent, timing, retries, transcripts, and campaign status."}),P!=="native"&&e.jsx("div",{className:"mt-3 grid grid-cols-2 gap-2",onClick:t=>t.stopPropagation(),children:xa.map(t=>e.jsxs("button",{type:"button",onClick:()=>he(t.value),className:`flex items-center justify-center gap-1.5 rounded-xl border px-3 py-2 text-xs font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 ${P===t.value?"border-brand-500 bg-brand-600 text-white shadow-md shadow-brand-600/25":"border-slate-200 bg-white text-slate-600 hover:border-brand-300 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300"}`,children:[e.jsx(mn,{brand:t.brand,size:13,className:P===t.value?"text-white":"text-slate-500 dark:text-slate-400"}),t.label]},t.value))}),e.jsxs("div",{className:"mt-4 grid gap-2 text-xs text-slate-500 dark:text-slate-400",children:[e.jsx("span",{children:"Your numbers and carrier registrations apply."}),e.jsx("span",{children:"Warm consent is still required for every lead."}),e.jsx("span",{children:"Connect your carrier right below — no need to leave this page. Until it's connected, leads park as “Connect provider” and no voice steps fire."})]})]})]}),P!=="native"&&e.jsxs("div",{className:"rounded-3xl border border-slate-200 bg-white/60 p-4 dark:border-white/10 dark:bg-slate-900/40",children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2 text-sm font-semibold text-ink",children:[e.jsx(te,{size:15,className:"text-brand-500"})," Calling and email setup"]}),e.jsx(un,{connections:j,onChange:O,agents:q,campaign:i,focusProvider:P==="byo_telnyx"?"telnyx":P==="byo_plivo"?"plivo":P==="byo_sip"?"sip":"twilio"})]}),e.jsxs("div",{className:"rounded-3xl border border-slate-200 bg-white p-4 dark:border-white/10 dark:bg-slate-900",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(te,{size:16,className:"text-brand-500"})," Campaign dialing controls"]}),e.jsx("p",{className:"mt-1 text-xs leading-5 text-slate-500 dark:text-slate-400",children:"Pick the caller ID, pace the calls, and decide what happens on voicemail."})]}),e.jsx("span",{className:"rounded-full bg-slate-100 px-2.5 py-1 text-[11px] font-semibold text-slate-600 dark:bg-white/10 dark:text-slate-300",children:"Warm only"})]}),e.jsxs("div",{className:"mt-4 grid gap-3 md:grid-cols-2",children:[e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Caller ID"}),e.jsxs("select",{className:"input mt-1 w-full",value:be,onChange:t=>Jt(t.target.value),children:[e.jsx("option",{value:"",children:"Use provider default"}),At.map(t=>e.jsx("option",{value:t,children:t},t))]})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Voice for this campaign"}),e.jsxs("select",{className:"input mt-1 w-full",value:jt,onChange:t=>is(t.target.value),children:[e.jsxs("option",{value:"",children:["Use agent voice",G?.voice?` (${G.voice})`:""]}),S.map(t=>e.jsxs("option",{value:t.id,children:[t.label,t.provider?` · ${t.provider}`:""]},t.id))]})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Calls per day"}),e.jsx("input",{className:"input mt-1 w-full",type:"number",min:1,max:P==="native"?100:2e3,value:P==="native"?Fe:Oe,onChange:t=>P==="native"?Zt(Number(t.target.value)||1):es(Number(t.target.value)||1)})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Simultaneous call starts"}),e.jsx("input",{className:"input mt-1 w-full",type:"number",min:1,max:10,value:kt,onChange:t=>ts(Number(t.target.value)||1)})]}),e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"label",children:"Voicemail mode"}),e.jsxs("select",{className:"input mt-1 w-full",value:re,onChange:t=>ss(t.target.value),children:[e.jsx("option",{value:"agent",children:"Agent leaves a short message"}),e.jsx("option",{value:"recorded",children:"Use recorded voicemail wording"}),e.jsx("option",{value:"skip",children:"Do not leave voicemail"})]})]}),e.jsxs("div",{className:"block md:col-span-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("span",{className:"label",children:"AI flexibility"}),e.jsx("button",{type:"button",className:"text-xs font-semibold text-slate-500 underline-offset-2 hover:text-ink hover:underline dark:text-slate-400 dark:hover:text-white",onClick:()=>wt(""),children:"Use agent default"})]}),e.jsxs("div",{className:"mt-2 flex items-center gap-3",children:[e.jsx(fn,{size:16,className:"shrink-0 text-brand-500"}),e.jsx("input",{className:"w-full accent-indigo-600",type:"range",min:0,max:1,step:.
405,value:Number(Os),onChange:t=>wt(t.target.value)}),e.jsx("span",{className:"w-10 text-right text-xs font-semibold tabular-nums text-slate-600 dark:text-slate-300",children:Number(Os).toFixed(2)})]}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"Lower is steadier. Higher is more adaptive for messy sales calls."})]})]}),Fs&&e.jsx("div",{className:"mt-3 rounded-2xl border border-amber-200 bg-amber-50 p-3 text-xs leading-5 text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:"Save this number in the provider setup above before using it as this campaign's caller ID."}),re!=="skip"&&e.jsxs("div",{className:"mt-3 space-y-2",children:[re==="recorded"&&e.jsxs(e.Fragment,{children:[e.jsx("input",{ref:Te,type:"file",accept:"audio/*,.mp3,.wav,.m4a,.aac,.ogg,.webm",className:"hidden",onChange:t=>t.target.files?.[0]&&void Ba(t.target.files[0])}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center",children:[e.jsxs("button",{type:"button",className:"btn-secondary w-full justify-center sm:w-auto",onClick:()=>Te.current?.click(),disabled:Z,children:[Z?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(pt,{size:14}),"Upload recording"]}),e.jsx("input",{className:"input w-full",placeholder:"Or paste a recorded voicemail URL",value:ge,onChange:t=>as(t.target.value)})]}),ge&&e.jsx("audio",{controls:!0,src:ge,className:"h-10 w-full",children:"Your browser does not support audio playback."})]}),e.jsx("textarea",{className:"input h-28 w-full",placeholder:"Optional exact voicemail script. Leave blank to use the preset voicemail.",value:Be,onChange:t=>ns(t.target.value)}),e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:"This updates the campaign's voicemail stage in the agent playbook."})]})]}),lt&&e.jsx("div",{className:"rounded-3xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(se,{size:17,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Save this delivery choice before launching."}),e.jsxs("p",{className:"mt-1 text-xs leading-5",children:["This campaign is still saved as ",Mt[Ce],". Leads will follow that saved provider until you press Save delivery workflow."]})]})]})}),ot&&!lt&&!ia(j,P)&&e.jsx("div",{className:"rounded-3xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-500/25 dark:bg-rose-500/10 dark:text-rose-100",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(se,{size:17,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-semibold",children:[Mt[P]," is not ready."]}),e.jsx("p",{className:"mt-1 text-xs leading-5",children:P==="native"?"Supafone native calling is not configured for this environment. Choose BYOK or ask support to finish the managed telephony setup.":"Connect this provider with a valid caller ID before launching voice steps."})]})]})}),e.jsx("div",{className:"rounded-3xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(se,{size:17,className:"mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold",children:"Warm outreach only."}),e.jsx("p",{className:"mt-1 text-xs leading-5",children:"Supafone only works leads with consent or a manual attestation. Rows without consent are marked Needs consent instead of being called or emailed."})]})]})}),e.jsx("button",{className:"btn-primary w-full sm:w-auto",onClick:Oa,disabled:h||Fs,children:h?e.jsx(N,{size:14,className:"animate-spin"}):"Save delivery workflow"})]}),x==="message"&&e.jsxs("div",{className:"card space-y-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("label",{className:"label",children:"Supafone agent"}),e.jsxs("button",{type:"button","data-quick-create-trigger":!0,onClick:()=>yt(!0),className:"btn-secondary inline-flex shrink-0 items-center gap-1 px-2.5 py-1 text-xs",children:[e.jsx(ee,{size:13})," New agent"]})]}),e.jsxs("select",{className:"input mt-1 w-full",value:Ie,onChange:t=>vt(t.target.value),children:[e.jsx("option",{value:"",children:"Choose the agent for this campaign"}),q.map(t=>e.jsxs("option",{value:t.id,children:[t.business_name||t.name||"Agent"," ",t.phone_number?`· ${t.phone_number}`:""]},t.id))]}),e.jsx(gn,{open:ga,onClose:()=>yt(!1),title:"New agent for this campaign",subtitle:"Spin up an agent right here — paste a website or type a business name. It's created and selected for this campaign.",ctaLabel:"Create & use",onCreated:t=>{yt(!1),E(s=>[...s.filter(n=>n.id!==t.id),t]),vt(t.id),o.success("Agent created and selected for this campaign")}}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"Voice steps use the same agent your inbound calls and web widget use. Email-only campaigns can launch without one."}),ot&&Rt&&e.jsx("div",{className:"mt-2 rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:"Save this step before launching so the backend has the selected voice agent."}),e.jsx("div",{className:"mt-3 rounded-2xl border border-brand-100 bg-brand-50/70 p-3 text-xs leading-5 text-slate-600 dar
4k:border-brand-500/20 dark:bg-brand-500/10 dark:text-slate-300",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(H,{size:14,className:"mt-0.5 shrink-0 text-brand-600 dark:text-brand-300"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-ink",children:G?`${G.business_name||G.name||"This agent"} handles the calls.`:"Pick one Supafone agent to handle the calls."}),e.jsx("p",{className:"mt-0.5",children:"Voice, knowledge, booking, warm transfer, follow-up emails, custom tools, transcripts, and call summaries stay attached."}),G&&e.jsxs(It,{to:`/app/agents/${G.id}`,className:"mt-2 inline-flex items-center gap-1 font-semibold text-brand-700 hover:text-brand-900 dark:text-brand-300",children:["Edit base agent ",e.jsx(Ot,{size:13})]})]})]})})]}),e.jsx("div",{className:"rounded-xl border border-slate-100 bg-slate-50/60 px-3.5 py-2.5 dark:border-white/10 dark:bg-white/5",children:e.jsx(Ks,{connections:j,context:"Campaign emails"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("label",{className:"label",children:"Email subject"}),e.jsxs("button",{type:"button",disabled:Gt||!a,onClick:async()=>{if(!a)return;Kt(!0);const t=o.loading("Writing your email from the agent’s prompt…");try{const{subject:s,body:n}=await u.generateEmail(a);s&&gt(s),n&&ft(n),o.success("Email drafted — review and save",{id:t})}catch(s){o.error(s instanceof Error?s.message:"Could not generate the email",{id:t})}finally{Kt(!1)}},className:"btn-secondary inline-flex shrink-0 items-center gap-1 px-2.5 py-1 text-xs",children:[Gt?e.jsx(N,{size:12,className:"animate-spin"}):e.jsx(H,{size:12}),"Generate with AI"]})]}),e.jsx("input",{className:"input mt-1 w-full",value:Ee,onChange:t=>gt(t.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Email body"}),e.jsx("textarea",{className:"input mt-1 h-48 w-full",value:De,onChange:t=>ft(t.target.value)}),e.jsxs("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:["Tokens: ",e.jsx("code",{children:"{{first_name}}"}),", ",e.jsx("code",{children:"{{name}}"}),", ",e.jsx("code",{children:"{{email}}"}),"."]})]}),e.jsx("button",{className:"btn-primary w-full sm:w-auto",onClick:Ma,disabled:h,children:h?e.jsx(N,{size:14,className:"animate-spin"}):"Save message"})]}),x==="script"&&e.jsx("div",{className:"space-y-5",children:gs||!z?e.jsx("div",{className:"card flex h-48 items-center justify-center",children:e.jsx(N,{className:"animate-spin text-slate-400 dark:text-slate-600"})}):e.jsxs(e.Fragment,{children:[e.jsx(vn,{connections:j}),e.jsx("div",{className:"hidden rounded-2xl border border-brand-100 bg-brand-50/70 p-4 dark:border-brand-500/20 dark:bg-brand-500/10 sm:block sm:p-6",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(H,{size:16,className:"mt-0.5 shrink-0 text-brand-600 dark:text-brand-300"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-ink",children:"This is the outbound playbook for your Supafone agent."}),e.jsx("p",{className:"mt-1 text-xs leading-5 text-slate-600 dark:text-slate-300",children:"Pick the goal and questions here. The Message step chooses which existing agent brings the voice, website knowledge, calendar, transfer rules, custom tools, transcripts, and post-call recaps."})]})]})}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(ma,{size:16,className:"text-brand-500"})," Outbound agent preset"]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("button",{type:"button",className:"btn-primary px-3 py-1.5 text-xs",onClick:za,disabled:Cs||z===null,title:"Save this exact script as a reusable preset AND lock it to this campaign so it can't be silently overwritten",children:[Cs?e.jsx(N,{size:13,className:"animate-spin"}):e.jsx(H,{size:13})," Save & lock this script"]}),e.jsxs("button",{type:"button",className:"btn-secondary px-3 py-1.5 text-xs",onClick:()=>ys(t=>!t),title:"Save this campaign's questions, scripts, email copy, and signing document as a reusable preset",children:[e.jsx(ee,{size:13})," Save current setup as preset"]})]})]}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"Pick a playbook — applying one saves it to the campaign instantly: goal, questions, scripts, and (for your own presets) email copy and the signing document. Everything stays editable; click a selected preset again to remove it."}),Na&&e.jsxs("div",{className:"mt-3 rounded-2xl border border-brand-200 bg-brand-50/60 p-3 dark:border-brand-500/25 dark:bg-brand-500/10",children:[e.jsxs("div",{className:"grid gap-2 sm:grid-cols-[1fr_1.4fr_auto]",children:[e.jsx("input",{className:"input",placeholder:"Preset name (e.g. Retainer signature chase)",value:Ke,onChange:t=>ks(t.target.value)}),e.jsx("input",{className:"input",placeholder:"Short description (optional)",value:js,onChange:t=>ws(t.target.value)}),e.jsxs("button",{type:"button",className:"btn-primary px-4 py-2 text-sm",onClick:()=>{Pa()},disabled:Ns||!Ke.trim(),children:[Ns?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(H,{size:14}),"Save preset"]})]}),e.jsx("p",{className:"mt-2 text-[11px] text-slate-500 dark:text-slate-400",children:"Bundles the current goal, qual
4ification questions, stage scripts, email subject/body, and the uploaded signing document — reusable on any campaign from “My presets”."})]}),St.length>0&&e.jsxs("div",{className:"mt-3",children:[e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-slate-400 dark:text-slate-500",children:"My presets"}),e.jsx("div",{className:"mt-2 grid gap-3 sm:grid-cols-2",children:St.map(t=>e.jsxs("div",{className:`relative rounded-2xl border p-4 text-left transition ${Y===t.id?"border-brand-400 bg-brand-50 shadow-lg shadow-brand-500/10 dark:border-brand-500/60 dark:bg-brand-500/10":"border-slate-200 bg-white hover:border-brand-300 dark:border-white/10 dark:bg-slate-900"}`,children:[e.jsxs("button",{type:"button",className:"block w-full text-left focus-visible:outline-none",onClick:()=>{Es(t)},disabled:Ge===t.id,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 pr-6",children:[e.jsx("span",{className:"text-sm font-semibold text-ink",children:t.label}),Ge===t.id?e.jsx(N,{size:13,className:"animate-spin text-brand-500"}):Y===t.id?e.jsx("span",{className:"rounded-full bg-brand-600 px-2 py-0.5 text-[10px] font-semibold text-white",children:"Selected"}):e.jsx("span",{className:"rounded-full bg-slate-100 px-2 py-0.5 text-[10px] font-semibold text-slate-500 dark:bg-white/10 dark:text-slate-300",children:"Yours"})]}),t.description&&e.jsx("p",{className:"mt-1 text-xs leading-5 text-slate-500 dark:text-slate-400",children:t.description}),e.jsxs("p",{className:"mt-2 text-[11px] text-slate-400 dark:text-slate-500",children:[t.qualification_criteria.length," question",t.qualification_criteria.length===1?"":"s",t.native_signing?.pdfUrl?" · signing document attached":"",t.email_subject?" · email copy":""]})]}),e.jsx("button",{type:"button",className:"absolute right-3 top-3 text-slate-300 transition hover:text-rose-500 dark:text-slate-600",onClick:()=>{La(t)},"aria-label":`Delete preset ${t.label}`,title:"Delete this preset",children:e.jsx(me,{size:13})})]},t.id))})]}),e.jsxs("div",{className:"mt-3 max-h-[26rem] overflow-y-auto pr-1",children:[St.length>0&&e.jsx("div",{className:"mb-2 text-[11px] font-semibold uppercase tracking-wide text-slate-400 dark:text-slate-500",children:"Built-in"}),e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:ps.map(t=>e.jsxs("button",{type:"button",onClick:()=>{Es(t)},disabled:Ge===t.id,className:`rounded-2xl border p-4 text-left transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 ${Y===t.id?"border-brand-400 bg-brand-50 shadow-lg shadow-brand-500/10 dark:border-brand-500/60 dark:bg-brand-500/10":"border-slate-200 bg-white hover:border-brand-300 dark:border-white/10 dark:bg-slate-900"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-ink",children:t.label}),Ge===t.id?e.jsx(N,{size:13,className:"animate-spin text-brand-500"}):Y===t.id?e.jsx("span",{className:"rounded-full bg-brand-600 px-2 py-0.5 text-[10px] font-semibold text-white",children:"Selected"}):null]}),e.jsx("p",{className:"mt-1 text-xs leading-5 text-slate-500 dark:text-slate-400",children:t.description}),e.jsxs("p",{className:"mt-2 text-[11px] text-slate-400 dark:text-slate-500",children:[t.qualification_criteria.length," qualifying question",t.qualification_criteria.length===1?"":"s"," · qualified →"," ",Yn[t.qualified_action]||t.qualified_action," · disqualified →"," ",Wn[t.disqualified_action]||t.disqualified_action]})]},t.id))})]})]}),e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(Zs,{size:16,className:"text-brand-500"})," Qualification criteria"]}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"The agent works through these questions naturally, saves each answer to the field name, then marks the lead qualified or disqualified — disqualified leads stop the cadence, qualified leads get the preset's next step."}),Qe.length===0&&e.jsx("div",{className:"mt-3 rounded-2xl border border-slate-200 bg-slate-50 p-3 text-xs text-slate-500 dark:border-white/10 dark:bg-white/5 dark:text-slate-400",children:"No qualifying questions — the agent just works toward the campaign goal. Pick a preset above or add a question."}),e.jsx("div",{className:"mt-3 max-h-80 space-y-2 overflow-y-auto pr-1",children:Qe.map((t,s)=>e.jsxs("div",{className:"rounded-xl border border-slate-100 bg-slate-50/50 p-2 dark:border-white/10 dark:bg-white/5",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-2 md:grid-cols-[1fr_11rem_auto_1.75rem] md:items-center",children:[e.jsx("input",{className:"input",placeholder:`Question ${s+1} the agent asks`,value:t.question,onChange:n=>nt(s,{question:n.target.value})}),e.jsx("input",{className:"input font-mono text-xs",placeholder:"field (auto from question)",title:"save_lead field the answer is stored under",value:t.field,onChange:n=>nt(s,{field:n.target.value})}),e.jsxs("label",{className:"flex cursor-pointer items-center gap-1.5 text-xs font-medium text-slate-600 dar
4k:text-slate-300",children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4 rounded border-slate-300 text-brand-600 focus:ring-brand-500 dark:border-white/20",checked:t.disqualifies_when!==void 0,onChange:n=>nt(s,{disqualifies_when:n.target.checked?"they say no":void 0})}),"Disqualifies"]}),e.jsx("button",{type:"button",className:"justify-self-end text-slate-400 transition hover:text-rose-500 dark:text-slate-600",onClick:()=>Ca(s),"aria-label":"Remove question",children:e.jsx(me,{size:15})})]}),t.disqualifies_when!==void 0&&e.jsxs("div",{className:"mt-2 flex items-center gap-2 text-xs text-slate-500 dark:text-slate-400",children:[e.jsx("span",{className:"shrink-0",children:"Disqualified when"}),e.jsx("input",{className:"input flex-1 text-xs",placeholder:"e.g. they already bought from someone else",value:t.disqualifies_when||"",onChange:n=>nt(s,{disqualifies_when:n.target.value})})]})]},s))}),e.jsxs("button",{type:"button",className:"btn-secondary mt-2",onClick:Sa,children:[e.jsx(ee,{size:14})," Add question"]})]}),e.jsxs("div",{className:"card",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between text-left",onClick:()=>wa(t=>!t),children:[e.jsxs("span",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(Ft,{size:16,className:"text-brand-500"})," Advanced: edit prompts"]}),e.jsx(yn,{size:16,className:`text-slate-400 transition-transform ${bs?"rotate-180":""}`})]}),bs&&e.jsxs("div",{className:"mt-3 space-y-4",children:[e.jsxs("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:["Each stage is auto-generated from the preset and criteria above — the placeholder shows the generated text. Type to replace a stage; leave it empty to keep auto-generation. Tokens:"," ",e.jsx("code",{children:"{{first_name}}"}),", ",e.jsx("code",{children:"{{name}}"}),","," ",e.jsx("code",{children:"{{business}}"}),", ",e.jsx("code",{children:"{{assistant_name}}"}),"."]}),Vn.map(t=>e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("label",{className:"label",title:t.hint,children:t.label}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] font-semibold ${(X[t.id]||"").trim()?"bg-brand-50 text-brand-700 dark:bg-brand-500/15 dark:text-brand-300":"bg-slate-100 text-slate-500 dark:bg-white/5 dark:text-slate-400"}`,children:(X[t.id]||"").trim()?"Custom":"Auto"})]}),e.jsx("textarea",{className:"input mt-1 w-full font-mono text-xs leading-5",rows:4,placeholder:z.stages[t.id].default,value:X[t.id]||"",onChange:s=>Ds(t.id,s.target.value)})]},t.id)),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("label",{className:"label",children:"Full system prompt override"}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] font-semibold ${(X.system_prompt_override||"").trim()?"bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300":"bg-slate-100 text-slate-500 dark:bg-white/5 dark:text-slate-400"}`,children:(X.system_prompt_override||"").trim()?"Active":"Off"})]}),e.jsx("textarea",{className:"input mt-1 w-full font-mono text-xs leading-5",rows:5,placeholder:"Replaces ALL four stage sections above with your own briefing. Lead details and the do-not-call rule are still appended.",value:X.system_prompt_override||"",onChange:t=>Ds("system_prompt_override",t.target.value)})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-1",children:[e.jsx("label",{className:"label",children:"Final composed prompt (preview)"}),e.jsx("span",{className:"text-[11px] text-slate-400 dark:text-slate-500",children:"updates automatically as you type · appended to the agent's stage prompt on every campaign call"})]}),e.jsx("pre",{className:"mt-1 max-h-64 overflow-auto whitespace-pre-wrap rounded-2xl border border-slate-100 bg-slate-50 p-3 font-mono text-[11px] leading-5 text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-300",children:z.composed.trim()})]})]})]}),!z.agent_attached&&e.jsx("div",{className:"rounded-2xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("span",{className:"flex items-start gap-1.5",children:[e.jsx(se,{size:13,className:"mt-0.5 shrink-0"}),"No Supafone agent is attached yet — pick one in the Message tab so voice steps can use this playbook."]})}),e.jsxs("div",{className:"sticky bottom-3 z-10 flex flex-col items-stretch gap-2 sm:flex-row sm:items-center",children:[e.jsxs("button",{className:"btn-primary w-full justify-center shadow-lg shadow-brand-500/25 sm:w-auto",onClick:Is,disabled:h,children:[h?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(H,{size:14}),"Save script & qualification"]}),e.jsx("span",{className:`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-[11px] font-semibold ${Je==="saving"?"bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300":Je==="error"?"bg-rose-50 text-rose-700 dark:bg-rose-500/15 dark:text-rose-300":"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300"}`,title:"Questions and scripts auto-save as you type",children:Je==="saving"?e.jsxs(e.Fragment,{children:[e.jsx(N,{size:11,className:"animate-spin"})," Saving…"]}):Je==="error"?"Auto-save failed — keep typing to retry or hit Save":"Auto-saves as you type"})]})]})}),x==="document"&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(ue,{size:16,className:"text-brand-500"})," Signing document"]}),e.jsx("span",{className:`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-[11px] font-semibold ${tt==="saving"?"bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300":tt==="error"?"bg-rose-50 text-rose-700 dark:bg-rose-500/15 dark:text-rose-300":"bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300"}`,children:tt==="saving"?e.jsxs(e.Fragment,{children:[e.jsx(N,{size:11,className:"animate-spin"})," Saving…"]}):tt==="error"?"Save failed — adjust a field to retry":"Auto-saves instantly"})]}),e.jsxs("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:["Upload the PDF this campaign sends for signature (retainer, agreement, order form…). Place the signature and date fields on the page — the recipient opens their tracked link, sees the document with the highlighted fields, signs once with a finger or mouse, and the signature is stamped into the PDF at exactly these spots. Signed copies land back on each lead. Email steps automatically carry the signing link (or place it yourself with ",e.jsx("code",{children:"{{sign_link}}"})," in the email body)."]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[e.jsx("input",{ref:at,type:"file",accept:"application/pdf,.pdf",className:"hidden",onChange:t=>{const s=t.target.files?.[0];s&&$a(s)}}),e.jsxs("button",{type:"button",className:"btn-primary",onClick:()=>at.current?.click(),disabled:Ls,children:[Ls?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(pt,{size:14}),F?.pdfUrl?"Replace PDF":"Upload PDF"]}),F?.pdfUrl&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-slate-100 px-2.5 py-1 text-[11px] font-semibold text-slate-600 dar
4k:bg-white/10 dark:text-slate-300",children:[e.jsx(Ut,{size:11})," ",F.sourceAssetName||"document.pdf"]}),e.jsxs("button",{type:"button",className:"btn-secondary px-3 py-1.5 text-xs",onClick:()=>{qa()},disabled:qs,title:"Scan the PDF for signature / date / initials lines",children:[qs?e.jsx(N,{size:13,className:"animate-spin"}):e.jsx(H,{size:13}),"Auto-detect fields"]}),e.jsxs("label",{className:"ml-auto flex cursor-pointer items-center gap-2 text-xs font-medium text-slate-600 dark:text-slate-300",children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4 rounded border-slate-300 text-brand-600 focus:ring-brand-500 dark:border-white/20",checked:F?.enabled!==!1,onChange:t=>Pt(s=>({...s,enabled:t.target.checked}))}),"Send this document with signing links"]})]})]}),le.length>0&&e.jsxs("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-2 rounded-2xl border border-emerald-200 bg-emerald-50 p-3 text-xs text-emerald-900 dark:border-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-100",children:[e.jsxs("span",{children:[le.length," field",le.length===1?"":"s"," detected on the document (",le.map(t=>t.type).join(", "),")."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{type:"button",className:"btn-primary px-3 py-1.5 text-xs",onClick:Aa,children:"Apply detected fields"}),e.jsx("button",{type:"button",className:"btn-secondary px-3 py-1.5 text-xs",onClick:()=>et([]),children:"Dismiss"})]})]})]}),F?.pdfUrl?e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("div",{className:"font-semibold text-ink",children:"Place the fields"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:[["signature","Signature"],["date","Date"],["initials","Initials"],["text","Text"]].map(([t,s])=>e.jsxs("button",{type:"button",className:"btn-secondary px-2.5 py-1 text-xs",onClick:()=>Ra(t),children:[e.jsx(ee,{size:12})," ",s]},t))})]}),de.length>0&&e.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:de.map(t=>e.jsxs("span",{className:`inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-semibold transition ${zs===t.key?"border-brand-400 bg-brand-50 text-brand-700 dark:border-brand-500/60 dark:bg-brand-500/15 dark:text-brand-300":"border-slate-200 bg-white text-slate-600 hover:border-brand-300 dark:border-white/10 dark:bg-slate-900 dark:text-slate-300"}`,onClick:()=>je(t.key),title:t.placement?"Placed — click the page to move it":"Not placed yet — click the page",children:[t.label||t.key,!t.placement&&e.jsx("span",{className:"text-amber-500",children:"· unplaced"}),e.jsx("button",{type:"button",className:"text-slate-300 transition hover:text-rose-500 dark:text-slate-600",onClick:s=>{s.stopPropagation(),Ta(t.key)},"aria-label":`Remove ${t.label||t.key}`,children:e.jsx(me,{size:11})})]},t.key))}),e.jsx("div",{className:"mt-3",children:e.jsx(Dn,{pdfUrl:F.pdfUrl,fields:de,activeFieldKey:zs,onActiveFieldKeyChange:je,onFieldsChange:zt})})]}):e.jsx("div",{className:"card text-sm text-slate-500 dark:text-slate-400",children:"No document yet — this step is optional. Campaigns without a document still mint plain tap-to-sign links (name + signature + consent) from the Leads tab."})]}),x==="cadence"&&e.jsxs("div",{className:"card space-y-3",children:[e.jsx("div",{className:"font-semibold text-ink",children:"Cadence"}),e.jsx("p",{className:"text-xs text-slate-500 dark:text-slate-400",children:"The steps each recipient walks through. The campaign stops when the steps run out, when someone replies or books, or when it needs a human."}),ie.some(t=>t.channel==="email")&&e.jsx(Ks,{connections:j,context:"Email steps"}),ie.length===0&&e.jsx("div",{className:"text-sm text-slate-500 dark:text-slate-500",children:"No steps — add one below."}),e.jsx("div",{className:"space-y-2",children:ie.map((t,s)=>e.jsxs("div",{className:"flex flex-col items-stretch gap-2 rounded-xl border border-slate-100 bg-slate-50 px-3 py-3 sm:flex-row sm:items-center sm:py-2 dark:border-white/10 dark:bg-white/5",children:[e.jsxs("span",{className:"text-xs font-semibold text-slate-500 dark:text-slate-500",children:["#",s+1]}),e.jsxs("select",{className:"input w-full sm:w-auto",value:t.channel,onChange:n=>Ws(s,{channel:n.target.value}),children:[e.jsx("option",{value:"voice",children:"Voice call"}),e.jsx("option",{value:"email",children:"Email"})]}),s===0?e.jsx("span",{className:"text-sm text-slate-500 dark:text-slate-400",children:"immediately at launch"}):e.jsxs("div",{className:"flex items-center gap-1 text-sm text-slate-500 dark:text-slate-400",children:["after",e.jsx("input",{type:"number",min:0,className:"input w-20",value:t.delay_hours,onChange:n=>Ws(s,{delay_hours:Number(n.target.value)||0})}),"h"]}),e.jsx("button",{className:"self-end text-slate-400 hover:text-rose-500 sm:ml-auto sm:self-auto dark:text-slate-600",onClick:()=>rn(s),children:e.jsx(me,{size:15})})]},s))}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row",children:[e.jsxs("button",{className:"btn-secondary w-full sm:w-auto",onClick:nn,children:[e.jsx(ee,{size:14})," Add step"]}),e.jsx("button",{className:"btn-primary w-full sm:w-auto",onClick:Fa,disabled:h,children:h?e.jsx(N,{size:14,className:"animate-spin"}):"Save cadence"})]}),e.jsxs("div",{className:"card mt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ne,{size:15,className:"text-brand-600"}),e.jsx("h3",{className:"text-sm font-semibold text-ink",children:"When a call ends…"})]}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"After each call, Supafone classifies the outcome and routes the lead automatically. The steps above only keep running while none of these fire."}),e.jsx("div",{className:"mt-3 space-y-1.5",children:[["✅ Booked","Stops the ca
4dence — the goal is met."],["🎯 Qualified","Stops the cadence — the next step already happened on the call."],["📞 Callback requested","Hands the lead to your team."],["🚫 Do not call","Opts them out — and never contacts them from any campaign in your account again."]].map(([t,s])=>e.jsxs("div",{className:"flex flex-wrap gap-x-2 rounded-lg bg-slate-50 px-3 py-2 text-sm dark:bg-white/5",children:[e.jsx("span",{className:"font-medium text-ink",children:t}),e.jsx("span",{className:"text-slate-500 dark:text-slate-400",children:s})]},t))}),z?e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"If the lead qualifies →"}),e.jsxs("select",{className:"input",value:z.qualified_action,onChange:t=>He({...z,qualified_action:t.target.value}),children:[e.jsx("option",{value:"book",children:"Book a time"}),e.jsx("option",{value:"transfer",children:"Live transfer to your team"}),e.jsx("option",{value:"callback",children:"Team callback"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"If the lead is disqualified →"}),e.jsxs("select",{className:"input",value:z.disqualified_action,onChange:t=>He({...z,disqualified_action:t.target.value}),children:[e.jsx("option",{value:"polite_exit",children:"Politely end — keep them contactable"}),e.jsx("option",{value:"remove",children:"Remove from outreach"})]})]}),e.jsx("div",{className:"sm:col-span-2",children:e.jsx("button",{className:"btn-secondary",onClick:Is,disabled:h,children:h?e.jsx(N,{size:14,className:"animate-spin"}):"Save rules"})})]}):e.jsxs("p",{className:"mt-3 text-xs text-slate-400 dark:text-slate-500",children:["Open the ",e.jsx("span",{className:"font-medium",children:"Script"})," tab to set what happens when a lead qualifies or is disqualified."]})]})]}),x==="analytics"&&e.jsx(Rn,{recipients:p,stats:i.stats}),x==="config"&&e.jsxs("div",{className:"card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold text-ink",children:[e.jsx(Ft,{size:16,className:"text-brand-500"})," Advanced setup"]}),e.jsx("p",{className:"mt-1 text-xs text-slate-500 dark:text-slate-400",children:"Review or reuse the saved campaign setup. Check it safely before saving changes."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:"btn-secondary px-3 py-1.5 text-xs",onClick:Ea,disabled:!V,title:"Copy the campaign setup to the clipboard",children:[e.jsx(Sn,{size:13})," Copy"]}),e.jsxs("button",{className:"btn-secondary px-3 py-1.5 text-xs",onClick:Da,disabled:!V,title:"Download as a .yaml file",children:[e.jsx(Pn,{size:13})," Export"]})]})]}),dt&&e.jsx("div",{className:"mt-3 rounded-2xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-900 dark:border-amber-500/25 dark:bg-amber-500/10 dark:text-amber-100",children:e.jsxs("span",{className:"flex items-start gap-1.5",children:[e.jsx(se,{size:13,className:"mt-0.5 shrink-0"}),"This campaign is active — pause it before applying config changes (export and validate still work)."]})}),e.jsx("div",{className:"mt-4",children:ms?e.jsx("div",{className:"flex h-72 items-center justify-center rounded-2xl border border-slate-100 dark:border-white/10",children:e.jsx(N,{className:"animate-spin text-slate-400 dark:text-slate-600"})}):e.jsx(pn,{initialConfig:V??void 0,onApplied:t=>{t.id===a?(U(t),Ne().catch(()=>{})):l(`/app/campaigns/${t.id}`)}})})]}),(()=>{const t=pe.indexOf(x);if(t<0)return null;const s=t>0?pe[t-1]:null,n=t<pe.length-1?pe[t+1]:null;return e.jsxs("div",{className:"mt-5 flex flex-col gap-3 border-t border-slate-100 pt-4 dark:border-white/10 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("p",{className:"flex items-center gap-1.5 text-xs text-slate-500 dark:text-slate-400",children:[e.jsx(H,{size:13,className:"shrink-0 text-brand-500"}),Un[x]]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",className:"btn-secondary px-4 py-2 text-sm disabled:opacity-40",disabled:!s,onClick:()=>s&&b(s),children:[e.jsx(ua,{size:15})," Back"]}),n?e.jsxs("button",{type:"button",className:"btn-primary px-5 py-2 text-sm",onClick:()=>b(n),children:["Next: ",Bn[n]," ",e.jsx(Ot,{size:15})]}):e.jsxs("button",{type:"button",className:"btn-primary px-5 py-2 text-sm disabled:opacity-50",disabled:h||!Xs,title:ct||"Launch this campaign",onClick:()=>{Ys()},children:[e.jsx(ta,{size:15})," ",dt?"Relaunch":"Launch campaign"]})]})]})})()]})]})}export{Mi as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.