PageSourceSearch

https://hyscore.io/assets/admin.newsletter.subscribers-DwlDkraF.js

js hyscore.io collected 2026-09-24 09:27:02 UTC 24,851 bytes, 2 lines download raw bytes

1import{b as p,a3 as Z,eQ as X,r as a,e as K,ae as O,a4 as Q,j as e}from"./index-B4mWWRqi.js";import{l as Y,b as ee,d as te,e as se,r as ne,f as re,h as de,i as ae,j as ie,k as le,m as oe,n as ce}from"./newsletter.functions-_UpUTTFD.js";import{b as ue}from"./comm-preferences.functions-KaHnO_lv.js";const W={pending:"Opt-in fehlt",confirmed:"Doppel-Opt-in",unsubscribed:"Abgemeldet",bounced:"Bounce"},me={pending:"bg-amber-500/15 text-amber-700 dark:text-amber-300",confirmed:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",unsubscribed:"bg-muted text-muted-foreground",bounced:"bg-destructive/15 text-destructive"};function w(s){if(!s)return"—";try{return new Date(s).toLocaleString("de-DE",{dateStyle:"medium",timeStyle:"short"})}catch{return s}}function H({status:s}){return e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${me[s]}`,children:W[s]})}function V(s){const d=String(s??"").toLowerCase();return d?d.includes("segment_missing")?"Die Gruppe „Artikel von hyScore“ konnte nicht gefunden oder angelegt werden.":d.includes("unauthorized")||d.includes("forbidden")||d.includes("401")||d.includes("403")?"Dafür fehlen dir die nötigen Rechte. Bitte melde dich neu an oder wende dich an einen Administrator.":d.includes("failed to fetch")||d.includes("network")||d.includes("timeout")?"Keine Verbindung zum Server. Bitte Internetverbindung prüfen und erneut versuchen.":d.includes("permission denied")||d.includes("row-level security")?"Der Zugriff auf die Abonnenten-Daten wurde abgelehnt. Bitte einen Administrator informieren.":`Der Abgleich konnte nicht abgeschlossen werden (${s}).`:"Unbekannter Fehler. Bitte später erneut versuchen."}function ve(){const s=p(Y),d=p(ee),x=p(te),h=p(se),g=p(ne),b=p(re),f=p(de),u=p(ae),i=Z(),j=X.useSearch(),[y,r]=a.useState(j.status??"all"),[N,_]=a.useState(""),[S,I]=a.useState(""),[n,m]=a.useState(null),[k,A]=a.useState("subs"),o=K({queryKey:["nl","subscribers",y,N,S],queryFn:()=>s({data:{status:y,search:N,segmentId:S||null,limit:200}})}),v=K({queryKey:["nl","segments"],queryFn:()=>d()}),F=p(ie),[E,C]=a.useState(null),R=O({mutationFn:()=>F({}),onMutate:()=>C(null),onSuccess:t=>{if(!t?.ok){const z=V(t?.error);C({tone:"error",text:z}),Q.error("Synchronisierung fehlgeschlagen",{description:z});return}i.invalidateQueries({queryKey:["nl","subscribers"]}
1),i.invalidateQueries({queryKey:["nl","segments"]});const l=[];t.added&&l.push(`${t.added} hinzugefügt`),t.removed&&l.push(`${t.removed} entfernt`);const T=l.length?l.join(", "):"keine Änderungen",M=`Die Gruppe „Artikel von hyScore“ hat jetzt ${t.members} ${t.members===1?"Mitglied":"Mitglieder"} (${T}).`;C({tone:"ok",text:M}),Q.success("Gruppe synchronisiert",{description:M})},onError:t=>{const l=V(t?.message);C({tone:"error",text:l}),Q.error("Synchronisierung fehlgeschlagen",{description:l})}}),[P,q]=a.useState(!1);async function c(){q(!0);try{const t=await u({data:{status:y,search:N,segmentId:S||null}}),l=new Blob([t.csv],{type:"text/csv;charset=utf-8"}),T=URL.createObjectURL(l),M=document.createElement("a");M.href=T,M.download=t.filename,document.body.appendChild(M),M.click(),M.remove(),URL.revokeObjectURL(T)}finally{q(!1)}}const U=a.useMemo(()=>{const t={all:0,pending:0,confirmed:0,unsubscribed:0,bounced:0};return(o.data??[]).forEach(l=>{t.all++,t[l.status]++}),t},[o.data]),D=O({mutationFn:t=>x({data:{id:t.id,status:t.s,...t.note?{manualConfirmNote:t.note}:{},...t.reason?{unsubscribeReason:t.reason}:{}}}),onSuccess:(t,l)=>{i.invalidateQueries({queryKey:["nl","subscribers"]}
1),i.invalidateQueries({queryKey:["nl","audit",l.id]}),n&&n.id===l.id&&m({...n,status:l.s,...l.s==="confirmed"?{confirmed_at:new Date().toISOString(),manual_confirm_note:l.note??n.manual_confirm_note,manual_confirmed_at:new Date().toISOString()}:{}})}}),J=O({mutationFn:t=>h({data:{id:t}}),onSuccess:()=>{i.invalidateQueries({queryKey:["nl","subscribers"]}),m(null)}}),$=O({mutationFn:t=>g({data:{id:t}})}),B=O({mutationFn:t=>b({data:{id:t}}),onSuccess:()=>i.invalidateQueries({queryKey:["nl","subscribers"]})}),L=O({mutationFn:()=>f(),onSuccess:()=>i.invalidateQueries({queryKey:["nl","subscribers"]})});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-end justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold",children:"Abonnenten"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Newsletter-Empfänger inkl. Double-Opt-in-Status und Zeitstempeln."})]}),e.jsx("div",{className:"flex gap-2 text-xs",children:["all","confirmed","pending","unsubscribed","bounced"].map(t=>e.jsxs("button",{onClick:()=>r(t),className:`rounded-full px-3 py-1.5 border ${y===t?"bg-primary text-primary-foreground border-primary":"border-border hover:bg-accent"}`,children:[t==="all"?"Alle":W[t]," (",U[t],")"]},t))})]}),e.jsx("div",{className:"flex gap-2 text-sm",children:[["subs","Newsletter-Abonnenten"],["crm","CRM-Kontakte (Artikel)"]].map(([t,l])=>e.jsx("button",{onClick:()=>A(t),className:`rounded-md border px-3 py-1.5 ${k===t?"bg-primary text-primary-foreground border-primary":"border-border hover:bg-accent"}`,children:l},t))}),k==="crm"?e.jsx(fe,{}):e.jsxs(e.Fragment,{children:[e.jsx("input",{value:N,onChange:t=>_(t.target.value),placeholder:"E-Mail suchen…",className:"w-full max-w-md rounded-md border border-border bg-background px-3 py-2 text-sm"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("select",{value:S,onChange:t=>I(t.target.value),className:"rounded-md border border-border bg-background px-3 py-2 text-sm",children:[e.jsx("option",{value:"",children:"Alle Segmente"}),(v.data??[]).map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]}),e.jsx("button",{onClick:c,disabled:P,className:"rounded-md border border-border px-3 py-2 text-sm hover:bg-accent disabled:opacity-50",children:P?"Exportiere…":"CSV-Export"}),e.jsx("button",{onClick:()=>L.mutate(),disabled:L.isPending,className:"rounded-md border border-border px-3 py-2 text-sm hover:bg-accent disabled:opacity-50",title:"Versendet DOI-Reminder an alle Pending-Subscriber, die älter als 3 Tage sind und noch keinen Reminder erhalten haben.",children:L.isPending?"Verarbeite…":"Fällige Reminder versenden"}),e.jsx("button",{onClick:()=>R.mutate(),disabled:R.isPending,className:"rounded-md border border-border px-3 py-2 text-sm hover:bg-accent disabled:opacity-50",title:"Gleicht die Gruppe „Artikel von hyScore“ mit allen bestätigten Abonnenten ab, die den Artikel-Haken gesetzt haben.",children:R.isPending?"Synchronisiere…":"Gruppe „Artikel von hyScore“ synchronisieren"}),R.isPending&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"Abgleich läuft…"}),!R.isPending&&E&&e.jsx("span",{className:`text-xs ${E.tone==="ok"?"text-emerald-700 dark:text-emerald-300":"text-destructive"}`,children:E.text}),L.isSuccess&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:[L.data?.queued??0," Reminder eingereiht."]}),L.isError&&e.jsx("span",{className:"text-xs text-destructive",children:L.error.message})]}),e.jsxs("div",{className:"rounded-2xl border border-border bg-card overflow-hidden",children:[o.isLoading&&e.jsx("div",{className:"p-6 text-sm text-muted-foreground",children:"Lade…"}),o.isError&&e.jsx("div",{className:"p-6 text-sm text-destructive",children:o.error.message}),o.data?.length===0&&e.jsx("div",{className:"p-6 text-sm text-muted-foreground",children:"Keine Einträge."}),o.data&&o.data.length>0&&e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-left text-xs uppercase tracking-wider text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3",children:"E-Mail"}),e.jsx("th",{className:"px-4 py-3",children:"Status"}),e.jsx("th",{className:"px-4 py-3",children:"Sprache"}),e.jsx("th",{className:"px-4 py-3",children:"Angemeldet"}),e.jsx("th",{className:"px-4 py-3",children:"Bestätigt"}),e.jsx("th",{className:"px-4 py-3",children:"Abgemeldet"}),e.jsx("th",{className:"px-4 py-3"})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:o.data.map(t=>e.jsxs("tr",{className:"hover:bg-muted/30",children:[e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"font-medium",children:t.email}),t.name&&e.jsx("div",{className:"text-xs text-muted-foreground",children:t.name})]}),e.jsx("td",{className:"px-4 py-3",children:e.jsx(H,{status:t.status})}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground uppercase text-xs",children:t.language??"de"}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground",children:w(t.signup_at)}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground",children:w(t.confirmed_at)}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground",children:w(t.unsubscribed_at)}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsx("button",{onClick:()=>m(t),className:"text-sm text-primary hover:underline",children:"Details"})})]},t.id))})]})]})]}),n&&e.jsx(xe,{subscriber:n,segments:v.data??[],onClose:()=>m(null),onStatus:t=>D.mutate({id:n.id,s:t}),onManualConfirm:t=>D.mutate({id:n.id,s:"confirmed",note:t}),onManualUnsubscribe:t=>D.mutate({id:n.id,s:"unsubscribed",reason:t}),statusError:D.isError?D.error.message:null,onDelete:()=>{confirm(`"${n.email}" wirklich löschen? (DSGVO-Audit geht verloren)`)&&J.mutate(n.id)},onResend:()=>$.mutate(n.id),onReminder:()=>B.mutate(n.id),resendInfo:$.isPending?"Wird in Outbox gelegt…":$.isSuccess?"DOI-Mail wurde in die Outbox gelegt.":$.isError?$.error.message:null,reminderInfo:B.isPending?"Reminder wird in Outbox gelegt…":B.isSuccess?"Reminder-Mail wurde in die Outbox gelegt.":B.isError?B.error.message:null})]})}function xe({subscriber:s,segments:d,onClose:x,onStatus:h,onManualConfirm:g,onManualUnsubscribe:b,statusError:f,onDelete:u,onResend:i,onReminder:j,resendInfo:y,reminderInfo:r}){const N=p(le),_=p(oe),S=Z(),I=K({queryKey:["nl","sub-segs",s.id],queryFn:()=>N({data:{subscriberId:s.id}})}
1),[n,m]=a.useState(null),k=n??I.data??[],[A,o]=a.useState(""),[v,F]=a.useState(!1),[E,C]=a.useState(""),[R,P]=a.useState(!1),q=O({mutationFn:()=>_({data:{subscriberId:s.id,segmentIds:k}}),onSuccess:()=>{S.invalidateQueries({queryKey:["nl","sub-segs",s.id]}),m(null)}});return e.jsx("div",{className:"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex justify-end",onClick:x,children:e.jsxs("div",{className:"w-full max-w-xl h-full bg-card border-l border-border overflow-y-auto p-6 space-y-5",onClick:c=>c.stopPropagation(),children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold break-all",children:s.email}),s.name&&e.jsx("p",{className:"text-sm text-muted-foreground",children:s.name})]}),e.jsx("button",{onClick:x,className:"rounded-md border border-border px-3 py-1 text-sm",children:"Schließen"})]}),e.jsx("div",{children:e.jsx(H,{status:s.status})}),e.jsxs("dl",{className:"grid grid-cols-2 gap-x-4 gap-y-2 text-sm",children:[e.jsx("dt",{className:"text-muted-foreground",children:"Angemeldet"}),e.jsx("dd",{children:w(s.signup_at)}),e.jsx("dt",{className:"text-muted-foreground",children:"Sprache"}),e.jsx("dd",{className:"uppercase",children:s.language??"de"}),e.jsx("dt",{className:"text-muted-foreground",children:"Bestätigt (DOI)"}),e.jsx("dd",{children:w(s.confirmed_at)}),e.jsx("dt",{className:"text-muted-foreground",children:"Bestätigungs-IP"}),e.jsx("dd",{className:"font-mono text-xs",children:s.confirm_ip??"—"}),e.jsx("dt",{className:"text-muted-foreground",children:"Abgemeldet"}),e.jsx("dd",{children:w(s.unsubscribed_at)}),e.jsx("dt",{className:"text-muted-foreground",children:"Abmeldegrund"}),e.jsx("dd",{children:s.unsubscribe_reason??"—"}),s.unsubscribed_at&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-muted-foreground",children:"Abgemeldet von"}),e.jsx("dd",{className:"text-xs",children:s.unsubscribed_by_user?`${s.unsubscribed_by_user.name??"—"}${s.unsubscribed_by_user.email?` (${s.unsubscribed_by_user.email})`:""}`:s.unsubscribed_by??"—"})]}),e.jsx("dt",{className:"text-muted-foreground",children:"Anmelde-IP"}),e.jsx("dd",{className:"font-mono text-xs",children:s.signup_ip??"—"}),e.jsx("dt",{className:"text-muted-foreground",children:"User-Agent"}),e.jsx("dd",{className:"text-xs break-words",children:s.signup_user_agent??"—"}),e.jsx("dt",{className:"text-muted-foreground",children:"Privacy-Version"}),e.jsx("dd",{children:s.privacy_version??"—"}),e.jsx("dt",{className:"text-muted-foreground",children:"DOI-Reminder gesendet"}),e.jsx("dd",{children:w(s.doi_reminder_sent_at)}),s.manual_confirmed_at&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-muted-foreground",children:"Manuell bestätigt am"}),e.jsx("dd",{children:w(s.manual_confirmed_at)}),e.jsx("dt",{className:"text-muted-foreground",children:"Manuell bestätigt von"}),e.jsx("dd",{className:"text-xs",children:s.manual_confirmed_by_user?`${s.manual_confirmed_by_user.name??"—"}${s.manual_confirmed_by_user.email?` (${s.manual_confirmed_by_user.email})`:""}`:s.manual_confirmed_by??"—"}),e.jsx("dt",{className:"text-muted-foreground",children:"Bestätigungsgrund"}),e.jsx("dd",{className:"text-xs whitespace-pre-wrap",children:s.manual_confirm_note??"—"})]})]}),e.jsxs("div",{className:"rounded-md border border-border p-3 text-xs text-muted-foreground",children:[e.jsx("div",{className:"font-medium text-foreground mb-1",children:"Einwilligungstext (Snapshot)"}),s.consent_text??"—"]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"Segmente"}),d.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Noch keine Segmente angelegt."}):e.jsx("div",{className:"flex flex-wrap gap-2",children:d.map(c=>{const U=k.includes(c.id);return e.jsx("button",{onClick:()=>m(U?k.filter(D=>D!==c.id):[...k,c.id]),className:`text-xs rounded-full px-3 py-1 border ${U?"bg-primary text-primary-foreground border-primary":"border-border hover:bg-accent"}`,children:c.name},c.id)})}),n!==null&&e.jsx("button",{onClick:()=>q.mutate(),disabled:q.isPending,className:"text-xs rounded-md bg-primary text-primary-foreground px-3 py-1.5 disabled:opacity-50",children:q.isPending?"Speichern…":"Segmente speichern"})]}),e.jsxs("div",{className:"border-t border-border pt-4 space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"Aktionen"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[s.status!=="confirmed"&&e.jsx("button",{onClick:()=>F(c=>!c),className:"text-xs rounded-md border border-border px-3 py-1.5 hover:bg-accent",children:"Manuell bestätigen"}),s.status==="pending"&&e.jsx("button",{onClick:i,className:"text-xs rounded-md border border-border px-3 py-1.5 hover:bg-accent",children:"DOI-Mail erneut senden"}),s.status==="pending"&&e.jsx("button",{onClick:j,className:"text-xs rounded-md border border-border px-3 py-1.5 hover:bg-accent",children:"Reminder-Mail senden"}),s.status!=="unsubscribed"&&e.jsx("button",{onClick:()=>P(c=>!c),className:"text-xs rounded-md border border-border px-3 py-1.5 hover:bg-accent",children:"Als abgemeldet markieren"}),e.jsx("button",{onClick:u,className:"text-xs rounded-md border border-destructive/40 text-destructive px-3 py-1.5 hover:bg-destructive/10",children:"Löschen"})]}),v&&s.status!=="confirmed"&&e.jsxs("div",{className:"mt-3 space-y-2 rounded-md border border-border p-3",children:[e.jsx("label",{className:"text-xs font-medium",children:"Grund für manuelle Bestätigung (Pflichtfeld, mind. 5 Zeichen)"}),e.jsx("textarea",{value:A,onChange:c=>o(c.target.value),rows:3,placeholder:"z. B. Berechtigtes Interesse nach Telefonat am 02.06.2026 – möchte informiert bleiben.",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 text-xs"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{disabled:A.trim().length<5,onClick:()=>g(A.trim()),className:"text-xs rounded-md bg-primary text-primary-foreground px-3 py-1.5 disabled:opacity-50",children:"Bestätigen & speichern"}),e.jsx("button",{onClick:()=>{F(!1),o("")},className:"text-xs rounded-md border border-border px-3 py-1.5",children:"Abbrechen"})]}),f&&e.jsx("p",{className:"text-xs text-destructive",children:f})]}),R&&s.status!=="unsubscribed"&&e.jsxs("div",{className:"mt-3 space-y-2 rounded-md border border-border p-3",children:[e.jsx("label",{className:"text-xs font-medium",children:"Grund für manuelle Abmeldung (Pflichtfeld, mind. 5 Zeichen)"}),e.jsx("textarea",{value:E,onChange:c=>C(c.target.value),rows:3,placeholder:"z. B. Telefonische Abmeldung am 02.06.2026 – Person möchte keine Mails mehr erhalten.",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 text-xs"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{disabled:E.trim().length<5,onClick:()=>{b(E.trim()),P(!1),C("")},className:"text-xs rounded-md bg-primary text-primary-foreground px-3 py-1.5 disabled:opacity-50",children:"Abmelden & speichern"}),e.jsx("button",{onClick:()=>{P(!1),C("")},className:"text-xs rounded-md border border-border px-3 py-1.5",children:"Abbrechen"})]}),f&&e.jsx("p",{className:"text-xs text-destructive",children:f})]}),y&&e.jsx("p",{className:"text-xs text-muted-foreground",children:y}),r&&e.jsx("p",{className:"text-xs text-muted-foreground",children:r})]}),e.jsx(be,{subscriberId:s.id})]})})}const pe={manual_confirm:"Manuell bestätigt",manual_enroll:"Manuell aufgenommen (ohne DOI)",manual_unsubscribe:"Manuell abgemeldet",delete:"Gelöscht"},he={manual_confirm:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",manual_enroll:"bg-sky-500/15 text-sky-700 dark:text-sky-300",manual_unsubscribe:"bg-amber-500/15 text-amber-700 dark:text-amber-300",delete:"bg-destructive/15 text-destructive"};function be({subscriberId:s}){const d=p(ce),x=10,[h,g]=a.useState(0),b=K({queryKey:["nl","audit",s,h],queryFn:()=>d({data:{subscriberId:s,limit:x,offset:h*x}}),placeholderData:r=>r}),f=b.data?.entries??[],u=b.data?.total??0,i=Math.max(1,Math.ceil(u/x)),j=u===0?0:h*x+1,y=Math.min(u,(h+1)*x);return e.jsxs("div",{className:"border-t border-border pt-4 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm font-medium",children:["Audit-Log",u>0?` (${u})`:""]}),u>0&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:[j,"–",y," von ",u]})]}),b.isLoading?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Lade…"}):f.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Noch keine manuellen Admin-Aktionen für diesen Abonnenten."}):e.jsxs(e.Fragment,{children:[e.jsx("ul",{className:"space-y-2",children:f.map(r=>e.jsxs("li",{className:"rounded-md border border-border bg-background/40 p-3 text-xs space-y-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 font-medium ${he[r.action_type]??"bg-muted text-muted-foreground"}`,children:pe[r.action_type]??r.action_type}),e.jsx("span",{className:"text-muted-foreground",children:w(r.performed_at)}),e.jsxs("span",{className:"text-muted-foreground",children:["·"," ",r.performed_by_user?r.performed_by_user.name??r.performed_by_user.email??r.performed_by??"—":r.performed_by??"—"]}
1)]}),r.reason&&e.jsxs("div",{className:"whitespace-pre-wrap",children:[e.jsx("span",{className:"text-muted-foreground",children:"Begründung: "}),r.reason]})]},r.id))}),i>1&&e.jsxs("div",{className:"flex items-center justify-between pt-2",children:[e.jsx("button",{type:"button",onClick:()=>g(r=>Math.max(0,r-1)),disabled:h===0||b.isFetching,className:"text-xs rounded-md border border-border px-3 py-1 disabled:opacity-40 hover:bg-accent",children:"← Zurück"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["Seite ",h+1," von ",i,b.isFetching?" · lädt…":""]}),e.jsx("button",{type:"button",onClick:()=>g(r=>Math.min(i-1,r+1)),disabled:h>=i-1||b.isFetching,className:"text-xs rounded-md border border-border px-3 py-1 disabled:opacity-40 hover:bg-accent",children:"Weiter →"})]})]})]})}const G={opt_in:"Opt-in",opt_out:"Kein Opt-in",suppressed:"Sperre"},ge={opt_in:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",opt_out:"bg-muted text-muted-foreground",suppressed:"bg-destructive/15 text-destructive"};function fe(){const s=p(ue),d=K({queryKey:["nl","crm-article-contacts"],queryFn:()=>s({})}),[x,h]=a.useState(""),[g,b]=a.useState("all"),[f,u]=a.useState(1),i=50,j=a.useMemo(()=>(d.data??[]).filter(n=>n.source==="crm"||n.source==="both"),[d.data]),y=a.useMemo(()=>{const n={all:j.length,opt_in:0,opt_out:0,suppressed:0};return j.forEach(m=>{n[m.status]++}),n},[j]),r=a.useMemo(()=>{const n=x.trim().toLowerCase();return j.filter(m=>g!=="all"&&m.status!==g?!1:n?m.email.toLowerCase().includes(n)||(m.name??"").toLowerCase().includes(n):!0)},[j,x,g]),N=Math.max(1,Math.ceil(r.length/i)),_=Math.min(f,N),S=r.slice((_-1)*i,_*i);function I(){const m=[["Name","E-Mail","Sprache","Quelle","Status"].join(";")].concat(r.map(v=>[v.name??"",v.email,v.language.toUpperCase(),v.source==="both"?"CRM + Newsletter":"CRM",G[v.status]??v.status].map(F=>`"${String(F).replace(/"/g,'""')}"`).join(";"))),k=new Blob(["\uFEFF"+m.join(`\r
2`)],{type:"text/csv;charset=utf-8"}),A=URL.createObjectURL(k),o=document.createElement("a");o.href=A,o.download="crm-artikel-kontakte.csv",document.body.appendChild(o),o.click(),o.remove(),URL.revokeObjectURL(A)}return e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"CRM-Kontakte mit Namen und E-Mail. Artikel-Mails erhalten nur Kontakte mit Opt-in – der Versand ändert sich durch diese Ansicht nicht."}),e.jsx("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:["all","opt_in","opt_out","suppressed"].map(n=>e.jsxs("button",{onClick:()=>{b(n),u(1)},className:`rounded-full px-3 py-1.5 border ${g===n?"bg-primary text-primary-foreground border-primary":"border-border hover:bg-accent"}`,children:[n==="all"?"Alle":G[n]," (",y[n],")"]},n))}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{value:x,onChange:n=>{h(n.target.value),u(1)},placeholder:"Name oder E-Mail suchen…",className:"w-full max-w-md rounded-md border border-border bg-background px-3 py-2 text-sm"}),e.jsx("button",{onClick:I,disabled:!r.length,className:"rounded-md border border-border px-3 py-2 text-sm hover:bg-accent disabled:opacity-50",children:"CSV-Export"})]}),e.jsxs("div",{className:"rounded-2xl border border-border bg-card overflow-hidden",children:[d.isLoading&&e.jsx("div",{className:"p-6 text-sm text-muted-foreground",children:"Lade…"}),d.isError&&e.jsx("div",{className:"p-6 text-sm text-destructive",children:d.error.message}),!d.isLoading&&!d.isError&&S.length===0&&e.jsx("div",{className:"p-6 text-sm text-muted-foreground",children:"Keine Einträge."}),S.length>0&&e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-left text-xs uppercase tracking-wider text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3",children:"Name"}),e.jsx("th",{className:"px-4 py-3",children:"E-Mail"}),e.jsx("th",{className:"px-4 py-3",children:"Sprache"}),e.jsx("th",{className:"px-4 py-3",children:"Quelle"}),e.jsx("th",{className:"px-4 py-3",children:"Artikel-Status"})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:S.map(n=>e.jsxs("tr",{className:"hover:bg-muted/30",children:[e.jsx("td",{className:"px-4 py-3 font-medium",children:n.name??"—"}),e.jsx("td",{className:"px-4 py-3 break-all",children:n.email}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground uppercase text-xs",children:n.language}),e.jsx("td",{className:"px-4 py-3 text-muted-foreground text-xs",children:n.source==="both"?"CRM + Newsletter":"CRM"}),e.jsx("td",{className:"px-4 py-3",children:e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${ge[n.status]}`,children:G[n.status]})})]},n.email))})]})]}),r.length>i&&e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:[r.length," Kontakte – Seite ",_," von ",N]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>u(n=>Math.max(1,n-1)),disabled:_<=1,className:"rounded-md border border-border px-3 py-1.5 hover:bg-accent disabled:opacity-50",children:"Zurück"}),e.jsx("button",{onClick:()=>u(n=>Math.min(N,n+1)),disabled:_>=N,className:"rounded-md border border-border px-3 py-1.5 hover:bg-accent disabled:opacity-50",children:"Weiter"})]})]})]})}export{ve as component};

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.