1import{j as e}from"./vendor-react-CMm599cy.js";import{c as h}from"./vendor-query-DR7y8XG_.js";import{B as u,C as j,e as g,f,M as y,a as N}from"./index-CuBcF6Fp.js";import{D as b}from"./download-BdN-4Ykj.js";import"./vendor-charts-DnUpxE1z.js";const v="";function w(s){return`R${s.toLocaleString("en-ZA",{minimumFractionDigits:0,maximumFractionDigits:2})}`}function r(s){if(!s)return"â";const n=new Date(s);return Number.isNaN(n.getTime())?"â":n.toLocaleDateString("en-ZA",{year:"numeric",month:"short",day:"numeric"})}const m={active:"Active",cancelled:"Cancelled",expired:"Expired"};function o(s){return`"${(/^[=+\-@\t\r]/.test(s)?`'${s}`:s).replace(/"/g,'""')}"`}function C(s){const n=["Name","Email","Status","Plan","Joined","Total paid (Rand)","Last payment","Current period end","Cancelled"],l=s.map(t=>[t.name,t.email,m[t.status]??t.status,t.plan,r(t.joinedAt),t.totalPaidRand.toFixed(2),r(t.lastPaymentAt),r(t.currentPeriodEnd),r(t.cancelledAt)].map(d=>o(String(d))).join(","));return[n.map(o).join(","),...l].join(`\r 2`)}function D(){const{data:s,isLoading:n,error:l}=h({queryKey:["admin","marketing-list"],queryFn:()=>fetch(`${v}/api/admin/marketing-list`,{credentials:"include"}).then(a=>{if(!a.ok)throw new Error("Failed to load marketing list");return a.json()})}),t=s?.customers??[];function d(){if(t.length===0)return;const a=C(t),x=new Blob(["\uFEFF"+a],{type:"text/csv;charset=utf-8;"}),c=URL.createObjectURL(x),i=document.createElement("a"),p=new Date().toISOString().slice(0,10);i.href=c,i.download=`tendersearch-marketing-list-${p}.csv`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(c)}return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Marketing List"}),e.jsx("p",{className:"text-sm text-muted-foreground max-w-2xl",children:"Everyone who has ever paid â active, cancelled, or expired. Never-paid signups and free partner accounts are excluded. Download it as a spreadsheet (CSV) for your email tools."})]}),e.jsxs(u,{onClick:d,disabled:t.length===0,className:"gap-2",children:[e.jsx(b,{className:"w-4 h-4"}),"Download CSV"]})]}),e.jsxs(j,{children:[e.jsx(g,{children:e.jsxs(f,{className:"text-base flex items-center gap-2",children:[e.jsx(y,{className:"w-4 h-4"}),n?"Loadingâ¦":`${t.length} paying ${t.length===1?"customer":"customers"}`]})}),e.jsx(N,{children:l?e.jsx("p",{className:"text-sm text-destructive",children:"Could not load the marketing list. Please try again."}):n?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading customersâ¦"}):t.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No paying customers yet. Once someone subscribes they'll appear here."}):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 text-muted-foreground",children:[e.jsx("th",{className:"text-left py-2 px-2",children:"Name"}),e.jsx("th",{className:"text-left py-2 px-2",children:"Email"}),e.jsx("th",{className:"text-left py-2 px-2",children:"Status"}),e.jsx("th",{className:"text-left py-2 px-2 capitalize",children:"Plan"}),e.jsx("th",{className:"text-right py-2 px-2",children:"Total paid"}),e.jsx("th",{className:"text-right py-2 px-2",children:"Joined"}),e.jsx("th",{className:"text-right py-2 px-2",children:"Last payment"})]})}),e.jsx("tbody",{children:t.map(a=>e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 px-2",children:a.name||"â"}),e.jsx("td",{className:"py-2 px-2",children:e.jsx("a",{href:`mailto:${a.email}`,className:"text-primary hover:underline",children:a.email})}),e.jsx("td",{className:"py-2 px-2",children:m[a.status]??a.status}),e.jsx("td",{className:"py-2 px-2 capitalize",children:a.plan}),e.jsx("td",{className:"py-2 px-2 text-right",children:w(a.totalPaidRand)}),e.jsx("td",{className:"py-2 px-2 text-right",children:r(a.joinedAt)}),e.jsx("td",{className:"py-2 px-2 text-right",children:r(a.lastPaymentAt)})]},a.id))})]})})})]})]})}export{D 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.