@@ -76,6 +76,7 @@ export default function LeaderBoard(): JSX.Element {
7676 const [ searchQuery , setSearchQuery ] = useState ( "" ) ;
7777 const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
7878 const [ timePeriod , setTimePeriod ] = useState < TimePeriod > ( "all" ) ;
79+ const [ isSelectChanged , setIsSelectChanged ] = useState ( false ) ;
7980 const itemsPerPage = 10 ;
8081
8182 // Get contributions within the selected time period
@@ -135,7 +136,20 @@ export default function LeaderBoard(): JSX.Element {
135136 )
136137 . filter ( ( contributor ) =>
137138 contributor . username . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
138- ) ;
139+ )
140+ // Re-sort contributors after filtering to ensure proper ranking
141+ . sort ( ( a , b ) => {
142+ // First sort by points (descending)
143+ if ( b . points !== a . points ) {
144+ return b . points - a . points ;
145+ }
146+ // If points are equal, sort by PRs (descending)
147+ if ( b . prs !== a . prs ) {
148+ return b . prs - a . prs ;
149+ }
150+ // If both points and PRs are equal, sort alphabetically by username (ascending)
151+ return a . username . localeCompare ( b . username ) ;
152+ } ) ;
139153
140154 const totalPages = Math . ceil ( filteredContributors . length / itemsPerPage ) ;
141155 const indexOfLast = currentPage * itemsPerPage ;
@@ -260,11 +274,38 @@ export default function LeaderBoard(): JSX.Element {
260274 { /* Top 3 Performers Section */ }
261275 { ! loading && ! error && filteredContributors . length > 2 && (
262276 < div className = "top-performers-container" >
263- < h2 className = { `top-performers-title ${ isDark ? "dark" : "light" } ` } > RecodeHive Top Performers</ h2 >
277+ < div className = "title-filter-container" >
278+ < h2 className = { `top-performers-title ${ isDark ? "dark" : "light" } ` } > RecodeHive Top Performers</ h2 >
279+ < div className = "time-filter-wrapper top-title-filter" >
280+ < label htmlFor = "time-period-filter" className = "filter-label" > Time Period:</ label >
281+ < select
282+ id = "time-period-filter"
283+ value = { timePeriod }
284+ onChange = { ( e ) => {
285+ setTimePeriod ( e . target . value as TimePeriod ) ;
286+ setCurrentPage ( 1 ) ;
287+ setIsSelectChanged ( true ) ;
288+ setTimeout ( ( ) => setIsSelectChanged ( false ) , 1200 ) ;
289+ } }
290+ className = { `time-filter-select ${ isDark ? "dark" : "light" } ${ isSelectChanged ? 'highlight-change' : '' } ` }
291+ >
292+ < option value = "all" > 🏆 All Time</ option >
293+ < option value = "yearly" > 📅 Past Year</ option >
294+ < option value = "monthly" > 📆 Past Month</ option >
295+ < option value = "weekly" > 📊 Past Week</ option >
296+ </ select >
297+ </ div >
298+ </ div >
264299 < div className = "top-performers-grid" >
265- < TopPerformerCard contributor = { filteredContributors [ 1 ] } rank = { 2 } />
266- < TopPerformerCard contributor = { filteredContributors [ 0 ] } rank = { 1 } />
267- < TopPerformerCard contributor = { filteredContributors [ 2 ] } rank = { 3 } />
300+ { filteredContributors . length >= 2 && (
301+ < TopPerformerCard contributor = { filteredContributors [ 1 ] } rank = { 2 } />
302+ ) }
303+ { filteredContributors . length >= 1 && (
304+ < TopPerformerCard contributor = { filteredContributors [ 0 ] } rank = { 1 } />
305+ ) }
306+ { filteredContributors . length >= 3 && (
307+ < TopPerformerCard contributor = { filteredContributors [ 2 ] } rank = { 3 } />
308+ ) }
268309 </ div >
269310 </ div >
270311 ) }
@@ -308,7 +349,7 @@ export default function LeaderBoard(): JSX.Element {
308349 </ div >
309350 ) }
310351
311- { /* Search and Filter */ }
352+ { /* Search */ }
312353 < div className = "search-container" >
313354 < div className = "search-wrapper" >
314355 < FaSearch className = { `search-icon ${ isDark ? "dark" : "light" } ` } />
@@ -323,21 +364,6 @@ export default function LeaderBoard(): JSX.Element {
323364 className = { `search-input ${ isDark ? "dark" : "light" } ` }
324365 />
325366 </ div >
326- < div className = "time-filter-wrapper" >
327- < select
328- value = { timePeriod }
329- onChange = { ( e ) => {
330- setTimePeriod ( e . target . value as TimePeriod ) ;
331- setCurrentPage ( 1 ) ;
332- } }
333- className = { `time-filter-select ${ isDark ? "dark" : "light" } ` }
334- >
335- < option value = "all" > All Time</ option >
336- < option value = "yearly" > Past Year</ option >
337- < option value = "monthly" > Past Month</ option >
338- < option value = "weekly" > Past Week</ option >
339- </ select >
340- </ div >
341367 </ div >
342368
343369 { loading && (
@@ -393,8 +419,8 @@ export default function LeaderBoard(): JSX.Element {
393419 className = { `contributor-row ${ isDark ? ( index % 2 === 0 ? "even" : "odd" ) : ( index % 2 === 0 ? "even" : "odd" ) } ` }
394420 >
395421 < div className = { `contributor-cell rank-cell` } >
396- < div className = { `rank-badge ${ getRankClass ( indexOfFirst + index ) } ` } >
397- { indexOfFirst + index + 1 }
422+ < div className = { `rank-badge ${ getRankClass ( filteredContributors . indexOf ( contributor ) ) } ` } >
423+ { filteredContributors . indexOf ( contributor ) + 1 }
398424 </ div >
399425 </ div >
400426 < div className = "contributor-cell avatar-cell" >
0 commit comments