PageSourceSearch

https://brandingbybooks.com/assets/publicist-CAX6RveZ.js

js brandingbybooks.com collected 2026-10-09 23:24:03 UTC 29,331 bytes, 1 lines download raw bytes

1import{d5 as _,fg as $,fe as V,fq as J,dQ as e,aU as j,aY as G,aS as W,n as f,fr as L,eR as X,ee as T,f7 as b,dn as N,cJ as g,_ as Z,a4 as ee,$ as te,a2 as ae,a3 as se,aH as w,bx as M,bA as D,bB as R,by as Q,bz as K,ap as v,b$ as ne,a1 as ie,t as B,u as U,B as q,eb as C,w as I,x as Y,v as re,an as de,aT as ce,cd as le,bQ as oe,y as ue}from"./index-DBQvtwUN.js";import{T as me}from"./tier-locked-overlay-IiX0AzCS.js";import{u as pe}from"./use-seo-BHUHuTsG.js";import{S as xe}from"./separator-BQbJCznf.js";import{T as he,b as ge,c as A,a as O}from"./tabs-B_ECh8PR.js";import{C as je}from"./chart-column-DSuR5oX3.js";import{A as ye}from"./arrow-left-M-_K-oFY.js";import{P as z}from"./plus-zurqte8E.js";import"./agent-roster-DhPR0FrB.js";import"./referral-7yWqT_Qi.js";import"./use-inapp-front-door-DBQJa9NZ.js";import"./arrow-up-right-Df3_np5E.js";const ve=_("MessageSquareReply",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}],["path",{d:"m10 7-3 3 3 3",key:"1eugdv"}],["path",{d:"M17 13v-1a2 2 0 0 0-2-2H7",key:"ernfh3"}]]);const fe=_("Sprout",[["path",{d:"M7 20h10",key:"e6iznv"}],["path",{d:"M10 20c5.5-2.5.8-6.4 3-10",key:"161w41"}],["path",{d:"M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z",key:"9gtqwd"}],["path",{d:"M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z",key:"bkxnd2"}]]);function be(){const{data:t,isLoading:c}=$({queryKey:["/api/feature-flags/author-outreach"],queryFn:async()=>(await fetch("/api/feature-flags/author-outreach",{credentials:"include"})).json(),staleTime:3e5});return{enabled:t?.enabled===!0,sending:t?.sending===!0,sequences:t?.sequences===!0,tracking:t?.tracking===!0,isLoading:c}}const Ne=["podcast","blog","youtube","library","bookstore"],we=["new","queued","contacted","replied","booked","not_interested"],Se=["interested","not_interested","booked","needs_follow_up"],$e={new:"bg-muted text-muted-foreground border-border",queued:"bg-blue-100 text-blue-800 border-blue-200",contacted:"bg-amber-100 text-amber-800 border-amber-200",replied:"bg-violet-100 text-violet-800 border-violet-200",booked:"bg-green-100 text-green-800 border-green-200",not_interested:"bg-red-100 text-red-800 border-red-200"},H={podcast:"Podcast",blog:"Blog",youtube:"YouTube",library:"Library",bookstore:"Bookstore"};function S(t){return t.replace(/_/g," ").replace(/\b\w/g,c=>c.toUpperCase())}function Te(t){if(!t)return"";const c=new Date(t);return isNaN(c.getTime())?"":c.toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}function F(t){return`${Math.round((t??0)*100)}%`}function Ce({projectId:t,sequencesEnabled:c}){const{toast:n}=L(),{isTeam:d}=X(),[p,r]=T.useState(!1),[o,x]=T.useState({type:"podcast",name:"",contactName:"",contactEmail:"",contactUrl:"",niche:"",location:"",notes:""}),m=$({queryKey:["/api/projects",t,"outreach-targets"],queryFn:async()=>(await g("GET",`/api/projects/${t}/outreach-targets`)).json()}),h=()=>C.invalidateQueries({queryKey:["/api/projects",t,"outreach-targets"]}),y=b({mutationFn:async()=>{const a={type:o.type,name:o.name.trim()};for(const i of["contactName","contactEmail","contactUrl","niche","location","notes"]){const s=o[i]?.trim();s&&(a[i]=s)}return(await g("POST",`/api/projects/${t}/outreach-targets`,a)).json()},onSuccess:()=>{h(),r(!1),x({type:"podcast",name:"",contactName:"",contactEmail:"",contactUrl:"",niche:"",location:"",notes:""}),n({title:"Target added"})},onError:a=>n({title:"Could not add target",description:N(a)||"Please try again.",variant:"destructive"})}),l=b({mutationFn:async()=>(await g("POST",`/api/projects/${t}/outreach-targets/seed`)).json(),onSuccess:()=>{h(),n({title:"Starter targets created",description:"One niche-tagged research starter per channel."})},onError:a=>n({title:"Could not seed targets",description:N(a)||"Please try again.",variant:"destructive"})}),u=b({mutationFn:async({id:a,status:i})=>(await g("POST",`/api/outreach-targets/${a}/status`,{status:i})).json(),onSuccess:()=>{h(),n({title:"Status updated"})},onError:a=>n({title:"Could not update status",description:N(a)||"Please try again.",variant:"destructive"})}),E=b({mutationFn:async({id:a,intent:i})=>(await g("POST",`/api/outreach-targets/${a}/record-reply`,{intent:i})).json(),onSuccess:()=>{h(),n({title:"Reply recorded"})},onError:a=>n({title:"Could not record reply",description:N(a)||"Please try again.",variant:"destructive"})}),k=m.data?.targets??[];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold","data-testid":"heading-targets",children:"Outreach targets"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Niche podcasts, blogs, channels, libraries and bookstores to pitch — with a simple status pipeline."})]}),e.jsxs("div",{className:"flex gap-2",children:[d&&e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>l.mutate(),disabled:l.isPending,"data-testid":"button-seed-targets",children:[l.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(fe,{className:"h-4 w-4 mr-1"}),"Seed starters"]}),e.jsxs(Z,{open:p,onOpenChange:r,children:[e.jsx(ee,{asChild:!0,children:e.jsxs(f,{size:"sm","data-testid":"button-add-target",children:[e.jsx(z,{className:"h-4 w-4 mr-1"})," Add target"]})}),e.jsxs(te,{"data-testid":"dialog-add-target",children:[e.jsx(ae,{children:e.jsx(se,{children:"Add an outreach target"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Type"}),e.jsxs(M,{value:o.type,onValueChange:a=>x(i=>({...i,type:a})),children:[e.jsx(D,{"data-testid":"select-target-type",children:e.jsx(R,{})}),e.jsx(Q,{children:Ne.map(a=>e.jsx(K,{value:a,"data-testid":`option-type-${a}`,children:H[a]},a))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Name"}),e.jsx(v,{value:o.name,onChange:a=>x(i=>({...i,name:a.target.value})),placeholder:"Show / blog / store name","data-testid":"input-target-name"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Contact name"}),e.jsx(v,{value:o.contactName,onChange:a=>x(i=>({...i,contactName:a.target.value})),"data-testid":"input-target-contact-name"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Contact email"}),e.jsx(v,{type:"email",value:o.contactEmail,onChange:a=>x(i=>({...i,contactEmail:a.target.value})),"data-testid":"input-target-contact-email"})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"URL"}),e.jsx(v,{value:o.contactUrl,onChange:a=>x(i=>({...i,contactUrl:a.target.value})),placeholder:"https://","data-testid":"input-target-url"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Niche"}),e.jsx(v,{value:o.niche,onChange:a=>x(i=>({...i,niche:a.target.value})),"data-testid":"input-target-niche"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Location"}),e.jsx(v,{value:o.location,onChange:a=>x(i=>({...i,location:a.target.value})),"data-testid":"input-target-location"})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{children:"Notes"}),e.jsx(ne,{value:o.notes,onChange:a=>x(i=>({...i,notes:a.target.value})),rows:2,"data-testid":"input-target-notes"})]})]}),e.jsx(ie,{children:e.jsxs(f,{onClick:()=>y.mutate(),disabled:y.isPending||!o.name.trim(),"data-testid":"button-save-target",children:[y.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):null," Add target"]})})]})]})]})]}),m.isLoading?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(j,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):k.length===0?e.jsxs("p",{className:"text-center text-muted-foreground py-12","data-testid":"text-targets-empty",children:["No targets yet. Add one above",d?" or seed starter targets":""," to begin building your outreach list."]}):e.jsx("div",{className:"space-y-3",children:k.map(a=>e.jsx(B,{"data-testid":`card-target-${a.id}`,children:e.jsxs(U,{className:"pt-4 space-y-2",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 flex-wrap",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(q,{variant:"outline","data-testid":`badge-target-type-${a.id}`,children:H[a.type]??a.type}),e.jsx("span",{className:"font-medium text-sm","data-testid":`text-target-name-${a.id}`,children:a.name})]}),(a.contactName||a.contactEmail)&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1","data-testid":`text-target-contact-${a.id}`,children:[a.contactName,a.contactName&&a.contactEmail?" · ":"",a.contactEmail]}),a.contactUrl&&e.jsx("a",{href:a.contactUrl,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary break-all","data-testid":`link-target-url-${a.id}`,children:a.contactUrl}),a.notes&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:a.notes})]}),e.jsxs("div",{className:"flex flex-col items-end gap-2",children:[e.jsxs(M,{value:a.status,onValueChange:i=>u.mutate({id:a.id,status:i}),children:[e.jsx(D,{className:"w-40","data-testid":`select-target-status-${a.id}`,children:e.jsx(R,{})}),e.jsx(Q,{children:we.map(i=>e.jsx(K,{value:i,"data-testid":`option-status-${a.id}-${i}`,children:S(i)},i))})]}),e.jsx(q,{variant:"outline",className:$e[a.status]??"","data-testid":`badge-target-status-${a.id}`,children:S(a.status)})]})]}),c&&e.jsxs(e.Fragment,{children:[e.jsx(xe,{}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(ve,{className:"h-3 w-3"})," Log reply:"]}),Se.map(i=>e.jsx(f,{size:"sm",variant:"ghost",className:"h-7 text-xs",onClick:()=>E.mutate({id:a.id,intent:i}),disabled:E.isPending,"data-testid":`button-reply-${a.id}-${i}`,children:S(i)},i))]})]})]})},a.id))})]})}function qe({projectId:t}){const{toast:c}=L(),[n,d]=T.useState(""),[p,r]=T.useState(""),[o,x]=T.useState(!1),m=$({queryKey:["/api/projects",t,"outreach-sending-identity"],queryFn:async()=>{const u=await(await g("GET",`/api/projects/${t}/outreach-sending-identity`)).json();return!o&&u?.identity&&(d(u.identity.fromName??""),r(u.identity.fromEmail??""),x(!0)),u}}),h=$({queryKey:["/api/projects",t,"outreach-sends"],queryFn:async()=>(await g("GET",`/api/projects/${t}/outreach-sends`)).json()}),y=b({mutationFn:async()=>(await g("PUT",`/api/projects/${t}/outreach-sending-identity`,{fromName:n.trim()||null,fromEmail:p.trim()})).json(),onSuccess:()=>{C.invalidateQueries({queryKey:["/api/projects",t,"outreach-sending-identity"]}),c({title:"Sending identity saved"})},onError:u=>c({title:"Could not save",description:N(u)||"Please try again.",variant:"destructive"})}),l=h.data?.sends??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(B,{children:[e.jsxs(I,{children:[e.jsx(Y,{className:"text-base",children:"Your sending identity"}),e.jsx(re,{children:"The from-name and address your outreach is sent from. Sends are paced with a warm-up ramp and daily cap to protect your reputation."})]}),e.jsx(U,{className:"space-y-4",children:m.isLoading?e.jsx("div",{className:"flex justify-center py-6",children:e.jsx(j,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{htmlFor:"fromN
1ame",children:"From name"}),e.jsx(v,{id:"fromName",value:n,onChange:u=>d(u.target.value),placeholder:"Your name","data-testid":"input-from-name"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(w,{htmlFor:"fromEmail",children:"From email"}),e.jsx(v,{id:"fromEmail",type:"email",value:p,onChange:u=>r(u.target.value),placeholder:"[email protected]","data-testid":"input-from-email"})]})]}),m.data?.identity&&e.jsxs("p",{className:"text-xs text-muted-foreground","data-testid":"text-identity-status",children:["Status: ",S(m.data.identity.status)," · sent today: ",m.data.identity.sentToday??0,m.data.identity.dailyCap?` / ${m.data.identity.dailyCap}`:""]}),e.jsxs(f,{onClick:()=>y.mutate(),disabled:y.isPending||!p.trim(),"data-testid":"button-save-identity",children:[y.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):null," Save identity"]})]})})]}),e.jsxs("div",{children:[e.jsxs("h3",{className:"text-sm font-semibold mb-2 flex items-center gap-1",children:[e.jsx(de,{className:"h-4 w-4"})," Recent sends"]}),h.isLoading?e.jsx("div",{className:"flex justify-center py-6",children:e.jsx(j,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):l.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4","data-testid":"text-sends-empty",children:"No sends yet."}):e.jsx("div",{className:"space-y-2",children:l.map(u=>e.jsxs("div",{className:"flex items-center justify-between gap-2 rounded-lg border bg-card px-3 py-2 text-sm","data-testid":`row-send-${u.id}`,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate font-medium",children:u.subject||"(no subject)"}),e.jsxs("p",{className:"text-xs text-muted-foreground truncate",children:[u.toEmail," · ",Te(u.createdAt)]})]}),e.jsx(q,{variant:"outline","data-testid":`badge-send-status-${u.id}`,children:S(u.status)})]},u.id))})]})]})}function ke({enrollment:t,target:c}){const{toast:n}=L(),d=$({queryKey:["/api/outreach-enrollments",t.id,"messages"],queryFn:async()=>(await g("GET",`/api/outreach-enrollments/${t.id}/messages`)).json()}),p=()=>{C.invalidateQueries({queryKey:["/api/outreach-enrollments",t.id,"messages"]}),C.invalidateQueries({queryKey:["/api/outreach-sequences",t.sequenceId,"enrollments"]})},r=b({mutationFn:async()=>(await g("POST",`/api/outreach-enrollments/${t.id}/generate`)).json(),onSuccess:()=>{p(),n({title:"Draft generated",description:"Review it, then approve to send."})},onError:h=>n({title:"Could not generate",description:N(h)||"Please try again.",variant:"destructive"})}),o=b({mutationFn:async()=>(await g("POST",`/api/outreach-enrollments/${t.id}/approve`)).json(),onSuccess:()=>{p(),n({title:"Touch approved",description:"It's been queued to send."})},onError:h=>n({title:"Could not approve",description:N(h)||"Please try again.",variant:"destructive"})}),x=d.data?.messages??[],m=x.find(h=>h.status==="draft");return e.jsxs("div",{className:"rounded-lg border bg-card p-3 space-y-2","data-testid":`row-enrollment-${t.id}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium","data-testid":`text-enrollment-target-${t.id}`,children:c?.name??`Target #${t.targetId}`}),e.jsx(q,{variant:"outline","data-testid":`badge-enrollment-status-${t.id}`,children:S(t.status)}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["step ",t.currentStep]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>r.mutate(),disabled:r.isPending,"data-testid":`button-generate-${t.id}`,children:[r.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(oe,{className:"h-4 w-4 mr-1"})," Generate draft"]}),e.jsxs(f,{size:"sm",onClick:()=>o.mutate(),disabled:o.isPending||!m,"data-testid":`button-approve-${t.id}`,children:[o.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(ue,{className:"h-4 w-4 mr-1"})," Approve & send"]})]})]}),t.replyIntent&&e.jsxs("p",{className:"text-xs text-violet-700","data-testid":`text-enrollment-reply-${t.id}`,children:["Reply: ",S(t.replyIntent)]}),d.isLoading?null:m?e.jsxs("div",{className:"rounded-md bg-muted/50 p-2 text-xs","data-testid":`text-draft-${t.id}`,children:[e.jsx("p",{className:"font-medium",children:m.subject}),e.jsx("p",{className:"whitespace-pre-wrap text-muted-foreground mt-1 line-clamp-6",children:m.body})]}):x.length>0?e.jsxs("p",{className:"text-xs text-muted-foreground",children:[x.length," touch",x.length===1?"":"es"," on file."]}):null]})}function Ee({sequence:t,targets:c}){const{toast:n}=L(),[d,p]=T.useState({purpose:"",generationHint:"",delayDays:0}),[r,o]=T.useState(""),x=$({queryKey:["/api/outreach-sequences",t.id,"steps"],queryFn:async()=>(await g("GET",`/api/outreach-sequences/${t.id}/steps`)).json()}),m=$({queryKey:["/api/outreach-sequences",t.id,"enrollments"],queryFn:async()=>(await g("GET",`/api/outreach-sequences/${t.id}/enrollments`)).json()}),h=x.data?.steps??[],y=m.data?.enrollments??[],l=new Map(c.map(s=>[s.id,s])),u=new Set(y.map(s=>s.targetId)),E=c.filter(s=>!u.has(s.id)&&s.contactEmail),k=b({mutationFn:async()=>(await g("POST",`/api/outreach-sequences/${t.id}/steps`,{stepOrder:h.length+1,purpose:d.purpose.trim()||null,generationHint:d.generationHint.trim()||null,delayDays:Number(d.delayDays)||0})).json(),onSuccess:()=>{C.invalidateQueries({queryKey:["/api/outreach-sequences",t.id,"steps"]}),p({purpose:"",generationHint:"",delayDays:0}),n({title:"Step added"})},onError:s=>n({title:"Could not add step",description:N(s)||"Please try again.",variant:"destructive"})}),a=b({mutationFn:async s=>(await g("PATCH",`/api/outreach-sequences/${t.id}`,{status:s})).json(),onSuccess:()=>{C.invalidateQueries({queryKey:["/api/projects"]}),n({title:"Sequence updated"})},onError:s=>n({title:"Could not update",description:N(s)||"Please try again.",variant:"destructive"})}),i=b({mutationFn:async()=>(await g("POST",`/api/outreach-sequences/${t.id}/enroll`,{targetId:Number(r)})).json(),onSuccess:()=>{C.invalidateQueries({queryKey:["/api/outreach-sequences",t.id,"enrollments"]}),o(""),n({title:"Target enrolled"})},onError:s=>n({title:"Could not enroll",description:N(s)||"Please try again.",variant:"destructive"})});return e.jsxs("div",{className:"space-y-5 pt-2",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Sequence status:"}),e.jsxs(M,{value:t.status,onValueChange:s=>a.mutate(s),children:[e.jsx(D,{className:"w-36 h-8","data-testid":`select-sequence-status-${t.id}`,children:e.jsx(R,{})}),e.jsx(Q,{children:["draft","active","paused","archived"].map(s=>e.jsx(K,{value:s,"data-testid":`option-seq-status-${t.id}-${s}`,children:S(s)},s))})]}),e.jsx(q,{variant:"outline","data-testid":`badge-sequence-autosend-${t.id}`,children:t.autoSend?"Auto-send":"Review-then-send"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h4",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(ce,{className:"h-4 w-4"})," Touches"]}),h.length===0?e.jsx("p",{className:"text-xs text-muted-foreground","data-testid":`text-steps-empty-${t.id}`,children:"No touches yet. Add the first one below."}):e.jsx("div",{className:"space-y-1",children:h.map(s=>e.jsxs("div",{className:"flex items-center gap-2 text-sm rounded-md border px-2 py-1","data-testid":`row-step-${s.id}`,children:[e.jsxs(q,{variant:"outline",children:["#",s.stepOrder]}),e.jsx("span",{className:"font-medium",children:s.purpose||"Touch"}),e.jsxs("span",{className:"text-xs text-muted-foreground ml-auto",children:["+",s.delayDays,"d"]})]},s.id))}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 p-3 space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-2",children:[e.jsx(v,{placeholder:"Purpose (e.g. initial pitch)",value:d.purpose,onChange:s=>p(P=>({...P,purpose:s.target.value})),"data-testid":`input-step-purpose-${t.id}`}),e.jsx(v,{placeholder:"AI hint (optional)",value:d.generationHint,onChange:s=>p(P=>({...P,generationHint:s.target.value})),"data-testid":`input-step-hint-${t.id}`}),e.jsx(v,{type:"number",min:0,placeholder:"Delay days",value:d.delayDays,onChange:s=>p(P=>({...P,delayDays:Number(s.target.value)})),"data-testid":`input-step-delay-${t.id}`})]}),e.jsxs(f,{size:"sm",variant:"outline",onClick:()=>k.mutate(),disabled:k.isPending,"data-testid":`button-add-step-${t.id}`,children:[k.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(z,{className:"h-4 w-4 mr-1"})," Add touch"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("h4",{className:"text-sm font-semibold flex items-center gap-1",children:[e.jsx(le,{className:"h-4 w-4"})," Enrolled targets"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(M,{value:r,onValueChange:o,children:[e.jsx(D,{className:"flex-1","data-testid":`select-enroll-target-${t.id}`,children:e.jsx(R,{placeholder:E.length?"Choose a target to enroll":"No eligible targets (need a contact email)"})}),e.jsx(Q,{children:E.map(s=>e.jsx(K,{value:String(s.id),"data-testid":`option-enroll-${s.id}`,children:s.name},s.id))})]}),e.jsxs(f,{size:"sm",onClick:()=>i.mutate(),disabled:i.isPending||!r,"data-testid":`button-enroll-${t.id}`,children:[i.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):null," Enroll"]})]}),m.isLoading?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(j,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):y.length===0?e.jsx("p",{className:"text-xs text-muted-foreground","data-testid":`text-enrollments-empty-${t.id}`,children:"No targets enrolled yet."}):e.jsx("div",{className:"space-y-2",children:y.map(s=>e.jsx(ke,{enrollment:s,target:l.get(s.targetId)},s.id))})]})]})}function Pe({projectId:t}){const{toast:c}=L(),[n,d]=T.useState(""),[p,r]=T.useState(null),o=$({queryKey:["/api/projects",t,"outreach-sequences"],queryFn:async()=>(await g("GET",`/api/projects/${t}/outreach-sequences`)).json()}),x=$({queryKey:["/api/projects",t,"outreach-targets"],queryFn:async()=>(await g("GET",`/api/projects/${t}/outreach-targets`)).json()}),m=b({mutationFn:async()=>(await g("POST",`/api/projects/${t}/outreach-sequences`,{name:n.trim()})).json(),onSuccess:l=>{C.invalidateQueries({queryKey:["/api/projects",t,"outreach-sequences"]}),d(""),l?.sequence?.id&&r(l.sequence.id),c({title:"Sequence created",description:"Add touches and enroll targets below."})},onError:l=>c({title:"Could not create",description:N(l)||"Please try again.",variant:"destructive"})}),h=o.data?.sequences??[],y=x.data?.targets??[];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold","data-testid":"heading-sequences",children:"Outreach sequences"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Build a multi-touch sequence in your voice. Each touch is generated for review, then approved before it sends."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(v,{placeholder:"New sequence name",value:n,onChange:l=>d(l.target.value),"data-testid":"input-sequence-name"}),e.jsxs(f,{onClick:()=>m.mutate(),disabled:m.isPending||!n.trim(),"data-testid":"button-create-sequence",children:[m.isPending?e.jsx(j,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(z,{className:"h-4 w-4 mr-1"})," Create"]})]}),o.isLoading?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(j,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):h.length===0?e.jsx("p",{className:"text-center text-muted-foreground py-12","data-testid":"text-sequences-empty",children:"No sequences yet. Create one above to get started."}):e.jsx("div",{className:"space-y-3",children:h.map(l=>e.jsxs(B,{"data-testid":`card-sequence-${l.id}`,children:[e.jsx(I,{className:"pb-2 cursor-pointer",onClick:()=>r(p===l.id?null:l.id),"data-testid":`button-toggle-sequence-${l.id}`,children:e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx(Y,{className:"text-base",children:l.name}),e.jsx(q,{variant:"outline",className:l.status==="active"?"bg-green-100 text-green-800 border-green-200":"","data-testid":`badge-sequence-status-${l.id}`,children:S(l.status)})]})}),p===l.id&&e.jsx(U,{children:e.jsx(Ee,{sequence:l,targets:y})})]},l.id))})]})}function Fe({projectId:t}){const c=$({queryKey:["/api/projects",t,"outreach-tracking"],queryFn:async()=>(await g("GET",`/api/projects/${t}/outreach-tracking`)).json()});if(c.isLoading)return e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(j,{className:"h-6 w-6 animate-spin text-muted-foreground"})});const n=c.data;if(!n?.overall)return e.jsx("p",{className:"text-center text-muted-foreground py-12","data-testid":"text-analytics-empty",children:"No tracking data yet."});const d=n.overall,p=[{label:"Sent",value:d.sent},{label:"Delivered",value:`${d.delivered} (${F(d.deliveryRate)})`},{label:"Opened",value:`${d.opened} (${F(d.openRate)})`},{label:"Replied",value:`${d.replied} (${F(d.replyRate)})`},{label:"Booked",value:`${d.booked} (${F(d.bookedRate)})`},{label:"Bounced",value:`${d.bounced} (${F(d.bounceRate)})`}];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold","data-testid":"heading-analytics",children:"Outreach anal
1ytics"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"How your outreach is performing across every target and sequence."})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 gap-3",children:p.map(r=>e.jsx(B,{"data-testid":`stat-${r.label.toLowerCase()}`,children:e.jsxs(U,{className:"pt-4",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:r.label}),e.jsx("p",{className:"text-xl font-bold",children:r.value})]})},r.label))}),n.funnel?.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2",children:"Funnel"}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:n.funnel.map(r=>e.jsxs("div",{className:"rounded-lg border bg-card px-3 py-2 text-center","data-testid":`funnel-${r.stage}`,children:[e.jsx("p",{className:"text-lg font-bold",children:r.count}),e.jsx("p",{className:"text-xs text-muted-foreground",children:S(r.stage)})]},r.stage))})]}),n.perSequence?.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2",children:"By sequence"}),e.jsx("div",{className:"space-y-2",children:n.perSequence.map(r=>e.jsxs("div",{className:"flex items-center justify-between gap-2 rounded-lg border bg-card px-3 py-2 text-sm","data-testid":`row-seq-stats-${r.sequenceId}`,children:[e.jsx("span",{className:"font-medium truncate",children:r.name}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[r.sent," sent · ",r.replied," replied · ",r.booked," booked"]})]},r.sequenceId))})]})]})}function He(){const c=V().id;pe({title:"Publicist — Outreach | Branding by Books",description:"Opportunities across podcasts, blogs, libraries and more, with pitches drafted for you to send.",canonicalPath:`/projects/${c}/publicist`});const n=be(),{isLocked:d}=J(),p=d("tier3"),r=e.jsx(W,{href:`/projects/${c}`,children:e.jsxs(f,{variant:"ghost",size:"sm",className:"mb-2 -ml-2","data-testid":"link-back-project",children:[e.jsx(ye,{className:"h-4 w-4 mr-1"})," Back to project"]})});return n.isLoading?e.jsx("div",{className:"flex items-center justify-center min-h-[40vh]","data-testid":"loading-publicist",children:e.jsx(j,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):n.enabled?p?e.jsxs("div",{className:"max-w-2xl mx-auto py-12 px-4",children:[r,e.jsxs("div",{className:"relative rounded-xl border bg-card p-8 min-h-[220px]","data-testid":"locked-publicist",children:[e.jsx(me,{requiredTier:"tier3"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(G,{className:"h-6 w-6 text-[#ff6a3d]"}),e.jsx("h1",{className:"text-2xl font-bold",children:"Publicist / Outreach"})]}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"Opportunities across podcasts, blogs, libraries and bookstores, with pitches drafted for you to send."})]})]}):e.jsxs("div",{className:"max-w-3xl mx-auto py-8 px-4 space-y-6",children:[e.jsxs("div",{children:[r,e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(G,{className:"h-6 w-6 text-[#ff6a3d]"})," Publicist"]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Build your outreach list, set up sending, run multi-touch sequences in your voice, and track every reply."})]}),e.jsxs(he,{defaultValue:"targets",children:[e.jsxs(ge,{"data-testid":"tabs-publicist",children:[e.jsx(A,{value:"targets","data-testid":"tab-targets",children:"Targets"}),n.sending&&e.jsx(A,{value:"sending","data-testid":"tab-sending",children:"Sending"}),n.sequences&&e.jsx(A,{value:"sequences","data-testid":"tab-sequences",children:"Sequences"}),n.tracking&&e.jsxs(A,{value:"analytics","data-testid":"tab-analytics",children:[e.jsx(je,{className:"h-4 w-4 mr-1"})," Analytics"]})]}),e.jsx(O,{value:"targets",className:"mt-4",children:e.jsx(Ce,{projectId:c,sequencesEnabled:n.sequences})}),n.sending&&e.jsx(O,{value:"sending",className:"mt-4",children:e.jsx(qe,{projectId:c})}),n.sequences&&e.jsx(O,{value:"sequences",className:"mt-4",children:e.jsx(Pe,{projectId:c})}),n.tracking&&e.jsx(O,{value:"analytics",className:"mt-4",children:e.jsx(Fe,{projectId:c})})]})]}):e.jsxs("div",{className:"max-w-2xl mx-auto py-16 px-4 text-center","data-testid":"disabled-publicist",children:[e.jsx("h1",{className:"text-xl font-semibold mb-2",children:"Publicist"}),e.jsx("p",{className:"text-muted-foreground",children:"This feature isn't available yet."}),r]})}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.