1import{a as W,u as O,b as D,j as e}from"./query-vendor-DVmmQ-ki.js";import{r as u,L as se}from"./react-vendor-BURXZ51T.js";import{h as te,B as m,T as ae,L as re}from"./index-DpP3iEYK.js";import{I as o}from"./input-Bx2apBJb.js";import{T as ne}from"./textarea-DHmKlUYM.js";import{L as d}from"./label-CiQuxLS0.js";import{B as Y}from"./badge-BrFuXnAq.js";import{C as k,a as T,b as B,c as L}from"./card-DwBoygcx.js";import{T as ie,a as le,b as R,c as y,d as de,e as N}from"./table-DGTNs8pb.js";import{D as Q,a as V,b as J,c as U,d as G,f as Z}from"./dialog-BPS4FN9z.js";import{t as j}from"./use-toast-j8LH5fHs.js";import{supabase as b}from"./client-BXzYhP5O.js";import{A as ce}from"./arrow-left-DrlG9OEE.js";import{R as oe}from"./radio-B7dc1GXG.js";import{P as ue}from"./plus-B0QqRDRs.js";import{S as me}from"./send-D49HTEyE.js";import"./radix-slot-BTvEbTmE.js";import"./ui-radix-LBOF5AHa.js";import"./x-CrVVxRiw.js";import"./supabase-DxfZiqN5.js";/** 2 * @license lucide-react v0.462.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 he=te("TestTubeDiagonal",[["path",{d:"M21 7 6.82 21.18a2.83 2.83 0 0 1-3.99-.01a2.83 2.83 0 0 1 0-4L17 3",key:"1ub6xw"}],["path",{d:"m16 2 6 6",key:"1gw87d"}],["path",{d:"M12 16H4",key:"1cjfip"}]]),$={draft:"bg-muted text-muted-foreground",test:"bg-blue-100 text-blue-800",scheduled:"bg-amber-100 text-amber-800",sending:"bg-emerald-100 text-emerald-800",sent:"bg-slate-200 text-slate-800",cancelled:"bg-red-100 text-red-800"};function Me(){const i=W(),[x,n]=u.useState(!1),[p,_]=u.useState(null),{data:C}=O({queryKey:["broadcast-enabled-setting"],queryFn:async()=>{const{data:t,error:l}=await b.from("settings").select("value").eq("key","broadcast_enabled").maybeSingle();if(l)throw l;return(t==null?void 0:t.value)==="true"}}),{data:a,isLoading:h}=O({queryKey:["broadcasts-list"],queryFn:async()=>{const{data:t,error:l}=await b.from("broadcasts").select("*").order("created_at",{ascending:!1});if(l)throw l;return t??[]}}),{data:r}=O({queryKey:["broadcast-sent-today"],queryFn:async()=>{const t=new Date;t.setUTCHours(0,0,0,0);const{count:l,error:w}=await b.from("broadcast_recipients").select("*",{count:"exact",head:!0}).gte("sent_at",t.toISOString()).eq("status","sent");if(w)throw w;return l??0},refetchInterval:3e4}),c=D({mutationFn:async()=>{const{data:t,error:l}=await b.from("broadcasts").insert({name:"Neuer Broadcast",subject:"",preheader:"",body_markdown:"",body_html:"",segment:{},status:"draft",daily_cap:200}).select().single();if(l)throw l;return t},onSuccess:t=>{i.invalidateQueries({queryKey:["broadcasts-list"]}),_(t),n(!0)},onError:t=>j({title:"Fehler",description:t.message,variant:"destructive"})});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx(se,{to:"/admin/marketing",children:e.jsxs(m,{variant:"ghost",size:"sm",className:"mb-4 -ml-2",children:[e.jsx(ce,{className:"h-4 w-4 mr-2"}),"Zurück zu Marketing"]})}),e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-3xl font-bold text-foreground mb-2 flex items-center gap-3",children:[e.jsx(oe,{className:"h-7 w-7"})," Broadcast-Center"]}),e.jsx("p",{className:"text-muted-foreground",children:"Newsletter & Blitz-Deals an segmentierte Empfänger aus der eigenen Datenbank."})]}),e.jsxs(m,{onClick:()=>c.mutate(),disabled:c.isPending,children:[e.jsx(ue,{className:"h-4 w-4 mr-2"})," Neuer Broadcast"]})]})]}),C===!1&&e.jsx(k,{className:"border-amber-300 bg-amber-50",children:e.jsxs(T,{className:"p-4 flex items-start gap-3",children:[e.jsx(ae,{className:"h-5 w-5 text-amber-700 mt-0.5"}),e.jsxs("div",{className:"text-sm text-amber-900",children:[e.jsx("p",{className:"font-semibold mb-1",children:"Echtversand ist deaktiviert."}),e.jsxs("p",{children:["Der globale Schalter ",e.jsx("code",{className:"bg-amber-100 px-1 rounded",children:"broadcast_enabled"})," steht auf ",e.jsx("b",{children:"false"}),". Editor, Segment-Vorschau und Testmail funktionieren wie gewohnt; der Echtversand ist blockiert, bis der Schalter in der Datenbank (",e.jsx("code",{children:"public.settings"}),") auf ",e.jsx("code",{children:"true"})," gesetzt wird."]})]})]})}),e.jsxs(k,{children:[e.jsxs(B,{className:"flex flex-row items-center justify-between",children:[e.jsx(L,{children:"Broadcasts"}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["Heute global versendet: ",e.jsx("b",{children:r??0})]})]}),e.jsx(T,{children:h?e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx(re,{className:"h-4 w-4 animate-spin"})," Lädt â¦"]}):!a||a.length===0?e.jsx("p",{className:"text-muted-foreground text-sm py-8 text-center",children:"Noch keine Broadcasts angelegt."}):e.jsxs(ie,{children:[e.jsx(le,{children:e.jsxs(R,{children:[e.jsx(y,{children:"Name"}),e.jsx(y,{children:"Betreff"}),e.jsx(y,{children:"Status"}),e.jsx(y,{children:"Tageslimit"}),e.jsx(y,{children:"Angelegt"}),e.jsx(y,{className:"text-right",children:"Aktion"})]})}),e.jsx(de,{children:a.map(t=>e.jsxs(R,{children:[e.jsx(N,{className:"font-medium",children:t.name}),e.jsx(N,{className:"text-muted-foreground",children:t.subject||e.jsx("em",{children:"â"})}),e.jsx(N,{children:e.jsx(Y,{className:$[t.status],children:t.status})}),e.jsxs(N,{children:[t.daily_cap,"/Tag"]}),e.jsx(N,{className:"text-muted-foreground",children:new Date(t.created_at).toLocaleDateString("de-DE")}),e.jsx(N,{className:"text-right",children:e.jsx(m,{variant:"outline",size:"sm",onClick:()=>{_(t),n(!0)},children:"Ãffnen"})})]},t.id))})]})})]}),p&&e.jsx(xe,{open:x,onOpenChange:n,broadcast:p,globallyEnabled:C===!0,onSaved:()=>i.invalidateQueries({queryKey:["broadcasts-list"]})})]})}function xe({open:i,onOpenChange:x,broadcast:n,globallyEnabled:p,onSaved:_}){var H,K;const C=W(),[a,h]=u.useState(n),[r,c]=u.useState(n.segment??{}),[t,l]=u.useState(null),[w,P]=u.useState(!1),[v,M]=u.useState(""),[X,E]=u.useState(!1),[z,A]=u.useState("");u.useEffect(()=>{h(n),c(n.segment??{}),l(null),M(""),A("")},[n.id]);const f=a.status==="sending"||a.status==="sent"||a.status==="cancelled",S=D({mutationFn:async()=>{const{error:s}=await b.from("broadcasts").update({name:a.name,subject:a.subject,preheader:a.preheader,body_markdown:a.body_markdown,body_html:a.body_html,segment:JSON.parse(JSON.stringify(r)),daily_cap:a.daily_cap}).eq("id",a.id);if(s)throw s},onSuccess:()=>{j({title:"Gespeichert"}),_()},onError:s=>j({title:"Fehler",description:s.message,variant:"destructive"})}),ee=async()=>{P(!0),l(null);try{const{data:s,error:g}=await b.functions.invoke("broadcast-segment-preview",{body:{segment:r}});if(g)throw g;l(s)}catch(s){j({title:"Vorschau fehlgeschlagen",description:s.message,variant:"destructive"})}finally{P(!1)}},F=D({mutationFn:async()=>
6{if(!v)throw new Error("Testadresse fehlt");await S.mutateAsync();const{data:s,error:g}=await b.functions.invoke("broadcast-send-test",{body:{broadcast_id:a.id,test_email:v}});if(g)throw g;return s},onSuccess:()=>{j({title:"Testmail versendet",description:`An ${v}`}),C.invalidateQueries({queryKey:["broadcasts-list"]}),h(s=>({...s,last_test_sent_at:new Date().toISOString(),last_test_email:v}))},onError:s=>j({title:"Testmail fehlgeschlagen",description:s.message,variant:"destructive"})}),q=D({mutationFn:async()=>{if(!t)throw new Error("Erst Empfänger berechnen");if(Number(z)!==t.eligible)throw new Error("Empfängeranzahl zur Bestätigung falsch eingetippt");await S.mutateAsync();const{data:s,error:g}=await b.functions.invoke("broadcast-start",{body:{broadcast_id:a.id,expected_recipient_count:t.eligible}});if(g)throw g;return s},onSuccess:()=>{j({title:"Versand gestartet",description:"Der Runner sendet innerhalb der Tagesgrenze weiter aus."}),E(!1),_(),x(!1)},onError:s=>j({title:"Start fehlgeschlagen",description:s.message,variant:"destructive"})}),I=p&&!!a.last_test_sent_at&&!!t&&t.eligible>0&&!f;return e.jsx(Q,{open:i,onOpenChange:x,children:e.jsxs(V,{className:"max-w-5xl max-h-[92vh] overflow-y-auto",children:[e.jsxs(J,{children:[e.jsxs(U,{className:"flex items-center gap-3",children:[a.name||"Broadcast"," ",e.jsx(Y,{className:$[a.status],children:a.status})]}),e.jsx(G,{children:"Newsletter oder Blitz-Deal. Empfänger stammen aus unserer eigenen Datenbank (nur bestätigte Newsletter-Abonnenten, ohne Suppressions)."})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(d,{children:"Name (intern)"}),e.jsx(o,{value:a.name,disabled:f,onChange:s=>h({...a,name:s.target.value})})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Betreff"}),e.jsx(o,{value:a.subject,disabled:f,onChange:s=>h({...a,subject:s.target.value})})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Preheader (Vorschautext)"}),e.jsx(o,{value:a.preheader??"",disabled:f,onChange:s=>h({...a,preheader:s.target.value})})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Inhalt (Markdown)"}),e.jsx(ne,{rows:16,value:a.body_markdown,disabled:f,onChange:s=>h({...a,body_markdown:s.target.value}),placeholder:`## Neue Blitz-Deals dieses Wochenende 7 8Guten Tag, 9 10heute drei interessante Angebote ...`}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Unterstützt: `##`/`###` Ãberschriften, `**fett**`, `*kursiv*`, `[link](https://â¦)`."})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Tageslimit (max. Sends/Tag pro Broadcast)"}),e.jsx(o,{type:"number",min:1,max:5e3,value:a.daily_cap,disabled:f,onChange:s=>h({...a,daily_cap:Math.max(1,parseInt(s.target.value||"0",10))})})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(m,{onClick:()=>S.mutate(),disabled:f||S.isPending,children:S.isPending?"Speichern â¦":"Entwurf speichern"})})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(k,{children:[e.jsx(B,{children:e.jsx(L,{className:"text-base",children:"Segment"})}),e.jsxs(T,{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Harte, nicht abschaltbare Regeln: nur Leads mit Newsletter-Opt-in + bestätigtem Double-Opt-In, ohne Unsubscribe und ohne Suppression. Duplikate werden entfernt."}),e.jsxs("div",{children:[e.jsx(d,{children:"Fahrzeuginteresse enthält"}),e.jsx(o,{placeholder:"z. B. BMW",value:r.vehicle_interest??"",onChange:s=>c({...r,vehicle_interest:s.target.value||null})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(d,{children:"Lead-Score min"}),e.jsx(o,{type:"number",value:r.lead_score_min??"",onChange:s=>c({...r,lead_score_min:s.target.value===""?null:Number(s.target.value)})})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Lead-Score max"}),e.jsx(o,{type:"number",value:r.lead_score_max??"",onChange:s=>c({...r,lead_score_max:s.target.value===""?null:Number(s.target.value)})})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(d,{children:"Nur qual
10ifizierte"}),e.jsxs("select",{className:"w-full h-10 rounded-md border border-input bg-background px-3 text-sm",value:r.qualified_lead===!0?"yes":r.qualified_lead===!1?"no":"",onChange:s=>c({...r,qualified_lead:s.target.value===""?null:s.target.value==="yes"}),children:[e.jsx("option",{value:"",children:"(egal)"}),e.jsx("option",{value:"yes",children:"Ja"}),e.jsx("option",{value:"no",children:"Nein"})]})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Low priority"}),e.jsxs("select",{className:"w-full h-10 rounded-md border border-input bg-background px-3 text-sm",value:r.low_priority===!0?"yes":r.low_priority===!1?"no":"",onChange:s=>c({...r,low_priority:s.target.value===""?null:s.target.value==="yes"}),children:[e.jsx("option",{value:"",children:"(egal)"}),e.jsx("option",{value:"no",children:"Nein (nur Priorisierte)"}),e.jsx("option",{value:"yes",children:"Ja (nur Low-Prio)"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(d,{children:"Erstellt ab"}),e.jsx(o,{type:"date",value:((H=r.created_from)==null?void 0:H.slice(0,10))??"",onChange:s=>c({...r,created_from:s.target.value?new Date(s.target.value).toISOString():null})})]}),e.jsxs("div",{children:[e.jsx(d,{children:"Erstellt bis"}),e.jsx(o,{type:"date",value:((K=r.created_to)==null?void 0:K.slice(0,10))??"",onChange:s=>c({...r,created_to:s.target.value?new Date(s.target.value).toISOString():null})})]})]}),e.jsxs("div",{children:[e.jsx(d,{children:"UTM-Quelle"}),e.jsx(o,{placeholder:"z. B. meta_ads",value:r.utm_source??"",onChange:s=>c({...r,utm_source:s.target.value||null})})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(m,{variant:"outline",onClick:ee,disabled:w,children:w?"Berechne â¦":"Empfänger berechnen"})}),t&&e.jsx(ge,{preview:t})]})]}),e.jsxs(k,{children:[e.jsx(B,{children:e.jsx(L,{className:"text-base",children:"Testmail"})}),e.jsxs(T,{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Bevor Sie echt versenden, muss mindestens eine Testmail rausgehen."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{type:"email",placeholder:"[email protected]",value:v,onChange:s=>M(s.target.value)}),e.jsxs(m,{variant:"outline",onClick:()=>F.mutate(),disabled:F.isPending||!v,children:[e.jsx(he,{className:"h-4 w-4 mr-2"}),"Test"]})]}),a.last_test_sent_at&&e.jsxs("p",{className:"text-xs text-emerald-700",children:["Letzte Testmail an ",e.jsx("b",{children:a.last_test_email})," am"," ",new Date(a.last_test_sent_at).toLocaleString("de-DE"),"."]})]})]}),e.jsxs(k,{className:I?"":"opacity-70",children:[e.jsx(B,{children:e.jsx(L,{className:"text-base",children:"Echtversand"})}),e.jsxs(T,{className:"space-y-3",children:[!p&&e.jsxs("p",{className:"text-xs text-amber-800 bg-amber-50 border border-amber-200 rounded p-2",children:["Global deaktiviert (",e.jsx("code",{children:"broadcast_enabled=false"}),"). Kein Echtversand möglich."]}),!a.last_test_sent_at&&e.jsx("p",{className:"text-xs text-amber-800",children:"Zuerst Testmail senden."}),!t&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Zuerst Empfänger berechnen."}),e.jsxs(m,{disabled:!I,onClick:()=>E(!0),className:"w-full",children:[e.jsx(me,{className:"h-4 w-4 mr-2"}),"Versand starten"]})]})]})]})]}),e.jsx(Z,{children:e.jsx(m,{variant:"outline",onClick:()=>x(!1),children:"SchlieÃen"})}),e.jsx(Q,{open:X,onOpenChange:E,children:e.jsxs(V,{className:"max-w-md",children:[e.jsxs(J,{children:[e.jsx(U,{children:"Versand bestätigen"}),e.jsxs(G,{children:["Bitte die Empfängeranzahl ",e.jsx("b",{children:(t==null?void 0:t.eligible)??0})," zur Bestätigung eintippen."]})]}),e.jsx(o,{value:z,onChange:s=>A(s.target.value),placeholder:String((t==null?void 0:t.eligible)??0)}),e.jsxs(Z,{children:[e.jsx(m,{variant:"outline",onClick:()=>E(!1),children:"Abbrechen"}),e.jsx(m,{disabled:Number(z)!==((t==null?void 0:t.eligible)??-1)||q.isPending,onClick:()=>q.mutate(),children:q.isPending?"Starte â¦":"Jetzt versenden"})]})]})})]})})}function ge({preview:i}){const x=u.useMemo(()=>Object.entries(i.excluded).filter(([,n])=>n>0),[i]);return e.jsxs("div",{className:"text-sm space-y-2 border-t pt-3",children:[e.jsxs("div",{className:"flex items-baseline justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Gültige Empf
10änger"}),e.jsx("span",{className:"text-2xl font-bold text-emerald-700",children:i.eligible})]}),e.jsxs("div",{className:"flex items-baseline justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:"Kandidaten insgesamt"}),e.jsx("span",{children:i.total_candidates})]}),x.length>0&&e.jsxs("div",{className:"text-xs",children:[e.jsx("p",{className:"text-muted-foreground mb-1",children:"Ausgeschlossen:"}),e.jsx("ul",{className:"list-disc list-inside space-y-0.5",children:x.map(([n,p])=>e.jsxs("li",{children:[e.jsx("b",{children:p})," ",je(n)]},n))})]}),i.sample.length>0&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Beispiele: ",i.sample.map(n=>n.email).join(", ")]})]})}function je(i){switch(i){case"no_opt_in":return"ohne Newsletter-Opt-in";case"no_doi":return"ohne bestätigten Double-Opt-In";case"unsubscribed":return"abgemeldet";case"suppressed":return"auf Suppression-Liste (Bounce/Spam)";case"invalid_email":return"ungültige E-Mail";case"duplicate":return"Duplikat";default:return i}}export{Me 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.