PageSourceSearch

https://harbor-os.com/assets/AdminEmailDripPage-Cj5a_4Q7.js

js harbor-os.com collected 2026-09-24 14:44:50 UTC 8,158 bytes, 1 lines download raw bytes

1import{bx as H,r as j,g as V,i as m,j as e,M as J,c6 as W,_ as Q,bC as X,aT as Y,aK as _}from"./vendor-BeA4siBz.js";import{u as Z,B as i,C as ee,d as se,g as K,D as P,h as k,j as T,k as q,m as I,I as r,f as d}from"./index-C2NQ_9nj.js";import{T as ae}from"./textarea-BzoSp81z.js";import{S as ne,a as te,b as ie,c as le,d as re}from"./select-26Ep3yy3.js";import{S as ce}from"./switch-D4mtp9yh.js";const de=["signup","purchase","intake_submitted","booking_completed","no_activity"];function he(){const{toast:o}=Z(),g=H(),[O,v]=j.useState(!1),[A,C]=j.useState(null),[u,y]=j.useState(null),[x,N]=j.useState({email:"",userId:""}),f={name:"",description:"",trigger:"signup",steps:[{delayDays:0,subject:"",body:"",cta:"",ctaUrl:""}]},[c,p]=j.useState(f),{data:M=[],isLoading:R}=V({queryKey:["/api/admin/email-drip/sequences"],queryFn:()=>d("GET","/api/admin/email-drip/sequences").then(s=>s.json())}),b=m({mutationFn:s=>d("POST","/api/admin/email-drip/sequences",s).then(a=>a.json()),onSuccess:()=>{g.invalidateQueries({queryKey:["/api/admin/email-drip/sequences"]}),v(!1),p(f),o({title:"Sequence created"})}}),w=m({mutationFn:({id:s,data:a})=>d("PATCH",`/api/admin/email-drip/sequences/${s}`,a).then(n=>n.json()),onSuccess:()=>{g.invalidateQueries({queryKey:["/api/admin/email-drip/sequences"]}),C(null),o({title:"Updated"})}}),$=m({mutationFn:s=>d("DELETE",`/api/admin/email-drip/sequences/${s}`).then(a=>a.json()),onSuccess:()=>{g.invalidateQueries({queryKey:["/api/admin/email-drip/sequences"]}),o({title:"Deleted"})}}),L=m({mutationFn:({id:s,isActive:a})=>d("PATCH",`/api/admin/email-drip/sequences/${s}`,{isActive:a}).then(n=>n.json()),onSuccess:()=>g.invalidateQueries({queryKey:["/api/admin/email-drip/sequences"]})}),E=m({mutationFn:s=>d("POST","/api/admin/email-drip/enroll",s).then(a=>a.json()),onSuccess:()=>{o({title:"Enrolled!"}),y(null),N({email:"",userId:""})},onError:()=>o({title:"Error",description:"May already be enrolled.",variant:"destructive"})}),D=m({mutationFn:()=>d("POST","/api/admin/email-drip/process").then(s=>s.json()),onSuccess:s=>o({title:"Processed",description:`${s.sent} emails sent out of ${s.processed} due.`})}),B=(s,a)=>a(n=>({...n,steps:[...n.steps,{delayDays:1,subject:"",body:"",cta:"",ctaUrl:""}]})),F=(s,a,n)=>n(t=>({...t,steps:t.steps.filter((l,S)=>S!==s)})),h=(s,a,n,t,l)=>l(S=>({...S,steps:S.steps.map((z,G)=>G===s?{...z,[a]:n}:z)})),U=({f:s,setF:a})=>e.jsxs("div",{className:"space-y-4 max-h-[60vh] overflow-y-auto pr-1",children:[e.jsx(r,{placeholder:"Sequence name *",value:s.name,onChange:n=>a(t=>({...t,name:n.target.value}))}),e.jsx(r,{placeholder:"Description",value:s.description,onChange:n=>a(t=>({...t,description:n.target.value}))}),e.jsxs(ne,{value:s.trigger,onValueChange:n=>a(t=>({...t,trigger:n})),children:[e.jsx(te,{children:e.jsx(ie,{placeholder:"Trigger"})}),e.jsx(le,{children:de.map(n=>e.jsx(re,{value:n,children:n.replace(/_/g," ")},n))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"font-medium text-sm",children:["Email Steps (",s.steps.length,")"]}),e.jsxs(i,{size:"sm",variant:"outline",onClick:()=>B(s,a),children:[e.jsx(Q,{className:"h-3 w-3 mr-1"})," Step"]})]}),s.steps.map((n,t)=>e.jsxs("div",{className:"border rounded-lg p-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs font-medium text-muted-foreground",children:["Step ",t+1]}),e.jsx(i,{variant:"ghost",size:"sm",onClick:()=>F(t,s,a),children:e.jsx(_,{className:"h-3 w-3 text-red-400"})})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{children:"Send after"}),e.jsx(r,{type:"number",min:0,value:n.delayDays,onChange:l=>h(t,"delayDays",parseInt(l.target.value)||0,s,a),className:"w-16"}),e.jsxs("span",{children:["day",n.delayDays!==1?"s":""]})]}),e.jsx(r,{placeholder:"Subject *",value:n.subject,onChange:l=>h(t,"subject",l.target.value,s,a)}),e.jsx(ae,{placeholder:"Email body *",value:n.body,onChange:l=>h(t,"body",l.target.value,s,a),rows:3}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(r,{placeholder:"CTA label (optional)",value:n.cta??"",onChange:l=>h(t,"cta",l.target.value,s,a),className:"flex-1"}),e.jsx(r,{placeholder:"CTA URL (optional)",value:n.ctaUrl??"",onChange:l=>h(t,"ctaUrl",l.target.value,s,a),className:"flex-1"})]})]},t))]})]});return e.jsxs("div",{className:"max-w-4xl mx-auto px-4 py-8",children:[e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(J,{className:"h-6 w-6 text-blue-500"})," Email Drip Campaigns"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(i,{size:"sm",variant:"outline",onClick:()=>D.mutate(),disabled:D.isPending,children:[e.jsx(W,{className:"h-4 w-4 mr-1"}),D.isPending?"Processing...":"Process Queue"]}),e.jsxs(i,{size:"sm",onClick:()=>{p(f),v(!0)},children:[e.jsx(Q,{className:"h-4 w-4 mr-1"})," New Sequence"]})]})]}),R?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading..."}):e.jsxs("div",{className:"space-y-3",children:[M.map(s=>{var a;return e.jsx(ee,{children:e.jsxs(se,{className:"flex items-start justify-between pt-4 gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-medium",children:s.name}),e.jsx(K,{variant:"outline",className:"text-xs",children:s.trigger.replace(/_/g," ")}),e.jsx(K,{variant:s.isActive?"secondary":"outline",className:"text-xs",children:s.isActive?"Active":"Paused"}),e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(X,{className:"h-3 w-3"}),s.activeCount??0," active"]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[((a=s.steps)==null?void 0:a.length)??0," steps"]})]}),s.description&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:s.description})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ce,{checked:s.isActive,onCheckedChange:n=>L.mutate({id:s.id,isActive:n})}),e.jsxs(i,{size:"sm",variant:"outline",onClick:()=>{y(s)},children:[e.jsx(Y,{className:"h-3.5 w-3.5 mr-1"})," Enroll"]}),e.jsx(i,{size:"sm",variant:"outline",onClick:()=>{C(s),p({...s,steps:s.steps??[]})},children:"Edit"}),e.jsx(i,{size:"sm",variant:"ghost",onClick:()=>$.mutate(s.id),children:e.jsx(_,{className:"h-4 w-4 text-red-400"})})]})]})},s.id)}),M.length===0&&e.jsx("p",{className:"text-center text-muted-foreground py-8",children:"No sequences yet. Create your first drip campaign."})]}),e.jsx(P,{open:O,onOpenChange:v,children:e.jsxs(k,{className:"max-w-xl",children:[e.jsx(T,{children:e.jsx(q,{children:"Create Drip Sequence"})}),e.jsx(U,{f:c,setF:p}),e.jsxs(I,{children:[e.jsx(i,{variant:"outline",onClick:()=>v(!1),children:"Cancel"}),e.jsx(i,{disabled:!c.name||!c.steps.length||b.isPending,onClick:()=>b.mutate(c),children:b.isPending?"Creating...":"Create"})]})]})}),e.jsx(P,{open:!!A,onOpenChange:()=>C(null),children:e.jsxs(k,{className:"max-w-xl",children:[e.jsx(T,{children:e.jsx(q,{children:"Edit Sequence"})}),e.jsx(U,{f:c,setF:p}),e.jsxs(I,{children:[e.jsx(i,{variant:"outline",onClick:()=>C(null),children:"Cancel"}),e.jsx(i,{disabled:!c.name||w.isPending,onClick:()=>w.mutate({id:A.id,data:c}),children:w.isPending?"Saving...":"Save Changes"})]})]})}),e.jsx(P,{open:!!u,onOpenChange:()=>y(null),children:e.jsxs(k,{children:[e.jsx(T,{children:e.jsxs(q,{children:['Enroll in "',u==null?void 0:u.name,'"']})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(r,{placeholder:"Email address *",value:x.email,onChange:s=>N(a=>({...a,email:s.target.value}))}),e.jsx(r,{placeholder:"User ID (optional)",value:x.userId,onChange:s=>N(a=>({...a,userId:s.target.value}))})]}),e.jsxs(I,{children:[e.jsx(i,{variant:"outline",onClick:()=>y(null),children:"Cancel"}),e.jsx(i,{disabled:!x.email||E.isPending,onClick:()=>E.mutate({sequenceId:u.id,email:x.email,userId:x.userId||void 0}),children:E.isPending?"Enrolling...":"Enroll"})]})]})})]})}export{he 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.