1import{e as J,r as l,u as W,d as M,j as e}from"./vendor-query-CnAhr2B8.js";import{g as xe,a as X,H as F,h as he,B as x,J as L,aC as u,O as Y,Q as G,R as Z,T as _,V as v,b as pe,p as E,s as q,aH as ee,ay as T,E as je,d as h,b0 as ge,i as se,j as ae,k as te,l as ie,N as ne,I as A,ak as $,U as ve,C as re,az as fe,m as Ne,a6 as Ce,aV as ye,M as be,bi as we}from"./index-CLUtDhnY.js";import{T as Se}from"./textarea-VdIEZsUv.js";import{C as Pe}from"./checkbox-DwgIx1mG.js";import{T as De,a as Te,b as z,c as j,d as Me,e as g}from"./table-2PZjRc6u.js";import{D as Fe,a as ke,b as Ae,c as D,d as U}from"./dropdown-menu-QOOilEE4.js";import{P as Ee,a as qe,b as Ie}from"./popover-En2VDOLx.js";import{f as Oe,C as Ve}from"./calendar-VsbRkqvx.js";import{C as le}from"./circle-x-CDWbgxd-.js";import{E as Re}from"./eye-Dal3N8ej.js";import{P as Be}from"./pencil-XqPqJhqP.js";import{P as Le}from"./play-rh91jfbb.js";import{P as $e}from"./pause-7bYPxYFA.js";import{T as Qe}from"./trash-2-B9b4XGw8.js";import"./vendor-ui-CYA7SV0W.js";import"./vendor-charts-CPMWc2oJ.js";import"./vendor-forms-UY-il7MQ.js";import"./circle-CM1Tn-8Z.js";function ce({status:r}){switch(r){case"draft":return e.jsx(h,{variant:"secondary",children:"Draft"});case"active":return e.jsx(h,{className:"bg-green-500 hover:bg-green-600 text-white",children:"Active"});case"paused":return e.jsx(h,{className:"bg-amber-500 hover:bg-amber-600 text-white",children:"Paused"});case"complete":return e.jsx(h,{className:"bg-blue-500 hover:bg-blue-600 text-white",children:"Complete"});default:return e.jsx(h,{variant:"outline",children:r})}}function de({type:r}){switch(r){case"broadcast":return e.jsxs(h,{variant:"outline",className:"border-purple-300 text-purple-700",children:[e.jsx(ee,{className:"h-3 w-3 mr-1"}),"Broadcast"]});case"sequence":return e.jsxs(h,{variant:"outline",className:"border-indigo-300 text-indigo-700",children:[e.jsx(ge,{className:"h-3 w-3 mr-1"}),"Sequence"]});default:return e.jsx(h,{variant:"outline",children:r})}}function w({label:r,value:n,icon:c,subtitle:t}){return e.jsx(E,{children:e.jsx(q,{className:"p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-muted",children:e.jsx(c,{className:"h-4 w-4 text-muted-foreground"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:n}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r}),t&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:t})]})]})})})}function He({open:r,onClose:n}){const{toast:c}=X(),t=J(),[o,i]=l.useState(""),[d,m]=l.useState("broadcast"),[f,N]=l.useState(!0),[S,k]=l.useState(""),[C,P]=l.useState(""),[y,b]=l.useState(""),[s,Q]=l.useState(""),[p,I]=l.useState(void 0),[O,H]=l.useState(null),oe=()=>{i(""),m("broadcast"),N(!0),k(""),P(""),b(""),Q(""),I(void 0),H(null)},V=()=>{oe(),n()},K=()=>{const a={allCustomers:f};return f||(S&&(a.inactiveDays=parseInt(S,10)),C.trim()&&(a.tags=C.split(",").map(ue=>ue.trim()).filter(Boolean)),y&&(a.minimumVisits=parseInt(y,10))),a},R=M({mutationFn:async()=>(await F("POST","/api/sms-campaigns/preview-audience",{audienceFilter:K()})).json(),onSuccess:a=>{H(a.count)},onError:a=>{c({title:"Preview failed",description:a.message,variant:"destructive"})}}),B=M({mutationFn:async()=>(await F("POST","/api/sms-campaigns",{name:o,type:d,audienceFilter:K(),messagePrompt:s,scheduledAt:p?p.toISOString():null})).json(),onSuccess:()=>{c({title:"Campaign created",description:"Your campaign has been saved as a draft."}),t.invalidateQueries({queryKey:["/api/sms-campaigns"]}),V()},onError:a=>{c({title:"Create failed",description:a.message,variant:"destructive"})}}),me=o.trim().length>0&&s.trim().length>0;return e.jsx(se,{open:r,onOpenChange:a=>!a&&V(),children:e.jsxs(ae,{className:"sm:max-w-[560px] max-h-[90vh] overflow-y-auto",children:[e.jsxs(te,{children:[e.jsx(ie,{children:"Create SMS Campaign"}),e.jsx(ne,{children:"Set up a new campaign to reach your customers via SMS."})]}),e.jsxs("div",{className:"space-y-5 py-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{htmlFor:"campaign-name",children:"Campaign Name"}),e.jsx(A,{id:"campaign-name",placeholder:"e.g., Spring Promo, Holiday Reminder",value:o,onChange:a=>i(a.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{children:"Campaign Type"}),e.jsxs(Y,{value:d,onValueChange:a=>m(a),children:[e.jsx(G,{children:e.jsx(Z,{})}),e.jsxs(_,{children:[e.jsx(v,{value:"broadcast",children:"Broadcast -- Single message to all"}),e.jsx(v,{value:"sequence",children:"Sequence -- Multi-step drip"})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(u,{children:"Audience"}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Pe,{id:"all-customers",checked:f,onCheckedChange:a=>N(!!a)}),e.jsx("label",{htmlFor:"all-customers",className:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",children:"All customers with SMS opt-in"})]}),!f&&e.jsxs("div",{className:"space-y-3 pl-6 border-l-2 border-muted",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{htmlFor:"inactive-days",className:"text-xs",children:"Inactive for (days)"}),e.jsx(A,{id:"inactive-days",type:"number",min:"0",placeholder:"e.g., 30",value:S,onChange:a=>k(a.target.value)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{htmlFor:"tags",className:"text-xs",children:"Customer Tags (comma-separated)"}),e.jsx(A,{id:"tags",placeholder:"e.g., VIP, loyal, new",value:C,onChange:a=>P(a.target.value)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{htmlFor:"min-visits",className:"text-xs",children:"Minimum Visits"}),e.jsx(A,{id:"min-visits",type:"number",min:"0",placeholder:"e.g., 3",value:y,onChange:a=>b(a.target.value)})]})]}),e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>R.mutate(),disabled:R.isPending,children:[R.isPending?e.jsx($,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(ve,{className:"h-3 w-3 mr-1"}),"Preview Audience"]}),O!==null&&e.jsxs("p",{className:"text-sm text-muted-foreground",children:[O," customer",O!==1?"s":""," match this filter"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{htmlFor:"message-prompt",children:"Message / AI Prompt"}),e.jsx(Se,{id:"message-prompt",rows:4,placeholder:"Describe what the SMS should say. The AI will craft a compliant, personalized message for each recipient.",value:s,onChange:a=>Q(a.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"The AI will generate the actual SMS text based on this prompt and each customer's context."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{children:"Schedule (optional)"}),e.jsxs(Ee,{children:[e.jsx(qe,{asChild:!0,children:e.jsxs(x,{variant:"outline",className:fe("w-full justify-start text-left font-normal",!p&&"text-muted-foreground"),children:[e.jsx(re,{className:"mr-2 h-4 w-4"}),p?Oe(p,"PPP"):"Send immediately (no schedule)"]})}),e.jsx(Ie,{className:"w-auto p-0",align:"start",children:e.jsx(Ve,{mode:"single",selected:p,onSelect:I,disabled:a=>a<new Date,initialFocus:!0})})]}),p&&e.jsx(x,{variant:"ghost",size:"sm",className:"text-xs",onClick:()=>I(void 0),children:"Clear schedule (send immediately)"})]})]}),e.jsxs(Ne,{children:[e.jsx(x,{variant:"outline",onClick:V,children:"Cancel"}),e.jsxs(x,{onClick:()=>B.mutate(),disabled:!me||B.isPending,children:[B.isPending?e.jsx($,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(L,{className:"h-4 w-4 mr-2"}),"Create Campaign"]})]})]})})}function Ke({open:r,campaignId:n,onClose:c}){const{data:t,isLoading:o}
1=W({queryKey:["/api/sms-campaigns",n],queryFn:async()=>{const d=await fetch(`/api/sms-campaigns/${n}`,{credentials:"include"});if(!d.ok)throw new Error("Failed to fetch campaign details");return d.json()},enabled:r&&n!==null}),i=t==null?void 0:t.metrics;return e.jsx(se,{open:r,onOpenChange:d=>!d&&c(),children:e.jsxs(ae,{className:"sm:max-w-[600px] max-h-[90vh] overflow-y-auto",children:[e.jsxs(te,{children:[e.jsx(ie,{children:(t==null?void 0:t.name)||"Campaign Details"}),e.jsx(ne,{children:"View campaign performance and delivery metrics."})]}),o?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx($,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):t?e.jsxs("div",{className:"space-y-6 py-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(de,{type:t.type}),e.jsx(ce,{status:t.status})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Created"}),e.jsx("p",{className:"font-medium",children:T(t.createdAt)})]}),t.launchedAt&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Launched"}),e.jsx("p",{className:"font-medium",children:T(t.launchedAt)})]}),t.completedAt&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Completed"}),e.jsx("p",{className:"font-medium",children:T(t.completedAt)})]}),t.scheduledAt&&!t.launchedAt&&e.jsxs("div",{children:[e.jsx("span",{className:"text-muted-foreground",children:"Scheduled"}),e.jsx("p",{className:"font-medium",children:T(t.scheduledAt)})]})]}),t.messagePrompt&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-1",children:"Message Prompt"}),e.jsx("p",{className:"text-sm bg-muted rounded-lg p-3",children:t.messagePrompt})]}),i&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"border-t pt-4",children:[e.jsx("h4",{className:"text-sm font-semibold mb-3",children:"Delivery Metrics"}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 gap-3",children:[e.jsx(w,{label:"Sent",value:i.sent,icon:Ce}),e.jsx(w,{label:"Delivered",value:i.delivered,icon:ye}),e.jsx(w,{label:"Replied",value:i.replied,icon:be}),e.jsx(w,{label:"Bookings",value:i.bookings,icon:re}),e.jsx(w,{label:"Opt-outs",value:i.optOuts,icon:le}),e.jsx(w,{label:"Reply Rate",value:`${i.replyRate.toFixed(1)}%`,icon:we,subtitle:i.sent>0?`${i.replied} of ${i.sent}
1 sent`:void 0})]})]}),i.sent>0&&e.jsxs("div",{className:"border-t pt-4",children:[e.jsx("h4",{className:"text-sm font-semibold mb-3",children:"Conversion"}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("div",{className:"flex-1 bg-muted rounded-full h-3 overflow-hidden",children:e.jsx("div",{className:"h-full bg-green-500 rounded-full transition-all",style:{width:`${Math.min(i.conversionRate,100)}%`}})}),e.jsxs("span",{className:"text-sm font-bold",children:[i.conversionRate.toFixed(1),"%"]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[i.bookings," booking",i.bookings!==1?"s":""," from"," ",i.sent," message",i.sent!==1?"s":""," sent"]})]})]})]}):e.jsx("p",{className:"text-sm text-muted-foreground py-8 text-center",children:"Campaign not found."})]})})}function ds(){const{user:r}=xe(),{toast:n}=X(),c=J(),[t,o]=l.useState(!1),[i,d]=l.useState(null),[m,f]=l.useState("all"),{data:N,isLoading:S,error:k}=W({queryKey:["/api/sms-campaigns"],queryFn:async()=>{const s=await fetch("/api/sms-campaigns",{credentials:"include"});if(!s.ok)throw new Error("Failed to fetch campaigns");return s.json()},staleTime:3e4,refetchOnWindowFocus:!0}),C=M({mutationFn:async s=>{await F("POST",`/api/sms-campaigns/${s}/launch`)},onSuccess:()=>{n({title:"Campaign launched",description:"Messages are now being sent."}),c.invalidateQueries({queryKey:["/api/sms-campaigns"]})},onError:s=>{n({title:"Launch failed",description:s.message,variant:"destructive"})}}),P=M({mutationFn:async s=>{await F("POST",`/api/sms-campaigns/${s}/pause`)},onSuccess:()=>{n({title:"Campaign paused",description:"Sending has been paused."}),c.invalidateQueries({queryKey:["/api/sms-campaigns"]})},onError:s=>{n({title:"Pause failed",description:s.message,variant:"destructive"})}}),y=M({mutationFn:async s=>{await F("DELETE",`/api/sms-campaigns/${s}`)},onSuccess:()=>{n({title:"Campaign deleted"}),c.invalidateQueries({queryKey:["/api/sms-campaigns"]})},onError:s=>{n({title:"Delete failed",description:s.message,variant:"destructive"})}}),b=N==null?void 0:N.filter(s=>m==="all"?!0:s.status===m);return e.jsxs(he,{title:"SMS Campaigns",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"SMS Campaigns"}),e.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:"Create and manage targeted SMS campaigns to engage your customers."})]}),e.jsxs(x,{onClick:()=>o(!0),children:[e.jsx(L,{className:"h-4 w-4 mr-2"}),"Create Campaign"]})]}),e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx(u,{className:"text-sm text-muted-foreground",children:"Status:"}),e.jsxs(Y,{value:m,onValueChange:f,children:[e.jsx(G,{className:"w-[140px]",children:e.jsx(Z,{})}),e.jsxs(_,{children:[e.jsx(v,{value:"all",children:"All"}),e.jsx(v,{value:"draft",children:"Draft"}),e.jsx(v,{value:"active",children:"Active"}),e.jsx(v,{value:"paused",children:"Paused"}),e.jsx(v,{value:"complete",children:"Complete"})]})]})]}),S?e.jsx(pe,{rows:5}):k?e.jsx(E,{children:e.jsxs(q,{className:"py-12 text-center",children:[e.jsx(le,{className:"h-8 w-8 text-destructive mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Failed to load campaigns. Please try refreshing the page."})]})}):!b||b.length===0?e.jsx(E,{children:e.jsxs(q,{className:"py-16 text-center",children:[e.jsx(ee,{className:"h-10 w-10 text-muted-foreground mx-auto mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-1",children:m!=="all"?"No campaigns match this filter":"No campaigns yet"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4 max-w-sm mx-auto",children:m!=="all"?"Try changing the status filter or create a new campaign.":"Create your first SMS campaign to reach customers with targeted messages."}),m==="all"&&e.jsxs(x,{onClick:()=>o(!0),children:[e.jsx(L,{className:"h-4 w-4 mr-2"}),"Create Campaign"]})]})}):e.jsx(E,{children:e.jsx(q,{className:"p-0",children:e.jsxs(De,{children:[e.jsx(Te,{children:e.jsxs(z,{children:[e.jsx(j,{children:"Campaign"}),e.jsx(j,{children:"Type"}),e.jsx(j,{children:"Status"}),e.jsx(j,{className:"text-right",children:"Audience"}),e.jsx(j,{className:"text-right",children:"Sent"}),e.jsx(j,{className:"text-right",children:"Created"}),e.jsx(j,{className:"w-[50px]"})]})}),e.jsx(Me,{children:b.map(s=>e.jsxs(z,{children:[e.jsx(g,{className:"font-medium",children:s.name}),e.jsx(g,{children:e.jsx(de,{type:s.type})}),e.jsx(g,{children:e.jsx(ce,{status:s.status})}),e.jsx(g,{className:"text-right",children:s.audienceCount.toLocaleStr
1ing()}),e.jsx(g,{className:"text-right",children:s.sentCount.toLocaleString()}),e.jsx(g,{className:"text-right text-muted-foreground text-sm",children:T(s.createdAt)}),e.jsx(g,{children:e.jsxs(Fe,{children:[e.jsx(ke,{asChild:!0,children:e.jsx(x,{variant:"ghost",size:"icon",className:"h-8 w-8",children:e.jsx(je,{className:"h-4 w-4"})})}),e.jsxs(Ae,{align:"end",children:[e.jsxs(D,{onClick:()=>d(s.id),children:[e.jsx(Re,{className:"h-4 w-4 mr-2"}),"View Details"]}),s.status==="draft"&&e.jsxs(D,{onClick:()=>d(s.id),children:[e.jsx(Be,{className:"h-4 w-4 mr-2"}),"Edit"]}),e.jsx(U,{}),(s.status==="draft"||s.status==="paused")&&e.jsxs(D,{onClick:()=>C.mutate(s.id),disabled:C.isPending,children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),"Launch"]}),s.status==="active"&&e.jsxs(D,{onClick:()=>P.mutate(s.id),disabled:P.isPending,children:[e.jsx($e,{className:"h-4 w-4 mr-2"}),"Pause"]}),s.status==="draft"&&e.jsxs(e.Fragment,{children:[e.jsx(U,{}),e.jsxs(D,{className:"text-destructive focus:text-destructive",onClick:()=>{window.confirm(`Delete campaign "${s.name}"? This cannot be undone.`)&&y.mutate(s.id)},disabled:y.isPending,children:[e.jsx(Qe,{className:"h-4 w-4 mr-2"}),"Delete"]})]})]})]})})]},s.id))})]})})}),e.jsx(He,{open:t,onClose:()=>o(!1)}),e.jsx(Ke,{open:i!==null,campaignId:i,onClose:()=>d(null)})]})}export{ds 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.