1import{a as n,j as e}from"./vendor-react-DoZqVJV9.js";import{P as B}from"./PageHeader-BKdI5d6t.js";import{i as N}from"./index-BWN_DVob.js";import{a as O}from"./crmService-iG_FlvMi.js";import{aj as E,be as K,bl as Q,b9 as _,bL as A,aa as G,S as H,ax as V}from"./vendor-CYy89fbB.js";import{u as W,F as X,T as J,S as Y,c as Z,D as T,P as F,L as ee}from"./index-BRBVc4Fs.js";import{P as R}from"./primitives-DnwAafit.js";import"./vendor-helpers-5liHvl6o.js";import"./context-CWgg3I6G.js";import"./vendor-motion-CAHSrZCt.js";import"./vendor-data-DIyefQL7.js";import"./vendor-radix-Cf-gsRIn.js";import"./motion-B_H_SukK.js";const te=async l=>(await N.get("/call-campaigns",{params:void 0})).data.campaigns||[],se=async l=>(await N.post("/call-campaigns",l)).data.campaign,ae=l=>N.delete(`/call-campaigns/${l}`),le=async(l,i=25)=>(await N.post(`/call-campaigns/${l}/dispatch`,{batchSize:i})).data,U={DRAFT:"muted",RUNNING:"info",PAUSED:"warn",COMPLETED:"ok",FAILED:"bad"};function je(){const[l,i]=n.useState([]),[c,x]=n.useState(!0),[f,C]=n.useState(null),[j,u]=n.useState(!1),[p,$]=n.useState(""),[y,w]=n.useState(null),d=n.useCallback(async()=>{x(!0);try{i(await te()),C(null)}catch(t){C(t?.response?.data?.message||"Failed to load")}finally{x(!1)}},[]);n.useEffect(()=>{const t=setTimeout(()=>{d()},0);return()=>clearTimeout(t)},[d]);const S=async t=>{const r=t.totalLeads-t.callsCompleted;if(r<=0){A.info("No pending contacts to dial.");return}if(confirm(`Dial up to 25 of ${r} pending contacts in "${t.name}"?`))try{const o=await le(t.id);A.success(`Dispatched ${o.dispatched}, failed ${o.failed}. Pending remaining: ${o.pendingRemaining}`),d()}catch(o){A.error(o?.response?.data?.message||"Dispatch failed")}},h=async t=>{if(confirm(`Delete "${t.name}"?`))try{await ae(t.id),i(r=>r.filter(o=>o.id!==t.id))}catch(r){A.error(r?.response?.data?.message||"Delete failed")}},g=n.useMemo(()=>{const t=p.trim().toLowerCase();return t?l.filter(r=>r.name.toLowerCase().includes(t)||r.status.toLowerCase().includes(t)):l},[l,p]),L=W("(min-width: 1024px)"),a=n.useMemo(()=>l.find(t=>t.id===y)??(L?g[0]:null)??null,[l,g,y,L]);return e.jsxs(X,{children:[e.jsx(B,{icon:E,title:"Call campaigns",description:"Dial CRM contacts in batches using an AI agent.",actions:e.jsxs("button",{type:"button",onClick:()=>u(!0),className:"inline-flex h-9 items-center gap-2 rounded-xl bg-brand-500 px-3 text-sm font-semibold text-white hover:bg-brand-600",children:[e.jsx(K,{size:14})," New campaign"]})}),e.jsx(J,{children:e.jsx(Y,{value:p,onChange:$,placeholder:"Search campaigns"})}),f&&e.jsx("div",{className:"rounded-xl border border-rose-500/40 bg-rose-500/10 px-4 py-3 text-sm text-rose-700 dark:text-rose-300",children:f}),e.jsx(Z,{storageKey:"crm-call-campaigns",listWidth:430,selected:!!a,detailKey:a?.id,onBack:()=>w(null),list:e.jsx(F,{title:"Campaigns",icon:E,bodyClassName:"p-0",className:"min-h-0",children:c?e.jsx("div",{className:"space-y-2 p-3",children:Array.from({length:6}).map((t,r)=>e.jsx("div",{className:"h-16 animate-pulse rounded-xl bg-line/70"},r))}):g.length===0?e.jsx(T,{title:"No campaigns",text:p?"No campaign matches this search.":"Create a campaign to start dialing CRM contacts."}):e.jsx("div",{className:"divide-y divide-line/70",children:g.map(t=>{const r=Math.max(0,t.totalLeads-t.callsCompleted),o=t.totalLeads>0?Math.round(t.callsCompleted/t.totalLeads*100):0;return e.jsx(ee,{active:a?.id===t.id,onClick:()=>w(t.id),children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"truncate text-sm font-semibold text-fg",children:t.name}),e.jsx(R,{tone:U[t.status],children:t.status.toLowerCase()})]}),e.jsx("div",{className:"mt-2 h-1.5 overflow-hidden rounded-full bg-bg-elevated",children:e.jsx("div",{className:"h-full rounded-full bg-brand-500",style:{width:`${o}%`}})}),e.jsxs("div",{className:"mt-1.5 flex items-center justify-between text-[11px] text-fg-subtle",children:[e.jsxs("span",{children:[t.callsCompleted,"/",t.totalLeads," dialed"]}),e.jsxs("span",{children:[r," pending"]})]})]})},t.id)})})}),detail:a?e.jsx(F,{title:a.name,icon:E,actions:e.jsxs(e.Fragment,{children:[a.totalLeads-a.callsCompleted>0&&a.status!=="COMPLETED"&&e.jsxs("button",{type:"button",onClick:()=>S(a),className:"inline-flex h-8 items-center gap-1.5 rounded-lg bg-emerald-500/10 px-2.5 text-xs font-semibold text-emerald-700 hover:bg-emerald-500/20 dark:text-emerald-300",children:[e.jsx(Q,{size:12})," Dial"]}),e.jsxs("button",{type:"button",onClick:()=>h(a),className:"inline-flex h-8 items-center gap-1.5 rounded-lg bg-rose-500/10 px-2.5 text-xs font-semibold text-rose-700 hover:bg-rose-500/20 dark:text-rose-300",children:[e.jsx(_,{size:12})," Delete"]})]}),bodyClassName:"p-4",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(R,{tone:U[a.status],children:a.status.toLowerCase()}),e.jsxs("span",{className:"text-xs text-fg-subtle",children:["Created ",new Date(a.createdAt).toLocaleStr
1ing()]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:[e.jsx(P,{label:"Contacts",value:a.totalLeads}),e.jsx(P,{label:"Dialed",value:a.callsCompleted,tone:"ok"}),e.jsx(P,{label:"Pending",value:Math.max(0,a.totalLeads-a.callsCompleted),tone:"warn"}),e.jsx(P,{label:"Progress",value:`${a.totalLeads>0?Math.round(a.callsCompleted/a.totalLeads*100):0}%`})]}),e.jsxs("div",{className:"rounded-2xl border border-line bg-bg-elevated p-4",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between text-sm font-semibold text-fg",children:[e.jsx("span",{children:"Dialing progress"}),e.jsxs("span",{children:[a.callsCompleted,"/",a.totalLeads]})]}),e.jsx("div",{className:"h-3 overflow-hidden rounded-full bg-card",children:e.jsx("div",{className:"h-full rounded-full bg-brand-500",style:{width:`${a.totalLeads>0?Math.round(a.callsCompleted/a.totalLeads*100):0}%`}})})]}),e.jsxs("dl",{className:"grid gap-3 text-sm sm:grid-cols-2",children:[e.jsx(M,{label:"Campaign ID",value:a.id}),e.jsx(M,{label:"Agent ID",value:a.agentId}),e.jsx(M,{label:"Updated",value:new Date(a.updatedAt).toLocaleString()}),e.jsx(M,{label:"Description",value:a.description||"-"})]})]})}):null,empty:e.jsx(T,{title:"Select a campaign",text:"Progress, contact counts, and controls open here."})}),j&&e.jsx(ne,{onClose:()=>u(!1),onCreated:()=>{u(!1),d()}})]})}function P({label:l,value:i,tone:c="brand"}){const x=c==="ok"?"text-emerald-700 dark:text-emerald-300":c==="warn"?"text-amber-700 dark:text-amber-300":"text-brand-600 dark:text-brand-300";return e.jsxs("div",{className:"rounded-2xl border border-line bg-bg-elevated p-3",children:[e.jsx("div",{className:"text-[11px] text-fg-subtle",children:l}),e.jsx("div",{className:`mt-1 text-2xl font-semibold ${x}`,children:i})]})}function M({label:l,value:i}){return e.jsxs("div",{className:"rounded-xl border border-line bg-bg-elevated px-3 py-2",children:[e.jsx("dt",{className:"text-[11px] font-semibold text-fg-subtle",children:l}),e.jsx("dd",{className:"mt-1 break-words font-mono text-xs text-fg-muted",children:i})]})}function ne({onClose:l,onCreated:i}){const[c,x]=n.useState(""),[f,C]=n.useState(""),[j,u]=n.useState(""),[p,$]=n.useState([]),[y,w]=n.useState([]),[d,S]=n.useState(new Set),[h,g]=n.useState(""),[L,a]=n.useState(!0),[t,r]=n.useState(!1),[o,k]=n.useState(null);n.useEffect(()=>{let s=!0;return Promise.all([N.get("/agents").then(m=>m.data?.data??m.data?.agents??[]).catch(()=>[]),O({}).catch(()=>[])]).then(([m,I])=>{if(!s)return;const v=m.map(b=>({id:b.id,name:b.name}));$(v),w(I),v.length>0&&u(v[0].id)}).finally(()=>s&&a(!1)),()=>{s=!1}},[]);const q=async()=>{if(!c.trim())return k("Name required");if(!j)return k("Agent required");if(d.size===0)return k("Pick at least one contact");r(!0);try{await se({name:c,description:f||void 0,agentId:j,contactIds:Array.from(d)}),i()}catch(s){k(s?.response?.data?.message||"Create failed")}finally{r(!1)}},D=y.filter(s=>h?`${s.firstName} ${s.lastName??""}`.toLowerCase().includes(h.toLowerCase())||Array.isArray(s.phones)&&s.phones.some(m=>String(m.number||"").includes(h)):!0);return e.jsxs("div",{className:"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex justify-end",children:[e.jsxs("div",{className:"w-full max-w-lg h-full bg-card border-l border-line shadow-2xl flex flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-4 border-b border-line",children:[e.jsx("h3",{className:"font-semibold",children:"New Call Campaign"}),e.jsx("button",{type:"button",onClick:l,children:e.jsx(G,{size:18})})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-5 space-y-3",children:[o&&e.jsx("div",{className:"rounded-lg border border-red-500/40 bg-red-500/10 px-3 py-2 text-xs text-red-400",children:o}),e.jsx(z,{label:"Campaign name *",children:e.jsx("input",{value:c,onChange:s=>x(s.target.value),className:"inp"})}),e.jsx(z,{label:"Description",children:e.jsx("textarea",{value:f,onChange:s=>C(s.target.value),rows:2,className:"inp"})}),e.jsx(z,{label:"Agent *",children:e.jsxs("select",{value:j,onChange:s=>u(s.target.value),className:"inp",children:[e.jsx("option",{value:"",children:"Select agentâ¦"}),p.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("span",{className:"text-xs font-semibold text-fg-muted",children:["Contacts to dial · ",e.jsxs("strong",{className:"text-fg",children:[d.size," selected"]})]}),e.jsxs("button",{type:"button",onClick:()=>S(new Set(D.map(s=>s.id))),className:"text-xs text-brand-400 hover:underline",children:["Select all (",D.length,")"]})]}),e.jsx("input",{value:h,onChange:s=>g(s.target.value),placeholder:"Search by name or phoneâ¦",className:"inp mb-2"}),e.jsx("div",{className:"rounded-lg border border-line max-h-64 overflow-y-auto",children:L?e.jsxs("div",{className:"p-4 text-center text-xs text-fg-muted",children:[e.jsx(H,{size:14,className:"animate-spin mx-auto mb-2"})," Loadingâ¦"]}):D.length===0?e.jsxs("div",{className:"p-4 text-center text-xs text-fg-muted flex flex-col items-center gap-1",children:[e.jsx(V,{size:16}),"No contacts match."]}):D.map(s=>{const m=d.has(s.id),I=Array.isArray(s.phones)&&s.phones.length>
10?s.phones[0].number:null;return e.jsxs("label",{className:"flex items-center gap-3 px-3 py-2 border-b border-line last:border-b-0 cursor-pointer hover:bg-card-hover/60",children:[e.jsx("input",{type:"checkbox",checked:m,onChange:v=>{const b=new Set(d);v.target.checked?b.add(s.id):b.delete(s.id),S(b)},className:"h-4 w-4 rounded"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"text-sm font-medium truncate",children:[s.firstName," ",s.lastName]}),e.jsx("div",{className:"text-[10px] text-fg-muted font-mono",children:I||"no phone"})]})]},s.id)})})]})]}),e.jsxs("div",{className:"border-t border-line px-5 py-4 flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:l,className:"h-9 px-4 rounded-lg text-sm border border-line",children:"Cancel"}),e.jsx("button",{type:"button",onClick:q,disabled:t||d.size===0,className:"h-9 px-4 rounded-lg text-sm bg-brand-500 text-white disabled:opacity-50",children:t?"Creatingâ¦":`Create with ${d.size}`})]})]}),e.jsx("style",{children:".inp { min-height: 34px; width: 100%; padding: 6px 10px; border-radius: 8px; border: 1px solid var(--color-line); background: var(--color-bg-elevated); font-size: 13px; outline: none; } .inp:focus { border-color: rgb(99,102,241); }"})]})}function z({label:l,children:i}){return e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"block text-xs font-semibold text-fg-muted mb-1",children:l}),i]})}export{je 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.