1import{c as se,u as ae,b as te,r as c,s as h,f as _,j as e,B as A,A as re,J as D,C as d,y as o,z as x,ae as I,a as m,aD as $,I as k,N as ne,a5 as ie}from"./index-DO0ZNUzu.js";import{T as F,a as R,b as p,c as r,d as B,e as t}from"./table-CnjIDQIw.js";import{A as le}from"./AdminCommunityVoiceNotes-CZa7sDdo.js";import{C as ce}from"./calendar-Dodd1r6N.js";import{R as de,L as oe,C as xe,X as me,Y as he,T as ue,a as je}from"./LineChart-B2vz4ggM.js";import"./textarea-CcV1k9Cd.js";import"./select-Tn3h6yZZ.js";import"./check-Cyw8qn0D.js";import"./square-BBuUZiRV.js";import"./loader-circle-CZ_geqae.js";import"./upload-5tqj8CNI.js";import"./trash-2-VtFXnL4x.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const fe=se("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),ke=()=>{const{user:C,loading:T}=ae(),g=te(),[l,H]=c.useState([]),[L,U]=c.useState([]),[S,O]=c.useState([]),[q,J]=c.useState(!0),[E,z]=c.useState(!1),[N,K]=c.useState(""),[M,W]=c.useState([]);c.useEffect(()=>{(async()=>{if(!T){if(!C){g("/auth");return}try{const[{data:a},{data:n}]=await Promise.all([h.rpc("has_role",{_user_id:C.id,_role:"admin"}),h.rpc("has_role",{_user_id:C.id,_role:"owner"})]);if(!a&&!n){_.error("Access denied. Admin or owner role required."),g("/admin/dashboard");return}z(!0);const{data:i,error:u}=await h.from("profiles").select("*").order("created_at",{ascending:!1});if(u)throw u;H(i||[]),U(i||[]);const{data:y,error:j}=await h.from("payment_failures").select("*").order("created_at",{ascending:!1}).limit(50);if(j)console.error("Error fetching payment failures:",j);else{const v=await Promise.all((y||[]).map(async b=>{if(b.user_id){const{data:f}=await h.from("profiles").select("display_name").eq("user_id",b.user_id).single();return{...b,profiles:f}}return b}));O(v)}if(i){const v={};i.forEach(f=>{const w=new Date(f.created_at).toLocaleDateString();v[w]=(v[w]||0)+1});const b=Object.entries(v).map(([f,w])=>({date:f,users:w})).sort((f,w)=>new Date(f.date).getTime()-new Date(w.date).getTime()).slice(-30);W(b)}}catch(a){console.error("Error:",a),_.error("Failed to load data")}finally{J(!1)}}})()},[C,T,g]),c.useEffect(()=>{if(!E)return;const s=h.channel("profile-changes").on("postgres_changes",{event:"INSERT",schema:"public",table:"profiles"},n=>{const i=n.new;H(u=>[i,...u]),_.success(`New user signed up: ${i.display_name||"Unknown"}`)}).subscribe(),a=h.channel("payment-failures-changes").on("postgres_changes",{event:"INSERT",schema:"public",table:"payment_failures"},n=>{const i=n.new;O(u=>[i,...u]),_.error("New payment failure detected!")}).subscribe();return()=>{h.removeChannel(s),h.removeChannel(a)}},[E]),c.useEffect(()=>{if(!N){U(l);return}const s=l.filter(a=>{var n;return((n=a.display_name)==null?void 0:n.toLowerCase().includes(N.toLowerCase()))||a.user_id.toLowerCase().includes(N.toLowerCase())});U(s)},[N,l]);const X=()=>{const s=["Display Name","User ID","Email","Joined Date"],a=l.map(j=>[j.display_name||"No name",j.user_id,"",new Date(j.created_at).toLocaleDateString()]),n=[s.join(","),...a.map(j=>j.join(","))].join(` 7`),i=new Blob([n],{type:"text/csv"}),u=window.URL.createObjectURL(i),y=document.createElement("a");y.href=u,y.download=`users-${new Date().toISOString().split("T")[0]}.csv`,y.click(),_.success("User data exported successfully!")},V=l.length,Y=l.filter(s=>s.subscription_status==="active").length,G=new Date().toDateString(),Q=l.filter(s=>new Date(s.created_at).toDateString()===G).length,Z=l.filter(s=>new Date(s.created_at)>new Date(Date.now()-7*24*60*60*1e3)).length,ee=l.filter(s=>new Date(s.created_at)>new Date(Date.now()-30*24*60*60*1e3)).length,P=l.filter(s=>s.stripe_customer_id);return T||q?e.jsx("div",{className:"min-h-screen flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto"}),e.jsx("p",{className:"mt-4 text-muted-foreground",children:"Loading..."})]})}):E?e.jsx("div",{className:"min-h-screen bg-background",children:e.jsxs("div",{className:"container mx-auto py-8 px-4 max-w-7xl",children:[e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsxs(A,{variant:"ghost",onClick:()=>
7g("/admin/dashboard"),children:[e.jsx(re,{className:"mr-2 h-4 w-4"}),"Back to Admin Dashboard"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(A,{variant:"outline",onClick:()=>g("/admin/dashboard"),className:"gap-2",children:[e.jsx(D,{className:"h-4 w-4"}),"View Dashboard"]}),e.jsxs(A,{variant:"outline",onClick:()=>g("/admin/analytics"),className:"gap-2",children:[e.jsx(D,{className:"h-4 w-4"}),"Analytics"]})]})]}),e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-3xl font-bold text-foreground mb-2",children:"Admin Dashboard"}),e.jsx("p",{className:"text-muted-foreground",children:"Track and manage user signups"})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4 mb-8",children:[e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"Total Users"}),e.jsx(I,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold",children:V}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"All registered users"})]})]}),e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"Active Subscribers"}),e.jsx(D,{className:"h-4 w-4 text-green-500"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold",children:Y}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Paying members"})]})]}),e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"New Today"}),e.jsx(fe,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold",children:Q}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Signups in last 24h"})]})]}),e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"This Week"}),e.jsx(ce,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold",children:Z}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Last 7 days"})]})]}),e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"This Month"}),e.jsx(D,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold",children:ee}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Last 30 days"})]})]}),e.jsxs(d,{children:[e.jsxs(o,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsx(x,{className:"text-sm font-medium",children:"Failed Payments"}),e.jsx($,{className:"h-4 w-4 text-red-500"})]}),e.jsxs(m,{children:[e.jsx("div",{className:"text-2xl font-bold text-red-600",children:S.length}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Total failures tracked"})]})]})]}),e.jsxs(d,{className:"mb-8",children:[e.jsxs(o,{children:[e.jsx(x,{children:"Signup Trends"}),e.jsx(k,{children:"Daily user registrations over the last 30 days"})]}),e.jsx(m,{children:e.jsx("div",{className:"h-[300px] w-full",children:e.jsx(de,{width:"100%",height:"100%",children:e.jsxs(oe,{data:M,children:[e.jsx(xe,{strokeDasharray:"3 3",className:"stroke-muted"}),e.jsx(me,{dataKey:"date",className:"text-xs",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(he,{className:"text-xs",tick:{fill:"hsl(var(--muted-foreground))"}}),e.jsx(ue,{contentStyle:{backgroundColor:"hsl(var(--card))",border:"1px solid hsl(var(--border))",borderRadius:"8px"}}),e.jsx(je,{type:"monotone",dataKey:"users",stroke:"hsl(var(--primary))",strokeWidth:2,dot:{fill:"hsl(var(--primary))"}})]})})})})]}),P.length>0&&e.jsxs(d,{className:"mb-8",children:[e.jsx(o,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(D,{className:"h-6 w-6 text-green-500"}),e.jsxs("div",{children:[e.jsx(x,{children:"Paying Subscribers"}),e.jsxs(k,{children:[P.length," users with active or past subscriptions"]})]})]})}),e.jsx(m,{children:e.jsx("div",{className:"rounded-md border overflow-x-auto",children:e.jsxs(F,{children:[e.jsx(R,{children:e.jsxs(p,{children:[e.jsx(r,{children:"Name"}),e.jsx(r,{children:"Status"}),e.jsx(r,{children:"Tier"}),e.jsx(r,{children:"End Date"}),e.jsx(r,{children:"Stripe ID"})]})}),e.jsx(B,{children:P.map(s=>{var a;return e.jsxs(p,{children:[e.jsx(t,{className:"font-medium",children:s.display_name||"No name set"}),e.jsx(t,{children:e.jsx("span",{className:`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${s.subscription_status==="active"?"bg-green-100 text-green-800":s.subscription_status==="canceled"?"bg-red-100 text-red-800":"bg-gray-100 text-gray-800"}`,children:s.subscription_status||"unknown"})}),e.jsx(t,{className:"capitalize",children:s.subscription_tier||"N/A"}),e.jsx(t,{children:s.subscription_end_date?new Date(s.subscription_end_date).toLocaleDateString():"N/A"}),e.jsxs(t,{className:"font-mono text-xs",children:[(a=s.stripe_customer_id)==null?void 0:a.substring(0,20),"..."]})]},s.id)})})]})})})]}),S.length>0&&e.jsxs(d,{className:"mb-8",children:[e.jsx(o,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{className:"h-6 w-6 text-red-500"}),e.jsxs("div",{children:[e.jsx(x,{children:"Recent Payment Failures"}),e.jsxs(k,{children:[S.length," failed payment attempts"]})]})]})}),e.jsx(m,{children:e.jsx("div",{className:"rounded-md border overflow-x-auto",children:e.jsxs(F,{children:[e.jsx(R,{children:e.jsxs(p,{children:[e.jsx(r,{children:"Date"}),e.jsx(r,{children:"User"}),e.jsx(r,{children:"Amount"}),e.jsx(r,{children:"Reason"}),e.jsx(r,{children:"Code"}),e.jsx(r,{children:"Invoice ID"})]})}),e.jsx(B,{children:S.map(s=>{var a,n;return e.jsxs(p,{children:[e.jsx(t,{children:new Date(s.created_at).toLocaleDateString()}),e.jsx(t,{className:"font-medium",children:((a=s.profiles)==null?void 0:a.display_name)||"Unknown User"}),e.jsxs(t,{className:"font-mono",children:["$",(s.amount_cents/100).toFixed(2)," ",s.currency.toUpperCase()]}),e.jsx(t,{className:"max-w-xs truncate",children:s.failure_reason||"Unknown"}),e.jsx(t,{children:e.jsx("code",{className:"text-xs bg-muted px-1.5 py-0.5 rounded",children:s.failure_code})}),e.jsxs(t,{className:"font-mono text-xs",children:[(n=s.stripe_invoice_id)==null?void 0:n.substring(0,20),"..."]})]},s.id)})})]})})})]}),e.jsxs(d,{children:[e.jsx(o,{children:e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center md:justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{className:"h-6 w-6 text-primary"}),e.jsxs("div",{children:[e.jsx(x,{children:"All Users"}),e.jsxs(k,{children:[L.length," of ",V," users"]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(ne,{placeholder:"Search by name or ID...",value:N,onChange:s=>K(s.target.value),className:"w-full sm:w-[250px]"}),e.jsxs(A,{onClick:X,variant:"outline",className:"gap-2",children:[e.jsx(ie,{className:"h-4 w-4"}),"Export CSV"]})]})]})}),e.jsx(m,{children:e.jsx("div",{className:"rounded-md border overflow-x-auto",children:e.jsxs(F,{children:[e.jsx(R,{children:e.jsxs(p,{children:[e.jsx(r,{children:"Display Name"}),e.jsx(r,{children:"User ID"}),e.jsx(r,{children:"Avatar"}),e.jsx(r,{children:"Joined Date"})]})}),e.jsx(B,{children:L.length===0?e.jsx(p,{children:e.jsx(t,{colSpan:4,className:"text-center text-muted-foreground py-8",children:N?"No users found matching your search":"No subscribers found"})}):L.map(s=>e.jsxs(p,{children:[e.jsx(t,{className:"font-medium",children:s.display_name||"No name set"}),e.jsx(t,{className:"font-mono text-xs",children:s.user_id}),e.jsx(t,{children:s.avatar_url?e.jsx("img",{src:s.avatar_url,alt:s.display_name||"User",className:"h-8 w-8 rounded-full object-cover"}):e.jsx("div",{className:"h-8 w-8 rounded-full bg-muted flex items-center justify-center",children:e.jsx(I,{className:"h-4 w-4 text-muted-foreground"})})}),e.jsx(t,{children:new Date(s.created_at).toLocaleDateString()})]},s.id))})]})})})]}),e.jsx(le,{})]})}):null};export{ke 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.