1 2!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="229d188f-6db8-5d8a-b91b-37aa124cdacc")}catch(e){}}(); 3import{j as e}from"./vendor-radix-D60p-_ms.js";import{r as j}from"./vendor-react-DRd396Ms.js";import{b as W,u as B,c as D}from"./vendor-query-CQDkrmBu.js";import{aa as h,_ as N,ab as Y,X as J,k as ee,M as V,at as te,W as se,E as w,t as S,b2 as ne}from"./index-vRxdZvmj.js";import{u as E}from"./user-facing-error-DLM6u6dy.js";import{L as x}from"./label-Dk_MsvbC.js";import{C as T}from"./checkbox-91d6NYLq.js";import{B as ie}from"./badge-CgJg1GxD.js";import{A as H}from"./arrow-up-BypPhMK-.js";import{S as ae}from"./save-CdZkQnJm.js";import{S as R}from"./send-q5QUywj2.js";import{C as re}from"./chart-column-CfdDvQpg.js";import{C as ce}from"./copy-DPcXc346.js";import{T as le}from"./trash-2-Cuh3Lz01.js";import"./vendor-classnames-B2rm_Apj.js";import"./vendor-motion-DZC2ImUw.js";import"./vendor-i18n-D-E_aly0.js";const de=[{value:"top_strip",label:"Top strip"},{value:"inline_widget",label:"Inline widget"},{value:"modal_interrupt",label:"Modal interrupt"},{value:"nav_badge_inbox",label:"Nav badge + inbox"},{value:"email",label:"Email",disabled:!0,badge:"coming soon"}],oe=["has_zero_courses","has_in_progress_course","has_published_course"],ue=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;function M(){return{slug:"",title:"",body:"",icon:"",ctaLabel:"",ctaHref:"",kind:"feature",priority:"normal",surfaces:[],targetPaths:[],targeting:{authState:"any",roles:[],tiers:[],posthogCohortId:"",signupAgeDays:{min:"",max:""},daysSinceLastVisit:{min:"",max:""},customPredicates:[]},lifecycle:{dismissStrategy:"permanent",maxViewsPerUser:"",dismissOnCtaClick:!0,expiresAt:""},sacredZones:[]}}function I(s){var d,o,u,r,a,g,b,f;const c=s.targeting||{},l=s.lifecycle||{};return{slug:s.slug||"",title:s.title||"",body:s.body||"",icon:s.icon||"",ctaLabel:s.ctaLabel||"",ctaHref:s.ctaHref||"",kind:s.kind||"feature",priority:s.priority||"normal",surfaces:s.surfaces||[],targetPaths:s.targetPaths||[],targeting:{authState:c.authState||"any",roles:c.roles||[],tiers:c.tiers||[],posthogCohortId:c.posthogCohortId||"",signupAgeDays:{min:((o=(d=c.signupAgeDays)==null?void 0:d.min)==null?void 0:o.toString())??"",max:((r=(u=c.signupAgeDays)==null?void 0:u.max)==null?void 0:r.toString())??""},daysSinceLastVisit:{min:((g=(a=c.daysSinceLastVisit)==null?void 0:a.min)==null?void 0:g.toString())??"",max:((f=(b=c.daysSinceLastVisit)==null?void 0:b.max)==null?void 0:f.toString())??""},customPredicates:c.customPredicates||[]},lifecycle:{dismissStrategy:l.dismissStrategy||"permanent",maxViewsPerUser:l.maxViewsPerUser!==void 0&&l.maxViewsPerUser!==null?String(l.maxViewsPerUser):"",dismissOnCtaClick:l.dismissOnCtaClick===void 0?!0:!!l.dismissOnCtaClick,expiresAt:l.expiresAt?new Date(l.expiresAt).toISOString().slice(0,16):""},sacredZones:s.sacredZones||[]}}function me(s){const c=s.targeting.signupAgeDays.min.trim(),l=s.targeting.signupAgeDays.max.trim(),d=s.targeting.daysSinceLastVisit.min.trim(),o=s.targeting.daysSinceLastVisit.max.trim(),u={};c!==""&&(u.min=Number(c)),l!==""&&(u.max=Number(l));const r={};d!==""&&(r.min=Number(d)),o!==""&&(r.max=Number(o));const a={};s.targeting.authState&&s.targeting.authState!=="any"&&(a.authState=s.targeting.authState),s.targeting.roles.length>0&&(a.roles=s.targeting.roles),s.targeting.tiers.length>0&&(a.tiers=s.targeting.tiers),s.targeting.posthogCohortId.trim()!==""&&(a.posthogCohortId=s.targeting.posthogCohortId.trim()),Object.keys(u).length>0&&(a.signupAgeDays=u),Object.keys(r).length>0&&(a.daysSinceLastVisit=r),s.targeting.customPredicates.length>0&&(a.customPredicates=s.targeting.customPredicates);const g={dismissStrategy:s.lifecycle.dismissStrategy,dismissOnCtaClick:s.lifecycle.dismissOnCtaClick};return s.lifecycle.maxViewsPerUser.trim()!==""&&(g.maxViewsPerUser=Number(s.lifecycle.maxViewsPerUser)),s.lifecycle.expiresAt.trim()!==""&&(g.expiresAt=new Date(s.lifecycle.expiresAt).toISOString()),{slug:s.slug.trim(),title:s.title.trim(),body:s.body,icon:s.icon.trim()||null,ctaLabel:s.ctaLabel.trim()||null,ctaHref:s.ctaHref.trim()||null,kind:s.kind,priority:s.priority,surfaces:s.surfaces,targetPaths:s.targetPaths,targeting:a,lifecycle:g,sacredZones:s.sacredZones}}function O({values:s,onChange:c,placeholder:l,testId:d}){const[o,u]=j.useState(""),r=()=>{const a=o.trim();if(a){if(s.includes(a)){u("");return}c([...s,a]),u("")}};return e.jsxs("div",{className:"flex flex-wrap gap-1.5 p-2 bg-zinc-950 border border-zinc-800 rounded-[6px] min-h-[40px]",children:[s.map(a=>e.jsxs(ie,{variant:"secondary",className:"bg-zinc-800 text-zinc-200 gap-1 pl-2 pr-1 font-mono text-xs",children:[a,e.jsx("button",{type:"button",onClick:()=>c(s.filter(g=>g!==a)),className:"rounded-full hover:bg-zinc-700 p-0.5","aria-label":`Remove ${a}`,children:e.jsx(J,{className:"w-3 h-3"})})]},a)),e.jsx("input",{value:o,onChange:a=>u(a.target.value),onKeyDown:a=>{a.key==="Enter"||a.key===","?(a.preventDefault(),r()):a.key==="Backspace"&&o===""&&s.length>0&&c(s.slice(0,-1))},onBlur:r,placeholder:l,"data-testid":d,className:"flex-1 min-w-[140px] bg-transparent text-sm text-zinc-200 outline-none placeholder:text-zinc-600"})]})}function U({initial:s,onSubmit:c,onBumpVersion:l,contentVersion:d,isSaving:o,isPublished:u}){const[r,a]=j.useState(()=>s?I(s):M()),[g,b]=j.useState(!1);j.useEffect(()=>{a(s?I(s):M()),b(!1)},[s==null?void 0:s.id]);const f=ue.test(r.slug),_=r.slug.length>0&&f&&r.title.length>0&&r.body.length>0,v=t=>{a(n=>({...n,surfaces:n.surfaces.includes(t)?n.surfaces.filter(y=>y!==t):[...n.surfaces,t]}))},k=t=>{a(n=>({...n,targeting:{...n.targeting,roles:n.targeting.roles.includes(t)?n.targeting.roles.filter(y=>y!==t):[...n.targeting.roles,t]}}))},p=t=>{a(n=>({...n,targeting:{...n.targeting,tiers:n.targeting.tiers.includes(t)?n.targeting.tiers.filter(y=>y!==t):[...n.targeting.tiers,t]}}))},z=t=>{a(n=>({...n,targeting:{...n.targeting,customPredicates:n.targeting.customPredicates.includes(t)?n.targeting.customPredicates.filter(y=>y!==t):[...n.targeting.customPredicates,t]}}))},F=t=>{_&&c(me(r),t)};return e.jsxs("form",{onSubmit:t=>{t.preventDefault(),F(!1)},className:"space-y-5","data-testid":"form-announcement",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"sm:col-span-2",children:[e.jsx(x,{htmlFor:"ann-slug",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Slug *"}),e.jsx(h,{id:"ann-slug",value:r.slug,onChange:t=>{b(!0),a(n=>({...n,slug:t.target.value.toLowerCase()}))},onBlur:()=>b(!0),placeholder:"courses-launched-v1","data-testid":"input-ann-slug",className:"bg-zinc-950 border-zinc-800 font-mono text-sm mt-1"}),g&&r.slug.length>0&&!f&&e.jsx("p",{className:"text-xs text-red-400 mt-1",children:"lowercase-kebab only (a-z, 0-9, dashes)"})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Content version"}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsxs("div",{className:"px-3 py-2 bg-zinc-950 border border-zinc-800 rounded-[6px] text-sm text-zinc-300 flex-1",children:["v",d??1]}),s&&l&&e.jsxs(N,{type:"button",size:"sm",variant:"outline",onClick:l,title:"Re-surface to dismissed users","data-testid":"button-bump-version",children:[e.jsx(H,{className:"w-3 h-3 mr-1"})," Bump"]})]})]})]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-title",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Title *"}),e.jsx(h,{id:"ann-title",value:r.title,onChange:t=>a(n=>({...n,title:t.target.value})),placeholder:"Courses are live","data-testid":"input-ann-title",className:"bg-zinc-950 border-zinc-800 mt-1"})]}),e.jsxs("div",{children:[e.jsxs(x,{htmlFor:"ann-body",className:"text-xs uppercase tracking-wide text-zinc-400",children:["Body * ",e.jsx("span",{className:"normal-case text-zinc-500",children:"(markdown ok)"})]}),e.jsx(Y,{id:"ann-body",value:r.body,onChange:t=>a(n=>({...n,body:t.target.value})),rows:5,placeholder:"Turn any chat into a structured course...","data-testid":"textarea-ann-body",className:"bg-zinc-950 border-zinc-800 mt-1 font-mono text-sm"})]}),e.jsxs("div",{children:[e.jsxs(x,{htmlFor:"ann-icon",className:"text-xs uppercase tracking-wide text-zinc-400",children:["Icon ",e.jsx("span",{className:"normal-case text-zinc-500",children:"(emoji or lucide-react name)"})]}
3),e.jsx(h,{id:"ann-icon",value:r.icon,onChange:t=>a(n=>({...n,icon:t.target.value})),placeholder:"GraduationCap","data-testid":"input-ann-icon",className:"bg-zinc-950 border-zinc-800 mt-1"})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-cta-label",className:"text-xs uppercase tracking-wide text-zinc-400",children:"CTA label"}),e.jsx(h,{id:"ann-cta-label",value:r.ctaLabel,onChange:t=>a(n=>({...n,ctaLabel:t.target.value})),placeholder:"Take a tour","data-testid":"input-ann-cta-label",className:"bg-zinc-950 border-zinc-800 mt-1"})]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-cta-href",className:"text-xs uppercase tracking-wide text-zinc-400",children:"CTA href"}),e.jsx(h,{id:"ann-cta-href",value:r.ctaHref,onChange:t=>a(n=>({...n,ctaHref:t.target.value})),placeholder:"/courses/new","data-testid":"input-ann-cta-href",className:"bg-zinc-950 border-zinc-800 mt-1 font-mono text-sm"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-kind",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Kind"}),e.jsxs("select",{id:"ann-kind",value:r.kind,onChange:t=>a(n=>({...n,kind:t.target.value})),"data-testid":"select-ann-kind",className:"w-full bg-zinc-950 border border-zinc-800 rounded-[6px] px-3 py-2 text-sm text-zinc-200 mt-1",children:[e.jsx("option",{value:"feature",children:"feature"}),e.jsx("option",{value:"system",children:"system"}),e.jsx("option",{value:"promo",children:"promo"}),e.jsx("option",{value:"behavioral",children:"behavioral"}),e.jsx("option",{value:"personal",children:"personal"}),e.jsx("option",{value:"digest",children:"digest"})]})]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-priority",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Priority"}),e.jsxs("select",{id:"ann-priority",value:r.priority,onChange:t=>a(n=>({...n,priority:t.target.value})),"data-testid":"select-ann-priority",className:"w-full bg-zinc-950 border border-zinc-800 rounded-[6px] px-3 py-2 text-sm text-zinc-200 mt-1",children:[e.jsx("option",{value:"low",children:"low"}),e.jsx("option",{value:"normal",children:"normal"}),e.jsx("option",{value:"high",children:"high"}),e.jsx("option",{value:"urgent",children:"urgent"})]})]})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Surfaces"}),e.jsx("div",{className:"mt-2 grid grid-cols-1 sm:grid-cols-2 gap-2",children:de.map(t=>{const n=r.surfaces.includes(t.value);return e.jsxs("label",{className:`flex items-center gap-2 px-3 py-2 border rounded-md text-sm ${t.disabled?"border-zinc-900 bg-zinc-950/40 text-zinc-600 cursor-not-allowed":"border-zinc-800 bg-zinc-950 hover:bg-zinc-900 cursor-pointer"}`,children:[e.jsx(T,{checked:n,disabled:t.disabled,onCheckedChange:()=>!t.disabled&&v(t.value),"data-testid":`checkbox-surface-${t.value}`}),e.jsx("span",{className:"flex-1",children:t.label}),t.badge&&e.jsx("span",{className:"text-[10px] uppercase tracking-wide text-zinc-500 border border-zinc-800 rounded-[6px] px-1.5 py-0.5",children:t.badge})]},t.value)})})]}),e.jsxs("div",{children:[e.jsxs(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:["Target paths ",e.jsx("span",{className:"normal-case text-zinc-500",children:"(for inline_widget; type + Enter)"})]}),e.jsx("div",{className:"mt-1",children:e.jsx(O,{values:r.targetPaths,onChange:t=>a(n=>({...n,targetPaths:t})),placeholder:"/explore",testId:"input-target-paths"})})]}),e.jsxs("div",{className:"border border-zinc-800 rounded-[8px] p-4 space-y-4 bg-zinc-900/30",children:[e.jsx("h3",{className:"text-sm font-semibold text-zinc-200",children:"Targeting"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-auth-state",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Auth state"}),e.jsxs("select",{id:"ann-auth-state",value:r.targeting.authState,onChange:t=>a(n=>({...n,targeting:{...n.targeting,authState:t.target.value}})),"data-testid":"select-auth-state",className:"w-full bg-zinc-950 border border-zinc-800 rounded-[6px] px-3 py-2 text-sm text-zinc-200 mt-1",children:[e.jsx("option",{value:"any",children:"any"}),e.jsx("option",{value:"unauthed",children:"unauthed"}),e.jsx("option",{value:"authed",children:"authed"}),e.jsx("option",{value:"authed_new",children:"authed_new"}),e.jsx("option",{value:"authed_returning",children:"authed_returning"})]})]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-cohort",className:"text-xs uppercase tracking-wide text-zinc-400",children:"PostHog cohort id"}),e.jsx(h,{id:"ann-cohort",value:r.targeting.posthogCohortId,onChange:t=>a(n=>({...n,targeting:{...n.targeting,posthogCohortId:t.target.value}})),placeholder:"optional","data-testid":"input-cohort",className:"bg-zinc-950 border-zinc-800 mt-1 font-mono text-sm"})]})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Roles"}),e.jsx("div",{className:"flex gap-3 mt-2",children:["user","creator","admin"].map(t=>e.jsxs("label",{className:"flex items-center gap-2 text-sm text-zinc-300",children:[e.jsx(T,{checked:r.targeting.roles.includes(t),onCheckedChange:()=>k(t),"data-testid":`checkbox-role-${t}`}),t]},t))})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Tiers"}),e.jsx("div",{className:"flex gap-3 mt-2",children:["free","pro","elite"].map(t=>e.jsxs("label",{className:"flex items-center gap-2 text-sm text-zinc-300",children:[e.jsx(T,{checked:r.targeting.tiers.includes(t),onCheckedChange:()=>p(t),"data-testid":`checkbox-tier-${t}`}),t]},t))})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Signup age (days)"}),e.jsxs("div",{className:"flex gap-2 mt-1",children:[e.jsx(h,{type:"number",value:r.targeting.signupAgeDays.min,onChange:t=>a(n=>({...n,targeting:{...n.targeting,signupAgeDays:{...n.targeting.signupAgeDays,min:t.target.value}}})),placeholder:"min","data-testid":"input-signup-min",className:"bg-zinc-950 border-zinc-800"}),e.jsx(h,{type:"number",value:r.targeting.signupAgeDays.max,onChange:t=>a(n=>({...n,targeting:{...n.targeting,signupAgeDays:{...n.targeting.signupAgeDays,max:t.target.value}}})),placeholder:"max","data-testid":"input-signup-max",className:"bg-zinc-950 border-zinc-800"})]})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Days since last visit"}),e.jsxs("div",{className:"flex gap-2 mt-1",children:[e.jsx(h,{type:"number",value:r.targeting.daysSinceLastVisit.min,onChange:t=>a(n=>({...n,targeting:{...n.targeting,daysSinceLastVisit:{...n.targeting.daysSinceLastVisit,min:t.target.value}}})),placeholder:"min","data-testid":"input-dlv-min",className:"bg-zinc-950 border-zinc-800"}),e.jsx(h,{type:"number",value:r.targeting.daysSinceLastVisit.max,onChange:t=>a(n=>({...n,targeting:{...n.targeting,daysSinceLastVisit:{...n.targeting.daysSinceLastVisit,max:t.target.value}}})),placeholder:"max","data-testid":"input-dlv-max",className:"bg-zinc-950 border-zinc-800"})]})]})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:"Custom predicates"}),e.jsx("div",{className:"flex flex-col gap-2 mt-2",children:oe.map(t=>e.jsxs("label",{className:"flex items-center gap-2 text-sm text-zinc-300 font-mono",children:[e.jsx(T,{checked:r.targeting.customPredicates.includes(t),onCheckedChange:()=>z(t),"data-testid":`checkbox-predicate-${t}`}),t]},t))})]})]}),e.jsxs("div",{className:"border border-zinc-800 rounded-[8px] p-4 space-y-4 bg-zinc-900/30",children:[e.jsx("h3",{className:"text-sm font-semibold text-zinc-200",children:"Lifecycle"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-dismiss-strategy",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Dismiss strategy"}),e.jsxs("select",{id:"ann-dismiss-strategy",value:r.lifecycle.dismissStrategy,onChange:t=>a(n=>({...n,lifecycle:{...n.lifecycle,dismissStrategy:t.target.value}})),"data-testid":"select-dismiss-strategy",className:"w-full bg-zinc-950 border border-zinc-800 rounded-[6px] px-3 py-2 text-sm text-zinc-200 mt-1",children:[e.jsx("option",{value:"permanent",children:"permanent"}),e.jsx("option",{value:"session",children:"session"}),e.jsx("option",{value:"cooldown_24h",children:"cooldown_24h"}),e.jsx("option",{value:"snooze_7d",children:"snooze_7d"})]})]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-max-views",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Max views per user"}),e.jsx(h,{id:"ann-max-views",type:"number",value:r.lifecycle.maxViewsPerUser,onChange:t=>a(n=>({...n,lifecycle:{...n.lifecycle,maxViewsPerUser:t.target.value}})),placeholder:"unlimited","data-testid":"input-max-views",className:"bg-zinc-950 border-zinc-800 mt-1"})]})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-zinc-300",children:[e.jsx(T,{checked:r.lifecycle.dismissOnCtaClick,onCheckedChange:t=>a(n=>({...n,lifecycle:{...n.lifecycle,dismissOnCtaClick:!!t}}
3)),"data-testid":"checkbox-dismiss-on-cta"}),"Dismiss on CTA click"]}),e.jsxs("div",{children:[e.jsx(x,{htmlFor:"ann-expires",className:"text-xs uppercase tracking-wide text-zinc-400",children:"Expires at"}),e.jsx(h,{id:"ann-expires",type:"datetime-local",value:r.lifecycle.expiresAt,onChange:t=>a(n=>({...n,lifecycle:{...n.lifecycle,expiresAt:t.target.value}})),"data-testid":"input-expires-at",className:"bg-zinc-950 border-zinc-800 mt-1"})]})]}),e.jsxs("div",{children:[e.jsxs(x,{className:"text-xs uppercase tracking-wide text-zinc-400",children:["Sacred zones ",e.jsx("span",{className:"normal-case text-zinc-500",children:"(additional path prefixes to skip)"})]}),e.jsx("div",{className:"mt-1",children:e.jsx(O,{values:r.sacredZones,onChange:t=>a(n=>({...n,sacredZones:t})),placeholder:"/onboarding/",testId:"input-sacred-zones"})})]}),e.jsxs("div",{className:"flex items-center justify-end gap-2 pt-2 border-t border-zinc-800",children:[e.jsxs(N,{type:"submit",variant:"outline",disabled:!_||o,"data-testid":"button-save-draft",children:[e.jsx(ae,{className:"w-4 h-4 mr-1"}),o?"Saving...":"Save draft"]}),e.jsxs(N,{type:"button",onClick:()=>F(!0),disabled:!_||o,className:"bg-blue-600 hover:bg-blue-500 text-white","data-testid":"button-save-publish",children:[e.jsx(R,{className:"w-4 h-4 mr-1"}),u?"Save (already published)":"Save & publish"]})]})]})}function Z(s){if(!s)return"";const c=new Date(s),l=Date.now()-c.getTime(),d=Math.floor(l/6e4);if(d<1)return"just now";if(d<60)return`${d}m ago`;const o=Math.floor(d/60);if(o<24)return`${o}h ago`;const u=Math.floor(o/24);return u<7?`${u}d ago`:c.toLocaleDateString()}function q({a:s}){var d;const c=(d=s.lifecycle)==null?void 0:d.expiresAt;return c&&new Date(c)<new Date?e.jsx("span",{className:"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-zinc-800 text-zinc-400 border border-zinc-700",children:"Archived"}):s.isPublished?e.jsx("span",{className:"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-green-900/40 text-green-400 border border-green-800",children:"Published"}):e.jsx("span",{className:"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-yellow-900/30 text-yellow-300 border border-yellow-800",children:"Draft"})}function K({announcementId:s}){const{data:c,isLoading:l}=B({queryKey:["admin-announcement-stats",s],queryFn:async()=>{const g=await fetch(`/api/admin/announcements/${s}/stats`,{credentials:"include"});if(!g.ok)throw new Error("Failed to load stats");return g.json()},staleTime:6e4});if(l)return e.jsx("span",{className:"text-[11px] text-zinc-600",children:"loading statsâ¦"});const d=c==null?void 0:c.stats;if(!d)return null;const o=Number(d.total_impressions||0),u=Number(d.dismissed_cta||0),r=Number(d.total_seen||0),a=r>0?Math.round(u/r*100):0;return e.jsxs("span",{className:"text-[11px] text-zinc-500",children:[o," impressions · ",a,"% CTR"]})}function xe({announcement:s,active:c,onSelect:l,onTogglePublish:d,onDuplicate:o,onBumpVersion:u,onDelete:r,busyAction:a}){var b;const g=((b=s.surfaces)==null?void 0:b.length)??0;return e.jsxs("div",{className:`border rounded-[8px] p-3 cursor-pointer transition ${c?"border-blue-600 bg-blue-950/20":"border-zinc-800 bg-zinc-900/40 hover:border-zinc-700 hover:bg-zinc-900/70"}`,onClick:l,"data-testid":`row-announcement-${s.slug}`,children:[e.jsx("div",{className:"flex items-start justify-between gap-2",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h3",{className:"font-semibold text-sm text-zinc-100 truncate",children:s.title}),e.jsx(q,{a:s})]}),e.jsxs("p",{className:"text-[11px] text-zinc-500 font-mono mt-0.5 truncate",children:[s.slug," · v",s.contentVersion]}),e.jsxs("p",{className:"text-[11px] text-zinc-500 mt-1",children:[g," surface",g===1?"":"s"," · updated ",Z(s.updatedAt)]}),e.jsx("div",{className:"mt-1",children:e.jsx(K,{announcementId:s.id})})]})}),e.jsxs("div",{className:"flex flex-wrap gap-1 mt-2",onClick:f=>f.stopPropagation(),children:[e.jsx(N,{size:"sm",variant:"ghost",className:"px-2 text-xs text-zinc-300 hover:bg-zinc-800",onClick:d,disabled:a==="publish","data-testid":`button-toggle-publish-${s.slug}`,children:s.isPublished?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"w-3 h-3 mr-1"})," Unpublish"]}):e.jsxs(e.Fragment,{children:[e.jsx(R,{className:"w-3 h-3 mr-1"})," Publish"]})}),e.jsxs(N,{size:"sm",variant:"ghost",className:"px-2 text-xs text-zinc-300 hover:bg-zinc-800",onClick:o,disabled:a==="duplicate","data-testid":`button-duplicate-${s.slug}`,children:[e.jsx(ce,{className:"w-3 h-3 mr-1"})," Duplicate"]}),e.jsxs(N,{size:"sm",variant:"ghost",className:"px-2 text-xs text-zinc-300 hover:bg-zinc-800",onClick:u,disabled:a==="bump","data-testid":`button-bump-${s.slug}`,children:[e.jsx(H,{className:"w-3 h-3 mr-1"})," Bump"]}),e.jsxs(N,{size:"sm",variant:"ghost",className:"px-2 text-xs text-red-400 hover:bg-red-950/40 hover:text-red-300",onClick:r,disabled:a==="delete","data-testid":`button-delete-${s.slug}`,children:[e.jsx(le,{className:"w-3 h-3 mr-1"})," Delete"]})]})]})}function De(){const s=W(),{toast:c}=ee(),[l,d]=j.useState(null),[o,u]=j.useState(!1),[r,a]=j.useState(null),[g,b]=j.useState("all"),{data:f,isLoading:_}=B({queryKey:["admin-announcements"],queryFn:async()=>{const i=await fetch("/api/admin/announcements",{credentials:"include"});if(!i.ok)throw new Error("Failed to load announcements");return i.json()},staleTime:15e3}),v=(f==null?void 0:f.announcements)||[],k=j.useMemo(()=>{const i=[...v].sort((m,C)=>{const A=new Date(m.updatedAt).getTime();return new Date(C.updatedAt).getTime()-A});return g==="draft"?i.filter(m=>!m.isPublished):g==="published"?i.filter(m=>m.isPublished):i},[v,g]);j.useEffect(()=>{!o&&l===null&&k.length>0&&d(k[0].id)},[k,l,o]);const p=j.useMemo(()=>l&&v.find(i=>i.id===l)||null,[v,l]),z=()=>{s.invalidateQueries({queryKey:["admin-announcements"]}),s.invalidateQueries({queryKey:["admin-announcement-stats"]})},F=D({mutationFn:async({payload:i,publish:m})=>{const P=(await(await w("POST","/api/admin/announcements",i)).json()).announcement;return m&&(await w("POST",`/api/admin/announcements/${P.id}/publish`,{}),S("admin_announcement_published",{slug:P.slug})),S("admin_announcement_created",{slug:P.slug,published:m}),P},onSuccess:i=>{c({title:"Announcement created"}),u(!1),d(i.id),z()},onError:i=>{c({title:"Failed to create announcement",description:E(i,"The announcement was not created. Please try again."),variant:"destructive"})}}),t=D({mutationFn:async({id:i,payload:m,publish:C,wasPublished:A})=>{const L=await(await w("PATCH",`/api/admin/announcements/${i}`,m)).json();return C&&!A&&(await w("POST",`/api/admin/announcements/${i}/publish`,{}),S("admin_announcement_published",{slug:m.slug})),S("admin_announcement_updated",{slug:m.slug}),L.announcement},onSuccess:()=>{c({title:"Announcement saved"}),z()},onError:i=>{c({title:"Failed to save announcement",description:E(i,"Your changes were not saved. Please try again."),variant:"destructive"})}}),n=D({mutationFn:async i=>{const m=i.isPublished?"unpublish":"publish";await w("POST",`/api/admin/announcements/${i.id}/${m}`,{}),S(i.isPublished?"admin_announcement_unpublished":"admin_announcement_published",{slug:i.slug})},onMutate:i=>a({id:i.id,action:"publish"}),onSettled:()=>a(null),onSuccess:(i,m)=>{c({title:m.isPublished?"Unpublished":"Published"}),z()},onError:()=>c({title:"Failed",variant:"destructive"})}),y=D({mutationFn:async i=>{await w("POST",`/api/admin/announcements/${i.id}/bump-version`,{}),S("admin_announcement_version_bumped",{slug:i.slug})},onMutate:i=>a({id:i.id,action:"bump"}),onSettled:()=>a(null),onSuccess:()=>{c({title:"Version bumped, dismissed users will re-see this"}),z()},onError:()=>c({title:"Failed to bump version",variant:"destructive"})}),Q=D({mutationFn:async i=>{const m=Date.now().toString(36),C=`${i.slug}-copy-${m}`,A={slug:C,title:`${i.title} (copy)`,body:i.body,icon:i.icon||null,ctaLabel:i.ctaLabel||null,ctaHref:i.ctaHref||null,kind:i.kind,priority:i.priority,surfaces:i.surfaces||[],targetPaths:i.targetPaths||[],targeting:i.targeting||{},lifecycle:i.lifecycle||{},sacredZones:i.sacredZones||[]},L=await(await w("POST","/api/admin/announcements",A)).json();return S("admin_announcement_created",{slug:C,duplicated_from:i.slug}),L.announcement},onMutate:i=>a({id:i.id,action:"duplicate"}),onSettled:()=>a(null),onSuccess:i=>{c({title:"Duplicated as draft"}),d(i.id),u(!1),z()},onError:()=>c({title:"Failed to duplicate",variant:"destructive"})}),G=D({mutationFn:async i=>{await w("DELETE",`/api/admin/announcements/${i.id}`),S("admin_announcement_deleted",{slug:i.slug})},onMutate:i=>a({id:i.id,action:"delete"}),onSettled:()=>a(null),onSuccess:(i,m)=>{c({title:"Deleted"}),l===m.id&&d(null),z()},onError:()=>c({title:"Failed to delete",variant:"destructive"})}),$=(i,m)=>{o||!p?F.mutate({payload:i,publish:m}):t.mutate({id:p.id,payload:i,publish:m,wasPublished:!!p.isPublished})},X=()=>{p&&y.mutate(p)};return e.jsxs("div",{className:"min-h-screen bg-zinc-950 text-white p-4 sm:p-6 max-w-7xl mx-auto",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(V,{className:"w-6 h-6 text-blue-400"}),e.jsx("h1",{className:"text-2xl font-bold",children:"Announcements"}),e.jsxs("span",{className:"text-xs text-zinc-500",children:[v.length," total · ",v.filter(i=>i.isPublished).length," published"]})]}),e.jsxs(N,{onClick:()=>{u(!0),d(null)},className:"bg-blue-600 hover:bg-blue-500 text-white","data-testid":"button-new-announcement",children:[e.jsx(te,{className:"w-4 h-4 mr-1"})," New Announcement"]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[380px_1fr] gap-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex gap-1 text-xs",children:["all","draft","published"].map(i=>e.jsx("button",{onClick:()=>b(i),className:`px-2 py-1 rounded uppercase tracking-wide transition ${g===i?"bg-zinc-800 text-white":"text-zinc-500 hover:text-zinc-300"}`,"data-testid":`filter-${i}`,children:i},i))}),_&&e.jsxs("div",{className:"text-zinc-500 text-center py-8 text-sm",children:[e.jsx(se,{className:"w-4 h-4 animate-spin inline mr-2"}),"Loading announcementsâ¦"]}),!_&&k.length===0&&e.jsxs("div",{className:"text-zinc-500 text-center py-12 text-sm border border-dashed border-zinc-800 rounded-[8px]",children:[e.jsx(V,{className:"w-6 h-6 mx-auto mb-2 opacity-50"}),"No announcements yet. Click + New to start."]}),e.jsx("div",{className:"space-y-2",children:k.map(i=>e.jsx(xe,{announcement:i,active:!o&&l===i.id,onSelect:()=>{d(i.id),u(!1)},onTogglePublish:()=>n.mutate(i),onDuplicate:()=>Q.mutate(i),onBumpVersion:()=>y.mutate(i),onDelete:()=>{window.confirm(`Delete announcement "${i.title}"? This cascades to user state and cannot be undone.`)&&G.mutate(i)},busyAction:(r==null?void 0:r.id)===i.id?r.action:null},i.id))})]}),e.jsx("div",{className:"border border-zinc-800 rounded-[8px] bg-zinc-900/30 p-4 sm:p-6",children:o?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold text-zinc-100",children:"New announcement"}),e.jsx(N,{variant:"ghost",size:"sm",onClick:()=>u(!1),className:"text-zinc-400 hover:text-zinc-200","data-testid":"button-cancel-new",children:"Cancel"})]}),e.jsx(U,{initial:null,onSubmit:$,contentVersion:1,isSaving:F.isPending})]}):p?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 flex-wrap gap-2",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-lg font-semibold text-zinc-100 flex items-center gap-2",children:[p.title,e.jsx(q,{a:p})]}),e.jsxs("p",{className:"text-xs text-zinc-500 font-mono mt-0.5",children:[p.slug," · v",p.contentVersion," · updated"," ",Z(p.updatedAt)]})]}),e.jsxs("div",{className:"flex items-center gap-1 text-xs text-zinc-500",children:[e.jsx(re,{className:"w-3 h-3"}),e.jsx(K,{announcementId:p.id})]})]}),e.jsx(U,{initial:p,onSubmit:$,onBumpVersion:X,contentVersion:p.contentVersion,isSaving:t.isPending,isPublished:!!p.isPublished},p.id)]}):e.jsxs("div",{className:"text-zinc-500 text-center py-16 text-sm",children:[e.jsx(V,{className:"w-8 h-8 mx-auto mb-3 opacity-40"}),"Select an announcement on the left, or click + New to create one."]})})]})]})}export{De as default}; 4 5//# debugId=229d188f-6db8-5d8a-b91b-37aa124cdacc
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.