@@ -5,23 +5,50 @@ import { isAdminEmail } from "@/lib/access";
55import { listUsers } from "@/lib/db" ;
66
77export default async function AdminPage ( ) {
8- const session = await getServerSession ( authOptions ) ;
8+ let session ;
9+ try {
10+ session = await getServerSession ( authOptions ) ;
11+ } catch {
12+ return (
13+ < div className = "min-h-screen bg-[#09090f] text-white p-8 flex items-center justify-center" >
14+ < div className = "text-center max-w-md" >
15+ < h1 className = "text-xl font-bold text-red-400 mb-3" > Configuration Error</ h1 >
16+ < p className = "text-zinc-400 text-sm" >
17+ AUTH_SECRET / NEXTAUTH_SECRET must be set in environment variables.
18+ </ p >
19+ </ div >
20+ </ div >
21+ ) ;
22+ }
923
1024 if ( ! isAdminEmail ( session ?. user ?. email ) ) {
1125 redirect ( "/dashboard" ) ;
1226 }
1327
14- // Fetch users from our updated db utility
15- const users = await listUsers ( ) ;
28+ let users : any [ ] = [ ] ;
29+ try {
30+ users = await listUsers ( ) ;
31+ } catch {
32+ return (
33+ < div className = "min-h-screen bg-[#09090f] text-white p-8 flex items-center justify-center" >
34+ < div className = "text-center max-w-md" >
35+ < h1 className = "text-xl font-bold text-red-400 mb-3" > Database Error</ h1 >
36+ < p className = "text-zinc-400 text-sm" >
37+ Could not connect to database. Check DATABASE_URL.
38+ </ p >
39+ </ div >
40+ </ div >
41+ ) ;
42+ }
1643
17- const totalMRR = users . reduce ( ( sum , user ) => {
44+ const totalMRR = users . reduce ( ( sum : number , user : any ) => {
1845 if ( user . plan === "agency" ) return sum + 99 ;
1946 if ( user . plan === "pro" ) return sum + 29 ;
2047 return sum ;
2148 } , 0 ) ;
2249
23- const activeUsers = users . filter ( ( user ) => user . plan !== "starter " ) . length ;
24- const trialUsers = users . filter ( ( user ) => user . plan === "starter " ) . length ;
50+ const activeUsers = users . filter ( ( user : any ) => user . plan !== "free " ) . length ;
51+ const trialUsers = users . filter ( ( user : any ) => user . plan === "free " ) . length ;
2552
2653 return (
2754 < main className = "min-h-screen bg-[#09090f] p-6 text-white" >
@@ -30,26 +57,21 @@ export default async function AdminPage() {
3057 Admin
3158 </ div >
3259 < h1 className = "text-4xl font-semibold" > Admin dashboard</ h1 >
33- < p className = "mt-2 text-zinc-400" > Operational snapshot for X- Teos Pro </ p >
60+ < p className = "mt-2 text-zinc-400" > Operational snapshot for Teos AI Engine </ p >
3461 </ header >
3562
3663 < div className = "mx-auto mb-8 grid max-w-7xl grid-cols-1 gap-4 md:grid-cols-4" >
37- < div className = "rounded-3xl border border-white/10 bg-white/5 p-5" >
38- < div className = "text-sm text-zinc-400" > Monthly MRR</ div >
39- < div className = "mt-2 text-3xl font-semibold text-violet-300" > ${ totalMRR } </ div >
40- </ div >
41- < div className = "rounded-3xl border border-white/10 bg-white/5 p-5" >
42- < div className = "text-sm text-zinc-400" > Active users</ div >
43- < div className = "mt-2 text-3xl font-semibold text-emerald-300" > { activeUsers } </ div >
44- </ div >
45- < div className = "rounded-3xl border border-white/10 bg-white/5 p-5" >
46- < div className = "text-sm text-zinc-400" > Trials</ div >
47- < div className = "mt-2 text-3xl font-semibold text-amber-300" > { trialUsers } </ div >
48- </ div >
49- < div className = "rounded-3xl border border-white/10 bg-white/5 p-5" >
50- < div className = "text-sm text-zinc-400" > Total users</ div >
51- < div className = "mt-2 text-3xl font-semibold text-cyan-300" > { users . length } </ div >
52- </ div >
64+ { [
65+ { label : "Monthly MRR" , value : `$${ totalMRR } ` , color : "text-violet-300" } ,
66+ { label : "Active users" , value : activeUsers , color : "text-emerald-300" } ,
67+ { label : "Trials" , value : trialUsers , color : "text-amber-300" } ,
68+ { label : "Total users" , value : users . length , color : "text-cyan-300" } ,
69+ ] . map ( s => (
70+ < div key = { s . label } className = "rounded-3xl border border-white/10 bg-white/5 p-5" >
71+ < div className = "text-sm text-zinc-400" > { s . label } </ div >
72+ < div className = { `mt-2 text-3xl font-semibold ${ s . color } ` } > { s . value } </ div >
73+ </ div >
74+ ) ) }
5375 </ div >
5476
5577 < div className = "mx-auto max-w-7xl overflow-hidden rounded-3xl border border-white/10 bg-white/5" >
@@ -64,24 +86,28 @@ export default async function AdminPage() {
6486 </ tr >
6587 </ thead >
6688 < tbody >
67- { ( users as any [ ] ) . map ( ( user ) => (
68- < tr key = { user . id } className = "border-t border-white/5" >
69- < td className = "px-4 py-4" >
70- < div className = "font-medium" > { user . name } </ div >
71- < div className = "text-sm text-zinc-400" > { user . email } </ div >
72- </ td >
73- < td className = "px-4 py-4 capitalize" > { user . plan } </ td >
74- < td className = "px-4 py-4 capitalize" >
75- { user . plan === "starter" ? "trial" : "active" }
76- </ td >
77- < td className = "px-4 py-4 text-sm text-zinc-400" >
78- { new Date ( user . createdAt ) . toLocaleDateString ( ) }
79- </ td >
80- < td className = "px-4 py-4 text-sm text-zinc-400" >
81- { user . posts ?. length ?? 0 }
82- </ td >
83- </ tr >
84- ) ) }
89+ { users . length === 0 ? (
90+ < tr > < td colSpan = { 5 } className = "text-center p-8 text-zinc-500" > No users yet</ td > </ tr >
91+ ) : (
92+ users . map ( ( user : any ) => (
93+ < tr key = { user . id } className = "border-t border-white/5" >
94+ < td className = "px-4 py-4" >
95+ < div className = "font-medium" > { user . name || "—" } </ div >
96+ < div className = "text-sm text-zinc-400" > { user . email } </ div >
97+ </ td >
98+ < td className = "px-4 py-4 capitalize" > { user . plan } </ td >
99+ < td className = "px-4 py-4 capitalize" >
100+ { user . plan === "free" ? "trial" : "active" }
101+ </ td >
102+ < td className = "px-4 py-4 text-sm text-zinc-400" >
103+ { user . createdAt ? new Date ( user . createdAt ) . toLocaleDateString ( ) : "—" }
104+ </ td >
105+ < td className = "px-4 py-4 text-sm text-zinc-400" >
106+ { user . posts ?. length ?? user . totalPostsUsed ?? 0 }
107+ </ td >
108+ </ tr >
109+ ) )
110+ ) }
85111 </ tbody >
86112 </ table >
87113 </ div >
0 commit comments