1import{r as R,j as i}from"./react-vendor-BxUrAMDo.js";import{u as v}from"./query-vendor-C8OxFoLA.js";import{o as T}from"./index-CQAF4vvG.js";import{p as b,b as A,c as L,u as I}from"./AdminAnalyticsDashboard-BcFA6zDA.js";import{d as P,T as x,a as S,s as g,b as k,u as C}from"./useStableParams-CCmx47yA.js";import{C as h}from"./ChartCard-CQDY5E4l.js";import{u as E}from"./chartTheme-7d0KzAdU.js";import{c as w}from"./compareOverlay-DrN1hA3q.js";import{T as j}from"./TimeSeriesChart-CerRyMKA.js";import{E as f}from"./EmptyState-CCePUi3r.js";import{K as m}from"./KPICard-DIwrGJRk.js";import"./scroll-area-NqSjhhDJ.js";import"./select-CbBqKqra.js";import"./popover-DjgHS5px.js";import{A as K}from"./AnalyticsPage-B6j55I7K.js";import{f as U}from"./format-BoAV63Jo.js";import"./ui-vendor-BRGvjLlB.js";import"./icons-B2ApzMU8.js";import"./types-DKfOy4iX.js";import"./textarea-DeKoTNkm.js";import"./en-US-UPLte4iB.js";import"./skeleton-CFN5HhQK.js";import"./generateCategoricalChart-DYjO9m1h.js";import"./index-CuAZr8ML.js";import"./Line-CJTYINav.js";import"./CartesianGrid-FE7MTn9S.js";(function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};r.SENTRY_RELEASE={id:"76af7de9158b89afec09e7e9dfdae5ea3e5aff85"};var l=new r.Error().stack;l&&(r._sentryDebugIds=r._sentryDebugIds||{},r._sentryDebugIds[l]="3381ffe0-3853-46fb-a6ba-b1e38bc06df8",r._sentryDebugIdIdentifier="sentry-dbid-3381ffe0-3853-46fb-a6ba-b1e38bc06df8")}catch{}})();const N={overview:"Overview KPIs",signups:"Signups",minutes:"Minutes processed"};function _(r){const{params:l,overview:a,signups:t,minutes:o}=r,d=P(l),n={section:"overview",title:"Overview",dateRange:d.dateRange,comparisonRange:d.comparisonRange,filters:d.filters,kpis:[],panels:[],series:[],definitions:["totalUsers","activeUsers30d","totalMinutes","successRate","avgMinutesPerUser","newSignups","share"],dataQuality:[]};if(a&&n.kpis.push({key:"totalUsers",label:"Total users",value:a.totalUsers,previousValue:a.previous?.totalUsers,unit:"count",betterWhen:"higher"},{key:"activeUsers30d",label:"Active 30d",value:a.activeUsers30d,previousValue:a.previous?.activeUsers30d,unit:"count",betterWhen:"higher"},{key:"totalMinutes",label:"Total minutes",value:a.totalMinutes,previousValue:a.previous?.totalMinutes,unit:"minutes",betterWhen:"higher"},{key:"successRate",label:"Success rate",value:b(a.successRate),previousValue:a.previous?b(a.previous.successRate):void 0,unit:"percent",betterWhen:"higher"},{key:"avgMinutesPerUser",label:"Avg min/user",value:a.avgMinutesPerUser,previousValue:a.previous?.avgMinutesPerUser,unit:"minutes",betterWhen:"higher"}),t){n.kpis.push({key:"newSignups",label:"New signups",value:t.total,previousValue:t.previous?.total,unit:"count",betterWhen:"higher"});const u={key:"signupsByTier",name:"Signups by tier",columns:[{key:"signups",label:"Signups",unit:"count"},{key:"share",label:"Share",unit:"percent"}],rows:x.map(s=>({label:S[s],values:[t.breakdown?.[s],g(t.breakdown?.[s],t.total)]}))};if(n.panels.push(u),t.byChannel?.length){const s=t.byChannel.reduce((e,c)=>e+(c.count||0),0);n.panels.push({key:"signupsByChannel",name:"Signups by acquisition channel",sortedBy:{column:"signups",direction:"desc"},columns:[{key:"signups",label:"Signups",unit:"count"},{key:"share",label:"Share",unit:"percent"}],rows:[...t.byChannel].sort((e,c)=>c.count-e.count).map(e=>({label:e.channel,values:[e.count,g(e.count,s)]}))});const p=t.byChannel.find(e=>e.channel==="unknown")?.count??0;p>0&&s>0&&n.dataQuality.push({code:"attribution_unknown_pct",value:p/s*100})}t.timeSeries?.length&&n.series.push({key:"signupsDaily",name:"Signups per day",unit:"count",aggregate:"sum",points:k(t.timeSeries,t.previousTimeSeries,s=>s.total)})}o&&(n.kpis.push({key:"avgMinutesPerUpload",label:"Avg minutes per upload",value:o.avgPerUpload,unit:"minutes"}),n.panels.push({key:"minutesByTier",name:"Minutes by tier",columns:[{key:"minutes",label:"Minutes",unit:"minutes"},{key:"share",label:"Share",unit:"percent"}],rows:x.map(u=>({label:S[u],values:[o.byTier?.[u],g(o.byTier?.[u],o.totalMinutes)]}))}),o.timeSeries?.length&&n.series.push({key:"minutesDaily",name:"Minutes processed per day",unit:"minutes",aggregate:"sum",points:k(o.timeSeries,o.previousTimeSeries,u=>u.minutes)})),d.compare||n.dataQuality.push({code:"comparison_off"});for(const u of r.failed??[])n.dataQuality.push({code:"partial_load",label:N[u]});return a&&t&&o&&a.totalMinutes===0&&t.total===0&&n.dataQuality.push({code:"no_data"}),n}function Q(r){const l=A()?.enabled===!0,a=C(r.params),t=[r.overview,r.signups,r.minutes],o=t.every(c=>c.isSuccess||c.isError),n=t.map((c,M)=>c.isError?["overview","signups","minutes"][M]:null).filter(c=>c!==null).join(","),{data:u}=r.overview,{data:s}=r.signups,{data:p}=r.minutes,e=R.useMemo(()=>!l||!o?null:_({params:a,overview:u,signups:s,minutes:p,failed:n?n.split(","):[]}),[l,o,a,u,s,p,n]);L(e)}function ce(){const{buildQueryParams:r,compare:l}=I(),a=r(),t=E(),o=v({queryKey:["/api/v2/admin/analytics/overview",a]}),d=v({queryKey:["/api/v2/admin/analytics/subscribers/signups",a]}),n=v({queryKey:["/api/v2/admin/analytics/usage/minutes",a]}),u=v({queryKey:["/api/v2/admin/analytics/recent-activity",{limit:8}]});Q({params:a,overview:o,signups:d,minutes:n});const s=o.data,p=s?.sparklines;return i.jsxs(K,{title:"Overview",description:"Key metrics across the entire platform",testId:"page-overview",children:[i.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 ga
1p-3",children:[i.jsx(m,{label:"Total users",value:(s?.totalUsers??0).toLocaleString(),previous:s?.previous?.totalUsers,current:s?.totalUsers,sparkline:p?.totalUsers,loading:o.isLoading,testId:"kpi-total-users"}),i.jsx(m,{label:"Active 30d",value:(s?.activeUsers30d??0).toLocaleString(),previous:s?.previous?.activeUsers30d,current:s?.activeUsers30d,sparkline:p?.activeUsers,loading:o.isLoading,testId:"kpi-active-30d"}),i.jsx(m,{label:"Total minutes",value:(s?.totalMinutes??0).toLocaleString(),previous:s?.previous?.totalMinutes,current:s?.totalMinutes,sparkline:p?.totalMinutes,loading:o.isLoading,testId:"kpi-minutes"}),i.jsx(m,{label:"Success rate",value:`${((s?.successRate??0)*100).toFixed(1)}%`,previous:s?.previous?.successRate,current:s?.successRate,loading:o.isLoading,testId:"kpi-success-rate"}),i.jsx(m,{label:"Avg min/user",value:(s?.avgMinutesPerUser??0).toFixed(1),previous:s?.previous?.avgMinutesPerUser,current:s?.avgMinutesPerUser,loading:o.isLoading,testId:"kpi-avg-min-user"})]}),i.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[i.jsx(h,{title:"Signups",description:"New accounts created in this period",loading:d.isLoading,exportSection:"signups",testId:"chart-signups",children:d.data?.timeSeries?.length?i.jsx(j,{variant:"area",data:d.data.timeSeries,xKey:"date",series:[{dataKey:"total",color:t.seriesColor(0)}],comparison:w(l,d.data.previousTimeSeries),testId:"chart-signups-area"}):i.jsx(f,{})}),i.jsx(h,{title:"Minutes processed",description:"Total transcribed minutes per day",loading:n.isLoading,exportSection:"minutes",testId:"chart-minutes",children:n.data?.timeSeries?.length?i.jsx(j,{variant:"line",data:n.data.timeSeries,xKey:"date",series:[{dataKey:"minutes",color:t.seriesColor(0)}],comparison:w(l,n.data.previousTimeSeries),testId:"chart-minutes-line"}):i.jsx(f,{})})]}),i.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-4",children:[i.jsx(y,{title:"Recent signups",loading:u.isLoading,items:u.data?.recentSignups.map(e=>({id:e.id,primary:e.email,secondary:`${e.tier} · ${e.createdAt?U(new Date(e.createdAt),"PP p"):""}`,status:e.tier}))??[]}),i.jsx(y,{title:"Recent transcriptions",loading:u.isLoading,items:u.data?.recentCompleted.map(e=>({id:e.id,primary:e.title||`Recording #${e.id}`,secondary:`${e.userEmail} · ${Math.round(e.duration/60)}m`,status:"completed"}))??[]}),i.jsx(y,{title:"Recent failures",loading:u.isLoading,items:u.data?.recentFailures.map(e=>({id:e.id,primary:e.title||`Recording #${e.id}`,secondary:`${e.userEmail} · ${e.createdAt?U(new Date(e.createdAt),"PP p"):""}`,status:"failed"}))??[]})]})]})}function y({title:r,items:l,loading:a}){return i.jsx(h,{title:r,loading:a,testId:`activity-${r.toLowerCase().replace(/\s+/g,"-")}`,children:l.length===0?i.jsx(f,{message:"Nothing recent"}):i.jsx("div",{className:"divide-y","data-testid":`activity-list-${r.toLowerCase().replace(/\s+/g,"-")}`,children:l.map(t=>i.jsxs("div",{className:"py-2 flex items-center justify-between gap-2 text-sm",children:[i.jsxs("div",{className:"min-w-0",children:[i.jsx("div",{className:"truncate font-medium",children:t.primary}),i.jsx("div",{className:"text-xs text-muted-foreground truncate",children:t.secondary})]}),i.jsx(T,{variant:t.status==="failed"?"destructive":"secondary",className:"text-[10px]",children:t.status})]},t.id))})})}export{ce 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.