PageSourceSearch

https://careerplatform.io/assets/admin-zYZlF2AS.js

js careerplatform.io collected 2026-09-24 15:05:40 UTC 65,832 bytes, 6 lines download raw bytes

1import{u as ue,r as y,s as xe,j as e,L as me,b7 as ge,b8 as pe,b9 as ve,ba as be,bb as fe,bc as Ne,bd as ye,a as w,e as I,B as b,a9 as L,b0 as se,f as R,t as N,b5 as H,be as E,bf as U,bg as M,bh as T,bi as x,bj as O,bk as u,E as we,b4 as he}from"./index-DNidg_Qc.js";import{I as k}from"./input-70YvsUaZ.js";import{L as C}from"./label-Bhudjdxi.js";import{S as G,a as Q,b as V,c as W,d as A}from"./select-C7qVj4jZ.js";import{a as Se,b as Ce,c as ke,d as Le,e as Ae,f as _e,g as Te,h as Pe,i as Ee,j as De,k as Fe,l as qe,m as $e,n as Re,o as je,p as Ie,q as Ue,r as Me,s as Oe,t as ze,u as Ke,v as Be,w as Ge,x as Qe,y as Ve,z as We,A as Je,B as He,C as Ze,D as Ye,E as Xe,F as es,G as ss,H as ts,I as as}from"./admin.functions-D2EedA8Q.js";import{a as ns}from"./announcement-content-BLqTnZKY.js";import"./index-Bk7P141l.js";import"./index-D-fQwQV1.js";import"./index-CPuSwFTH.js";import"./index-IQCvXwi3.js";import"./index-IAXwTvsN.js";import"./chevron-down-CPsmHmNT.js";import"./check-DWkmcDeA.js";import"./chevron-up-GmuFuLDl.js";import"./types-e6apbZGd.js";function Z(d){return d?he[d]??d:"-"}function rs(){const d=w(je),h=R({mutationFn:()=>d({data:void 0}),onError:a=>N.error(a.message)}),i=h.data?.topics??[];return e.jsxs(L,{className:"p-6 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"SEO topic suggestions"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1 max-w-2xl",children:"Career keywords with meaningful search volume and achievable difficulty. Use these to plan blog posts that can actually rank. Powered by Semrush - each click consumes API quota, so don't spam."})]}),e.jsx(b,{onClick:()=>h.mutate(),disabled:h.isPending,children:h.isPending?"Generating…":i.length?"Regenerate":"Generate suggestions"})]}),h.isError?e.jsx("p",{className:"text-sm text-destructive",children:h.error.message}):null,i.length>0?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Generated ",h.data?new Date(h.data.generatedAt).toLocaleString():""," · ",i.length," topics"]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Keyword"}),e.jsx(x,{className:"text-right",children:"Volume / mo"}),e.jsx(x,{className:"text-right",children:"Difficulty"}),e.jsx(x,{className:"text-right",children:"CPC ($)"}),e.jsx(x,{className:"text-right",children:"Opportunity"})]})}),e.jsx(O,{children:i.map(a=>e.jsxs(T,{children:[e.jsx(u,{className:"font-medium",children:a.keyword}),e.jsx(u,{className:"text-right tabular-nums",children:a.volume.toLocaleString()}),e.jsx(u,{className:"text-right tabular-nums",children:e.jsx(E,{variant:a.kd<=20?"secondary":a.kd<=35?"outline":"destructive",children:a.kd})}),e.jsx(u,{className:"text-right tabular-nums text-muted-foreground",children:a.cpc.toFixed(2)}),e.jsx(u,{className:"text-right tabular-nums font-semibold",children:a.score})]},a.keyword))})]})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[e.jsx("strong",{children:"Difficulty:"})," ≤20 easy · 21–35 moderate · 36–45 ambitious. ",e.jsx("strong",{children:"Opportunity"})," ranks volume vs. difficulty - higher is better."]})]}):!h.isPending&&!h.isError?e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Click ",e.jsx("strong",{children:"Generate suggestions"})," to fetch fresh keyword opportunities from Semrush."]}):null]})}const ce=Object.keys(H);function Rs(){const d=ue(),[h,i]=y.useState("checking");return y.useEffect(()=>{(async()=>{try{const{data:a,error:v}=await xe.auth.getUser();if(v||!a.user){d({to:"/login"});return}const{data:g,error:s}=await xe.from("user_roles").select("role").eq("user_id",a.user.id).eq("role","admin").maybeSingle();if(s){console.error("admin role check failed",s),i("denied");return}i(g?"ok":"denied")}catch(a){console.error("admin access check threw",a),i("denied")}})()},[d]),h==="checking"?e.jsx("div",{className:"container mx-auto max-w-6xl px-4 py-10 text-sm text-muted-foreground",children:"Checking access…"}):h==="denied"?e.jsx("div",{className:"container mx-auto max-w-6xl px-4 py-10 text-sm text-destructive",children:"Access denied - you are not an admin."}):e.jsxs("div",{className:"container mx-auto max-w-6xl px-4 py-10",children:[e.jsx(me,{to:"/dashboard",className:"inline-flex items-center text-sm text-muted-foreground hover:text-foreground mb-6",children:"← Back to dashboard"}),e.jsx("h1",{className:"text-3xl font-bold mb-6",children:"Admin"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-8",children:[e.jsx(le,{to:"/admin/user-history",label:"User tool history",description:"Review a user's saved outputs for support or abuse."}),e.jsx(le,{to:"/admin?group=users&tab=users",label:"User lookup",description:"Find users, adjust usage, manage grants."}),e.jsx(le,{to:"/admin?group=system&tab=errors",label:"Tool errors",description:"Recent failures and refund status."}),e.jsx(le,{to:"/analytics",label:"Analytics",description:"Usage, conversion, and revenue trends."})]}),e.jsx(is,{})]})}function le({to:d,label:h,description:i}){return e.jsxs(me,{to:d,className:"block rounded-lg border p-4 hover:bg-muted/50 transition-colors",children:[e.jsx("div",{className:"font-semibold text-sm",children:h}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:i})]})}const ne=[{value:"overview",label:"Overview",tabs:[{value:"overview",label:"Overview",render:()=>e.jsx(hs,{})},{value:"analytics",label:"Analytics",render:()=>e.jsx(js,{})},{value:"margins",label:"Margins",render:()=>e.jsx(Ne,{})}]},{value:"users",label:"Users",tabs:[{value:"users",label:"User Lo
1okup",render:()=>e.jsx(us,{})},{value:"all-users",label:"All Users",render:()=>e.jsx(vs,{})},{value:"abuse",label:"Abuse",render:()=>e.jsx(cs,{})}]},{value:"content",label:"Content",tabs:[{value:"blog",label:"Blog",render:()=>e.jsx(bs,{})},{value:"seo-topics",label:"SEO Topics",render:()=>e.jsx(rs,{})},{value:"public-tools",label:"Public Tools",render:()=>e.jsx(Ns,{})},{value:"reviews",label:"Reviews",render:()=>e.jsx(ye,{})}]},{value:"finance",label:"Finance",tabs:[{value:"coupons",label:"Coupons",render:()=>e.jsx(ms,{})}]},{value:"system",label:"System",tabs:[{value:"jobs",label:"AI Jobs",render:()=>e.jsx(gs,{})},{value:"errors",label:"Tool Errors",render:()=>e.jsx(ls,{})},{value:"support",label:"Support Chats",render:()=>e.jsx(fs,{})},{value:"announcements",label:"Announcements",render:()=>e.jsx(ds,{})}]}];function is(){const d=ge.useSearch(),h=ue(),i=ne.find(s=>s.value===d.group)??ne.find(s=>s.tabs.some(j=>j.value===d.tab))??ne[0],a=i.tabs.find(s=>s.value===d.tab)??i.tabs[0],v=s=>{const j=ne.find(c=>c.value===s);j&&h({to:"/admin",search:{group:j.value,tab:j.tabs[0].value},replace:!0})},g=s=>{h({to:"/admin",search:{group:i.value,tab:s},replace:!0})};return e.jsxs("div",{children:[e.jsx("div",{className:"flex flex-wrap gap-2 mb-3",children:ne.map(s=>{const j=s.value===i.value;return e.jsx("button",{onClick:()=>v(s.value),className:"px-4 py-2 rounded-md text-sm font-semibold transition-colors "+(j?"bg-primary text-primary-foreground":"bg-muted text-muted-foreground hover:bg-muted/70"),children:s.label},s.value)})}),e.jsxs(pe,{value:a.value,onValueChange:g,children:[e.jsx(ve,{children:i.tabs.map(s=>e.jsx(be,{value:s.value,children:s.label},s.value))}),e.jsx("div",{className:"border-b mt-2"}),i.tabs.map(s=>e.jsx(fe,{value:s.value,className:"mt-6",children:s.render()},s.value))]})]})}function _({label:d,value:h,tone:i}){return e.jsxs("div",{className:"border rounded-lg p-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:d}),e.jsx("div",{className:`text-2xl font-bold ${i==="primary"?"text-primary":i==="destructive"?"text-destructive":""}`,children:h})]})}function ls(){const[d,h]=y.useState("all"),i=w(Qe),{data:a,isLoading:v,refetch:g}=I({queryKey:["admin","tool-errors",d],queryFn:()=>i({data:{limit:100,tool:d==="all"?void 0:d}})});return e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 gap-4 flex-wrap",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Recent tool failures"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(G,{value:d,onValueChange:s=>h(s),children:[e.jsx(Q,{className:"w-[200px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"all",children:"All tools"}),ce.map(s=>e.jsx(A,{value:s,children:H[s]},s))]})]}),e.jsx(b,{variant:"outline",size:"sm",onClick:()=>g(),children:"Refresh"})]})]}),v?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):a?.errors?.length?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"When"}),e.jsx(x,{children:"User"}),e.jsx(x,{children:"Tool"}),e.jsx(x,{children:"Refunded"}),e.jsx(x,{children:"Error"})]})}),e.jsx(O,{children:a.errors.map(s=>e.jsxs(T,{children:[e.jsx(u,{className:"whitespace-nowrap text-xs text-muted-foreground",children:new Date(s.created_at).toLocaleString()}),e.jsx(u,{className:"text-xs",children:s.email??s.user_id.slice(0,8)}),e.jsxs(u,{className:"text-xs",children:[H[s.tool]??s.tool,s.job_kind?e.jsxs("span",{className:"text-muted-foreground",children:[" · ",s.job_kind]}):null]}),e.jsx(u,{children:s.refunded?e.jsx(E,{variant:"secondary",children:"Yes"}):e.jsx(E,{variant:"destructive",children:"No"})}),e.jsx(u,{className:"text-xs max-w-md truncate",title:s.error_message,children:s.error_message})]},s.id))})]})}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No errors recorded."})]})}function ds(){const d=w(Je),h=w(He),i=w(Ze),a=w(Ye),v=w(Xe),g=w(es),s=w(ss),j=se(),c=()=>({title:"",subject:"",preheader:"",headline:"",body:"",promoCode:"",promoDetail:"",promoExpires:"",buttonLabel:"",buttonUrl:"",closing:"",audience:{kind:"all"},bannerEnabled:!1,bannerFrom:"",bannerUntil:""}),[r,p]=y.useState(null),[l,m]=y.useState(""),[o,F]=y.useState(null),[D,f]=y.useState(""),B=I({queryKey:["admin","announcements"],queryFn:()=>d({data:void 0})}),Y=B.data?.planLabels??{};y.useEffect(()=>{if(!r)return;const t=setTimeout(async()=>{try{const{html:$}=await a({data:r});m($)}catch{}},500);return()=>clearTimeout(t)},[r,a]);const S=R({mutationFn:t=>h({data:t}),onSuccess:t=>{N.success("Saved"),p($=>$&&{...$,id:t.id}),j.invalidateQueries({queryKey:["admin","announcements"]})},onError:t=>N.error(t.message)}),J=R({mutationFn:t=>i({data:{id:t}}),onSuccess:()=>{N.success("Draft deleted"),p(null),j.invalidateQueries({queryKey:["admin","announcements"]})},onError:t=>N.error(t.message)}),te=R({mutationFn:t=>v({data:{id:t}}),onSuccess:t=>F(t),onError:t=>N.error(t.message)}),X=R({mutationFn:t=>g({data:t}),onSuccess:t=>N.success(`Test sent to ${t.sentTo}`),onError:t=>N.error(t.message)}),ae=R({mutationFn:t=>s({data:t}),onSuccess:t=>{N.success(`Sent ${t.sent}, skipped ${t.skipped}, failed ${t.failed}`),F(null),f(""),p($=>$&&{...$,status:"sent"}),j.invalidateQueries({queryKey:["admin","announcements"]})},onError:t=>N.error(t.message)}),P=(t,$)=>p(n=>n&&{...n,[t]:$}),z=r?.status==="sent",K=o?.stats?.eligible??0;return r?e.jsxs("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4 items-start",children:[e.jsxs(L,{className:"p-6 space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold",children:r.id?z?"Sent announcement":"Edit announcement":"New announcement"}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>p(null),children:"Back to list"})]}),z&&e.jsx("p",{className:"text-sm text-muted-foreground rounded-md border border-border bg-muted/30 p-3",children:"This announcement has been sent, so the email cannot change. The dashboard banner below can still be switched on or off."}),e.jsxs("fieldset",{disabled:z,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Internal name"}),e.jsx(k,{value:r.title,onChange:t=>P("title",t.target.value),placeholder:"September code and Salary Negotiator",maxLength:120})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Email subject"}),e.jsx(k,{value:r.subject,onChange:t=>P("subject",t.target.value),placeholder:"A new tool and a code for September",maxLength:150})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Preview line (shown after the subject in the inbox)"}
1),e.jsx(k,{value:r.preheader,onChange:t=>P("preheader",t.target.value),maxLength:200})]})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Headline"}),e.jsx(k,{value:r.headline,onChange:t=>P("headline",t.target.value),maxLength:120})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Body"}),e.jsx(we,{value:r.body,onChange:t=>P("body",t.target.value),rows:9,maxLength:6e3,placeholder:`Paragraphs separated by a blank line.
2
3Lines starting with "- " become bullets:
4- One precise number
5- A phone script`}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:'Blank line between paragraphs. Start a line with "- " for a bullet. The greeting and sign-off are added for you.'})]}),e.jsxs("div",{className:"rounded-md border border-border p-3 space-y-3",children:[e.jsx("div",{className:"text-sm font-medium",children:"Promo code (optional)"}),e.jsxs("div",{className:"grid sm:grid-cols-3 gap-3",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Code"}),e.jsx(k,{value:r.promoCode,onChange:t=>P("promoCode",t.target.value.toUpperCase()),placeholder:"SEPT20",maxLength:40})]}),e.jsxs("div",{children:[e.jsx(C,{children:"What it gives"}),e.jsx(k,{value:r.promoDetail,onChange:t=>P("promoDetail",t.target.value),placeholder:"20% off any plan",maxLength:160})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Valid until"}),e.jsx(k,{type:"date",value:r.promoExpires,onChange:t=>P("promoExpires",t.target.value)})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"The code must also exist under Coupons; this only announces it."})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Button label (optional)"}),e.jsx(k,{value:r.buttonLabel,onChange:t=>P("buttonLabel",t.target.value),placeholder:"See the Salary Negotiator",maxLength:60})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Button link"}),e.jsx(k,{value:r.buttonUrl,onChange:t=>P("buttonUrl",t.target.value),placeholder:"/tools/salary or https://…",maxLength:500})]})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Closing line (optional)"}),e.jsx(k,{value:r.closing,onChange:t=>P("closing",t.target.value),placeholder:"Reply to this email if anything is unclear.",maxLength:300})]}),e.jsxs("div",{className:"rounded-md border border-border p-3 space-y-3",children:[e.jsx("div",{className:"text-sm font-medium",children:"Who receives it"}),e.jsxs("div",{className:"flex flex-wrap gap-3 items-end",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Audience"}),e.jsxs(G,{value:r.audience.kind,onValueChange:t=>P("audience",{...r.audience,kind:t}),children:[e.jsx(Q,{className:"w-[240px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"all",children:"Everyone"}),e.jsx(A,{value:"paid",children:"Paid plans"}),e.jsx(A,{value:"free",children:"Free accounts"}),e.jsx(A,{value:"plans",children:"Specific plans"}),e.jsx(A,{value:"signed_up_within",children:"Signed up recently"})]})]})]}),r.audience.kind==="plans"&&e.jsx("div",{className:"flex flex-wrap gap-2",children:["essentials","starter","pro","bundle_90"].map(t=>{const $=(r.audience.plans??[]).includes(t);return e.jsx(b,{type:"button",size:"sm",variant:$?"default":"outline",onClick:()=>P("audience",{...r.audience,plans:$?(r.audience.plans??[]).filter(n=>n!==t):[...r.audience.plans??[],t]}),children:he[t]},t)})}),r.audience.kind==="signed_up_within"&&e.jsxs("div",{children:[e.jsx(C,{children:"Days"}),e.jsx(k,{type:"number",min:1,max:365,className:"w-[120px]",value:r.audience.days??30,onChange:t=>P("audience",{...r.audience,days:Math.max(1,Math.min(365,Number(t.target.value)||30))})})]})]})]})]}),e.jsxs("div",{className:"rounded-md border border-border p-3 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium",children:"Dashboard banner"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Also show the headline, code and button at the top of the dashboard for signed-in users, until they dismiss it."})]}),e.jsx(b,{type:"button",size:"sm",variant:r.bannerEnabled?"default":"outline",onClick:()=>P("bannerEnabled",!r.bannerEnabled),children:r.bannerEnabled?"On":"Off"})]}),r.bannerEnabled&&e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(C,{children:"From"}),e.jsx(k,{type:"date",value:r.bannerFrom,onChange:t=>P("bannerFrom",t.target.value)})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Until"}
5),e.jsx(k,{type:"date",value:r.bannerUntil,onChange:t=>P("bannerUntil",t.target.value)})]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 items-center pt-2 border-t border-border",children:[e.jsx(b,{onClick:()=>S.mutate(r),disabled:S.isPending||!r.title.trim(),children:S.isPending?"Saving…":"Save"}),!z&&e.jsx(b,{variant:"outline",onClick:()=>X.mutate(r),disabled:X.isPending||!r.title.trim(),children:X.isPending?"Sending…":"Send a test to me"}),!z&&r.id&&e.jsx(b,{variant:"outline",onClick:()=>te.mutate(r.id),disabled:te.isPending,children:te.isPending?"Counting…":"Count recipients"}),!z&&r.id&&e.jsx(b,{variant:"ghost",className:"text-destructive",onClick:()=>J.mutate(r.id),disabled:J.isPending,children:"Delete draft"})]}),o&&!z&&e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(_,{label:"Total users",value:o.stats.totalUsers}),e.jsx(_,{label:"Outside audience",value:o.stats.outsideAudience}),e.jsx(_,{label:"Opted out or suppressed",value:o.stats.suppressed+o.stats.unsubscribedAll+o.stats.productUpdatesOff}),e.jsx(_,{label:"Already sent",value:o.stats.alreadySent}),e.jsx(_,{label:"Will receive",value:K,tone:"primary"})]}),o.sample.length>0&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["First recipients: ",o.sample.join(", ")]}),K>0?e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{children:[e.jsxs(C,{children:["Type the number ",K," to confirm"]}),e.jsx(k,{className:"w-[160px]",value:D,onChange:t=>f(t.target.value)})]}),e.jsx(b,{disabled:ae.isPending||D.trim()!==String(K),onClick:()=>ae.mutate({id:r.id,confirmCount:K}),children:ae.isPending?"Sending…":`Send to ${K} ${K===1?"person":"people"}`})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nobody would receive this right now."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Save your latest edits before sending; the send uses what is saved."})]})]}),e.jsxs(L,{className:"p-3 xl:sticky xl:top-4",children:[e.jsx("div",{className:"text-sm font-medium px-2 py-1",children:"Preview"}),l?e.jsx("iframe",{title:"Announcement preview",srcDoc:l,className:"w-full rounded-md border border-border bg-white",style:{height:"70vh"},sandbox:""}):e.jsx("p",{className:"text-sm text-muted-foreground p-2",children:"Start typing and the email appears here."})]})]}):e.jsxs(L,{className:"p-6 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Announcements"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1 max-w-2xl",children:"An email to your users, and optionally a banner on their dashboard: a new feature, a code for the month, anything worth telling them. Every send honours the suppression list and the product-updates preference, and nobody gets the same announcement twice."})]}),e.jsx(b,{onClick:()=>{p(c()),F(null),m("")},children:"New announcement"})]}),B.isLoading?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):(B.data?.announcements.length??0)===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing yet. The Chrome extension email sent in July is in the send log under its own name."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Title"}),e.jsx(x,{children:"Audience"}),e.jsx(x,{children:"Status"}),e.jsx(x,{className:"text-right",children:"Sent"}),e.jsx(x,{children:"Banner"}),e.jsx(x,{children:"Updated"}),e.jsx(x,{})]})}),e.jsx(O,{children:B.data.announcements.map(t=>e.jsxs(T,{children:[e.jsx(u,{className:"font-medium",children:t.title}),e.jsx(u,{className:"text-xs",children:ns(t.audience,Y)}),e.jsx(u,{children:t.status==="sent"?e.jsxs(E,{className:"bg-emerald-100 text-emerald-900 border-emerald-200",variant:"outline",children:["Sent ",t.sentAt?new Date(t.sentAt).toLocaleDateString():""]}):e.jsx(E,{variant:"outline",children:"Draft"})}),e.jsx(u,{className:"text-right tabular-nums text-xs",children:t.status==="sent"?`${t.sentCount}${t.failedCount?` (${t.failedCount} failed)`:""}`:"-"}),e.jsx(u,{className:"text-xs",children:t.bannerEnabled?`On${t.bannerUntil?` until ${t.bannerUntil}`:""}`:"Off"}),e.jsx(u,{className:"text-xs text-muted-foreground whitespace-nowrap",children:new Date(t.updatedAt).toLocaleDateString()}),e.jsx(u,{children:e.jsx(b,{size:"sm",variant:"outline",onClick:()=>{p(t),F(null),m("")},children:t.status==="sent"?"View":"Edit"})})]},t.id))})]})})]})}function cs(){const d=w(qe),{data:h,isLoading:i}=I({queryKey:["admin","abuse","duplicates"],queryFn:()=>d({data:{minCount:2}})}),a=h?.duplicates??[];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs(L,{className:"p-5 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-lg",children:"Duplicate signup devices"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Browser fingerprints that have been used to create more than one account. Likely free-tier abuse. Investigate before banning - shared computers and family devices can legitimately produce duplicates."})]}),e.jsxs(E,{variant:"secondary",children:[a.length," flagged"]})]}),i?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):a.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No duplicate-device signups yet. New signups start being tracked from now."}):e.jsx("div",{className:"space-y-3",children:a.map(v=>e.jsxs(L,{className:"p-4 bg-muted/30",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("code",{className:"text-xs text-muted-foreground",children:[v.visitor_id.slice(0,16),"…"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[v.flagged&&e.jsx(E,{variant:"destructive",children:"Auto-flagged"}),e.jsxs(E,{variant:"secondary",children:[v.count," accounts"]})]})]}),e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Email"}),e.jsx(x,{children:"Signed up"})]})}),e.jsx(O,{children:v.accounts.map((g,s)=>e.jsxs(T,{children:[e.jsx(u,{className:"font-mono text-xs",children:g.email}),e.jsx(u,{className:"text-xs text-muted-foreground",children:new Date(g.created_at).toLocaleStr
5ing()})]},`${v.visitor_id}-${s}`))})]})]},v.visitor_id))})]}),e.jsx(xs,{})]})}const os={alias_reuse:"Alias reuse (blocked)",fingerprint_reuse:"Fingerprint reuse (blocked)",fingerprint_missing:"Fingerprint missing (review)"};function xs(){const d=w(as),{data:h,isLoading:i}=I({queryKey:["admin","abuse","flagged-referrals"],queryFn:()=>d()}),a=h?.referrals??[],v=a.filter(s=>s.blocked_reason).length,g=a.filter(s=>s.review_flag).length;return e.jsxs(L,{className:"p-5 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-lg",children:"Flagged referrals"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:`Referrals blocked outright (alias or device reuse - credits withheld) and referrals only flagged for review (e.g. the referred signup's device fingerprint failed to capture - credits still granted, nothing enforced automatically). Investigate the "review" rows before assuming abuse - a missing fingerprint is often just a privacy browser or blocker.`})]}),e.jsxs("div",{className:"flex flex-col items-end gap-1 shrink-0",children:[e.jsxs(E,{variant:"destructive",children:[v," blocked"]}),e.jsxs(E,{variant:"secondary",children:[g," review"]})]})]}),i?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):a.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No flagged or blocked referrals."}):e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Referrer"}),e.jsx(x,{children:"Referred"}),e.jsx(x,{children:"Reason"}),e.jsx(x,{children:"Credits awarded"}),e.jsx(x,{children:"Created"})]})}),e.jsx(O,{children:a.map(s=>{const j=s.blocked_reason??s.review_flag??"";return e.jsxs(T,{children:[e.jsx(u,{className:"font-mono text-xs",children:s.referrer_email??" - "}),e.jsx(u,{className:"font-mono text-xs",children:s.referred_email??" - "}),e.jsx(u,{children:e.jsx(E,{variant:s.blocked_reason?"destructive":"secondary",children:os[j]??j})}),e.jsxs(u,{className:"text-xs text-muted-foreground",children:[s.referrer_credits_awarded," / ",s.referred_credits_awarded]}),e.jsx(u,{className:"text-xs text-muted-foreground",children:new Date(s.created_at).toLocaleString()})]},s.id)})})]})]})}function us(){const[d,h]=y.useState(""),[i,a]=y.useState(null),v=w(Le),g=w(Ae),s=se(),{data:j,isFetching:c}=I({enabled:!!i,queryKey:["admin","user",i],queryFn:()=>v({data:{email:i}})}),r=R({mutationFn:m=>g({data:m}),onSuccess:(m,o)=>{N.success(`${o.delta>0?"Refunded":"Charged"} ${H[o.tool]} (now ${m.count})`),s.invalidateQueries({queryKey:["admin","user",i]})},onError:m=>N.error(m.message)}),p=new Map((j?.user?.usage??[]).map(m=>[m.tool,m.count])),l=new Map((j?.user?.lifetimeUsage??[]).map(m=>[m.tool,m.count]));return e.jsxs(L,{className:"p-6 space-y-6",children:[e.jsxs("form",{className:"flex gap-2",onSubmit:m=>{m.preventDefault(),a(d.trim().toLowerCase())},children:[e.jsx(k,{type:"email",placeholder:"[email protected]",value:d,onChange:m=>h(m.target.value),required:!0}),e.jsx(b,{type:"submit",disabled:!d.trim(),children:"Look up"})]}),c?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Searching…"}):i&&!j?.user?e.jsxs("p",{className:"text-sm text-muted-foreground",children:["No user found for ",i,"."]}):j?.user?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm",children:j.user.email}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["ID: ",e.jsx("code",{className:"text-[10px]",children:j.user.id})," · Signed up"," ",new Date(j.user.created_at).toLocaleDateString()]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold mb-2",children:"Subscriptions"}),j.user.subscriptions.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"None"}):e.jsx("div",{className:"space-y-1",children:j.user.subscriptions.map((m,o)=>e.jsxs("div",{className:"text-xs flex gap-2 flex-wrap",children:[e.jsx(E,{variant:"outline",children:m.environment}),e.jsxs("span",{children:[e.jsx("strong",{children:Z(m.plan)})," · ",m.status]}),m.current_period_end&&e.jsxs("span",{className:"text-muted-foreground",children:["until ",new Date(m.current_period_end).toLocaleDateString()]}),m.cancel_at_period_end&&e.jsx(E,{variant:"destructive",children:"Cancelling"})]},o))})]}),e.jsxs("div",{children:[e.jsxs("h3",{className:"font-semibold mb-2",children:["Usage · lifetime and this period (",j.user.period,")"]}),e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Tool"}),e.jsx(x,{className:"text-right",children:"Lifetime"}),e.jsx(x,{className:"text-right",children:"This period"}),e.jsx(x,{className:"text-right",children:"Adjust"})]})}),e.jsx(O,{children:ce.map(m=>{const o=p.get(m)??0,F=l.get(m)??0;return e.jsxs(T,{children:[e.jsx(u,{children:H[m]}),e.jsx(u,{className:"text-right tabular-nums font-medium",children:F}),e.jsx(u,{className:"text-right tabular-nums",children:o}),e.jsx(u,{className:"text-right",children:e.jsxs("div",{className:"inline-flex gap-1",children:[e.jsx(b,{size:"sm",variant:"outline",disabled:o===0||r.isPending,onClick:()=>r.mutate({userId:j.user.id,tool:m,delta:-1}),children:"−1"}),e.jsx(b,{size:"sm",variant:"outline",disabled:r.isPending,onClick:()=>r.mutate({userId:j.user.id,tool:m,delta:1}),children:"+1 (charge)"}),e.jsx(b,{size:"sm",variant:"secondary",disabled:o===0||r.isPending,onClick:()=>r.mutate({userId:j.user.id,tool:m,delta:-1}),title:"Refund one use",children:"Refund"})]})})]},m)})})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"Refund = decrement counter so the user can run the tool again this month."})]})]}):null]})}function ms(){const[d,h]=y.useState("live"),i=w(Me),a=w(Oe),v=w(ze),g=se(),{data:s,isLoading:j}=I({queryKey:["admin","coupons",d],queryFn:()=>i({data:{environment:d}})}),[c,r]=y.useState({code:"",description:"",percentage:"10",expiresAt:"",usageLimit:"",recur:!1,maxIntervals:""}),p=R({mutationFn:()=>a({data:{environment:d,code:c.code,description:c.description,percentage:Number(c.percentage),expiresAt:c.expiresAt?new Date(c.expiresAt).toISOString():null,usageLimit:c.usageLimit?Number(c.usageLimit):null,recur:c.recur,maximumRecurringIntervals:c.recur&&c.maxIntervals?Number(c.maxIntervals):null}}),onSuccess:()=>{N.success("Coupon created"),r({code:"",description:"",percentage:"10",expiresAt:"",usageLimit:"",recur:!1,maxIntervals:""}),g.invalidateQueries({queryKey:["admin","coupons",d]})},onError:o=>N.error(o.message)}),l=R({mutationFn:o=>v({data:{environment:d,id:o}}),onSuccess:()=>{N.success("Coupon archived"),g.invalidateQueries({queryKey:["admin","coupons",d]})},onError:o=>N.error(o.message)}),m=s?.discounts??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(G,{value:d,onValueChange:o=>h(o),children:[e.jsx(Q,{className:"w-[160px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"live",children:"Live"}),e.jsx(A,{value:"sandbox",children:"Test (sandbox)"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Coupons are environment-specific. Create the same code in both to support test checkouts."})]}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Create coupon"}),e.jsxs("form",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",onSubmit:o=>{o.preventDefault(),p.mutate()},children:[e.jsxs("div",{children:[e.jsx(C,{children:"Code"}),e.jsx(k,{value:c.code,onChange:o=>r({...c,code:o.target.value.toUpperCase()}),placeholder:"LAUNCH20",maxLength:32,required:!0})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Percentage off"}),e.jsx(k,{type:"number",min:1,max:100,value:c.percentage,onChange:o=>r({...c,percentage:o.target.value}),required:!0})]}),e.jsxs("div",{className:"md:col-span-2",children:[e.jsx(C,{children:"Description (internal)"}),e.jsx(k,{value:c.description,onChange:o=>r({...c,description:o.target.value}),placeholder:"Launch week 20% off",required:!0})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Expires at (optional)"}),e.jsx(k,{type:"datetime-local",value:c.expiresAt,onChange:o=>r({...c,expiresAt:o.target.value})})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Usage limit (optional)"}),e.jsx(k,{type:"number",min:1,value:c.usageLimit,onChange:o=>r({...c,usageLimit:o.target.value}),placeholder:"Unlimited"})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:c.recur,onCh
5ange:o=>r({...c,recur:o.target.checked})}),"Apply across multiple billing cycles"]}),c.recur&&e.jsxs("div",{children:[e.jsx(C,{children:"Number of billing cycles"}),e.jsx(k,{type:"number",min:1,value:c.maxIntervals,onChange:o=>r({...c,maxIntervals:o.target.value}),placeholder:"Forever if blank"})]}),e.jsx("div",{className:"md:col-span-2",children:e.jsx(b,{type:"submit",disabled:p.isPending,children:p.isPending?"Creating…":`Create in ${d}`})})]})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4",children:["Existing coupons (",d,")"]}),j?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):m.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No coupons yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Code"}),e.jsx(x,{children:"Description"}),e.jsx(x,{children:"Amount"}),e.jsx(x,{children:"Used / Limit"}),e.jsx(x,{children:"Expires"}),e.jsx(x,{children:"Status"}),e.jsx(x,{})]})}),e.jsx(O,{children:m.map(o=>e.jsxs(T,{children:[e.jsx(u,{className:"font-mono text-xs",children:o.code??" - "}),e.jsx(u,{className:"text-xs",children:o.description}),e.jsxs(u,{className:"text-xs",children:[o.percentage!=null?`${o.percentage}%`:" - ",o.recur&&e.jsx("span",{className:"text-muted-foreground",children:" · recurring"})]}),e.jsxs(u,{className:"text-xs tabular-nums",children:[o.times_used??0," / ",o.usage_limit??"∞"]}),e.jsx(u,{className:"text-xs",children:o.expires_at?new Date(o.expires_at).toLocaleDateString():"Never"}),e.jsx(u,{children:e.jsx(E,{variant:o.status==="active"?"secondary":"outline",children:o.status})}),e.jsx(u,{children:o.status==="active"&&e.jsx(b,{size:"sm",variant:"outline",disabled:l.isPending,onClick:()=>l.mutate(o.id),children:"Archive"})})]},o.id))})]})})]})]})}function hs(){const d=w(Se),h=w(Ce),[i,a]=y.useState(!1),[v,g]=y.useState(null),{data:s,isLoading:j,refetch:c,isFetching:r}=I({queryKey:["admin","overview"],queryFn:()=>d()});if(j)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"});if(!s)return null;const p=async l=>{a(!0),g(null);try{const m=await h({data:{environment:l}}),o=m.results.filter(D=>D.status==="ok").length,F=m.results.filter(D=>D.status==="error");g(`${l}: ${o}/${m.results.length} updated`+(F.length?` - failed: ${F.map(D=>`${D.product} (${D.error})`).join(", ")}`:""))}catch(m){g(`Error: ${m?.message??String(m)}`)}finally{a(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(b,{variant:"outline",size:"sm",onClick:()=>c(),disabled:r,children:r?"Refreshing…":"Refresh"})}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-2",children:"Stripe tax codes"}),e.jsxs("p",{className:"text-sm text-muted-foreground mb-4",children:["Set ",e.jsx("code",{children:"txcd_10103001"})," (SaaS / electronic services) on every product. Safe to re-run."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(b,{size:"sm",onClick:()=>
5p("sandbox"),disabled:i,children:i?"Working…":"Apply to sandbox"}),e.jsx(b,{size:"sm",variant:"destructive",onClick:()=>p("live"),disabled:i,children:"Apply to live"})]}),v&&e.jsx("p",{className:"mt-3 text-xs font-mono whitespace-pre-wrap",children:v})]}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Users"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(_,{label:"Total",value:s.users.total}),e.jsx(_,{label:"New · 24h",value:s.users.signups24h,tone:"primary"}),e.jsx(_,{label:"New · 7d",value:s.users.signups7d}),e.jsx(_,{label:"New · 30d",value:s.users.signups30d})]})]}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Subscriptions (live)"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(_,{label:"Active paid",value:s.subs.activeLive,tone:"primary"}),e.jsx(_,{label:"Cancelling",value:s.subs.cancelling,tone:"destructive"}),Object.entries(s.subs.byPlan).map(([l,m])=>e.jsx(_,{label:Z(l),value:m},l))]})]}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-4",children:"AI jobs"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3",children:[e.jsx(_,{label:"Pending",value:s.jobs.pending}),e.jsx(_,{label:"Processing",value:s.jobs.processing,tone:"primary"}),e.jsx(_,{label:"Last 24h",value:s.jobs.last24h}),e.jsx(_,{label:"Failed · 24h",value:s.jobs.failed24h,tone:"destructive"}),e.jsx(_,{label:"Tool errors · 24h",value:s.errors24h,tone:"destructive"})]})]})]})}function de({values:d,color:h="#60a5fa",height:i=48}){const a=Math.max(1,...d);return e.jsx("div",{className:"flex items-end gap-0.5",style:{height:i},children:d.map((v,g)=>{const s=v===0?2:Math.max(3,Math.round(v/a*i));return e.jsx("div",{className:"flex-1 rounded-sm transition-all",style:{height:s,background:v===0?"rgba(148,163,184,0.2)":h},title:`${v}`},g)})})}function js(){const[d,h]=y.useState(30),i=w(ke),{data:a,isLoading:v,refetch:g,isFetching:s}=I({queryKey:["admin","analytics",d],queryFn:()=>i({data:{days:d}})});if(v||!a)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"});const j=(p,l)=>l===0?" - ":`${Math.round(p/l*1e3)/10}%`,c=Object.entries(a.jobsByKind).sort((p,l)=>l[1]-p[1]),r=Math.max(1,...c.map(([,p])=>p));return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[e.jsxs(G,{value:String(d),onValueChange:p=>h(Number(p)),children:[e.jsx(Q,{className:"w-[160px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"7",children:"Last 7 days"}),e.jsx(A,{value:"30",children:"Last 30 days"}),e.jsx(A,{value:"90",children:"Last 90 days"})]})]}),e.jsx(b,{variant:"outline",size:"sm",onClick:()=>g(),disabled:s,children:s?"Refreshing…":"Refresh"})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4",children:["Conversion funnel · last ",d,"d cohort"]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"border rounded-lg p-4",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Signed up"}),e.jsx("div",{className:"text-3xl font-bold",children:a.funnel.cohortSize}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"100%"})]}),e.jsxs("div",{className:"border rounded-lg p-4",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Activated (ran a tool)"}),e.jsx("div",{className:"text-3xl font-bold text-primary",children:a.funnel.activated}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:[j(a.funnel.activated,a.funnel.cohortSize)," of signups"]})]}),e.jsxs("div",{className:"border rounded-lg p-4",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Converted to paid"}),e.jsx("div",{className:"text-3xl font-bold text-primary",children:a.funnel.paid}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:[j(a.funnel.paid,a.funnel.cohortSize)," of signups"]})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:"Signups / day"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.totals.signupsWindow," total"]})]}),e.jsx(de,{values:a.series.signups,color:"#60a5fa"})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:"AI jobs / day"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.totals.jobsWindow," total"]})]}),e.jsx(de,{values:a.series.jobs,color:"#34d399"})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:"Failed jobs / day"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.totals.failedWindow," total"]})]}),e.jsx(de,{values:a.series.failed,color:"#f87171"})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:"New paid subs / day"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.totals.newPaidWindow," total"]})]}),e.jsx(de,{values:a.series.newPaid,color:"#a78bfa"})]})]}),e.jsxs(L,{className:"p-6",children:[e.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Lifetime totals"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(_,{label:"Total users",value:a.totals.users}),e.jsx(_,{label:"Activated users",value:a.totals.activatedUsers,tone:"primary"}),e.jsx(_,{label:"Paid users (live)",value:a.totals.paidUsers,tone:"primary"}),e.jsx(_,{label:"Failure rate (window)",value:Number(j(a.totals.failedWindow,a.totals.jobsWindow).replace("%",""))||0,tone:a.totals.failedWindow>0?"destructive":void 0})]})]}),e.jsxs(L,{className:"p-6",children:[e.jsxs("h2",{className:"text-lg font-semibold mb-4",children:["Tool usage · last ",d,"d"]}),c.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No AI jobs in this window."}):e.jsx("div",{className:"space-y-2",children:c.map(([p,l])=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-40 text-xs truncate",title:p,children:p}),e.jsx("div",{className:"flex-1 h-3 bg-muted rounded",children:e.jsx("div",{className:"h-3 rounded bg-primary",style:{width:`${Math.max(2,Math.round(l/r*100))}%`}})}),e.jsx("div",{className:"w-12 text-right text-xs tabular-nums",children:l})]},p))})]})]})}function gs(){const[d,h]=y.useState("all"),i=w(Ke),a=w(Be),v=w(Ge),g=se(),{data:s,isLoading:j,refetch:c}=I({queryKey:["admin","ai-jobs",d],queryFn:()=>i({data:{status:d==="all"?void 0:d,limit:100}}),refetchInterval:1e4}),r=R({mutationFn:l=>a({data:{id:l}}),onSuccess:()=>{N.success("Job requeued"),g.invalidateQueries({queryKey:["admin","ai-jobs"]})},onError:l=>N.error(l.message)}),p=R({mutationFn:l=>v({data:{id:l}}),onSuccess:()=>{N.success("Job cancelled"),g.invalidateQueries({queryKey:["admin","ai-jobs"]})},onError:l=>N.error(l.message)});return e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 gap-2 flex-wrap",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"AI jobs (auto-refresh 10s)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(G,{value:d,onValueChange:l=>h(l),children:[e.jsx(Q,{className:"w-[160px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"all",children:"All"}),e.jsx(A,{value:"pending",children:"Pending"}),e.jsx(A,{value:"processing",children:"Processing"}),e.jsx(A,{value:"completed",children:"Completed"}),e.jsx(A,{value:"failed",children:"Failed"})]})]}),e.jsx(b,{variant:"outline",size:"sm",onClick:()=>c(),children:"Refresh"})]})]}),j?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}
5):s?.jobs?.length?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Created"}),e.jsx(x,{children:"User"}),e.jsx(x,{children:"Kind"}),e.jsx(x,{children:"Status"}),e.jsx(x,{children:"Attempts"}),e.jsx(x,{children:"Plan"}),e.jsx(x,{children:"Error"}),e.jsx(x,{})]})}),e.jsx(O,{children:s.jobs.map(l=>e.jsxs(T,{children:[e.jsx(u,{className:"text-xs whitespace-nowrap text-muted-foreground",children:new Date(l.created_at).toLocaleString()}),e.jsx(u,{className:"text-xs",children:l.email??l.user_id.slice(0,8)}),e.jsx(u,{className:"text-xs",children:l.kind}),e.jsx(u,{children:e.jsx(E,{variant:l.status==="failed"?"destructive":l.status==="completed"?"secondary":"outline",children:l.status})}),e.jsx(u,{className:"text-xs tabular-nums",children:l.attempts}),e.jsx(u,{className:"text-xs",children:Z(l.plan)}),e.jsx(u,{className:"text-xs max-w-xs truncate",title:l.error??"",children:l.error??" - "}),e.jsx(u,{children:e.jsxs("div",{className:"flex gap-1",children:[(l.status==="failed"||l.status==="processing")&&e.jsx(b,{size:"sm",variant:"outline",onClick:()=>r.mutate(l.id),disabled:r.isPending,children:"Retry"}),(l.status==="pending"||l.status==="processing")&&e.jsx(b,{size:"sm",variant:"ghost",onClick:()=>p.mutate(l.id),disabled:p.isPending,children:"Cancel"})]})})]},l.id))})]})}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No jobs."})]})}function ps({onDone:d}){const h=w(ts),[i,a]=y.useState(""),[v,g]=y.useState(""),[s,j]=y.useState("none"),[c,r]=y.useState(()=>{const l=new Date;return l.setDate(l.getDate()+30),l.toISOString().slice(0,10)}),p=R({mutationFn:()=>h({data:{email:i.trim(),fullName:v.trim(),plan:s==="none"?null:s,expiresAt:s==="none"?void 0:new Date(`${c}T23:59:59Z`).toISOString()}}),onSuccess:l=>{l.mode==="invited"?N.success(`Invitation sent to ${i.trim()}${s==="none"?"":" with the plan in place"}`):l.mode==="resent"?N.success(`${i.trim()} was invited before and has not signed in yet; a fresh set-password link was sent${s==="none"?"":" with the plan in place"}`):l.mode==="granted_existing"?N.success(`${i.trim()} already has an account; the plan was granted and they have been emailed`):N.info(`${i.trim()} already has an account. Pick them in the list below to grant a plan or credits.`),a(""),g(""),d()},onError:l=>N.error(l.message)});return e.jsxs(L,{className:"p-6",children:[e.jsx("h3",{className:"font-semibold mb-1",children:"Invite someone by email"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-4",children:"They get an invitation email to set a password. Choose a plan to have it waiting when they first sign in; leave it on Free to just invite."}),e.jsxs("div",{className:"flex flex-wrap gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Email"}),e.jsx(k,{type:"email",value:i,onChange:l=>a(l.target.value),placeholder:"[email protected]",className:"w-[260px]"})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Name (optional)"}),e.jsx(k,{value:v,onChange:l=>g(l.target.value),className:"w-[200px]"})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Plan"}),e.jsxs(G,{value:s,onValueChange:j,children:[e.jsx(Q,{className:"w-[200px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"none",children:"Free (invite only)"}),e.jsx(A,{value:"starter",children:"Job Seeker"}),e.jsx(A,{value:"pro",children:"Career Accelerator"}),e.jsx(A,{value:"bundle_90",children:"90-Day Bundle"})]})]})]}),s!=="none"&&e.jsxs("div",{children:[e.jsx(C,{children:"Plan expires"}),e.jsx(k,{type:"date",value:c,onChange:l=>r(l.target.value),className:"w-[180px]"})]}),e.jsx(b,{onClick:()=>p.mutate(),disabled:p.isPending||!i.trim()||s!=="none"&&!c,children:p.isPending?"Sending…":"Send invitation"})]})]})}function vs(){const[d,h]=y.useState(""),[i,a]=y.useState(null),v=w(_e),g=w(Te),s=w(Pe),j=w(Ee),c=w(De),r=w(Fe),p=se(),{data:l,isLoading:m,refetch:o}=I({queryKey:["admin","all-users",d],queryFn:()=>v({data:{search:d||void 0,limit:200}})}),[F,D]=y.useState(ce[0]),[f,B]=y.useState("10"),[Y,S]=y.useState(""),[J,te]=y.useState("pro"),[X,ae]=y.useState(()=>{const n=new Date;return n.setDate(n.getDate()+30),n.toISOString().slice(0,10)}),P=I({queryKey:["admin","user-grants",i?.id],queryFn:()=>r({data:{userId:i.id}}),enabled:!!i}),z=R({mutationFn:n=>g({data:n}),onSuccess:(n,q)=>{N.success(`${q.amount>0?"Granted":"Revoked"} ${Math.abs(q.amount)} ${H[q.tool]} credit${Math.abs(q.amount)===1?"":"s"} - new balance: ${n.balance}`),p.invalidateQueries({queryKey:["admin"]})},onError:n=>N.error(n.message)}),K=R({mutationFn:n=>s({data:n}),onSuccess:(n,q)=>{N.success(`${Z(q.plan)} granted until ${new Date(q.expiresAt).toLocaleDateString()}`),p.invalidateQueries({queryKey:["admin"]})},onError:n=>N.error(n.message)}),t=R({mutationFn:n=>c({data:{userId:n}}),onSuccess:n=>{const q=n.revoked.reduce((re,ie)=>re+ie.amount,0);N.success(q>
50?`Revoked ${q.toLocaleString()} credits across ${n.revoked.length} tool${n.revoked.length===1?"":"s"}`:"No credits to revoke"),p.invalidateQueries({queryKey:["admin"]})},onError:n=>N.error(n.message)}),$=R({mutationFn:n=>j({data:{userId:n}}),onSuccess:()=>{N.success("Plan grant revoked"),p.invalidateQueries({queryKey:["admin"]})},onError:n=>N.error(n.message)});return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ps,{onDone:()=>o()}),e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex gap-2 mb-4",children:[e.jsx(k,{placeholder:"Filter by email…",value:d,onChange:n=>h(n.target.value)}),e.jsx(b,{variant:"outline",onClick:()=>o(),children:"Refresh"})]}),m?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{className:"w-12",children:"#"}),e.jsx(x,{children:"Email"}),e.jsx(x,{children:"Plan"}),e.jsx(x,{children:"Credits"}),e.jsx(x,{children:"Country"}),e.jsx(x,{children:"Signed up"}),e.jsx(x,{children:"Last seen"}),e.jsx(x,{})]})}),e.jsx(O,{children:(l?.users??[]).sort((n,q)=>n.email==="[email protected]"&&q.email!=="[email protected]"?-1:q.email==="[email protected]"&&n.email!=="[email protected]"?1:n.is_admin&&!q.is_admin?-1:!n.is_admin&&q.is_admin?1:new Date(q.created_at).getTime()-new Date(n.created_at).getTime()).map((n,q)=>{const re=Object.entries(n.credits??{}).filter(([,ee])=>ee>0),ie=re.reduce((ee,[,oe])=>ee+oe,0);return e.jsxs(T,{children:[e.jsx(u,{className:"text-xs text-muted-foreground",children:q+1}),e.jsxs(u,{className:"text-xs",children:[n.email," ",n.is_admin&&e.jsx(E,{variant:"secondary",className:"ml-1",children:"admin"})]}),e.jsx(u,{className:"text-xs",children:Z(n.plan)}),e.jsx(u,{className:"text-xs",children:ie===0?e.jsx("span",{className:"text-muted-foreground",children:" - "}):e.jsx("span",{title:re.map(([ee,oe])=>`${H[ee]??ee}: ${oe}`).join(`
6`),children:e.jsx(E,{variant:"outline",children:ie})})}),e.jsx(u,{className:"text-xs text-muted-foreground",children:n.country??" - "}),e.jsx(u,{className:"text-xs text-muted-foreground",children:new Date(n.created_at).toLocaleString(void 0,{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"})}),e.jsx(u,{className:"text-xs text-muted-foreground",title:n.last_seen_at?new Date(n.last_seen_at).toLocaleString():void 0,children:n.last_seen_at?new Date(n.last_seen_at).toLocaleString(void 0,{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"}):" - "}),e.jsx(u,{children:e.jsx(b,{size:"sm",variant:"outline",onClick:()=>a({id:n.id,email:n.email}),children:"Grant credits"})})]},n.id)})})]})})]}),i&&e.jsxs(L,{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("h3",{className:"font-semibold",children:["Manage access - ",i.email]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>a(null),children:"Close"})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-semibold mb-2",children:"Grant full plan (time-bound)"}),e.jsxs("div",{className:"flex flex-wrap gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Plan"}),e.jsxs(G,{value:J,onValueChange:te,children:[e.jsx(Q,{className:"w-[200px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"starter",children:"Job Seeker ($29.99)"}),e.jsx(A,{value:"pro",children:"Career Accelerator ($59.99)"}),e.jsx(A,{value:"bundle_90",children:"90-Day Bundle ($149.99)"}),e.jsx(A,{value:"power",children:"Intensive (legacy)"})]})]})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Expires"}),e.jsx(k,{type:"date",value:X,onChange:n=>ae(n.target.value),className:"w-[180px]"})]}),e.jsx(b,{onClick:()=>K.mutate({userId:i.id,plan:J,expiresAt:new Date(`${X}T23:59:59Z`).toISOString()}),disabled:K.isPending||!X,children:K.isPending?"Granting…":"Grant plan"}),e.jsx(b,{variant:"outline",onClick:()=>$.mutate(i.id),disabled:$.isPending,children:"Revoke all plan grants"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"Grants full plan access until the expiry date. Replaces any prior admin plan grant for this user."})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-semibold mb-2",children:"Grant tool credits"}),e.jsxs("div",{className:"flex flex-wrap gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx(C,{children:"Tool"}),e.jsxs(G,{value:F,onValueChange:n=>D(n),children:[e.jsx(Q,{className:"w-[220px]",children:e.jsx(V,{})}),e.jsx(W,{children:ce.map(n=>e.jsx(A,{value:n,children:H[n]},n))})]})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Amount (negative to revoke)"}),e.jsx(k,{type:"number",value:f,onChange:n=>B(n.target.value),className:"w-[140px]"})]}),e.jsxs("div",{children:[e.jsx(C,{children:"Expires (optional)"}),e.jsx(k,{type:"date",value:Y,onChange:n=>S(n.target.value),className:"w-[180px]"})]}),e.jsx(b,{onClick:()=>z.mutate({userId:i.id,tool:F,amount:Number(f),expiresAt:Y?new Date(`${Y}T23:59:59Z`).toISOString():void 0}),disabled:z.isPending||!f,children:z.isPending?"Granting…":"Grant credits"}),e.jsx(b,{variant:"outline",onClick:()=>t.mutate(i.id),disabled:t.isPending,children:t.isPending?"Revoking…":"Revoke all credits"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:'Credits are consumed before monthly plan limits. Leave expiry blank for permanent credits. "Revoke all credits" cancels every credit this user holds, on every tool, in one step - plan grants are separate (above).'})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-semibold mb-2",children:"Active admin grants"}),P.isLoading?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading…"}):e.jsxs("div",{className:"grid md:grid-cols-2 gap-4 text-xs",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium mb-1",children:"Plan grants"}),(P.data?.plans??[]).length===0?e.jsx("p",{className:"text-muted-foreground",children:"None"}):e.jsx("ul",{className:"space-y-1",children:P.data.plans.map(n=>e.jsxs("li",{className:"text-muted-foreground",children:[e.jsx(E,{variant:n.status==="active"?"secondary":"outline",className:"mr-1",children:n.status}),Z(n.plan)," · ",n.environment," · until ",n.current_period_end?new Date(n.current_period_end).toLocaleDateString():" - "]},n.id))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium mb-1",children:"Credit grants (last 50)"}),(P.data?.credits??[]).length===0?e.jsx("p",{className:"text-muted-foreground",children:"None"}):e.jsx("ul",{className:"space-y-1",children:P.data.credits.map(n=>e.jsxs("li",{className:"text-muted-foreground",children:[n.delta>0?"+":"",n.delta," ",n.tool,n.expires_at?` · exp ${new Date(n.expires_at).toLocaleDateString()}`:""]},n.id))})]})]})]})]})]})}function bs(){const d=w($e),h=w(Re),i=w(je),a=w(Ie),v=se(),[g,s]=y.useState(!1),[j,c]=y.useState(""),[r,p]=y.useState(!1),[l,m]=y.useState([]),{data:o,isLoading:F,refetch:D}=I({queryKey:["admin","blog"],queryFn:()=>d()}),f=R({mutationFn:S=>h({data:{id:S}}),onSuccess:()=>
6{N.success("Post deleted"),v.invalidateQueries({queryKey:["admin","blog"]})},onError:S=>N.error(S.message)});async function B(){s(!0);try{await a({data:{topic:j.trim()||void 0}}),N.success("New article generated"),c(""),D()}catch(S){N.error(S.message)}finally{s(!1)}}async function Y(){p(!0);try{const J=(await i({data:void 0}))?.topics??[];m(J),J.length||N.info("No suggestions matched the filters")}catch(S){N.error(S.message)}finally{p(!1)}}return e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 gap-2 flex-wrap",children:[e.jsxs("h2",{className:"text-lg font-semibold",children:["Blog posts (",o?.posts.length??0,")"]}),e.jsx("div",{className:"flex gap-2",children:e.jsx(b,{variant:"outline",size:"sm",onClick:()=>D(),children:"Refresh"})})]}),e.jsxs("div",{className:"mb-4 flex gap-2 flex-wrap items-end",children:[e.jsxs("div",{className:"flex-1 min-w-[260px]",children:[e.jsx("label",{className:"text-xs text-muted-foreground mb-1 block",children:"Topic (optional - leave blank for a random topic)"}),e.jsx(k,{value:j,onChange:S=>c(S.target.value),placeholder:"e.g. How to negotiate a remote salary in 2026",disabled:g})]}),e.jsx(b,{size:"sm",onClick:B,disabled:g,children:g?"Generating…":j.trim()?"Generate on this topic":"Generate random article"}),e.jsx(b,{size:"sm",variant:"outline",onClick:Y,disabled:r||g,children:r?"Loading…":"Suggest topics (SEO)"})]}),l.length>0&&e.jsxs("div",{className:"mb-4 p-3 rounded-md border border-border bg-muted/30",children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-2",children:"Click a keyword to use it as the topic. Ranked by search volume vs difficulty (Semrush, US market)."}),e.jsx("div",{className:"flex flex-wrap gap-2",children:l.map(S=>e.jsxs("button",{type:"button",onClick:()=>c(S.keyword),disabled:g,className:"text-left text-xs px-3 py-2 rounded-md border border-border hover:bg-accent hover:text-accent-foreground transition-colors disabled:opacity-50",children:[e.jsx("div",{className:"font-medium",children:S.keyword}),e.jsxs("div",{className:"text-muted-foreground mt-0.5",children:[S.volume.toLocaleString(),"/mo · KD ",S.kd]})]},S.keyword))})]}),F?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):o?.posts.length?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Title"}),e.jsx(x,{children:"Slug"}),e.jsx(x,{children:"Source"}),e.jsx(x,{children:"Published"}),e.jsx(x,{})]})}),e.jsx(O,{children:o.posts.map(S=>e.jsxs(T,{children:[e.jsx(u,{className:"text-xs max-w-md truncate",title:S.title,children:S.title}),e.jsx(u,{className:"text-xs",children:e.jsx("a",{href:`/blog/${S.slug}`,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:S.slug})}),e.jsx(u,{className:"text-xs",children:S.generated_by_ai?e.jsx(E,{variant:"outline",children:"AI"}):e.jsx(E,{variant:"secondary",children:"manual"})}),e.jsx(u,{className:"text-xs text-muted-foreground",children:new Date(S.published_at).toLocaleDateString()}),e.jsx(u,{children:e.jsx(b,{size:"sm",variant:"ghost",className:"text-destructive",disabled:f.isPending,onClick:()=>{confirm(`Delete "${S.title}"?`)&&f.mutate(S.id)},children:"Delete"})})]},S.id))})]})}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No posts yet."})]})}function fs(){const[d,h]=y.useState(""),[i,a]=y.useState(""),[v,g]=y.useState(null),s=w(Ve),j=w(We),[c,r]=y.useState(null),{data:p,isLoading:l,refetch:m,isFetching:o}=I({queryKey:["admin","support-chats",i],queryFn:()=>s({data:{limit:100,search:i||void 0}})}),F=p?.chats??[],D=F.find(f=>f.id===v);return e.jsxs(L,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 gap-2 flex-wrap",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Support conversations"}),e.jsxs("form",{className:"flex gap-2",onSubmit:f=>{f.preventDefault(),a(d.trim())},children:[e.jsx(k,{placeholder:"Search message text…",value:d,onChange:f=>h(f.target.value),className:"w-[260px]"}),e.jsx(b,{type:"submit",variant:"outline",size:"sm",children:"Search"}),e.jsx(b,{type:"button",variant:"ghost",size:"sm",onClick:()=>m(),disabled:o,children:"Refresh"})]})]}),l?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):F.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No support chats yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Updated"}),e.jsx(x,{children:"User"}),e.jsx(x,{children:"Plan"}),e.jsx(x,{className:"text-right",children:"Msgs"}),e.jsx(x,{children:"Last user message"}),e.jsx(x,{children:"Status"}),e.jsx(x,{})]})}),e.jsx(O,{children:F.map(f=>e.jsxs(T,{children:[e.jsx(u,{className:"whitespace-nowrap text-xs text-muted-foreground",children:new Date(f.updated_at).toLocaleStr
6ing()}),e.jsx(u,{className:"text-xs",children:f.email??(f.user_id?f.user_id.slice(0,8):e.jsx("span",{className:"text-muted-foreground",children:"anonymous"}))}),e.jsx(u,{className:"text-xs",children:f.plan?e.jsx(E,{variant:"outline",children:Z(f.plan)}):e.jsx("span",{className:"text-muted-foreground",children:" - "})}),e.jsx(u,{className:"text-right tabular-nums text-xs",children:f.message_count}),e.jsx(u,{className:"text-xs max-w-md truncate",title:f.last_user_message??"",children:f.last_user_message??e.jsx("span",{className:"text-muted-foreground",children:" - "})}),e.jsx(u,{className:"text-xs whitespace-nowrap",children:f.needs_human?e.jsx(E,{className:"bg-amber-100 text-amber-900 border-amber-200",variant:"outline",children:"Needs a person"}):e.jsx("span",{className:"text-muted-foreground",children:" - "})}),e.jsxs(u,{className:"whitespace-nowrap",children:[e.jsx(b,{size:"sm",variant:"outline",onClick:()=>g(f.id),children:"View"}),f.needs_human&&e.jsx(b,{size:"sm",variant:"ghost",className:"ml-1",disabled:c===f.id,onClick:async()=>{r(f.id);try{await j({data:{id:f.id}}),await m()}finally{r(null)}},children:"Mark handled"})]})]},f.id))})]})}),D&&e.jsx("div",{className:"fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4",onClick:()=>g(null),children:e.jsxs("div",{className:"bg-background border rounded-lg shadow-lg max-w-2xl w-full max-h-[80vh] flex flex-col",onClick:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"p-4 border-b flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-semibold",children:D.email??"Anonymous visitor"}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[D.plan?Z(D.plan):"no plan"," · ",D.message_count," messages"]})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>g(null),children:"Close"})]}),e.jsx("div",{className:"overflow-y-auto p-4 space-y-3",children:D.messages.map((f,B)=>e.jsx("div",{className:f.role==="user"?"text-right":"text-left",children:e.jsxs("div",{className:"inline-block max-w-[85%] text-left",children:[e.jsx("div",{className:"text-[10px] uppercase text-muted-foreground mb-1",children:f.role}),e.jsx("div",{className:`rounded-lg px-3 py-2 text-sm whitespace-pre-wrap ${f.role==="user"?"bg-primary text-primary-foreground":"bg-muted"}`,children:f.content})]})},B))})]})})]})}function Ns(){const[d,h]=y.useState(30),i=w(Ue),{data:a,isLoading:v,refetch:g,isFetching:s}=I({queryKey:["admin","public-tools",d],queryFn:()=>i({data:{days:d}})}),j=Math.max(1,...(a?.daily??[]).map(c=>c.count));return e.jsxs(L,{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Free tool usage"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1 max-w-2xl",children:"Anonymous usage of the public LinkedIn and ATS tools. IPs are hashed. Use this to decide which free tools are pulling enough traffic to deepen."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(G,{value:String(d),onValueChange:c=>h(Number(c)),children:[e.jsx(Q,{className:"w-[140px]",children:e.jsx(V,{})}),e.jsxs(W,{children:[e.jsx(A,{value:"7",children:"Last 7 days"}),e.jsx(A,{value:"30",children:"Last 30 days"}),e.jsx(A,{value:"90",children:"Last 90 days"})]})]}),e.jsx(b,{variant:"outline",size:"sm",onClick:()=>g(),disabled:s,children:"Refresh"})]})]}),v?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):a?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid sm:grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(_,{label:`Total runs (${a.windowDays}d)`,value:a.totals.all,tone:"primary"}),e.jsx(_,{label:"Unique visitors",value:a.totals.uniqueVisitors}),e.jsx(_,{label:"Tools tracked",value:a.byTool.length}),e.jsx(_,{label:"Failures",value:a.byTool.reduce((c,r)=>c+r.failures,0),tone:"destructive"})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2",children:"Per tool"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(x,{children:"Tool"}),e.jsx(x,{className:"text-right",children:"Last 24h"}),e.jsx(x,{className:"text-right",children:"Last 7d"}),e.jsxs(x,{className:"text-right",children:[a.windowDays,"d total"]}),e.jsx(x,{className:"text-right",children:"Unique visitors"}),e.jsx(x,{className:"text-right",children:"Failures"})]})}),e.jsx(O,{children:a.byTool.map(c=>e.jsxs(T,{children:[e.jsx(u,{className:"font-medium",children:c.label}),e.jsx(u,{className:"text-right tabular-nums",children:c.last24h}),e.jsx(u,{className:"text-right tabular-nums",children:c.last7d}),e.jsx(u,{className:"text-right tabular-nums",children:c.total}),e.jsx(u,{className:"text-right tabular-nums",children:c.uniqueVisitors}),e.jsx(u,{className:"text-right tabular-nums",children:c.failures})]},c.key))})]})})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold mb-2",children:"Daily runs (all tools)"}),e.jsx("div",{className:"flex items-end gap-1 h-32 border rounded-md p-3 bg-muted/30",children:a.daily.map(c=>{const r=c.count===0?2:Math.max(6,Math.round(c.count/j*100));return e.jsx("div",{className:"flex-1 bg-primary/70 rounded-t hover:bg-primary transition-colors",style:{height:`${r}%`},title:`${c.date}: ${c.count} runs`},c.date)})}),e.jsxs("div",{className:"flex justify-between text-[10px] text-muted-foreground mt-1 font-mono",children:[e.jsx("span",{children:a.daily[0]?.date}),e.jsx("span",{children:a.daily[a.daily.length-1]?.date})]})]})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No data."})]})}
6export{Rs 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.