22
33import { useState , useEffect } from "react"
44import { Card , CardContent , CardDescription , CardHeader , CardTitle } from "@/components/ui/card"
5+ import { Tabs , TabsContent , TabsList , TabsTrigger } from "@/components/ui/tabs"
56import { ModerationQueue } from "@/components/moderation/ModerationQueue"
6- import { AlertCircle , CheckCircle , Clock , Filter } from "lucide-react"
7+ import { HackathonModerationQueue } from "@/components/moderation/HackathonModerationQueue"
8+ import { AlertCircle , CheckCircle , Clock , Filter , Calendar , Trophy } from "lucide-react"
79
810export default function ModerationPage ( ) {
9- const [ stats , setStats ] = useState ( {
11+ const [ activeTab , setActiveTab ] = useState ( "events" )
12+ const [ eventStats , setEventStats ] = useState ( {
13+ pending : 0 ,
14+ approved : 0 ,
15+ rejected : 0 ,
16+ } )
17+ const [ hackathonStats , setHackathonStats ] = useState ( {
1018 pending : 0 ,
1119 approved : 0 ,
1220 rejected : 0 ,
1321 } )
1422 const [ loading , setLoading ] = useState ( true )
1523
1624 useEffect ( ( ) => {
17- // Fetch moderation stats
25+ // Fetch moderation stats for both events and hackathons
1826 const fetchStats = async ( ) => {
1927 try {
20- const response = await fetch ( '/api/admin/moderation/events?limit=1000' )
21- if ( response . ok ) {
22- const data = await response . json ( )
28+ // Fetch event stats
29+ const eventsResponse = await fetch ( '/api/admin/moderation/events?limit=1000' )
30+ if ( eventsResponse . ok ) {
31+ const data = await eventsResponse . json ( )
32+ if ( data . success ) {
33+ setEventStats ( {
34+ pending : data . data . total ,
35+ approved : 0 ,
36+ rejected : 0 ,
37+ } )
38+ }
39+ }
40+
41+ // Fetch hackathon stats
42+ const hackathonsResponse = await fetch ( '/api/admin/moderation/hackathons?limit=1000' )
43+ if ( hackathonsResponse . ok ) {
44+ const data = await hackathonsResponse . json ( )
2345 if ( data . success ) {
24- setStats ( {
46+ setHackathonStats ( {
2547 pending : data . data . total ,
26- approved : 0 , // Would need separate endpoint for this
27- rejected : 0 , // Would need separate endpoint for this
48+ approved : 0 ,
49+ rejected : 0 ,
2850 } )
2951 }
3052 }
@@ -38,17 +60,19 @@ export default function ModerationPage() {
3860 fetchStats ( )
3961 } , [ ] )
4062
63+ const stats = activeTab === "events" ? eventStats : hackathonStats
64+
4165 return (
4266 < div className = "bg-black min-h-screen px-4 py-8 md:px-8 lg:px-16 space-y-8" >
4367 { /* Header */ }
4468 < div className = "flex flex-col sm:flex-row sm:items-center sm:justify-between pb-6 border-b border-zinc-800/60 gap-4" >
4569 < div >
4670 < h1 className = "text-2xl sm:text-3xl md:text-4xl font-extrabold tracking-tight text-white drop-shadow-sm flex items-center gap-3" >
4771 < span className = "inline-block w-2 h-6 sm:h-8 bg-gradient-to-b from-purple-400 to-blue-400 rounded-full mr-2" />
48- Event Moderation Queue
72+ Content Moderation
4973 </ h1 >
5074 < p className = "text-zinc-400 mt-1 font-medium text-sm sm:text-base" >
51- Review and approve events submitted by companies
75+ Review and approve events and hackathons submitted by companies
5276 </ p >
5377 </ div >
5478 </ div >
@@ -113,25 +137,61 @@ export default function ModerationPage() {
113137 </ Card >
114138 </ div >
115139
116- { /* Moderation Queue */ }
117- < Card className = "border-0 shadow-2xl rounded-2xl bg-gradient-to-br from-zinc-100/80 to-zinc-200/60 dark:from-zinc-900/60 dark:to-zinc-800/40" >
118- < CardHeader >
119- < div className = "flex items-center justify-between" >
120- < div >
121- < CardTitle className = "text-lg font-bold text-zinc-900 dark:text-white flex items-center gap-2" >
122- < Filter className = "h-5 w-5 text-purple-400" />
123- Pending Events
124- </ CardTitle >
125- < CardDescription className = "text-zinc-500 dark:text-zinc-300 font-medium text-sm" >
126- Review events and take action
127- </ CardDescription >
128- </ div >
129- </ div >
130- </ CardHeader >
131- < CardContent >
132- < ModerationQueue />
133- </ CardContent >
134- </ Card >
140+ { /* Moderation Queue with Tabs */ }
141+ < Tabs value = { activeTab } onValueChange = { setActiveTab } className = "w-full" >
142+ < TabsList className = "grid w-full max-w-md grid-cols-2 mb-6" >
143+ < TabsTrigger value = "events" className = "flex items-center gap-2" >
144+ < Calendar className = "h-4 w-4" />
145+ Events
146+ </ TabsTrigger >
147+ < TabsTrigger value = "hackathons" className = "flex items-center gap-2" >
148+ < Trophy className = "h-4 w-4" />
149+ Hackathons
150+ </ TabsTrigger >
151+ </ TabsList >
152+
153+ < TabsContent value = "events" >
154+ < Card className = "border-0 shadow-2xl rounded-2xl bg-gradient-to-br from-zinc-100/80 to-zinc-200/60 dark:from-zinc-900/60 dark:to-zinc-800/40" >
155+ < CardHeader >
156+ < div className = "flex items-center justify-between" >
157+ < div >
158+ < CardTitle className = "text-lg font-bold text-zinc-900 dark:text-white flex items-center gap-2" >
159+ < Filter className = "h-5 w-5 text-purple-400" />
160+ Pending Events
161+ </ CardTitle >
162+ < CardDescription className = "text-zinc-500 dark:text-zinc-300 font-medium text-sm" >
163+ Review events and take action
164+ </ CardDescription >
165+ </ div >
166+ </ div >
167+ </ CardHeader >
168+ < CardContent >
169+ < ModerationQueue />
170+ </ CardContent >
171+ </ Card >
172+ </ TabsContent >
173+
174+ < TabsContent value = "hackathons" >
175+ < Card className = "border-0 shadow-2xl rounded-2xl bg-gradient-to-br from-zinc-100/80 to-zinc-200/60 dark:from-zinc-900/60 dark:to-zinc-800/40" >
176+ < CardHeader >
177+ < div className = "flex items-center justify-between" >
178+ < div >
179+ < CardTitle className = "text-lg font-bold text-zinc-900 dark:text-white flex items-center gap-2" >
180+ < Filter className = "h-5 w-5 text-purple-400" />
181+ Pending Hackathons
182+ </ CardTitle >
183+ < CardDescription className = "text-zinc-500 dark:text-zinc-300 font-medium text-sm" >
184+ Review hackathons and take action
185+ </ CardDescription >
186+ </ div >
187+ </ div >
188+ </ CardHeader >
189+ < CardContent >
190+ < HackathonModerationQueue />
191+ </ CardContent >
192+ </ Card >
193+ </ TabsContent >
194+ </ Tabs >
135195 </ div >
136196 )
137197}
0 commit comments