@@ -5,7 +5,6 @@ import { useState, useMemo } from 'react';
55import {
66 Search ,
77 ArrowUpDown ,
8- ChevronDown ,
98 Archive ,
109 PencilLine ,
1110 Dot ,
@@ -28,7 +27,6 @@ import { Badge } from '@/components/ui/badge';
2827import { useHackathons } from '@/hooks/use-hackathons' ;
2928import type { Hackathon , HackathonDraft } from '@/lib/api/hackathons' ;
3029
31- // Helper function to calculate draft completion percentage
3230const calculateDraftCompletion = ( draft : HackathonDraft ) : number => {
3331 const fields = [
3432 draft . information ?. title ,
@@ -54,7 +52,6 @@ const calculateDraftCompletion = (draft: HackathonDraft): number => {
5452 return Math . round ( ( filledFields / fields . length ) * 100 ) ;
5553} ;
5654
57- // Helper function to format time remaining
5855const getTimeRemaining = ( endDate : string ) : string => {
5956 const now = new Date ( ) ;
6057 const end = new Date ( endDate ) ;
@@ -77,37 +74,36 @@ export default function HackathonsPage() {
7774 const organizationId = params . id as string ;
7875 const router = useRouter ( ) ;
7976
80- // Filter states
8177 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
8278 const [ sortBy , setSortBy ] = useState < 'newest' | 'oldest' > ( 'newest' ) ;
8379 const [ statusFilter , setStatusFilter ] = useState < 'all' | 'open' | 'draft' > (
8480 'all'
8581 ) ;
8682 const [ categoryFilter , setCategoryFilter ] = useState < string > ( 'all' ) ;
8783
88- // Fetch hackathons
8984 const { hackathons, hackathonsLoading, drafts, draftsLoading } =
9085 useHackathons ( {
9186 organizationId,
9287 autoFetch : true ,
9388 } ) ;
9489
95- // Filter and combine drafts and hackathons
9690 const allHackathons = useMemo ( ( ) => {
9791 const items : Array < {
9892 type : 'draft' | 'hackathon' ;
9993 data : HackathonDraft | Hackathon ;
10094 } > = [ ] ;
10195
102- // Add drafts
10396 drafts . forEach ( draft => {
10497 if ( statusFilter === 'all' || statusFilter === 'draft' ) {
10598 items . push ( { type : 'draft' , data : draft } ) ;
10699 }
107100 } ) ;
108101
109- // Add published hackathons
110102 hackathons . forEach ( hackathon => {
103+ if ( hackathon . status === 'draft' ) {
104+ return ;
105+ }
106+
111107 if (
112108 statusFilter === 'all' ||
113109 ( statusFilter === 'open' && hackathon . status === 'published' )
@@ -116,7 +112,6 @@ export default function HackathonsPage() {
116112 }
117113 } ) ;
118114
119- // Apply search filter
120115 let filtered = items ;
121116 if ( searchQuery ) {
122117 const query = searchQuery . toLowerCase ( ) ;
@@ -126,15 +121,13 @@ export default function HackathonsPage() {
126121 } ) ;
127122 }
128123
129- // Apply category filter
130124 if ( categoryFilter !== 'all' ) {
131125 filtered = filtered . filter ( item => {
132126 const category = item . data . information ?. category ?. toLowerCase ( ) || '' ;
133127 return category === categoryFilter . toLowerCase ( ) ;
134128 } ) ;
135129 }
136130
137- // Sort
138131 filtered . sort ( ( a , b ) => {
139132 const dateA = new Date ( a . data . createdAt || 0 ) . getTime ( ) ;
140133 const dateB = new Date ( b . data . createdAt || 0 ) . getTime ( ) ;
@@ -148,9 +141,8 @@ export default function HackathonsPage() {
148141 return (
149142 < div className = 'flex min-h-screen flex-col bg-black text-white' >
150143 < div className = 'flex-1' >
151- < main className = 'mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8' >
152- { /* Header Section */ }
153- < div className = 'mb-8' >
144+ < main className = '' >
145+ < div className = 'mx-auto mb-8 max-w-7xl border-b border-gray-900 px-4 py-8 sm:px-6 lg:px-8' >
154146 < h1
155147 className = 'mb-6 text-left text-2xl font-normal text-white'
156148 style = { { fontFamily : 'sans-serif' } }
@@ -160,21 +152,24 @@ export default function HackathonsPage() {
160152
161153 < div className = 'flex items-center gap-3' >
162154 < div className = 'relative flex-1' >
163- < Search className = 'absolute top-1/2 left-3 size-4 -translate-y-1/2 text-gray-400 ' />
155+ < Search className = 'absolute top-1/2 left-3 size-4 -translate-y-1/2 text-gray-700 ' />
164156 < Input
165157 type = 'search'
166158 placeholder = 'Search'
167159 value = { searchQuery }
168160 onChange = { e => setSearchQuery ( e . target . value ) }
169- className = 'border-gray-700 bg-transparent pl-10 text-white placeholder:text-gray-400 '
161+ className = 'h-11 border-gray-700 bg-transparent pl-10 text-white placeholder:text-gray-700 focus-visible:ring-0 focus-visible:ring-offset-0 '
170162 />
171163 </ div >
172164
173165 < Select
174166 value = { sortBy }
175167 onValueChange = { value => setSortBy ( value as 'newest' | 'oldest' ) }
176168 >
177- < SelectTrigger className = 'w-[120px] border-gray-700 bg-transparent text-white' >
169+ < SelectTrigger
170+ size = 'sm'
171+ className = '!h-11 w-[120px] border-gray-700 bg-transparent text-white focus-visible:ring-0 focus-visible:ring-offset-0'
172+ >
178173 < ArrowUpDown className = 'mr-2 size-4' />
179174 < SelectValue placeholder = 'Sort' />
180175 </ SelectTrigger >
@@ -190,9 +185,8 @@ export default function HackathonsPage() {
190185 setStatusFilter ( value as 'all' | 'open' | 'draft' )
191186 }
192187 >
193- < SelectTrigger className = 'w-[120px] border-gray-700 bg-transparent text-white' >
188+ < SelectTrigger className = '!h-11 w-[120px] border-gray-700 bg-transparent text-white focus-visible:ring-0 focus-visible:ring-offset-0 ' >
194189 < SelectValue placeholder = 'Status' />
195- < ChevronDown className = 'ml-2 size-4' />
196190 </ SelectTrigger >
197191 < SelectContent >
198192 < SelectItem value = 'all' > All</ SelectItem >
@@ -202,9 +196,8 @@ export default function HackathonsPage() {
202196 </ Select >
203197
204198 < Select value = { categoryFilter } onValueChange = { setCategoryFilter } >
205- < SelectTrigger className = 'w-[120px] border-gray-700 bg-transparent text-white' >
206- < SelectValue placeholder = 'Category' />
207- < ChevronDown className = 'ml-2 size-4' />
199+ < SelectTrigger className = '!h-11 w-[120px] border-gray-700 bg-transparent text-white focus-visible:ring-0 focus-visible:ring-offset-0' >
200+ < SelectValue placeholder = 'Category' className = 'text-sm' />
208201 </ SelectTrigger >
209202 < SelectContent >
210203 < SelectItem value = 'all' > All</ SelectItem >
@@ -220,8 +213,7 @@ export default function HackathonsPage() {
220213 </ div >
221214 </ div >
222215
223- { /* Hackathon Cards */ }
224- < div className = 'space-y-4' >
216+ < div className = 'mx-auto max-w-7xl space-y-4 px-4 py-8 sm:px-6 lg:px-8' >
225217 { isLoading ? (
226218 < div className = 'flex items-center justify-center py-20' >
227219 < div className = 'flex flex-col items-center gap-4' >
@@ -243,10 +235,14 @@ export default function HackathonsPage() {
243235 </ div >
244236 ) : (
245237 allHackathons . map ( item => {
246- const isDraft = item . type === 'draft' ;
238+ const isDraft =
239+ item . type === 'draft' ||
240+ ( item . data as Hackathon | HackathonDraft ) . status === 'draft' ;
247241 const hackathon = item . data ;
248242 const title =
249- hackathon . information ?. title || 'Untitled Hackathon' ;
243+ hackathon . information ?. title ||
244+ hackathon . title ||
245+ 'Untitled Hackathon' ;
250246 const completion = isDraft
251247 ? calculateDraftCompletion ( hackathon as HackathonDraft )
252248 : 0 ;
@@ -301,7 +297,7 @@ export default function HackathonsPage() {
301297 < BoundlessButton
302298 variant = 'default'
303299 size = 'lg'
304- className = 'ml-4 gap-2'
300+ className = 'gap-2'
305301 onClick = { e => {
306302 e . stopPropagation ( ) ;
307303 router . push (
@@ -321,12 +317,7 @@ export default function HackathonsPage() {
321317 return (
322318 < Card
323319 key = { `hackathon-${ hackathon . _id } ` }
324- className = 'bg-background hover:border-primary/40 cursor-pointer !rounded-none !rounded-t-[6px] !rounded-b-[20px] border-gray-900 p-0 transition-all duration-300'
325- onClick = { ( ) =>
326- router . push (
327- `/organizations/${ organizationId } /hackathons/${ hackathon . _id } `
328- )
329- }
320+ className = 'bg-background hover:border-primary/40 !rounded-none !rounded-t-[6px] !rounded-b-[20px] border-gray-900 p-0 transition-all duration-300'
330321 >
331322 < CardContent className = 'flex flex-col p-0' >
332323 < div className = 'bg-background-card flex items-start justify-between rounded-t-[6px] rounded-b-[20px] p-5' >
@@ -364,7 +355,6 @@ export default function HackathonsPage() {
364355 </ h2 >
365356
366357 < div className = 'flex items-center gap-4 uppercase' >
367- { /* TODO: Add participants and submissions count when API provides them */ }
368358 < div >
369359 < span className = 'font-medium text-white' > 0</ span > { ' ' }
370360 < span className = 'text-sm text-gray-500' >
@@ -399,7 +389,7 @@ export default function HackathonsPage() {
399389 < BoundlessButton
400390 variant = 'outline'
401391 size = 'lg'
402- className = 'ml-4 gap-2'
392+ className = 'gap-2'
403393 onClick = { e => {
404394 e . stopPropagation ( ) ;
405395 router . push (
@@ -413,7 +403,7 @@ export default function HackathonsPage() {
413403 < BoundlessButton
414404 variant = 'default'
415405 size = 'lg'
416- className = 'ml-4 gap-2'
406+ className = 'gap-2'
417407 onClick = { e => {
418408 e . stopPropagation ( ) ;
419409 router . push (
0 commit comments