1import{j as e}from"./query-_koPiPsI.js";import{f as T,r}from"./react-vendor-h1rQ_Bae.js";import{f as A,s as d,L as v,C as h,o as f,p as j,n as p,k as M,g as q}from"./index-Dq2zLArw.js";import"./ui-radix-CKwvnS8F.js";import"./supabase-DL6nu9mS.js";import"./charts-Xu79y1bN.js";import"./motion-nVmI7L5T.js";const g=[{key:"signup",label:"Signup"},{key:"email_verified",label:"Email verified"},{key:"pricing_viewed",label:"Pricing viewed"},{key:"checkout_started",label:"Checkout started"},{key:"checkout_redirected",label:"Checkout redirected"},{key:"subscription_active",label:"Subscribed"}];function J(){const{user:c,loading:o}=A(),N=T(),[l,_]=r.useState(null),[u,k]=r.useState({}),[m,w]=r.useState([]),[i,S]=r.useState(30),[C,y]=r.useState(!0),[x,b]=r.useState({open:!1});r.useEffect(()=>{if(!o){if(!c){N("/auth");return}d.from("user_roles").select("role").eq("user_id",c.id).eq("role","admin").maybeSingle().then(({data:s})=>_(!!s))}},[c,o,N]),r.useEffect(()=>{if(!l)return;let s=!1;return(async()=>{y(!0);const[{data:t},{data:a,error:n}]=await Promise.all([d.rpc("get_signup_funnel_summary",{p_days:i}),d.rpc("get_stuck_funnel_users")]);s||(k(t??{}),n&&console.error(n),w(a??[]),y(!1))})(),()=>{s=!0}},[l,i]);const E=async s=>{const{data:t,error:a}=await d.from("signup_funnel_events").select("step, reason, metadata, created_at").eq("user_id",s).order("created_at",{ascending:!0});if(a){q.error(a.message);return}b({open:!0,user_id:s,rows:t??[]})};if(o||l===null)return e.jsx("div",{className:"flex items-center justify-center min-h-screen",children:e.jsx(v,{className:"w-6 h-6 animate-spin"})});if(!l)return e.jsx("div",{className:"p-8 text-center text-muted-foreground",children:"Admin only."});const L=Math.max(1,...g.map(s=>u[s.key]??0));return e.jsxs("div",{className:"p-6 max-w-6xl mx-auto space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold",children:"Signup â Pay funnel"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Drop-off telemetry. Tech-shaped failures alert in admin alerts."})]}),e.jsx("div",{className:"flex gap-2",children:[7,30,90].map(s=>e.jsxs("button",{onClick:()=>S(s),className:`px-3 py-1 text-sm rounded border ${i===s?"bg-foreground text-background":"hover:bg-muted"}`,children:[s,"d"]},s))})]}),e.jsxs(h,{children:[e.jsx(f,{children:e.jsxs(j,{children:["Funnel (",i," days)"]})}),e.jsx(p,{children:C?e.jsx(v,{className:"w-5 h-5 animate-spin"}):e.jsx("div",{className:"space-y-3",children:g.map((s,t)=>{const a=u[s.key]??0,n=t===0?a:u[g[t-1].key]??0,P=n>0&&t>0?Math.round((1-a/n)*100):0,D=Math.max(2,Math.round(a/L*100));return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:s.label}),e.jsxs("span",{className:"tabular-nums",children:[a," ",t>0&&n>0&&e.jsxs("span",{className:"text-muted-foreground ml-2",children:["(",P,"% drop)"]})]})]}),e.jsx("div",{className:"h-6 bg-muted rounded overflow-hidden",children:e.jsx("div",{className:"h-full bg-foreground",style:{width:`${D}%`}})})]},s.key)})})})]}),e.jsxs(h,{children:[e.jsx(f,{children:e.jsxs(j,{children:["Stuck users (",m.length,")"]})}),e.jsx(p,{children:m.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No users currently stuck mid-funnel."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-left text-muted-foreground border-b",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-2",children:"Email"}),e.jsx("th",{children:"Last step"}),e.jsx("th",{children:"When"}),e.jsx("th",{children:"Hours"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:m.map(s=>e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 font-mono text-xs",children:s.email??s.user_id.slice(0,8)}),e.jsx("td",{children:e.jsx(M,{variant:"outline",children:s.last_step})}),e.jsx("td",{className:"text-muted-foreground",children:new Date(s.last_step_at).toLocaleStr
1ing()}),e.jsxs("td",{className:"tabular-nums",children:[s.hours_since,"h"]}),e.jsx("td",{children:e.jsx("button",{onClick:()=>E(s.user_id),className:"text-xs underline hover:no-underline",children:"view trail"})})]},s.user_id))})]})})})]}),x.open&&e.jsxs(h,{children:[e.jsxs(f,{className:"flex flex-row items-center justify-between",children:[e.jsxs(j,{className:"text-base",children:["Event trail · ",x.user_id?.slice(0,8)]}),e.jsx("button",{onClick:()=>b({open:!1}),className:"text-xs underline",children:"close"})]}),e.jsx(p,{children:e.jsx("ol",{className:"space-y-2 text-sm",children:x.rows?.map((s,t)=>e.jsxs("li",{className:"border-l-2 pl-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"font-medium",children:s.step}),e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(s.created_at).toLocaleString()})]}),s.reason&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["reason: ",s.reason]}),s.metadata&&Object.keys(s.metadata).length>0&&e.jsx("pre",{className:"text-xs bg-muted p-2 mt-1 rounded overflow-x-auto",children:JSON.stringify(s.metadata,null,2)})]},t))})})]})]})}export{J 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.