1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var a=1;a<arguments.length;a++){var t=arguments[a];if(null!=t)for(var l in t)t.hasOwnProperty(l)&&(e[l]=t[l])}return e}({},e._sentryModuleMetadata[(new e.Error).stack],{"_sentryBundlerPluginAppKey:blabber-web":!0});var a=(new e.Error).stack;a&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[a]="565ae0ae-0ffb-4419-9d48-dad924b99821",e._sentryDebugIdIdentifier="sentry-dbid-565ae0ae-0ffb-4419-9d48-dad924b99821")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8416],{12486:(e,a,t)=>{t.d(a,{A:()=>l});let l=(0,t(19946).A)("send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]])},26661:(e,a,t)=>{t.d(a,{A:()=>l});let l=(0,t(19946).A)("calendar-clock",[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]])},27213:(e,a,t)=>{t.d(a,{A:()=>l});let l=(0,t(19946).A)("image",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}]])},48416:(e,a,t)=>{t.r(a),t.d(a,{PushNotificationModal:()=>N});var l=t(95155),s=t(12115),r=t(54165),n=t(30285),i=t(62523),d=t(85057),o=t(88539),c=t(59409),h=t(23861),m=t(51154),u=t(92657),b=t(12486),x=t(74575),g=t(26661),p=t(27213),f=t(54416),j=t(53904),v=t(56671),y=t(59434),w=t(59116);function N(e){let{trigger:a}=e,[t,N]=(0,s.useState)(!1),[k,A]=(0,s.useState)(!1),[S,_]=(0,s.useState)(!1),[L,C]=(0,s.useState)(null),[E,F]=(0,s.use
1State)(null),[M,P]=(0,s.useState)([]),[D,z]=(0,s.useState)(!1),[I,J]=(0,s.useState)({title:"",body:"",target:"all",channel:"both",linkUrl:"",linkLabel:"",scheduledAt:""}),T=(0,s.useCallback)(async()=>{z(!0);try{var e;let a=await fetch("/api/admin/broadcast",{cache:"no-store"}),t=await a.json().catch(()=>({}));if(!a.ok)throw Error(t.error||"Failed to load campaigns");P(null!=(e=t.campaigns)?e:[])}catch(e){v.toast.error(e instanceof Error?e.message:"Failed to load campaigns")}finally{z(!1)}},[]);(0,s.useEffect)(()=>{t&&T()},[t,T]);let U=()=>{let e=new FormData;return e.set("title",I.title.trim()),e.set("body",I.body.trim()),e.set("target",I.target),e.set("channel",I.channel),e.set("linkUrl",I.linkUrl.trim()),e.set("linkLabel",I.linkLabel.trim()),I.scheduledAt&&e.set("scheduledAt",new Date(I.scheduledAt).toISOString()),E&&e.set("image",E),e},B=async e=>{if(e.preventDefault(),!I.title.trim()||!I.body.trim())return void v.toast.error("Please fill in both title and body");A(!0);try{let e=await fetch("/api/admin/broadcast",{method:"POST",body:U()}),a=await e.json().catch(()=>({}));if(!e.ok)throw Error(a.error||"Failed to send broadcast");v.toast.success("scheduled"===a.status?"Broadcast scheduled for ".concat(a.recipients.toLocaleString()," recipients"):"Broadcast queued for ".concat(a.recipients.toLocaleString()," recipients")),J({title:"",body:"",target:"all",channel:"both",linkUrl:"",linkLabel:"",scheduledAt:""}),F(null),C(null),await T()}catch(e){console.error("Error sending broadcast:",e),v.toast.error(e instanceof Error?e.message:"Failed to send broadcast")}finally{A(!1)}},G=async()=>{if(!I.title.trim()||!I.body.trim())return void v.toast.error("Add a title and message before previewing");_(!0);try{let e=await fetch("/api/admin/broadcast/preview",{method:"POST",body:U()}),a=await e.json().catch(()=>({}));if(!e.ok)throw Error(a.error||"Failed to render preview");C(a.html)}catch(e){v.toast.error(e instanceof Error?e.message:"Failed to render preview")}finally{_(!1)}},O=(e,a)=>{J(t=>({...t,[e]:a})),C(null)},q=e=>{if(e&&e.size>5242880)return void v.toast.error("Image or GIF must be under 5 MB");F(e),C(null)};return(0,l.jsxs)(r.lG,{open:t,onOpenChange:N,children:[(0,l.jsx)(r.zM,{asChild:!0,children:a||(0,l.jsxs)(w.L6,{children:[(0,l.jsx)(h.A,{className:"h-4 w-4"}),"Send broadcast"]})}),(0,l.jsx)(w.yf,{icon:h.A,title:"Send broadcast",description:"Send a push notification, branded email, or both to users or creators.",size:"wide",footer:(0,l.jsxs)(l.Fragment,{children:[("email"===I.channel||"both"===I.channel)&&(0,l.jsxs)(n.$,{type:"button",variant:"outline",className:w.gT,onClick:()=>void G(),disabled:k||S,children:[S?(0,l.jsx)(m.A,{className:"h-4 w-4 animate-spin"}):(0,l.jsx)(u.A,{className:"h-4 w-4"}),"Preview email"]}),(0,l.jsx)(n.$,{type:"button",variant:"outline",className:w.gT,onClick:()=>N(!1),disabled:k,children:"Cancel"}),(0,l.jsx)(w.Yb,{type:"submit",form:"admin-push-form",disabled:k||!I.title.trim()||!I.body.trim(),children:k?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(m.A,{className:"h-4 w-4 animate-spin"}),"Queueingâ¦"]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(b.A,{className:"h-4 w-4"}),I.scheduledAt?"Schedule broadcast":"Queue broadcast"]})})]}),children:(0,l.jsxs)("form",{id:"admin-push-form",onSubmit:B,className:"space-y-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"channel",children:"Delivery channel"}),(0,l.jsxs)(c.l6,{value:I.channel,onValueChange:e=>O("channel",e),children:[(0,l.jsx)(c.bq,{id:"channel",className:(0,y.cn)("mt-1.5 w-full",w.o3),children:(0,l.jsx)(c.yv,{})}),(0,l.jsxs)(c.gC,{children:[(0,l.jsx)(c.eb,{value:"both",children:"Push + email"}),(0,l.jsx)(c.eb,{value:"push",children:"Push only"}),(0,l.jsx)(c.eb,{value:"email",children:"Email only"})]})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"target",children:"Target audience"}),(0,l.jsxs)(c.l6,{value:I.target,onValueChange:e=>O("target",e),children:[(0,l.jsx)(c.bq,{id:"target",className:(0,y.cn)("mt-1.5 w-full",w.o3),children:(0,l.jsx)(c.yv,{})}),(0,l.jsxs)(c.gC,{children:[(0,l.jsx)(c.eb,{value:"all",children:"All users"}),(0,l.jsx)(c.eb,{value:"creators",children:"Creators only"})]})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"title",children:"Title / email subject"}),(0,l.jsx)(i.p,{id:"title",value:I.title,onChange:e=>O("title",e.target.value),placeholder:"Enter notification titleâ¦",className:(0,y.cn)("mt-1.5",w.m_),maxLength:100})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"body",children:"Message"}),(0,l.jsx)(o.T,{id:"body",value:I.body,onChange:e=>O("body",e.target.value),placeholder:"Enter notification messageâ¦",className:(0,y.cn)("mt-1.5",w.Ym),rows:5,maxLength:5e3}),("push"===I.channel||"both"===I.channel)&&I.body.length>240&&(0,l.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"Push previews are truncated to 240 characters; email keeps the full message."})]}),("email"===I.channel||"both"===I.channel)&&(0,l.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"link-url",children:"Email link (optional)"}),(0,l.jsxs)("div",{className:"relative mt-1.5",children:[(0,l.jsx)(x.A,{className:"absolute left-3 top-3 h-4 w-4 text-muted-foreground"}),(0,l.jsx)(i.p,{id:"link-url",type:"url",value:I.linkUrl,onChange:e=>O("linkUrl",e.target.value),placeholder:"https://blabber.ai/...",className:(0,y.cn)("pl-9",w.m_),maxLength:2e3})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"link-label",children:"Button label"}),(0,l.jsx)(i.p,{id:"link-label",value:I.linkLabel,onChange:e=>O("linkLabel",e.target.value),placeholder:"Learn more",className:(0,y.cn)("mt-1.5",w.m_),maxLength:80,disabled:!I.linkUrl})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"scheduled-at",children:"Schedule (optional)"}),(0,l.jsxs)("div",{className:"relative mt-1.5",children:[(0,l.jsx)(g.A,{className:"absolute left-3 top-3 h-4 w-4 text-muted-foreground"}),(0,l.jsx)(i.p,{id:"scheduled-at",type:"datetime-local",value:I.scheduledAt,onChange:e=>O("scheduledAt",e.target.value),min:new Date(Date.now()-6e4*new Date().getTimezoneOffset()).toISOString().slice(0,16),className:(0,y.cn)("pl-9",w.m_)})]}),(0,l.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"Uses your local time. Leave blank to queue immediately."})]}),("email"===I.channel||"both"===I.channel)&&(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{htmlFor:"broadcast-image",children:"Email image or GIF (optional)"}),(0,l.jsx)(i.p,{id:"broadcast-image",type:"file",accept:"image/gif,image/jpeg,image/png,image/webp",onChange:e=>{var a,t;return q(null!=(t=null==(a=e.target.files)?void 0:a[0])?t:null)},className:(0,y.cn)("mt-1.5",w.m_)}),(0,l.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"GIF, JPEG, PNG, or WebP. Maximum 5 MB. GIF animation depends on the email client."}),E&&(0,l.jsxs)("div",{className:"mt-2 flex items-center gap-2 rounded-lg border border-border p-2 text-sm",children:[(0,l.jsx)(p.A,{className:"h-4 w-4 text-muted-foreground"}),(0,l.jsx)("span",{className:"min-w-0 flex-1 truncate",children:E.name}),(0,l.jsx)(n.$,{type:"button",variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>q(null),"aria-label":"Remove image",children:(0,l.jsx)(f.A,{className:"h-4 w-4"})})]})]}),L&&(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"mb-1.5 flex items-center justify-between",children:[(0,l.jsx)(d.J,{children:"Email preview"}),(0,l.jsx)(n.$,{type:"button",variant:"ghost",size:"sm",onClick:()=>C(null),children:"Close preview"})]}),(0,l.jsx)("iframe",{title:"Email preview",srcDoc:L,sandbox:"",className:"h-[420px] w-full rounded-xl border border-border bg-white"})]}),(0,l.jsxs)("div",{className:"border-t border-border pt-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex items-center justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(d.J,{children:"Broadcast analytics"}),(0,l.jsx)("p",{className:"text-xs text-muted-foreground",children:"Latest 25 campaigns"})]}),(0,l.jsxs)(n.$,{type:"button",variant:"ghost",size:"sm",onClick:()=>void T(),disabled:D,children:[(0,l.jsx)(j.A,{className:(0,y.cn)("h-4 w-4",D&&"animate-spin")}),"Refresh"]})]}),(0,l.jsx)("div",{className:"max-h-64 space-y-2 overflow-y-auto pr-1",children:0!==M.length||D?M.map(e=>(0,l.jsxs)("div",{className:"rounded-lg border border-border p-3",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,l.jsxs)("div",{className:"min-w-0",children:[(0,l.jsx)("p",{className:"truncate text-sm font-semibold",children:e.title}),(0,l.jsxs)("p",{className:"text-xs text-muted-foreground",children:[e.channel," \xb7 ",e.target," \xb7"," ",new Date(e.scheduled_at).toLocaleStr
1ing()]})]}),(0,l.jsx)("span",{className:"shrink-0 rounded-full bg-secondary px-2 py-1 text-[11px] font-semibold capitalize",children:e.status})]}),(0,l.jsxs)("div",{className:"mt-2 grid grid-cols-2 gap-x-3 gap-y-1 text-xs sm:grid-cols-4",children:[(0,l.jsxs)("span",{children:["Audience: ",Number(e.total_recipients).toLocaleString()]}),(0,l.jsxs)("span",{children:["Remaining: ",Number(e.remaining).toLocaleString()]}),"email"!==e.channel&&(0,l.jsxs)("span",{children:["Push: ",Number(e.push_sent).toLocaleString()," sent",Number(e.push_failed)>0?" \xb7 ".concat(Number(e.push_failed).toLocaleString()," failed"):""]}),"push"!==e.channel&&(0,l.jsxs)("span",{children:["Email: ",Number(e.email_delivered).toLocaleString()," delivered \xb7"," ",Number(e.email_sent).toLocaleString()," accepted",Number(e.email_bounced)>0?" \xb7 ".concat(Number(e.email_bounced).toLocaleString()," bounced"):"",Number(e.email_failed)>0?" \xb7 ".concat(Number(e.email_failed).toLocaleString()," failed"):""]})]})]},e.id)):(0,l.jsx)("p",{className:"rounded-lg border border-border p-3 text-sm text-muted-foreground",children:"No broadcast campaigns yet."})})]})]})})]})}},51154:(e,a,t)=>{t.d(a,{A:()=>l});let l=(0,t(19946).A)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]])},88539:(e,a,t)=>{t.d(a,{T:()=>r});var l=t(95155);t(12115);var s=t(59434);function r(e){let{className:a,...t}=e;return(0,l.jsx)("textarea",{"data-slot":"textarea",className:(0,s.cn)("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",a),...t})}}}]);
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.