11import React from "react" ;
22import Link from "next/link" ;
3- import { Users , FileText , Settings , BarChart3 , UserCheck } from "lucide-react" ;
3+ import { Users , FileText , BarChart3 , UserCheck } from "lucide-react" ;
4+ import { db } from "@/db" ;
5+ import { getSessionUser , isAdmin } from "@/lib/utils/auth" ;
6+ import { redirect } from "next/navigation" ;
7+
8+ export default async function AdminDashboard ( ) {
9+ const user = await getSessionUser ( ) ;
10+ if ( ! user || ! ( await isAdmin ( user . id ) ) ) {
11+ redirect ( "/portal" ) ;
12+ }
13+
14+ const now = new Date ( ) ;
15+ const startOfMonth = new Date ( now . getFullYear ( ) , now . getMonth ( ) , 1 ) ;
16+
17+ const [
18+ totalForms ,
19+ activeMembers ,
20+ pendingApplications ,
21+ submissionsThisMonth ,
22+ latestForm ,
23+ ] = await Promise . all ( [
24+ db . forms . count ( ) ,
25+ db . members . count ( ) ,
26+ db . applications . count ( { where : { status : null } } ) ,
27+ db . submissions . count ( { where : { created_at : { gte : startOfMonth } } } ) ,
28+ db . forms . findFirst ( {
29+ where : { type : "recruitment" } ,
30+ orderBy : { created_at : "desc" } ,
31+ } ) ,
32+ ] ) ;
433
5- export default function AdminDashboard ( ) {
634 const adminRoutes = [
735 {
836 title : "Forms Management" ,
@@ -34,6 +62,13 @@ export default function AdminDashboard() {
3462 } ,
3563 ] ;
3664
65+ const stats = [
66+ { label : "Total Forms" , value : totalForms , icon : FileText , color : "text-blue-500" } ,
67+ { label : "Active Members" , value : activeMembers , icon : Users , color : "text-green-500" } ,
68+ { label : "Pending Applications" , value : pendingApplications , icon : UserCheck , color : "text-yellow-500" } ,
69+ { label : "Submissions This Month" , value : submissionsThisMonth , icon : BarChart3 , color : "text-orange-500" } ,
70+ ] ;
71+
3772 return (
3873 < div className = "min-h-screen bg-background-800 text-white p-6" >
3974 < div className = "max-w-6xl mx-auto" >
@@ -47,47 +82,46 @@ export default function AdminDashboard() {
4782 </ p >
4883 </ div >
4984
50- { /* Quick Stats */ }
51- < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8" >
52- < div className = "bg-background-700 border border-background-600 rounded-lg p-6" >
53- < div className = "flex items-center justify-between" >
54- < div >
55- < p className = "text-gray-400 text-sm" > Total Forms</ p >
56- < p className = "text-2xl font-semibold text-white" > -</ p >
57- </ div >
58- < FileText className = "w-8 h-8 text-blue-500" />
85+ { latestForm ?. title && (
86+ < div className = "mb-8 border border-background-600 bg-background-700 rounded-lg p-4 flex items-center justify-between" >
87+ < div >
88+ < p className = "text-gray-400 text-sm" > Latest recruitment form</ p >
89+ < p className = "text-lg font-semibold" > { latestForm . title } </ p >
5990 </ div >
60- </ div >
61-
62- < div className = "bg-background-700 border border-background-600 rounded-lg p-6" >
63- < div className = "flex items-center justify-between" >
64- < div >
65- < p className = "text-gray-400 text-sm" > Active Members < /p >
66- < p className = "text-2xl font-semibold text-white" > - </ p >
67- </ div >
68- < Users className = "w-8 h-8 text-green-500" />
91+ < div className = "text-sm text-gray-400 text-right" >
92+ { latestForm . open_at ? (
93+ < p >
94+ { latestForm . open_at . toLocaleDateString ( ) } — { " " }
95+ { latestForm . close_at ?. toLocaleDateString ( ) || "open-ended" }
96+ </ p >
97+ ) : (
98+ < p className = "text-yellow-500" > Not scheduled yet </ p >
99+ ) }
69100 </ div >
70101 </ div >
102+ ) }
71103
72- < div className = "bg-background-700 border border-background-600 rounded-lg p-6" >
73- < div className = "flex items-center justify-between" >
74- < div >
75- < p className = "text-gray-400 text-sm" > Pending Applications</ p >
76- < p className = "text-2xl font-semibold text-white" > -</ p >
77- </ div >
78- < UserCheck className = "w-8 h-8 text-yellow-500" />
79- </ div >
80- </ div >
81-
82- < div className = "bg-background-700 border border-background-600 rounded-lg p-6" >
83- < div className = "flex items-center justify-between" >
84- < div >
85- < p className = "text-gray-400 text-sm" > This Month</ p >
86- < p className = "text-2xl font-semibold text-white" > -</ p >
104+ { /* Quick Stats */ }
105+ < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8" >
106+ { stats . map ( ( stat ) => {
107+ const Icon = stat . icon ;
108+ return (
109+ < div
110+ key = { stat . label }
111+ className = "bg-background-700 border border-background-600 rounded-lg p-6"
112+ >
113+ < div className = "flex items-center justify-between" >
114+ < div >
115+ < p className = "text-gray-400 text-sm" > { stat . label } </ p >
116+ < p className = "text-2xl font-semibold text-white" >
117+ { stat . value }
118+ </ p >
119+ </ div >
120+ < Icon className = { `w-8 h-8 ${ stat . color } ` } />
121+ </ div >
87122 </ div >
88- < BarChart3 className = "w-8 h-8 text-orange-500" />
89- </ div >
90- </ div >
123+ ) ;
124+ } ) }
91125 </ div >
92126
93127 { /* Admin Routes Grid */ }
0 commit comments