PageSourceSearch

https://www.smallbizagent.ai/assets/index-B6cEaWOV.js

js smallbizagent.ai collected 2026-10-05 15:05:47 UTC 71,941 bytes, 16 lines download raw bytes

1import{j as e,e as ee,r as N,d as M,u as I}from"./vendor-query-CnAhr2B8.js";import{c as ue,p as y,s as S,ak as w,M as k,B as f,W as Ge,D as Qe,F as Je,a as B,H as T,q as X,r as Z,d as _,aC as v,I as O,O as q,Q as U,R as Y,T as K,V as g,bj as Xe,o as Me,b6 as he,aG as ke,Y as Ie,bi as pe,aJ as Pe,aK as De,aL as $,ag as Le,n as ge,bk as Ze,b7 as te,aD as de,J as me,_ as je,ab as xe,i as ve,j as Ne,k as fe,l as be,N as ye,aR as es,aT as ss,a8 as Te,ac as Ce,aN as ts,aA as as,g as ns,h as is,bg as ls,aM as V,a1 as Fe}from"./index-CLUtDhnY.js";import{F as rs}from"./feature-tip-D5lKzg4O.js";import{S as G}from"./switch-wa839A7l.js";import{S as re}from"./star-W3rPNB9i.js";import{C as cs,P as os}from"./pen-line-Dh32-MMT.js";import{U as ds}from"./user-x-2VCvja1x.js";import{H as ms}from"./heart-BPUPw7pK.js";import{T as C}from"./textarea-VdIEZsUv.js";import{S as xs}from"./save-9pPXGTas.js";import{R as us}from"./rotate-ccw-D2ZymChC.js";import{E as hs}from"./eye-Dal3N8ej.js";import{A as Oe}from"./activity-Cj-zUpsQ.js";import{A as $e}from"./arrow-down-left-Dcc0WaQb.js";import{T as We,a as qe,b as ne,c as E,d as Ue,e as R}from"./table-2PZjRc6u.js";import{S as ps}from"./square-pen-6eLYV1-R.js";import{P as gs}from"./pause-7bYPxYFA.js";import{P as js}from"./play-rh91jfbb.js";import{T as vs}from"./trash-2-B9b4XGw8.js";import{C as Ns}from"./circle-x-CDWbgxd-.js";import"./vendor-ui-CYA7SV0W.js";import"./vendor-charts-CPMWc2oJ.js";import"./vendor-forms-UY-il7MQ.js";import"./lightbulb-CC4qJ2Zf.js";/**
2 * @license lucide-react v0.453.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Ye=ue("FlaskConical",[["path",{d:"M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2",key:"pzvekw"}],["path",{d:"M8.5 2h7",key:"csnxdl"}],["path",{d:"M7 16h10",key:"wp8him"}]]);/**
7 * @license lucide-react v0.453.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const fs=ue("LayoutDashboard",[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]]);/**
12 * @license lucide-react v0.453.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const we=ue("Workflow",[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2",key:"by2w9f"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4",key:"xkn7yn"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2",key:"1cgmvn"}]]),bs={follow_up:{label:"Follow-Up",description:"Thank-you and upsell SMS after completed jobs or appointments",icon:ms,color:"text-pink-600 dark:text-pink-400"},no_show:{label:"No-Show",description:"SMS customers to reschedule when you mark an appointment as no-show",icon:ds,color:"text-orange-600 dark:text-orange-400"},estimate_follow_up:{label:"Estimate Follow-Up",description:"Automated SMS follow-ups on pending quotes",icon:Je,color:"text-blue-600 dark:text-blue-400"},invoice_collection:{label:"Invoice Collection",description:"Escalating SMS reminders for overdue invoices with payment links",icon:Qe,color:"text-emerald-600 dark:text-emerald-400"},rebooking:{label:"Rebooking",description:"Proactive rebooking prompts for inactive customers",icon:cs,color:"text-green-600 dark:text-green-400"},maintenance_reminder:{label:"Maintenance Reminder",description:"Predictive maintenance SMS when a customer's equipment is overdue for service",icon:Ge,color:"text-cyan-600 dark:text-cyan-400"},review_response:{label:"Review Response",description:"AI-drafted responses to Google reviews",icon:re,color:"text-amber-600 dark:text-amber-400"}};function Q(s){return bs[s]??{label:s,description:"",icon:k,color:"text-muted-foreground"}}function ys({agentType:s,enabled:t,smsSentCount:n=0,repliesReceivedCount:o=0,lastActivityAt:r,isToggling:c,onToggle:h,isOwner:a,onTest:m}){const x=Q(s),l=x.icon;return e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"pt-6 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2.5 rounded-lg bg-muted",children:e.jsx(l,{className:`h-5 w-5 ${x.color}`})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground",children:x.label}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5 max-w-[200px]",children:x.description})]})]}),e.jsx("div",{className:"flex items-center gap-2",children:c?e.jsx(w,{className:"h-4 w-4 animate-spin text-muted-foreground"}):e.jsx(G,{checked:t,onCheckedChange:h})})]}),e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(k,{className:"h-3 w-3"}),e.jsxs("span",{children:[n," sent"]})]}),e.jsx("div",{className:"flex items-center gap-1",children:e.jsxs("span",{children:[o," replies"]})}),a&&m&&e.jsxs(f,{variant:"ghost",size:"sm",className:"ml-auto h-6 px-2 text-xs gap-1",onClick:()=>m(s),children:[e.jsx(Ye,{className:"h-3 w-3"}),"Test"]}),!m&&r&&e.jsxs("div",{className:"ml-auto",children:["Last: ",new Date(r).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})]})]})]})})}const ws={follow_up:["{customerName}","{businessName}","{bookingLink}"],no_show:["{customerName}","{appointmentTime}","{businessName}","{businessPhone}","{bookingLink}"],estimate_follow_up:["{customerName}","{businessName}","{quoteTotal}"],rebooking:["{customerName}","{businessName}","{daysSinceVisit}","{serviceName}","{bookingLink}","{businessPhone}"],maintenance_reminder:["{customerName}","{businessName}","{equipmentLabel}","{monthsSinceService}","{bookingLink}","{businessPhone}"],review_response:[]},Ss={customerName:"Sarah",businessName:"Your Business",businessPhone:"(555) 123-4567",bookingLink:"smallbizagent.ai/book/your-business",appointmentTime:"2:00 PM",quoteTotal:"$450.00",daysSinceVisit:"42",serviceName:"haircut",validUntil:"March 15",equipmentLabel:"Trane AC unit",monthsSinceService:"13"};function ks(s){if(!s)return"";let t=s;for(const[n,o]of Object.entries(Ss))t=t.replace(new RegExp(`\\{${n}\\}`,"g"),o);return t}function F({template:s,label:t}){const n=ks(s);return n?e.jsxs("div",{className:"mt-2",children:[t&&e.jsxs("div",{className:"flex items-center gap-1.5 mb-1.5",children:[e.jsx(hs,{className:"h-3 w-3 text-muted-foreground"}),e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:t})]}),e.jsxs("div",{className:"bg-muted/50 rounded-xl p-3 border border-border",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Xe,{className:"h-4 w-4 text-muted-foreground mt-0.5 shrink-0"}),e.jsx("div",{className:"bg-blue-500 text-white text-sm rounded-2xl rounded-tl-sm px-3 py-2 max-w-[280px]",children:n})]}),e.jsxs("div",{className:"text-[10px] text-muted-foreground mt-1.5 ml-6",children:[n.length," characters ",n.length>160?"(2 SMS segments)":"(1 SMS segment)"]})]})]}):null}function Ts({agentType:s,currentConfig:t,enabled:n}){const{toast:o}=B(),r=ee(),c=Q(s),h=c.icon,[a,m]=N.useState(t??{});N.useEffect(()=>{t&&m(t)},[t]);const x=M({mutationFn:async()=>(await T("PUT",`/api/automations/settings/${s}`,{enabled:n,config:a})).json(),onSuccess:()=>{o({title:"Settings saved",description:`${c.label} agent configuration updated.`}),r.invalidateQueries({queryKey:["/api/automations/settings"]})},onError:i=>{o({title:"Failed to save",description:i.message,variant:"destructive"})}}),l=M({mutationFn:async()=>(await T("PUT",`/api/automations/settings/${s}`,{enabled:n,config:null})).json(),onSuccess:()=>{m({}),o({title:"Reset to defaults",description:`${c.label} agent reset to default configuration.`}),r.invalidateQueries({queryKey:["/api/automations/settings"]})},onError:i=>{o({title:"Failed to reset",description:i.message,variant:"destructive"})}}),p=ws[s]??[];return e.jsxs(y,{className:"border-border bg-card",children:[e.jsx(X,{children:e.jsxs(Z,{className:"text-base flex items-center gap-2",children:[e.jsx(h,{className:`h-4 w-4 ${c.color}`}),c.label," Settings"]})}),e.jsxs(S,{className:"space-y-6",children:[p.length>0&&e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Available variables:"}),p.map(i=>e.jsx(_,{variant:"outline",className:"text-xs",children:i},i))]}),s==="follow_up"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Enable Thank-You SMS"}),e.jsx(G,{checked:a.enableThankYou??!0,onCheckedChange:i=>m({...a,enableThankYou:i})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Thank-You Template"}),e.jsx(C,{value:a.thankYouTemplate??"",onChange:i=>m({...a,thankYouTemplate:i.target.value}),placeholder:"Hi {customerName}! Thank you for choosing {businessName}...",rows:3}),e.jsx(F,{template:a.thankYouTemplate??"",label:"Customer will see"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Delay (minutes)"}),e.jsx(O,{type:"number",min:0,max:1440,value:a.thankYouDelayMinutes??30,onChange:i=>m({...a,thankYouDelayMinutes:parseInt(i.target.value)||30}),className:"w-32"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Enable Upsell SMS"}),e.jsx(G,{checked:a.enableUpsell??!0,onCheckedChange:i=>m({...a,enableUpsell:i})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Upsell Template"}),e.jsx(C,{value:a.upsellTemplate??"",onChange:i=>m({...a,upsellTemplate:i.target.value}),placeholder:"Hi {customerName}, ready to book your next visit...",rows:3}),e.jsx(F,{template:a.upsellTemplate??"",label:"Customer will see"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Upsell Delay (hours)"}),e.jsx(O,{type:"number",min:1,max:168,value:a.upsellDelayHours??48,onChange:i=>m({...a,upsellDelayHours:parseInt(i.target.value)||48}),className:"w-32"})]})]}),s==="no_show"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Message Template"}),e.jsx(C,{value:a.messageTemplate??"",onChange:i=>m({...a,messageTemplate:i.target.value}),placeholder:"Hey {customerName}, we missed you...",rows:3}),e.jsx(F,{template:a.messageTemplate??"",label:"Initial SMS to customer"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Reschedule Reply Template"}),e.jsx(C,{value:a.rescheduleReplyTemplate??"",onChange:i=>m({...a,rescheduleReplyTemplate:i.target.value}),placeholder:"Great! Book online at {bookingLink}...",rows:2}),e.jsx(F,{template:a.rescheduleReplyTemplate??"",label:"If customer says YES"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Decline Reply Template"}),e.jsx(C,{value:a.declineReplyTemplate??"",onChange:i=>m({...a,declineReplyTemplate:i.target.value}),placeholder:"No problem! We'll be here...",rows:2}),e.jsx(F,{template:a.declineReplyTemplate??"",label:"If customer says NO"})]}),e.jsx("div",{className:"rounded-lg bg-blue-50 border border-blue-200 p-3 text-sm text-blue-800",children:'When you mark an appointment as "No Show", the customer will automatically receive the SMS above offering to reschedule.'}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Reply Window (hours)"}),e.jsx(O,{type:"number",min:1,max:72,value:a.expirationHours??24,onChange:i=>m({...a,expirationHours:parseInt(i.target.value)||24}),className:"w-32"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"How long the customer has to reply before the conversation expires"})]})]}),s==="estimate_follow_up"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Follow-Up Messages (one per attempt)"}),(a.messageTemplates??["","",""]).map((i,u)=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs(v,{className:"text-xs text-muted-foreground",children:["Attempt ",u+1]}),e.jsx(C,{value:i,onChange:A=>{const P=[...a.messageTemplates??["","",""]];P[u]=A.target.value,m({...a,messageTemplates:P})},rows:2})]},u))]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Max Attempts"}),e.jsx(O,{type:"number",min:1,max:5,value:a.maxAttempts??3,onChange:i=>m({...a,maxAttempts:parseInt(i.target.value)||3}),className:"w-32"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Auto-expire quotes after max attempts"}),e.jsx(G,{checked:a.autoExpire??!0,onCheckedChange:i=>m({...a,autoExpire:i})})]})]}),s==="rebooking"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Default Rebooking Interval (days)"}),e.jsx(O,{type:"number",min:7,max:365,value:a.defaultIntervalDays??42,onChange:i=>m({...a,defaultIntervalDays:parseInt(i.target.value)||42}),className:"w-32"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Days since last visit before sending reminder"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Message Template"}),e.jsx(C,{value:a.messageTemplate??"",onChange:i=>m({...a,messageTemplate:i.target.value}),placeholder:"Hi {customerName}! It's been {daysSinceVisit} days...",rows:3}),e.jsx(F,{template:a.messageTemplate??"",label:"Initial SMS to customer"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Booking Reply Template"}),e.jsx(C,{value:a.bookingReplyTemplate??"",onChange:i=>m({...a,bookingReplyTemplate:i.target.value}),placeholder:"Awesome! Book here: {bookingLink}...",rows:2}),e.jsx(F,{template:a.bookingReplyTemplate??"",label:"If customer says YES"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Decline Reply Template"}),e.jsx(C,{value:a.declineReplyTemplate??"",onChange:i=>m({...a,declineReplyTemplate:i.target.value}
16),placeholder:"No worries! We'll be here when you're ready.",rows:2}),e.jsx(F,{template:a.declineReplyTemplate??"",label:"If customer says NO"})]})]}),s==="maintenance_reminder"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Service Interval (days)"}),e.jsx(O,{type:"number",min:30,max:1095,value:a.intervalDays??365,onChange:i=>m({...a,intervalDays:parseInt(i.target.value)||365}),className:"w-32"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Days since last service (or install) before a unit counts as due"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Cooldown Between Reminders (days)"}),e.jsx(O,{type:"number",min:30,max:730,value:a.cooldownDays??180,onChange:i=>m({...a,cooldownDays:parseInt(i.target.value)||180}),className:"w-32"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Minimum quiet period per unit after a reminder is sent"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Message Template"}),e.jsx(C,{value:a.messageTemplate??"",onChange:i=>m({...a,messageTemplate:i.target.value}),placeholder:"Hi {customerName}! It's been {monthsSinceService} months since we serviced your {equipmentLabel}...",rows:3}),e.jsx(F,{template:a.messageTemplate??"",label:"Initial SMS to customer"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Booking Reply Template"}),e.jsx(C,{value:a.bookingReplyTemplate??"",onChange:i=>m({...a,bookingReplyTemplate:i.target.value}),placeholder:"Great! Book here: {bookingLink}...",rows:2}),e.jsx(F,{template:a.bookingReplyTemplate??"",label:"If customer says YES"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Decline Reply Template"}),e.jsx(C,{value:a.declineReplyTemplate??"",onChange:i=>m({...a,declineReplyTemplate:i.target.value}),placeholder:"No problem! We'll be here when you need us.",rows:2}),e.jsx(F,{template:a.declineReplyTemplate??"",label:"If customer says NO"})]})]}),s==="review_response"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Response Tone"}),e.jsxs(q,{value:a.tone??"professional",onValueChange:i=>m({...a,tone:i}),children:[e.jsx(U,{className:"w-48",children:e.jsx(Y,{})}),e.jsxs(K,{children:[e.jsx(g,{value:"professional",children:"Professional"}),e.jsx(g,{value:"friendly",children:"Friendly"}),e.jsx(g,{value:"casual",children:"Casual"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(v,{className:"text-sm",children:"Max Response Length (words)"}),e.jsx(O,{type:"number",min:50,max:500,value:a.maxResponseLength??200,onChange:i=>m({...a,maxResponseLength:parseInt(i.target.value)||200}),className:"w-32"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Include Business Name"}),e.jsx(G,{checked:a.includeBusinessName??!0,onCheckedChange:i=>m({...a,includeBusinessName:i})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(v,{className:"text-sm",children:"Thank for Positive Reviews"}),e.jsx(G,{checked:a.thankForPositive??!0,onCheckedChange:i=>m({...a,thankForPositive:i})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(v,{className:"text-sm",children:"Apologize for Negative Reviews"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:"Include an apology and offer to make it right for 1-2 star reviews"})]}),e.jsx(G,{checked:a.apologizeForNegative??!0,onCheckedChange:i=>m({...a,apologizeForNegative:i})})]}),e.jsx("p",{className:"text-xs text-muted-foreground border-l-2 border-muted pl-3",children:"All AI-drafted responses require your approval before posting to Google. Review pending responses in the Reviews tab."})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsxs(f,{onClick:()=>x.mutate(),disabled:x.isPending,children:[x.isPending?e.jsx(w,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(xs,{className:"h-4 w-4 mr-2"}),"Save Settings"]}),e.jsxs(f,{variant:"outline",onClick:()=>l.mutate(),disabled:l.isPending,children:[l.isPending?e.jsx(w,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(us,{className:"h-4 w-4 mr-2"}),"Reset to Defaults"]})]})]})]})}const Cs={sms_sent:k,reply_received:$e,status_changed:he,escalated:Me}
16,Rs={sms_sent:"bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400",reply_received:"bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400",status_changed:"bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400",escalated:"bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400"};function _s(s){return s.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase())}function As(){const[s,t]=N.useState("all"),{data:n=[],isLoading:o}=I({queryKey:["/api/automations/activity",{agentType:s!=="all"?s:void 0,limit:"100"}]});return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:"Filter by agent:"}),e.jsxs(q,{value:s,onValueChange:t,children:[e.jsx(U,{className:"w-48",children:e.jsx(Y,{})}),e.jsxs(K,{children:[e.jsx(g,{value:"all",children:"All Agents"}),e.jsx(g,{value:"follow_up",children:"Follow-Up"}),e.jsx(g,{value:"no_show",children:"No-Show"}),e.jsx(g,{value:"estimate_follow_up",children:"Estimate Follow-Up"}),e.jsx(g,{value:"invoice_collection",children:"Invoice Collection"}),e.jsx(g,{value:"rebooking",children:"Rebooking"}),e.jsx(g,{value:"maintenance_reminder",children:"Maintenance Reminder"}),e.jsx(g,{value:"review_response",children:"Review Response"})]})]})]}),o?e.jsx("div",{className:"flex items-center justify-center h-40",children:e.jsx(w,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):n.length===0?e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(Oe,{className:"h-10 w-10 text-muted-foreground/40 mb-3"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No agent activity yet. Activity will appear here as agents send messages and process replies."})]})}):e.jsx(y,{className:"border-border bg-card overflow-hidden",children:e.jsx("div",{className:"divide-y divide-border",children:n.map(r=>{var m,x;const c=Q(r.agentType),h=Cs[r.action]??k,a=Rs[r.action]??"bg-muted text-muted-foreground";return e.jsx("div",{className:"p-4 hover:bg-muted/30 transition-colors",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${a}`,children:e.jsx(h,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(_,{variant:"secondary",className:"text-xs",children:c.label}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:_s(r.action)}),r.referenceType&&r.referenceId&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:[r.referenceType," #",r.referenceId]})]}),((m=r.details)==null?void 0:m.message)&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 line-clamp-2",children:r.details.message}),((x=r.details)==null?void 0:x.newState)&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["State changed to: ",e.jsx("span",{className:"font-medium",children:r.details.newState}),r.details.reason&&` (${r.details.reason.replace(/_/g," ")})`]})]}),e.jsx("div",{className:"text-xs text-muted-foreground whitespace-nowrap",children:new Date(r.createdAt).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})})]})},r.id)})})})]})}const Es={awaiting_reply:"bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400",replied:"bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400",resolved:"bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400",expired:"bg-neutral-100 dark:bg-neutral-800 text-neutral-500",escalated:"bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400"};function Re({conversations:s,isLoading:t}){return t?e.jsx("div",{className:"flex items-center justify-center h-40",children:e.jsx("div",{className:"h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent"})}):s.length===0?e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(k,{className:"h-10 w-10 text-muted-foreground
16/40 mb-3"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No active conversations. Conversations appear here when agents send messages that expect a reply."})]})}):e.jsx(y,{className:"border-border bg-card overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-border bg-muted/50",children:[e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"Agent"}),e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"Phone"}),e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"Reference"}),e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"State"}),e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"Last Sent"}),e.jsx("th",{className:"p-3 text-left font-medium text-muted-foreground",children:"Expires"})]})}),e.jsx("tbody",{children:s.map(n=>{const o=Q(n.agentType),r=Es[n.state]??"bg-muted text-muted-foreground";return e.jsxs("tr",{className:"border-b border-border/50 hover:bg-muted/30 transition-colors",children:[e.jsx("td",{className:"p-3",children:e.jsx(_,{variant:"secondary",className:"text-xs",children:o.label})}),e.jsx("td",{className:"p-3 text-muted-foreground font-mono text-xs",children:n.customerPhone}),e.jsx("td",{className:"p-3 text-muted-foreground text-xs",children:n.referenceType&&n.referenceId?`${n.referenceType} #${n.referenceId}`:"---"}),e.jsx("td",{className:"p-3",children:e.jsx(_,{className:`text-xs ${r}`,children:n.state.replace(/_/g," ")})}),e.jsx("td",{className:"p-3 text-muted-foreground text-xs",children:n.lastMessageSentAt?new Date(n.lastMessageSentAt).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}):"---"}),e.jsx("td",{className:"p-3 text-muted-foreground text-xs",children:n.expiresAt?new Date(n.expiresAt).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}):"---"})]},n.id)})})]})})})}function Ms({rating:s}){return s===null?e.jsx("span",{className:"text-xs text-muted-foreground",children:"No rating"}):e.jsx("div",{className:"flex items-center gap-0.5",children:Array.from({length:5},(t,n)=>e.jsx(re,{className:`h-3.5 w-3.5 ${n<s?"fill-amber-400 text-amber-400":"text-muted-foreground/30"}`},n))})}function Is({status:s}){const t={pending:{label:"Pending Approval",variant:"secondary"},posted:{label:"Posted",variant:"default"},dismissed:{label:"Dismissed",variant:"outline"}},n=t[s??"pending"]??t.pending;return e.jsx(_,{variant:n.variant,className:"text-xs",children:n.label})}function Ps({review:s,onUpdate:t}){const{toast:n}=B(),[o,r]=N.useState(!1),[c,h]=N.useState(s.finalResponse||s.aiDraftResponse||""),a=M({mutationFn:async()=>(await T("POST",`/api/automations/reviews/${s.id}/approve`,{finalResponse:c})).json(),onSuccess:()=>{n({title:"Response posted",description:"Your response has been posted to Google."}),r(!1),t()},onError:p=>{n({title:"Failed to post",description:p.message,variant:"destructive"})}}),m=M({mutationFn:async()=>(await T("POST",`/api/automations/reviews/${s.id}/dismiss`)).json(),onSuccess:()=>{n({title:"Review dismissed"}),t()},onError:p=>{n({title:"Failed to dismiss",description:p.message,variant:"destructive"})}}),x=M({mutationFn:async()=>(await T("PUT",`/api/automations/reviews/${s.id}`,{finalResponse:c})).json(),onSuccess:()=>{n({title:"Draft saved"}),r(!1),t()},onError:p=>{n({title:"Failed to save",description:p.message,variant:"destructive"})}}),l=s.status==="pending";return e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"pt-5 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h4",{className:"text-sm font-semibold text-foreground",children:s.reviewerName||"Anonymous"}),e.jsx(Ms,{rating:s.reviewRating})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Is,{status:s.status}),s.createdAt&&e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(s.createdAt).toLocaleDateString("en-US",{month:"short",day:"numeric"})})]})]}),s.reviewText&&e.jsx("div",{className:"bg-muted/50 rounded-md p-3",children:e.jsxs("p",{className:"text-sm text-foreground leading-relaxed",children:['"',s.reviewText,'"']})}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:s.status==="posted"?"Posted Response":"AI Draft Response"})]}),o?e.jsxs("div",{className:"space-y-2",children:[e.jsx(C,{value:c,onChange:p=>h(p.target.value),rows:4,className:"text-sm"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>x.mutate(),disabled:x.isPending,children:[x.isPending?e.jsx(w,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):e.jsx(ke,{className:"h-3.5 w-3.5 mr-1.5"}),"Save Draft"]}),e.jsx(f,{size:"sm",variant:"ghost",onClick:()=>{h(s.finalResponse||s.aiDraftResponse||""),r(!1)},children:"Cancel"})]})]}):e.jsx("p",{className:"text-sm text-muted-foreground bg-muted/30 rounded-md p-3 leading-relaxed",children:s.finalResponse||s.aiDraftResponse||"No response generated."})]}),l&&!o&&e.jsxs("div",{className:"flex gap-2 pt-1",children:[e.jsxs(f,{size:"sm",onClick:()=>a.mutate(),disabled:a.isPending,children:[a.isPending?e.jsx(w,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):e.jsx(ke,{className:"h-3.5 w-3.5 mr-1.5"}),"Approve & Post"]}),e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>r(!0),children:[e.jsx(os,{className:"h-3.5 w-3.5 mr-1.5"}),"Edit"]}),e.jsxs(f,{size:"sm",variant:"ghost",onClick:()=>m.mutate(),disabled:m.isPending,children:[m.isPending?e.jsx(w,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):e.jsx(Ie,{className:"h-3.5 w-3.5 mr-1.5"}),"Dismiss"]})]})]})})}function Ds(){const{toast:s}=B(),t=ee(),[n,o]=N.useState("all"),{data:r=[],isLoading:c}=I({queryKey:["/api/automations/reviews",n],queryFn:async()=>{const l=n==="all"?"/api/automations/reviews":`/api/automations/reviews?status=${n}`,p=await fetch(l,{credentials:"include"});if(!p.ok)throw new Error("Failed to fetch reviews");return p.json()}}),h=M({mutationFn:async()=>(await T("POST","/api/automations/reviews/fetch")).json(),onSuccess:l=>
16{s({title:"Reviews fetched",description:l.message||`Found ${l.count??0} new review(s).`}),t.invalidateQueries({queryKey:["/api/automations/reviews"]})},onError:l=>{s({title:"Failed to fetch reviews",description:l.message,variant:"destructive"})}}),a=()=>{t.invalidateQueries({queryKey:["/api/automations/reviews"]})},m=[{value:"all",label:"All"},{value:"pending",label:"Pending"},{value:"posted",label:"Posted"},{value:"dismissed",label:"Dismissed"}],x=r.filter(l=>l.status==="pending").length;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"flex items-center gap-3",children:m.map(l=>e.jsxs(f,{size:"sm",variant:n===l.value?"default":"outline",onClick:()=>o(l.value),className:"text-xs",children:[l.label,l.value==="pending"&&x>0&&e.jsx(_,{variant:"secondary",className:"ml-1.5 text-xs px-1.5 py-0",children:x})]},l.value))}),e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>h.mutate(),disabled:h.isPending,children:[h.isPending?e.jsx(w,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):e.jsx(he,{className:"h-3.5 w-3.5 mr-1.5"}),"Fetch New Reviews"]})]}),c?e.jsx("div",{className:"flex items-center justify-center h-48",children:e.jsx(w,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):r.length===0?e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(re,{className:"h-10 w-10 text-muted-foreground/30 mb-3"}),e.jsx("h3",{className:"text-sm font-semibold mb-1",children:"No reviews yet"}),e.jsx("p",{className:"text-xs text-muted-foreground max-w-sm",children:n==="all"?'Click "Fetch New Reviews" to pull reviews from your Google Business Profile, or enable the Review Response agent to fetch automatically.':`No ${n} reviews found.`})]})}):e.jsx("div",{className:"space-y-3",children:r.map(l=>e.jsx(Ps,{review:l,onUpdate:a},l.id))})]})}function J({label:s,value:t,icon:n,subtitle:o}){return e.jsx(y,{className:"border-border bg-card",children:e.jsx(S,{className:"pt-5 pb-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(n,{className:"h-4 w-4 text-muted-foreground"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold text-foreground",children:t}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s}),o&&e.jsx("p",{className:"text-xs text-muted-foreground/70 mt-0.5",children:o})]})]})})})}function Ls({data:s}){if(s.length===0)return null;const t=Math.max(...s.map(o=>Math.max(o.sent,o.replies)),1),n=Math.max(4,Math.floor(100/s.length)-1);return e.jsxs(y,{className:"border-border bg-card",children:[e.jsx(X,{className:"pb-2",children:e.jsxs(Z,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(pe,{className:"h-4 w-4 text-muted-foreground"}),"Daily Activity"]})}),e.jsxs(S,{children:[e.jsx("div",{className:"flex items-end gap-1 h-32",children:s.map((o,r)=>
16e.jsxs("div",{className:"flex flex-col items-center gap-0.5 flex-1",title:`${o.date}: ${o.sent} sent, ${o.replies} replies`,children:[e.jsxs("div",{className:"flex items-end gap-px w-full justify-center",style:{height:"100px"},children:[e.jsx("div",{className:"bg-blue-400 dark:bg-blue-500 rounded-t-sm",style:{height:`${o.sent/t*100}%`,width:`${n}%`,minHeight:o.sent>0?"2px":"0",minWidth:"3px",maxWidth:"12px"}}),e.jsx("div",{className:"bg-green-400 dark:bg-green-500 rounded-t-sm",style:{height:`${o.replies/t*100}%`,width:`${n}%`,minHeight:o.replies>0?"2px":"0",minWidth:"3px",maxWidth:"12px"}})]}),(r===0||r===s.length-1||r===Math.floor(s.length/2))&&e.jsx("span",{className:"text-[9px] text-muted-foreground",children:new Date(o.date).toLocaleDateString("en-US",{month:"short",day:"numeric"})})]},o.date))}),e.jsxs("div",{className:"flex items-center gap-4 mt-3 text-xs text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-blue-400 dark:bg-blue-500"}),"Sent"]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-green-400 dark:bg-green-500"}),"Replies"]})]})]})]})}function Fs(){var m,x;const[s,t]=N.useState("month"),{data:n,isLoading:o}=I({queryKey:["/api/automations/report",{period:s}]});if(o)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(w,{className:"h-8 w-8 animate-spin text-muted-foreground"})});if(!n)return e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(pe,{className:"h-10 w-10 text-muted-foreground/40 mb-3"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No report data available. Enable agents and let them run to see performance metrics."})]})});const{totals:r,agents:c,trend:h}=n,a=c.filter(l=>l.smsSent>0||l.totalConversations>0);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Performance metrics for your SMS automation agents."}),e.jsx(Pe,{value:s,onValueChange:l=>t(l),children:e.jsxs(De,{className:"h-8",children:[e.jsx($,{value:"week",className:"text-xs px-2.5 h-7",children:"Week"}),e.jsx($,{value:"month",className:"text-xs px-2.5 h-7",children:"Month"}),e.jsx($,{value:"quarter",className:"text-xs px-2.5 h-7",children:"Quarter"}),e.jsx($,{value:"year",className:"text-xs px-2.5 h-7",children:"Year"})]})})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 xl:grid-cols-6 gap-3",children:[e.jsx(J,{label:"Messages Sent",value:r.smsSent,icon:k}),e.jsx(J,{label:"Replies Received",value:r.repliesReceived,icon:$e}),e.jsx(J,{label:"Reply Rate",value:`${r.replyRate}%`,icon:Le}),e.jsx(J,{label:"Conversations",value:r.totalConversations,icon:k}),e.jsx(J,{label:"Resolved",value:`${r.resolutionRate}%`,icon:ge,subtitle:`${r.resolved} of ${r.totalConversations}`}),e.jsx(J,{label:"SMS Bookings",value:r.appointmentsBooked,icon:Ze,subtitle:"Booked via SMS"})]}),h.length>1&&e.jsx(Ls,{data:h}),a.length>0&&e.jsxs(y,{className:"border-border bg-card",children:[e.jsx(X,{className:"pb-2",children:e.jsx(Z,{className:"text-sm font-medium",children:"Per-Agent Breakdown"})}),e.jsx(S,{children:e.jsxs(We,{children:[e.jsx(qe,{children:e.jsxs(ne,{children:[e.jsx(E,{className:"w-[160px]",children:"Agent"}),e.jsx(E,{className:"text-right",children:"Sent"}),e.jsx(E,{className:"text-right",children:"Replies"}),e.jsx(E,{className:"text-right",children:"Reply Rate"}),e.jsx(E,{className:"text-right",children:"Conversations"}),e.jsx(E,{className:"text-right",children:"Resolution"}),e.jsx(E,{className:"text-right",children:"Avg Response"})]})}),e.jsx(Ue,{children:a.map(l=>{const p=Q(l.agentType),i=p.icon;return e.jsxs(ne,{children:[e.jsx(R,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(i,{className:`h-4 w-4 ${p.color}`}),e.jsx("span",{className:"text-sm font-medium",children:p.label})]})}),e.jsx(R,{className:"text-right text-sm",children:l.smsSent}),e.jsx(R,{className:"text-right text-sm",children:l.repliesReceived}),e.jsx(R,{className:"text-right",children:e.jsxs("div",{className:"flex items-center gap-2 justify-end",children:[e.jsx(te,{value:l.replyRate,className:"w-12 h-1.5"}),e.jsxs("span",{className:"text-sm w-10 text-right",children:[l.replyRate,"%"]})]})}),e.jsxs(R,{className:"text-right text-sm",children:[l.totalConversations,l.active>0&&e.jsxs("span",{className:"text-xs text-muted-foreground ml-1",children:["(",l.active," active)"]})]}),e.jsx(R,{className:"text-right",children:e.jsxs("div",{className:"flex items-center gap-2 justify-end",children:[e.jsx(te,{value:l.resolutionRate,className:"w-12 h-1.5"}),e.jsxs("span",{className:"text-sm w-10 text-right",children:[l.resolutionRate,"%"]})]})}),e.jsx(R,{className:"text-right text-sm text-muted-foreground",children:l.avgResponseTimeHours!==null?l.avgResponseTimeHours<1?`${Math.round(l.avgResponseTimeHours*60)}m`:`${l.avgResponseTimeHours}h`:"—"})]},l.agentType)})})]})})]}),a.some(l=>l.totalConversations>0)&&e.jsxs(y,{className:"border-border bg-card",children:[e.jsx(X,{className:"pb-2",children:e.jsx(Z,{className:"text-sm font-medium",children:"Conversation Outcomes"})}),e.jsx(S,{children:e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:a.filter(l=>l.totalConversations>
160).map(l=>{const p=Q(l.agentType),i=p.icon,u=l.totalConversations;return e.jsxs("div",{className:"space-y-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(i,{className:`h-4 w-4 ${p.color}`}),e.jsx("span",{className:"text-sm font-medium",children:p.label}),e.jsxs("span",{className:"text-xs text-muted-foreground ml-auto",children:[u," total"]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsx("span",{className:"text-green-600 dark:text-green-400",children:"Resolved"}),e.jsxs("span",{children:[l.resolved," (",u>0?Math.round(l.resolved/u*100):0,"%)"]})]}),e.jsx(te,{value:u>0?l.resolved/u*100:0,className:"h-1.5"}),e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsx("span",{className:"text-amber-600 dark:text-amber-400",children:"Expired"}),e.jsxs("span",{children:[l.expired," (",u>0?Math.round(l.expired/u*100):0,"%)"]})]}),e.jsx(te,{value:u>0?l.expired/u*100:0,className:"h-1.5"}),l.active>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsx("span",{className:"text-blue-600 dark:text-blue-400",children:"Active"}),e.jsx("span",{children:l.active})]}),e.jsx(te,{value:u>0?l.active/u*100:0,className:"h-1.5"})]})]})]},l.agentType)})})})]}),c.some(l=>l.agentType==="review_response"&&(l.reviewsDrafted>0||l.reviewsPosted>0))&&e.jsxs(y,{className:"border-border bg-card",children:[e.jsx(X,{className:"pb-2",children:e.jsx(Z,{className:"text-sm font-medium",children:"Review Response Agent"})}),e.jsx(S,{children:e.jsxs("div",{className:"flex items-center gap-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xl font-bold text-foreground",children:((m=c.find(l=>l.agentType==="review_response"))==null?void 0:m.reviewsDrafted)??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Responses Drafted"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xl font-bold text-foreground",children:((x=c.find(l=>l.agentType==="review_response"))==null?void 0:x.reviewsPosted)??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Responses Posted"})]})]})})]})]})}const Se={"appointment.completed":"Appointment Completed","appointment.no_show":"Appointment No-Show","job.completed":"Job Completed","invoice.overdue":"Invoice Overdue","invoice.paid":"Invoice Paid",manual:"Manual Trigger"},Ke={FOLLOW_UP_THANK_YOU:"Thank You",FOLLOW_UP_UPSELL:"Upsell / Rebooking Offer",REVIEW_REQUEST:"Review Request",NO_SHOW_FOLLOWUP:"No-Show Follow-Up",REBOOKING_NUDGE:"Rebooking Nudge",INVOICE_COLLECTION_REMINDER:"Invoice Reminder",INVOICE_COLLECTION_FINAL:"Invoice Final Notice",ESTIMATE_FOLLOWUP:"Estimate Follow-Up",WIN_BACK:"Win-Back Message"},Os={draft:"secondary",active:"success",paused:"warning"};function He(s){return s>=1440&&s%1440===0?{value:s/1440,unit:"days"}:s>=60&&s%60===0?{value:s/60,unit:"hours"}:{value:s,unit:"minutes"}}function _e(s,t){return t==="days"?s*1440:t==="hours"?s*60:s}function $s(s){const{value:t,unit:n}=He(s);return`${t} ${n}`}function Ws({open:s,onClose:t}){const{toast:n}=B(),o=ee(),{data:r=[],isLoading:c}=I({queryKey:["/api/workflows/templates"],enabled:s}),h=M({mutationFn:async a=>(await T("POST","/api/workflows/install-template",{templateId:a})).json(),onSuccess:a=>{n({title:"Template installed",description:`"${a.name}" has been added as a draft workflow.`}),o.invalidateQueries({queryKey:["/api/workflows"]}),t()},onError:a=>{n({title:"Failed to install template",description:a.message,variant:"destructive"})}});return e.jsx(ve,{open:s,onOpenChange:a=>!a&&t(),children:e.jsxs(Ne,{className:"sm:max-w-2xl max-h-[80vh] overflow-y-auto",children:[e.jsxs(fe,{children:[e.jsxs(be,{className:"flex items-center gap-2",children:[e.jsx(de,{className:"h-5 w-5"}),"Install Workflow Template"]}),e.jsx(ye,{children:"Choose a pre-built workflow to get started quickly. You can customize it after installation."})]}),c?e.jsx("div",{className:"flex items-center justify-center h-32",children:e.jsx(w,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-3 mt-2",children:[r.map(a=>e.jsx(y,{className:"border-border",children:e.jsx(S,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h4",{className:"text-sm font-semibold text-foreground",children:a.name}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:a.description}),e.jsxs("div",{className:"flex items-center gap-2 mt-2",children:[e.jsxs(_,{variant:"outline",className:"text-xs",children:[e.jsx(je,{className:"h-3 w-3 mr-1"}),Se[a.triggerEvent]||a.triggerEvent]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.steps.length," steps"]})]})]}),e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>h.mutate(a.id),disabled:h.isPending,children:[h.isPending?e.jsx(w,{className:"h-3.5 w-3.5 animate-spin mr-1"}):e.jsx(es,{className:"h-3.5 w-3.5 mr-1"}),"Install"]})]})})},a.id)),r.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground text-center py-8",children:"No templates available."})]})]})})}function qs({step:s,index:t,onChange:n,onRemove:o}){const r=s.type==="wait"?He(s.config.delayMinutes||60):{value:60,unit:"minutes"};return e.jsxs("div",{className:"flex items-start gap-3 p-3 rounded-lg border border-border bg-muted/30",children:[e.jsx("div",{className:"flex items-center justify-center w-6 h-6 rounded-full bg-primary/10 text-primary text-xs font-bold shrink-0 mt-1",children:t+1}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs(q,{value:s.type,onValueChange:c=>{n(c==="wait"?{type:"wait",config:{delayMinutes:60}}:{type:"send_sms",config:{messageType:"FOLLOW_UP_THANK_YOU"}})},children:[e.jsx(U,{className:"w-full h-8 text-sm",children:e.jsx(Y,{})}),e.jsxs(K,{children:[e.jsx(g,{value:"wait",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(xe,{className:"h-3.5 w-3.5"})," Wait"]})}),e.jsx(g,{value:"send_sms",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(k,{className:"h-3.5 w-3.5"})," Send SMS"]})})]})]}),s.type==="wait"&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(O,{type:"number",min:1,
16className:"w-20 h-8 text-sm",value:r.value,onChange:c=>{const h=parseInt(c.target.value)||1;n({type:"wait",config:{delayMinutes:_e(h,r.unit)}})}}),e.jsxs(q,{value:r.unit,onValueChange:c=>{n({type:"wait",config:{delayMinutes:_e(r.value,c)}})},children:[e.jsx(U,{className:"w-28 h-8 text-sm",children:e.jsx(Y,{})}),e.jsxs(K,{children:[e.jsx(g,{value:"minutes",children:"Minutes"}),e.jsx(g,{value:"hours",children:"Hours"}),e.jsx(g,{value:"days",children:"Days"})]})]})]}),s.type==="send_sms"&&e.jsxs(q,{value:s.config.messageType||"FOLLOW_UP_THANK_YOU",onValueChange:c=>{n({type:"send_sms",config:{...s.config,messageType:c}})},children:[e.jsx(U,{className:"w-full h-8 text-sm",children:e.jsx(Y,{})}),e.jsx(K,{children:Object.entries(Ke).map(([c,h])=>e.jsx(g,{value:c,children:h},c))})]})]}),e.jsx(f,{variant:"ghost",size:"sm",className:"h-8 w-8 p-0 shrink-0 text-muted-foreground hover:text-destructive",onClick:o,children:e.jsx(Ie,{className:"h-4 w-4"})})]})}function Us({open:s,workflow:t,onClose:n}){var ie,se;const{toast:o}=B(),r=ee(),c=t!==null,[h,a]=N.useState((t==null?void 0:t.name)||""),[m,x]=N.useState((t==null?void 0:t.description)||""),[l,p]=N.useState((t==null?void 0:t.triggerEvent)||"appointment.completed"),[i,u]=N.useState((ie=t==null?void 0:t.steps)!=null&&ie.length?t.steps:[{type:"wait",config:{delayMinutes:120}}]),A=t==null?void 0:t.id,[P,W]=N.useState(A);A!==P&&(W(A),a((t==null?void 0:t.name)||""),x((t==null?void 0:t.description)||""),p((t==null?void 0:t.triggerEvent)||"appointment.completed"),u((se=t==null?void 0:t.steps)!=null&&se.length?t.steps:[{type:"wait",config:{delayMinutes:120}}]));const H=M({mutationFn:async()=>{const b={name:h,description:m||void 0,triggerEvent:l,steps:i};return c?(await T("PUT",`/api/workflows/${t.id}`,b)).json():(await T("POST","/api/workflows",b)).json()},onSuccess:()=>{o({title:c?"Workflow updated":"Workflow created"}),r.invalidateQueries({queryKey:["/api/workflows"]}),n()},onError:b=>{o({title:"Failed to save workflow",description:b.message,variant:"destructive"})}}),j=(b,D)=>{u(le=>le.map((ce,Ve)=>
16Ve===b?D:ce))},d=b=>{u(D=>D.filter((le,ce)=>ce!==b))},z=()=>{u(b=>[...b,{type:"wait",config:{delayMinutes:60}}])},L=h.trim().length>0&&i.length>0;return e.jsx(ve,{open:s,onOpenChange:b=>!b&&n(),children:e.jsxs(Ne,{className:"sm:max-w-xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(fe,{children:[e.jsxs(be,{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5"}),c?"Edit Workflow":"New Workflow"]}),e.jsx(ye,{children:c?"Update this workflow's trigger, steps, and settings.":"Define a trigger event and a sequence of steps to automate your follow-ups."})]}),e.jsxs("div",{className:"space-y-4 mt-2",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Name"}),e.jsx(O,{placeholder:"e.g. Post-Appointment Follow-Up",value:h,onChange:b=>a(b.target.value)})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Description"}),e.jsx(C,{placeholder:"What does this workflow do?",value:m,onChange:b=>x(b.target.value),rows:2})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Trigger Event"}),e.jsxs(q,{value:l,onValueChange:p,children:[e.jsx(U,{className:"w-full",children:e.jsx(Y,{})}),e.jsx(K,{children:Object.entries(Se).map(([b,D])=>e.jsx(g,{value:b,children:D},b))})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-sm font-medium",children:"Steps"}),e.jsx("div",{className:"space-y-2",children:i.map((b,D)=>e.jsx(qs,{step:b,index:D,onChange:le=>j(D,le),onRemove:()=>d(D)},D))}),e.jsxs(f,{variant:"outline",size:"sm",className:"w-full mt-2",onClick:z,children:[e.jsx(me,{className:"h-3.5 w-3.5 mr-1"}),"Add Step"]})]}),e.jsxs(f,{className:"w-full",onClick:()=>H.mutate(),disabled:H.isPending||!L,children:[H.isPending&&e.jsx(w,{className:"h-4 w-4 animate-spin mr-2"}),c?"Save Changes":"Create Workflow"]})]})]})})}function Ys({workflow:s,onEdit:t,onDelete:n,onActivate:o,onPause:r,isActioning:c}){const h=s.steps||[],a=h.filter(x=>x.type==="send_sms").length,m=h.filter(x=>x.type==="wait").length;return e.jsx(y,{className:"border-border bg-card",children:e.jsxs(S,{className:"pt-6 space-y-3",children:[e.jsx("div",{className:"flex items-start justify-between gap-2",children:e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground truncate",children:s.name}),e.jsx(_,{variant:Os[s.status]||"secondary",className:"capitalize shrink-0",children:s.status})]}),s.description&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 line-clamp-2",children:s.description})]})}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs(_,{variant:"outline",className:"text-xs",children:[e.jsx(je,{className:"h-3 w-3 mr-1"}),Se[s.triggerEvent]||s.triggerEvent]}),e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(k,{className:"h-3 w-3"}),a," message",a!==1?"s":""]}),e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(xe,{className:"h-3 w-3"}),m," delay",m!==1?"s":""]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground bg-muted/50 rounded-md p-2 space-y-1",children:[h.slice(0,4).map((x,l)=>e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("span",{className:"text-primary font-medium",children:[l+1,"."]}),x.type==="wait"?e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(xe,{className:"h-3 w-3"}),"Wait ",$s(x.config.delayMinutes||0)]}):e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(k,{className:"h-3 w-3"}),Ke[x.config.messageType||""]||x.config.messageType||"SMS"]})]},l)),h.length>4&&e.jsxs("div",{className:"text-muted-foreground/60",children:["+",h.length-4," more steps"]})]}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsxs(f,{variant:"outline",size:"sm",className:"h-7 text-xs gap-1",onClick:t,children:[e.jsx(ps,{className:"h-3 w-3"}),"Edit"]}),s.status==="active"?e.jsxs(f,{variant:"outline",size:"sm",className:"h-7 text-xs gap-1",onClick:r,disabled:c,
16children:[c?e.jsx(w,{className:"h-3 w-3 animate-spin"}):e.jsx(gs,{className:"h-3 w-3"}),"Pause"]}):e.jsxs(f,{variant:"outline",size:"sm",className:"h-7 text-xs gap-1",onClick:o,disabled:c,children:[c?e.jsx(w,{className:"h-3 w-3 animate-spin"}):e.jsx(js,{className:"h-3 w-3"}),"Activate"]}),e.jsx(f,{variant:"ghost",size:"sm",className:"h-7 text-xs gap-1 ml-auto text-muted-foreground hover:text-destructive",onClick:n,disabled:c,children:e.jsx(vs,{className:"h-3 w-3"})})]})]})})}function Ks(){const{toast:s}=B(),t=ee(),[n,o]=N.useState(!1),[r,c]=N.useState(!1),[h,a]=N.useState(null),[m,x]=N.useState(null),{data:l=[],isLoading:p}=I({queryKey:["/api/workflows"]}),i=M({mutationFn:async j=>(x(j),(await T("POST",`/api/workflows/${j}/activate`)).json()),onSuccess:()=>{s({title:"Workflow activated"}),t.invalidateQueries({queryKey:["/api/workflows"]}),x(null)},onError:j=>{s({title:"Failed to activate",description:j.message,variant:"destructive"}),x(null)}}),u=M({mutationFn:async j=>(x(j),(await T("POST",`/api/workflows/${j}/pause`)).json()),onSuccess:()=>{s({title:"Workflow paused"}),t.invalidateQueries({queryKey:["/api/workflows"]}),x(null)},onError:j=>{s({title:"Failed to pause",description:j.message,variant:"destructive"}),x(null)}}),A=M({mutationFn:async j=>(x(j),(await T("DELETE",`/api/workflows/${j}`)).json()),onSuccess:()=>{s({title:"Workflow deleted"}),t.invalidateQueries({queryKey:["/api/workflows"]}),x(null)},onError:j=>{s({title:"Failed to delete",description:j.message,variant:"destructive"}),x(null)}}),P=j=>{a(j),c(!0)},W=()=>{a(null),c(!0)},H=()=>{c(!1),a(null)};return p?e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(w,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:"Workflows"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Multi-step automation sequences triggered by events in your business."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>o(!0),children:[e.jsx(de,{className:"h-4 w-4 mr-1.5"}),"Install Template"]}),e.jsxs(f,{size:"sm",onClick:W,children:[e.jsx(me,{className:"h-4 w-4 mr-1.5"}),"New Workflow"]})]})]}),l.length===0?e.jsx(y,{className:"border-dashed",children:e.jsx(S,{className:"py-12",children:e.jsxs("div",{className:"text-center space-y-3",children:[e.jsx(we,{className:"h-10 w-10 mx-auto text-muted-foreground/40"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"No workflows yet"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Create a custom workflow or install a template to automate your follow-ups."})]}),e.jsxs("div",{className:"flex items-center justify-center gap-2",children:[e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>o(!0),children:[e.jsx(de,{className:"h-4 w-4 mr-1.5"}),"Install Template"]}),e.jsxs(f,{size:"sm",onClick:W,children:[e.jsx(me,{className:"h-4 w-4 mr-1.5"}),"New Workflow"]})]})]})})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:l.map(j=>e.jsx(Ys,{workflow:j,onEdit:()=>P(j),onDelete:()=>A.mutate(j.id),onActivate:()=>i.mutate(j.id),onPause:()=>u.mutate(j.id),isActioning:m===j.id},j.id))}),e.jsx(Ws,{open:n,onClose:()=>o(!1)}),e.jsx(Us,{open:r,workflow:h,onClose:H})]})}function oe(s){const t=s.replace(/\D/g,"");return t.length===11&&t[0]==="1"?`(${t.slice(1,4)}) ${t.slice(4,7)}-${t.slice(7)}`:t.length===10?`(${t.slice(0,3)}) ${t.slice(3,6)}-${t.slice(6)}`:s}function Ae(s){if(s.startsWith("drip:")){const t=s.split(":"),n=t[1]||"",o=t[2]||"";return{"onboarding:day1":"Onboarding — Day 1","onboarding:day3":"Onboarding — Day 3","onboarding:day7":"Onboarding — Day 7","trial:expired":"Trial Expired","trial:winback3":"Trial Win-back","winback:day7":"Win-back — Day 7","winback:day30":"Win-back — Day 30"}[`${n}:${o}`]||`Drip: ${n} ${o}`}return s.startsWith("agent_")?{agent_follow_up:"Follow-Up",agent_no_show:"No-S
16how Recovery",agent_rebooking:"Rebooking",agent_estimate_follow_up:"Estimate Follow-Up",agent_invoice_collection:"Invoice Collection"}[s]||s.replace("agent_","").replace(/_/g," ").replace(/\b\w/g,n=>n.toUpperCase()):s.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase())}function ae(s){return s.startsWith("agent_")}function Ee(s){return s.includes("appointment")||s.includes("reminder")||s.includes("booking")}function Hs(s){return new Date(s).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}function zs({businessId:s}){const[t,n]=N.useState("all"),[o,r]=N.useState("all"),[c,h]=N.useState(50),[a,m]=N.useState(new Set),{data:x=[],isLoading:l,refetch:p,isFetching:i}=I({queryKey:["/api/notification-log",c],queryFn:async()=>(await T("GET",`/api/notification-log?limit=${c}`)).json(),enabled:!!s});let u=x;t!=="all"&&(u=u.filter(d=>d.channel===t)),o==="agents"?u=u.filter(d=>ae(d.type)):o==="appointments"?u=u.filter(d=>Ee(d.type)):o==="other"&&(u=u.filter(d=>!ae(d.type)&&!Ee(d.type)));const A=x.filter(d=>d.channel==="sms").length,P=x.filter(d=>d.channel==="email").length,W=x.filter(d=>d.status==="failed").length,H=x.filter(d=>ae(d.type)).length,j=d=>{m(z=>{const L=new Set(z);return L.has(d)?L.delete(d):L.add(d),L})};return e.jsxs(y,{children:[e.jsxs(X,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(Z,{className:"flex items-center gap-2",children:[e.jsx(k,{className:"h-5 w-5"}),"Sent Messages"]}),e.jsx(ss,{children:"Every SMS and email sent to your customers — appointment reminders, confirmations, and AI agent messages"})]}),e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>p(),disabled:i,children:[e.jsx(he,{className:`h-4 w-4 mr-1 ${i?"animate-spin":""}`}),"Refresh"]})]}),e.jsxs("div",{className:"flex gap-3 pt-2 flex-wrap",children:[e.jsxs(_,{variant:"secondary",className:"gap-1",children:[e.jsx(k,{className:"h-3 w-3"}),A," SMS"]}),P>0&&e.jsxs(_,{variant:"secondary",className:"gap-1",children:[e.jsx(Te,{className:"h-3 w-3"}),P," emails"]}),H>0&&e.jsxs(_,{variant:"secondary",className:"gap-1",children:[e.jsx(Ce,{className:"h-3 w-3"}),H," from agents"]}),W>0&&e.jsxs(_,{variant:"destructive",className:"gap-1",children:[e.jsx(Me,{className:"h-3 w-3"}),W," failed"]})]})]}),e.jsxs(S,{children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4 flex-wrap",children:[e.jsxs(q,{value:t,onValueChange:n,children:[e.jsx(U,{className:"w-[140px]",children:e.jsx(Y,{placeholder:"Channel"})}),e.jsxs(K,{children:[e.jsx(g,{value:"all",children:"All channels"}),e.jsx(g,{value:"sms",children:"SMS only"}),e.jsx(g,{value:"email",children:"Email only"})]})]}),e.jsxs(q,{value:o,onValueChange:r,children:[e.jsx(U,{className:"w-[160px]",children:e.jsx(Y,{placeholder:"Type"})}),e.jsxs(K,{children:[e.jsx(g,{value:"all",children:"All types"}),e.jsx(g,{value:"appointments",children:"Appointments"}),e.jsx(g,{value:"agents",children:"AI Agents"}),e.jsx(g,{value:"other",children:"Other"})]})]}),e.jsxs(q,{value:String(c),onValueChange:d=>h(parseInt(d)),children:[e.jsx(U,{className:"w-[120px]",children:e.jsx(Y,{placeholder:"Show"})}),e.jsxs(K,{children:[e.jsx(g,{value:"25",children:"Last 25"}),e.jsx(g,{value:"50",children:"Last 50"}),e.jsx(g,{value:"100",children:"Last 100"}),e.jsx(g,{value:"200",children:"Last 200"})]})]})]}),l?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading sent messages..."}):u.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No messages sent yet. SMS and emails to your customers will appear here."}):e.jsx("div",{className:"rounded-md border overflow-x-auto",children:e.jsxs(We,{children:[e.jsx(qe,{children:e.jsxs(ne,{children:[e.jsx(E,{className:"w-[40px]"}),e.jsx(E,{children:"Customer"}),e.jsx(E,{children:"Type"}),e.jsx(E,{children:"Message"}),e.jsx(E,{className:"w-[70px]",children:"Status"}),e.jsx(E,{className:"w-[130px]",children:"Sent"})]})}),e.jsx(Ue,{children:u.map(d=>{const z=a.has(d.id),L=!!(d.message||d.subject),ie=d.subject||(d.message?d.message.slice(0,80)+(d.message.length>80?"...":""):"—"),se=d.customerPhone||d.recipient;return e.jsxs(N.Fragment,{children:[e.jsxs(ne,{className:L?"cursor-pointer hover:bg-muted/50":"",onClick:()=>L&&j(d.id),children:[e.jsx(R,{children:d.channel==="email"?e.jsx(Te,{className:"h-4 w-4 text-blue-500"}):ae(d.type)?e.jsxs("div",{className:"relative",children:[e.jsx(k,{className:"h-4 w-4 text-purple-500"}),e.jsx(Ce,{className:"h-2.5 w-2.5 text-purple-500 absolute -top-1 -right-1"})]}):e.jsx(k,{className:"h-4 w-4 text-green-500"})}),e.jsx(R,{className:"text-sm",children:e.jsx("div",{className:"flex flex-col",children:d.customerName?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"font-medium text-foreground",children:d.customerName}),e.jsx("span",{className:"text-xs text-muted-foreground",children:oe(se)})]}):e.jsx("span",{className:"text-muted-foreground",children:oe(se)})})}),e.jsx(R,{className:"text-sm",children:e.jsx(_,{variant:ae(d.type)?"secondary":"outline",className:"text-xs",children:Ae(d.type)})}),e.jsx(R,{className:"text-sm max-w-[300px]",children:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:z?"":"truncate",children:z?"":ie}),L&&(z?e.jsx(ts,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}):e.jsx(as,{className:"h-3.5 w-3.5 text-muted-foreground flex-shrink-0"}))]})}),e.jsx(R,{children:d.status==="sent"||d.status==="delivered"?e.jsx(ge,{className:"h-4 w-4 text-green-500"}):e.jsx(Ns,{className:"h-4 w-4 text-destructive"})}),e.jsx(R,{className:"text-xs text-muted-foreground whitespace-nowrap",children:d.sentAt?Hs(d.sentAt):"—"})]}),z&&L&&e.jsx(ne,{children:e.jsxs(R,{colSpan:6,className:"bg-muted/30 px-6 py-3",children:[d.subject&&e.jsxs("div",{className:"text-xs font-medium text-muted-foreground mb-1",children:["Subject: ",d.subject]}),e.jsx("div",{className:"text-sm whitespace-pre-wrap break-words leading-relaxed",children:d.message||"No message body recorded."})]})},`${d.id}-expanded`)]},d.id)})})]})}),u.some(d=>d.status==="failed"&&d.error)&&e.jsxs("div",{className:"mt-4 space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-destructive",children:"Failed message details:"}),u.filter(d=>d.status==="failed"&&d.error).slice(0,5).map(d=>e.jsxs("div",{className:"text-xs bg-destructive/5 border border-destructive/20 rounded p-2",children:[e.jsx("span",{className:"font-medium",children:Ae(d.type)})," to ",d.customerName||oe(d.recipient),":"," ",e.jsx("span",{className:"text-destructive",children:d.error})]},d.id))]})]})]})}const ze=["follow_up","no_show","estimate_follow_up","invoice_collection","rebooking","maintenance_reminder","review_response"],Be=new Set(["maintenance_reminder"]),Bs={follow_up:"You'll receive a thank-you SMS. This is a one-way message — no reply tracking.",no_show:"You'll receive a no-show check-in SMS. Reply YES to test the full conversational booking flow.",estimate_follow_up:"You'll receive an estimate follow-up SMS. This is a one-way message — no reply tracking.",invoice_collection:"You'll receive an invoice payment reminder SMS. This is a one-way message — no reply tracking.",rebooking:"You'll receive a rebooking prompt. Reply YES to test the full conversational booking flow.",maintenance_reminder:"You'll receive a maintenance-due reminder SMS. Reply YES to test the full conversational booking flow.",review_response:"We'll generate a sample AI response to a mock 4-star review. No SMS will be sent."};function Vs({open:s,agentType:t,businessPhone:n,onClose:o}){const[r,c]=N.useState(n||""),[h,a]=N.useState(null),{toast:m}=B(),x=M({mutationFn:async()=>(await T("POST",`/api/automations/test/${t}`,{phone:r})).json(),onSuccess:u=>{a({message:u.message,aiDraft:u.aiDraft})},onError:u=>{m({title:"Test failed",description:u.message,variant:"destructive"})}}),l=t?Q(t):null,p=t==="review_response",i=()=>{a(null),c(n||""),o()};return e.jsx(ve,{open:s,onOpenChange:u=>!u&&i(),children:e.jsxs(Ne,{className:"sm:max-w-md",children:[e.jsxs(fe,{children:[e.jsxs(be,{className:"flex items-center gap-2",children:[e.jsx(Ye,{className:"h-4 w-4"}),"Test ",l==null?void 0:l.label," Agent"]}),e.jsx(ye,{children:t?Bs[t]:""})]}),h?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-green-600 dark:text-green-400",children:[e.jsx(ge,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm font-medium",children:p?"AI response generated":"Test SMS sent"})]}),e.jsxs("div",{className:"p-3 rounded-lg bg-muted text-sm",children:[e.jsx("p",{className:"font-medium text-xs text-muted-foreground mb-1",children:p?"Mock Review:":"Message Sent:"}),e.jsx("p",{children:h.message})]}),h.aiDraft&&e.jsxs("div",{className:"p-3 rounded-lg bg-muted text-sm",children:[e.jsx("p",{className:"font-medium text-xs text-muted-foreground mb-1",children:"AI Draft Response:"}),e.jsx("p",{children:h.aiDraft})]}),!p&&(t==="no_show"||t==="rebooking")&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Reply YES to test the conversational booking flow. The test conversation expires in 1 hour. No real appointments will be created."}),e.jsx(f,{variant:"outline",className:"w-full",onClick:i,children:"Close"})]}):e.jsxs("div",{className:"space-y-4",children:[!p&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:"Phone Number"}),e.jsx(O,{placeholder:"+1 (555) 123-4567",value:r,onChange:u=>c(u.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter your phone number to receive the test SMS."})]}),e.jsxs(f,{className:"w-full",onClick:()=>x.mutate(),disabled:x.isPending||!p&&(!r||r.replace(/\D/g,"").length<10),children:[x.isPending?e.jsx(w,{className:"h-4 w-4 animate-spin mr-2"}):null,p?"Generate Test Response":"Send Test SMS"]})]})]})})}function Gs(){const{data:s}=I({queryKey:["/api/automations/report",{period:"month"}]});if(!(s!=null&&s.totals)||s.totals.smsSent===0)return null;const{smsSent:t,repliesReceived:n,resolved:o,appointmentsBooked:r}=s.totals,c=r*85;return e.jsx(y,{className:"border-primary/20 bg-primary/5",children:e.jsx(S,{className:"py-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-primary/10",children:e.jsx(je,{className:"h-5 w-5 text-primary"})}),e.jsx("div",{className:"flex-1",children:e.jsxs("p",{className:"text-sm font-medium text-foreground",children:["Your agents sent ",e.jsx("span",{className:"font-bold",children:t})," messages this month",n>0&&e.jsxs(e.Fragment,{children:[", got ",e.jsx("span",{className:"font-bold",children:n})," replies"]}),o>0&&e.jsxs(e.Fragment,{children:[", and resolved ",e.jsx("span",{className:"font-bold",children:o})," conversations"]}),c>0&&e.jsxs(e.Fragment,{children:[" — recovering an estimated ",e.jsxs("span",{className:"font-bold text-green-600 dark:text-green-400",children:["$",c.toLocaleStr
16ing()]})," in revenue"]}),"."]})}),c>0&&e.jsxs("div",{className:"hidden sm:flex items-center gap-1 text-green-600 dark:text-green-400",children:[e.jsx(Le,{className:"h-4 w-4"}),e.jsxs("span",{className:"text-sm font-bold",children:["$",c.toLocaleString()]})]})]})})})}function Qs({isOwner:s,onTest:t}){const{toast:n}=B(),o=ee(),[r,c]=N.useState(null),{data:h=[],isLoading:a}=I({queryKey:["/api/automations/dashboard"]}),{data:m}=I({queryKey:["/api/business"]}),x=Fe(m==null?void 0:m.industry),l=M({mutationFn:async({agentType:i,enabled:u})=>(c(i),(await T("PUT",`/api/automations/settings/${i}`,{enabled:u})).json()),onSuccess:(i,{agentType:u,enabled:A})=>{const P=u.replace(/_/g," ").replace(/\b\w/g,W=>W.toUpperCase());n({title:A?`${P} enabled`:`${P} disabled`,description:A?"This agent will now run automatically.":"This agent has been paused."}),o.invalidateQueries({queryKey:["/api/automations/dashboard"]}),o.invalidateQueries({queryKey:["/api/automations/settings"]}),c(null)},onError:i=>{n({title:"Failed to toggle agent",description:i.message,variant:"destructive"}),c(null)}});if(a)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(w,{className:"h-8 w-8 animate-spin text-muted-foreground"})});const p=ze.filter(i=>!Be.has(i)||x).map(i=>h.find(u=>u.agentType===i)??{agentType:i,enabled:!1,smsSentCount:0,repliesReceivedCount:0,lastActivityAt:null});return e.jsxs("div",{className:"space-y-4",children:[e.jsx(rs,{tipId:"agents-intro",title:"Your AI Agents Work While You Sleep",description:"These SMS agents automatically follow up after completed jobs, recover no-shows, send rebooking reminders to inactive customers, and request reviews. They're all enabled by default and respect customer opt-out preferences."}),s&&e.jsx(Gs,{}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:p.map(i=>e.jsx(ys,{agentType:i.agentType,enabled:i.enabled,smsSentCount:i.smsSentCount,repliesReceivedCount:i.repliesReceivedCount,lastActivityAt:i.lastActivityAt,isToggling:r===i.agentType,onToggle:u=>l.mutate({agentType:i.agentType,enabled:u}),isOwner:s,onTest:t},i.agentType))})]})}function Js(){const{data:s=[],isLoading:t}=I({queryKey:["/api/automations/settings"]}),{data:n}=I({queryKey:["/api/business"]}),o=Fe(n==null?void 0:n.industry);if(t)return e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(w,{className:"h-8 w-8 animate-spin text-muted-foreground"})});const r=ze.filter(c=>!Be.has(c)||o).map(c=>s.find(h=>h.agentType===c)??{agentType:c,enabled:!1,config:null,businessId:0});return e.jsx("div",{className:"space-y-6",children:r.map(c=>e.jsx(Ts,{agentType:c.agentType,currentConfig:c.config,enabled:c.enabled},c.agentType))})}function Xs({businessId:s}){const{data:t=[],isLoading:n}=I({queryKey:["/api/automations/conversations"]}),o=t.filter(c=>c.state==="awaiting_reply"||c.state==="replied"),r=t.filter(c=>c.state!=="awaiting_reply"&&c.state!=="replied");return e.jsxs("div",{className:"space-y-6",children:[o.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("h3",{className:"text-sm font-medium text-foreground",children:"Active Conversations"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Ongoing SMS conversations waiting for a customer reply."}),e.jsx(Re,{conversations:o,isLoading:n})]}),s&&e.jsx(zs,{businessId:s}),r.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("h3",{className:"text-sm font-medium text-foreground",children:"Past Conversations"}),e.jsx(Re,{conversations:r,isLoading:n})]})]})}function wt(){const{user:s}=ns(),t=(s==null?void 0:s.role)!=="staff",[n,o]=N.useState(null),{data:r}=I({queryKey:["/api/business"],enabled:!!(s!=null&&s.businessId)});return e.jsxs(is,{title:"AI Agents",children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold text-foreground",children:"AI Agents"}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Your AI-powered agents work around the clock — following up, recovering no-shows, closing estimates, rebooking inactive customers, and responding to reviews."})]}),e.jsxs(Pe,{defaultValue:"overview",className:"w-full",children:[e.jsxs(De,{className:`grid w-full ${t?"grid-cols-7":"grid-cols-5"}`,children:[e.jsxs($,{value:"overview",className:"flex items-center gap-1.5",children:[e.jsx(fs,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Overview"})]}),e.jsxs($,{value:"activity",className:"flex items-center gap-1.5",children:[e.jsx(Oe,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Activity"})]}),e.jsxs($,{value:"conversations",className:"flex items-center gap-1.5",children:[e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Messages"})]}),e.jsxs($,{value:"reviews",className:"flex items-center gap-1.5",children:[e.jsx(re,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Reviews"})]}),t&&e.jsxs($,{value:"workflows",className:"flex items-center gap-1.5",children:[e.jsx(we,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Workflows"})]}),t&&e.jsxs($,{value:"report",className:"flex items-center gap-1.5",children:[e.jsx(pe,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Report"})]}),e.jsxs($,{value:"settings",className:"flex items-center gap-1.5",children:[e.jsx(ls,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:"Settings"})]})]}),e.jsx(V,{value:"overview",children:e.jsx(Qs,{isOwner:t,onTest:o})}),e.jsx(V,{value:"activity",children:e.jsx(As,{})}),e.jsx(V,{value:"conversations",children:e.jsx(Xs,{businessId:(s==null?void 0:s.businessId)??void 0})}),e.jsx(V,{value:"reviews",children:e.jsx(Ds,{})}),t&&e.jsx(V,{value:"workflows",children:e.jsx(Ks,{})}),t&&e.jsx(V,{value:"report",children:e.jsx(Fs,{})}),e.jsx(V,{value:"settings",children:e.jsx(Js,{})})]})]}),e.jsx(Vs,{open:n!==null,agentType:n,businessPhone:(r==null?void 0:r.phone)||"",onClose:()=>o(null)})]})}export{wt 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.