1import{r as o,s as j,j as a,I as y,B as p}from"./index-BfjHogyd.js";import{S as E}from"./SpringboardStaffLayout-BGuhVXiL.js";import{B as h}from"./badge-BbAScMDt.js";import"./PageLayout-C4FFeSGk.js";import"./SiteFooter-BpkKuvEO.js";import"./ChatWidget-B0pHQBe1.js";import"./blue-control-room-wide-CIQ9u9e1.js";import"./concert-crowd-acdc-B2NaYUQ0.js";import"./violin-underwater-DPdNnEP6.js";import"./heroTitle-Clu977N3.js";const R={subscriber:"Subscriber",ticket:"Ticket buyer",affiliate:"Affiliate"},q=()=>{const[l,w]=o.useState([]),[v,S]=o.useState(!0),[g,L]=o.useState(""),[m,N]=o.useState("all");o.useEffect(()=>{(async()=>{const[e,i,_]=await Promise.all([j.from("springboard_subscribers").select("id,email,first_name,last_name,joined_main_list,created_at,unsubscribed_at").order("created_at",{ascending:!1}),j.from("springboard_tickets").select("id,email,first_name,last_name,created_at,status").order("created_at",{ascending:!1}),j.from("springboard_affiliates").select("id,email,name,created_at").order("created_at",{ascending:!1})]),d=new Map,c=(t,s)=>{if(!t)return;const u=t.trim().toLowerCase();if(!u)return;const r=d.get(u);r?(r.sources.includes(s.source)||r.sources.push(s.source),r.first_name=r.first_name||s.first_name||null,r.last_name=r.last_name||s.last_name||null,s.joined_main_list&&(r.joined_main_list=!0),s.unsubscribed_at&&(r.unsubscribed_at=s.unsubscribed_at),s.created_at&&s.created_at>r.created_at&&(r.created_at=s.created_at)):d.set(u,{id:s.id??u,email:t,first_name:s.first_name??null,last_name:s.last_name??null,joined_main_list:s.joined_main_list??!1,unsubscribed_at:s.unsubscribed_at??null,created_at:s.created_at??new Date().toISOString(),sources:[s.source]})};(e.data??[]).forEach(t=>c(t.email,{source:"subscriber",id:t.id,first_name:t.first_name,last_name:t.last_name,joined_main_list:t.joined_main_list,unsubscribed_at:t.unsubscribed_at,created_at:t.created_at})),(i.data??[]).filter(t=>t.status!=="canceled"&&t.status!=="refunded").forEach(t=>c(t.email,{source:"ticket",id:t.id,first_name:t.first_name,last_name:t.last_name,created_at:t.created_at})),(_.data??[]).forEach(t=>{const[s,...u]=(t.name||"").trim().split(/\s+/);c(t.email,{source:"affiliate",id:t.id,first_name:s||null,last_name:u.join(" ")||null,created_at:t.created_at})});const n=Array.from(d.values()).sort((t,s)=>t.created_at<s.created_at?1:-1);w(n),S(!1)})()},[]);const f=o.useMemo(()=>{const e=g.toLowerCase();return l.filter(i=>m!=="all"&&!i.sources.includes(m)?!1:e?i.email.toLowerCase().includes(e)||`${i.first_name??""} ${i.last_name??""}`.toLowerCase().includes(e):!0)},[l,g,m]),b=o.useMemo(()=>({all:l.length,subscriber:l.filter(e=>e.sources.includes("subscriber")).length,ticket:l.filter(e=>e.sources.includes("ticket")).length,affiliate:l.filter(e=>e.sources.includes("affiliate")).length}),[l]),k=()=>{const i=[["email","first_name","last_name","sources","joined_main_list","created_at","unsubscribed_at"].join(","),...f.map(n=>[n.email,n.first_name??"",n.last_name??"",n.sources.join("|"),n.joined_main_list,n.created_at,n.unsubscribed_at??""].map(t=>`"${String(t).replace(/"/g,'""')}"`).join(","))].join(` 2`),_=new Blob([i],{type:"text/csv"}),d=URL.createObjectURL(_),c=document.createElement("a");c.href=d,c.download=`springboard-mailing-list-${new Date().toISOString().slice(0,10)}.csv`,c.click(),URL.revokeObjectURL(d)},C=()=>{const e=f.filter(i=>!i.unsubscribed_at).map(i=>i.email).join(",");window.location.href=`mailto:?bcc=${e}`},x=(e,i,_)=>a.jsxs(p,{size:"sm",variant:m===e?"default":"outline",onClick:()=>N(e),className:m===e?"bg-[#0000ff] hover:bg-[#0000cc] text-white":"",children:[i," (",_,")"]},e);return a.jsxs(E,{pageTitle:"Springboard Mailing List",children:[a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 mb-4",children:[a.jsxs("h2",{className:"font-heading text-3xl uppercase tracking-wider text-foreground",children:["Mailing List (",f.length,")"]}),a.jsxs("div",{className:"flex flex-wrap gap-2",children:[a.jsx(y,{placeholder:"Search by name or email",value:g,onChange:e=>L(e.target.value),className:"max-w-xs"}),a.jsx(p,{onClick:k,variant:"outline",children:"Export CSV"}),a.jsx(p,{onClick:C,className:"bg-[#0000ff] hover:bg-[#0000cc] text-white",children:"Mail BCC all"})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-2 mb-6",children:[x("all","All",b.all),x("subscriber","Subscribers",b.subscriber),x("ticket","Ticket buyers",b.ticket),x("affiliate","Affiliates",b.affiliate)]}),v?a.jsx("p",{className:"text-muted-foreground",children:"Loadingâ¦"}):f.length===0?a.jsx("p",{className:"py-6 text-center text-muted-foreground",children:"No contacts yet."}):a.jsx("div",{className:"space-y-2",children:f.map(e=>a.jsxs("div",{className:"rounded-md border border-[hsl(208_60%_70%)] bg-[aliceblue] p-3 flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{children:[a.jsx("div",{className:"font-medium text-black",children:[e.first_name,e.last_name].filter(
2Boolean).join(" ")||"â"}),a.jsx("a",{href:`mailto:${e.email}`,className:"text-xs text-[#0000ff] hover:underline",children:e.email})]}),a.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:[e.sources.map(i=>a.jsx(h,{variant:"secondary",children:R[i]},i)),e.joined_main_list&&a.jsx(h,{children:"Main list"}),e.unsubscribed_at&&a.jsx(h,{variant:"destructive",children:"Unsubscribed"}),a.jsx("span",{className:"text-muted-foreground",children:new Date(e.created_at).toLocaleDateString()})]})]},e.id))})]})};export{q 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.