1import{r as d,s as p,j as e,C as A,h as z,k as H,g as W,B as G,d as V,R as ee,m as R,b0 as ce,a4 as Q,cb as f,am as C,aS as de,bV as F,cg as me,z as ue}from"./index-vQd7viLS.js";import{f as U}from"./currencyService-zE5g1OhT.js";import{f as X}from"./storageQuotaService-Qy9wxvfw.js";import{E as pe}from"./ExportAccountsButton-DpObD-yE.js";import{A as te}from"./activity-Bh0uN1yL.js";import{D as _e}from"./dollar-sign-3FiMID6p.js";import{T as Z}from"./trending-up-CMgfoW9o.js";import{F as xe}from"./file-up-DrdZuULK.js";import{H as ge}from"./hard-drive-fNfr2StY.js";import"./en-US-BukEqXxE.js";import"./calendar-DWrP23HI.js";const he=["role_mapping_auto_repair","role_mapping_missing_filled","role_mapping_broken","director_fallback_used","model_callability_failing"];function be(){const[t,a]=d.useState(null),[m,l]=d.useState(!1),n=d.useCallback(async()=>{l(!0);try{const g=new Date(Date.now()-864e5).toISOString(),T=new Date(Date.now()-3600*1e3).toISOString(),[j,$,N,E]=await Promise.all([p.from("cg_model_role_mappings").select("mapping_status").eq("enabled",!0),p.from("cg_admin_alerts").select("severity, alert_type").in("alert_type",he).eq("status","open"),p.from("cg_routing_resolver_misses").select("id",{count:"exact",head:!0}).gte("created_at",g),p.from("cg_model_callability_probes").select("status").gte("checked_at",T)]);let y=0,x=0,o=0;for(const v of j.data??[]){const b=String(v.mapping_status??"green");b==="green"?y++:b==="red_stale"?o++:x++}let i=0,h=0;for(const v of $.data??[]){const b=String(v.severity??"");b==="warning"?i++:(b==="error"||b==="critical")&&h++}let S=0;for(const v of E.data??[])String(v.status??"").toLowerCase()!=="ok"&&S++;a({mapping_green:y,mapping_yellow:x,mapping_red:o,alerts_warning:i,alerts_error:h,router_misses_24h:N.count??0,callability_fail_1h:S})}finally{l(!1)}},[]);d.useEffect(()=>{n()},[n]);const c=d.useMemo(()=>t?t.mapping_red>0||t.alerts_error>0?"red":t.mapping_yellow>0||t.alerts_warning>0||t.router_misses_24h>0||t.callability_fail_1h>0?"yellow":"green":"green",[t]),_=d.useCallback(async()=>{l(!0);try{await p.functions.invoke("cg-router-health-watch",{body:{}}),await n()}catch{}finally{l(!1)}},[n]);return e.jsxs(A,{children:[e.jsxs(z,{className:"flex flex-row items-center justify-between gap-3 pb-2",children:[e.jsxs("div",{children:[e.jsxs(H,{
1className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(te,{className:"h-4 w-4"}),"Routing & Model Health",e.jsx(W,{variant:"outline",className:c==="green"?"text-emerald-700 border-emerald-500/50":c==="red"?"text-destructive border-destructive/50":"text-amber-700 border-amber-500/50",children:c==="green"?"All good":c==="red"?"Attention":"Watch"})]}),e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:"Mapping table health, open routing alerts, resolver misses, and callability probes."})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(G,{size:"sm",variant:"outline",onClick:()=>void _(),disabled:m,children:m?e.jsx(V,{className:"h-4 w-4"}):e.jsx(ee,{className:"h-4 w-4"})})})]}),e.jsxs(R,{className:"pt-2",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 text-sm",children:[e.jsx(M,{label:"Mapping · green",value:(t==null?void 0:t.mapping_green)??"â",tone:"ok"}),e.jsx(M,{label:"Mapping · yellow / red",value:t?`${t.mapping_yellow} / ${t.mapping_red}`:"â",tone:t&&t.mapping_red>0?"err":t&&t.mapping_yellow>0?"warn":"ok"}),e.jsx(M,{label:"Open alerts (warn / err)",value:t?`${t.alerts_warning} / ${t.alerts_error}`:"â",tone:t&&t.alerts_error>0?"err":t&&t.alerts_warning>0?"warn":"ok",icon:e.jsx(ce,{className:"h-3 w-3"})}),e.jsx(M,{label:"Router misses (24h)",value:(t==null?void 0:t.router_misses_24h)??"â",tone:t&&t.router_misses_24h>0?"warn":"ok",icon:e.jsx(Q,{className:"h-3 w-3"})})]}),t&&t.callability_fail_1h>0&&e.jsxs("div",{className:"mt-3 text-xs text-amber-800 dark:text-amber-200 flex items-center gap-2",children:[e.jsx(Q,{className:"h-3 w-3"}),t.callability_fail_1h," callability probe failure",t.callability_fail_1h===1?"":"s"," in the last hour."]})]})]})}function M({label:t,value:a,tone:m,icon:l}){const n=m==="err"?"border-destructive/40 text-destructive":m==="warn"?"border-amber-500/40 text-amber-700 dark:text-amber-300":"border-emerald-500/40 text-emerald-700 dark:text-emerald-300";return e.jsxs("div",{className:`rounded border ${n} px-3 py-2 flex items-center justify-between gap-2 bg-background/40`,children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs opacity-80",children:[l,t]}),e.jsx("div",{className:"text-base font-semibold tabular-nums",children:a})]})}const Ae=({refreshKey:t})=>{const[a,m]=d.useState(null),[l,n]=d.useState(!0),[c,_]=d.useState(!1),g=d.useCallback(async()=>{n(!0);try{const{data:i,error:h}=await p.functions.invoke("cg-admin-query",{body:{query_type:"overview_stats"}});if(h)throw h;m((i==null?void 0:i.data)||null)}catch(i){console.error("[AdminOverview] Load error:",i)}finally{n(!1)}},[]);d.useEffect(()=>{g()},[g,t]);const T=d.useCallback(async()=>{_(!0);try{const[i,h,S,v,b]=await Promise.all([p.from("cg_plan_catalog").select("*").order("sort_order"),p.from("cg_plan_limits").select("*"),p.from("cg_model_role_mappings").select("*").eq("enabled",!0),p.from("cg_model_pricing").select("*").eq("is_active",!0),p.from("cg_stripe_price_map").select("*").eq("status","active")]),se=i.data||[],ae=h.data||[],re=S.data||[],ie=v.data||[],oe=b.data||[],ne=Object.fromEntries(ae.map(s=>[s.plan_code,s])),w={};oe.forEach(s=>{w[s.plan_code]||(w[s.plan_code]=[]),w[s.plan_code].push(s)});const P=se.map(s=>{var K,J;const r=ne[s.plan_code]||{},L=(K=w[s.plan_code])==null?void 0:K.find(I=>I.billing_interval==="monthly"),B=(J=w[s.plan_code])==null?void 0:J.find(I=>I.billing_interval==="annual");return{"Plan Code":s.plan_code,"Display Name":s.display_name,"Public Label":s.public_label||"",Status:s.status,Public:s.is_public?"Yes":"No","Monthly Price (USD)":r.monthly_price_minor?`$${(r.monthly_price_minor/100).toFixed(2)}`:"","Annual Price (USD)":r.annual_price_minor?`$${(r.annual_price_minor/100).toFixed(2)}`:"","Raw Storage (MB)":r.raw_storage_mb||0,"Indexed Storage (MB)":r.indexed_storage_mb||0,"Max Input Tokens/Request":r.max_input_tokens_per_request||0,"Max Output Tokens/Request":r.max_output_tokens_per_request||0,"Max Tool Calls/Request":r.max_tool_calls_per_request||0,"Search Calls/Month":r.search_calls_per_month||0,"Expert Credits/Month":r.expert_credits_per_month||0,"Max Upload Size (MB)":r.max_upload_file_size_mb||0,"Max Uploads/Day":r.max_uploads_per_day||0,"Daily Spend Cap (USD)":r.daily_spend_cap_minor?`$${(r.daily_spend_cap_minor/100).toFixed(2)}`:"","Monthly Spend Cap (USD)":r.monthly_spend_cap_minor?`$${(r.monthly_spend_cap_minor/100).toFixed(2)}`:"","Max Role Ceiling":r.max_role_ceiling||"","Allowed Roles":Array.isArray(r.allowed_roles)?r.allowed_roles.join(", "):"","Stripe Monthly Price ID":(L==null?void 0:L.stripe_price_id)||"","Stripe Annual Price ID":(B==null?void 0:B.stripe_price_id)||""}}),O=re.map(s=>
1({"Role Code":s.role_code,"Display Name":s.display_name,"Model Code":s.model_code,"Mapping Type":s.mapping_type,Description:s.description||""})),q=ie.map(s=>({"Model Code":s.model_code||"",Currency:s.currency_code,"Input / 1M Tokens (minor)":s.input_per_million_minor,"Output / 1M Tokens (minor)":s.output_per_million_minor,"Cached Input / 1M (minor)":s.cached_input_per_million_minor||"","Search Call (minor)":s.search_call_minor||"","Storage / GB/Day (minor)":s.storage_per_gb_day_minor||"","Effective From":s.effective_from,Notes:s.notes||""})),k=f.utils.book_new(),Y=f.utils.json_to_sheet(P);if(Y["!cols"]=P.length>0?Object.keys(P[0]).map(s=>({wch:Math.max(s.length,14)})):[],f.utils.book_append_sheet(k,Y,"Plans & Limits"),O.length>0){const s=f.utils.json_to_sheet(O);s["!cols"]=Object.keys(O[0]).map(r=>({wch:Math.max(r.length,14)})),f.utils.book_append_sheet(k,s,"Model Mappings")}if(q.length>0){const s=f.utils.json_to_sheet(q);s["!cols"]=Object.keys(q[0]).map(r=>({wch:Math.max(r.length,14)})),f.utils.book_append_sheet(k,s,"Model Pricing")}const le=new Date().toISOString().slice(0,10);f.writeFile(k,`jairen-plan-report-${le}.xlsx`),C({title:"Report exported",description:"Plan report downloaded successfully."})}catch(i){console.error("[AdminOverview] Export error:",i),C({title:"Export failed",description:"Could not generate the plan report.",variant:"destructive"})}finally{_(!1)}},[]);if(l||!a)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(V,{className:"h-6 w-6 animate-spin text-muted-foreground"})});const j=a.month_contribution_minor,$=a.month_income_minor>0?(j/a.month_income_minor*100).toFixed(1):"â",N=new Date,E=N.getDate(),y=N.toLocaleString("en-GB",{month:"long",year:"numeric"}),x=`MTD · day ${E} of ${y}`,o=i=>()=>{window.location.hash=i,window.scrollTo({top:0,behavior:"smooth"})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold text-foreground",children:"Platform Overview"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[y," operational summary · all values in USD · ",x]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(G,{onClick:T,disabled:c,variant:"outline",size:"sm",children:[c?e.jsx(V,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(de,{className:"h-4 w-4 mr-1"}),"Export Plan Report"]}),e.jsx(pe,{onSuccess:()=>C({title:"Accounts report exported"}),onError:i=>C({title:"Export failed",description:i,variant:"destructive"})}),e.jsxs(G,{onClick:g,disabled:l,variant:"outline",size:"sm",children:[e.jsx(ee,{className:"h-4 w-4 mr-1"})," Refresh"]})]})]}),e.jsx(be,{}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(u,{icon:F,title:"Total Accounts",value:a.total_accounts,subtitle:"All registered accounts",onClick:o("accounts")}),e.jsx(u,{icon:me,title:"Active Paid Subscriptions",value:a.subscriptions_active,subtitle:"Excludes trials",onClick:o("revenue")}),e.jsx(u,{icon:F,title:"Active Trials",value:a.trials_active,subtitle:a.trials_expired>0?`${a.trials_expired} expired this month`:"Trial status = active",onClick:o("trials")}),e.jsx(u,{icon:F,title:"Past Due",value:a.subscriptions_past_due,subtitle:"Failed renewals",alert:a.subscriptions_past_due>0,onClick:o("revenue")})]}),e.jsxs(A,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(H,{className:"text-sm font-medium text-muted-foreground",children:"Accounts by Plan"})}),e.jsx(R,{children:e.jsx("div",{className:"flex flex-wrap gap-3",children:Object.entries(a.plan_breakdown).map(([i,h])=>e.jsxs("button",{type:"button",onClick:o("plans"),className:"flex items-center gap-2 border border-border rounded-lg px-3 py-2 hover:bg-accent hover:border-accent-foreground/20 transition-colors cursor-pointer text-left","aria-label":`View ${i} plan details`,children:[e.jsx(W,{variant:"outline",className:"text-xs",children:i}),e.jsx("span",{className:"text-lg font-bold text-foreground",children:h})]},i))})})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 gap-4",children:[e.jsx(u,{icon:_e,title:"Estimated Spend (MTD)",value:U(a.month_estimated_spend_minor),subtitle:x,onClick:o("economics")}),e.jsx(u,{icon:Z,title:"Recognised Income (MTD)",value:U(a.month_income_minor),subtitle:x,onClick:o("revenue")}),e.jsx(u,{icon:Z,title:"Contribution (MTD)",value:U(j),subtitle:`${$}% margin · ${x}`,alert:j<0,onClick:o("economics")})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(u,{icon:te,title:"AI Requests (MTD)",value:a.month_requests.toLocaleStr
1ing(),subtitle:x,onClick:o("ai-usage")}),e.jsx(u,{icon:ue,title:"Search Calls (MTD)",value:a.month_search_calls.toLocaleString(),subtitle:x,onClick:o("ai-usage")}),e.jsx(u,{icon:xe,title:"Uploads (MTD)",value:a.month_uploads.toLocaleString(),subtitle:x,onClick:o("storage")}),e.jsx(u,{icon:ge,title:"Storage (live)",value:X(a.raw_storage_mb),subtitle:`${X(a.indexed_storage_mb)} indexed`,onClick:o("storage")})]}),e.jsxs(A,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(H,{className:"text-sm font-medium text-muted-foreground",children:"Subscription Status"})}),e.jsxs(R,{children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(D,{label:"Active",count:a.subscriptions_active,variant:"default",onClick:o("revenue")}),e.jsx(D,{label:"Past Due",count:a.subscriptions_past_due,variant:"destructive",onClick:o("revenue")}),e.jsx(D,{label:"Cancelled",count:a.subscriptions_cancelled,variant:"outline",onClick:o("revenue")}),e.jsx(D,{label:"Paused",count:a.subscriptions_paused,variant:"secondary",onClick:o("revenue")})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-3",children:["Note: trial accounts have status ",e.jsx("code",{className:"px-1 rounded bg-muted",children:"trial"})," and are counted separately under ",e.jsx("strong",{children:"Active Trials"}),", not under Active Paid Subscriptions."]})]})]})]})};function u({icon:t,title:a,value:m,subtitle:l,alert:n,onClick:c}){const _=!!c;return e.jsx(A,{className:[n?"border-destructive/50":"",_?"cursor-pointer hover:border-foreground
1/30 hover:shadow-sm transition-all":""].filter(Boolean).join(" "),onClick:c,role:_?"button":void 0,tabIndex:_?0:void 0,onKeyDown:_?g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),c==null||c())}:void 0,"aria-label":_?`${a} â open details`:void 0,children:e.jsxs(R,{className:"pt-4 pb-3 px-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:a}),e.jsx(t,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx("p",{className:`text-xl font-bold ${n?"text-destructive":"text-foreground"}`,children:m}),l&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:l})]})})}function D({label:t,count:a,variant:m,onClick:l}){const n=!!l;return e.jsxs("button",{type:"button",onClick:l,disabled:!n,className:["flex items-center gap-2 rounded-md px-2 py-1 -mx-2 -my-1",n?"hover:bg-accent transition-colors cursor-pointer":"cursor-default"].join(" "),"aria-label":n?`${t} ${a} â open details`:void 0,children:[e.jsx(W,{variant:m,children:t}),e.jsx("span",{className:"text-lg font-bold text-foreground",children:a})]})}export{Ae as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.