diff --git a/src/app/_components/leaderboard.tsx b/src/app/_components/leaderboard.tsx index 62db5fb..6e8e486 100644 --- a/src/app/_components/leaderboard.tsx +++ b/src/app/_components/leaderboard.tsx @@ -1,7 +1,7 @@ 'use client' import type React from 'react' -import { useRef } from 'react' +import { type ComponentPropsWithoutRef, Fragment, useRef } from 'react' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -68,15 +68,13 @@ export function LeaderboardPage() { // Get the current leaderboard based on selected tab const currentLeaderboard = - leaderboardType === 'ranked' - ? rankedLeaderboard.alltime - : vanillaLeaderboard.alltime + leaderboardType === 'ranked' ? rankedLeaderboard : vanillaLeaderboard // Filter leaderboard by search query const filteredLeaderboard = currentLeaderboard.filter((entry) => entry.name.toLowerCase().includes(searchQuery.toLowerCase()) ) - + console.log(filteredLeaderboard) // Sort leaderboard const sortedLeaderboard = [...filteredLeaderboard].sort((a, b) => { // biome-ignore lint/style/useSingleVarDeclarator: @@ -85,8 +83,8 @@ export function LeaderboardPage() { // Handle special case for rank which is already sorted if (sortColumn === 'rank') { - valueA = a.data.rank - valueB = b.data.rank + valueA = a.rank + valueB = b.rank } else if (sortColumn === 'name') { valueA = a.name.toLowerCase() valueB = b.name.toLowerCase() @@ -94,8 +92,8 @@ export function LeaderboardPage() { ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA) } else { - valueA = a.data[sortColumn as keyof typeof a.data] as number - valueB = b.data[sortColumn as keyof typeof b.data] as number + valueA = a[sortColumn as keyof typeof a] as number + valueB = b[sortColumn as keyof typeof b] as number } return sortDirection === 'asc' ? valueA - valueB : valueB - valueA @@ -118,12 +116,11 @@ export function LeaderboardPage() { if (rank === 3) return return null } - console.log(currentLeaderboard) return ( -
-
- +
+
+
@@ -157,12 +154,12 @@ export function LeaderboardPage() {
- +
@@ -181,7 +178,7 @@ export function LeaderboardPage() {
- + - + (null) // Set a fixed row height for virtualization - const ROW_HEIGHT = 56 // Adjust based on your actual row height - + const ROW_HEIGHT = 39 // Adjust based on your actual row height + console.log(leaderboard.length) // Create virtualizer instance const rowVirtualizer = useVirtualizer({ count: leaderboard.length, getScrollElement: () => tableContainerRef.current, estimateSize: () => ROW_HEIGHT, - overscan: 10, // Number of items to render before/after the visible area + overscan: 12, // Number of items to render before/after the visible area }) // Get the virtualized rows const virtualRows = rowVirtualizer.getVirtualItems() + console.log({ virtualRows }) + console.log(rowVirtualizer.getTotalSize()) const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start : 0 const paddingBottom = virtualRows.length > 0 @@ -249,15 +248,15 @@ function LeaderboardTable({ (virtualRows?.[virtualRows.length - 1]?.end ?? 0) : 0 return ( -
+
- + - + + {paddingTop > 0 && ( + + + )} {leaderboard.length > 0 ? ( - leaderboard.map((entry) => { - const winrate = entry.data.winrate * 100 + virtualRows.map((virtualRow) => { + const entry = leaderboard[virtualRow.index] + const winrate = entry.winrate * 100 return ( - - -
- {getMedal(entry.data.rank)} - {entry.data.rank} -
-
- - - {/**/} - {/* */} - {/* */} - {/* {entry.name.slice(0, 2).toUpperCase()}*/} - {/* */} - {/**/} - {entry.name} - {entry.data.streak >= 3 && ( - - - Hot Streak - - )} - - - - {Math.round(entry.data.mmr)} - - -
- - {Math.round(entry.data.peak_mmr)} -
-
- - 60 - ? 'border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-800 dark:bg-emerald-950 dark:text-emerald-300' - : winrate < 40 - ? 'border-rose-200 bg-rose-50 text-rose-700 dark:border-rose-800 dark:bg-rose-950 dark:text-rose-300' - : 'border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-300' - )} - > - {Math.round(winrate)}% - - - - {entry.data.wins} - - - {entry.data.losses} - - - {entry.data.totalgames} - - - {entry.data.streak > 0 ? ( - - - {entry.data.streak} - - ) : entry.data.streak < 0 ? ( - - - {Math.abs(entry.data.streak)} - - ) : ( - 0 + + {/* Add padding to the top to push content into view */} + + - + > + +
+ {getMedal(entry.rank)} + {entry.rank} +
+
+ + + {/**/} + {/* */} + {/* */} + {/* {entry.name.slice(0, 2).toUpperCase()}*/} + {/* */} + {/**/} + {entry.name} + {entry.streak >= 3 && ( + + + Hot Streak + + )} + + + + {Math.round(entry.mmr)} + + +
+ {Math.round(entry.peak_mmr)} + +
+
+ + 60 + ? 'border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-800 dark:bg-emerald-950 dark:text-emerald-300' + : winrate < 40 + ? 'border-rose-200 bg-rose-50 text-rose-700 dark:border-rose-800 dark:bg-rose-950 dark:text-rose-300' + : 'border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-300' + )} + > + {Math.round(winrate)}% + + + + {entry.wins} + + + {entry.losses} + + + {entry.totalgames} + + + {entry.streak > 0 ? ( + + + {entry.streak} + + ) : entry.streak < 0 ? ( + + + + {Math.abs(entry.streak)} + + + ) : ( + 0 + )} + +
+ ) }) ) : ( @@ -441,6 +456,11 @@ function LeaderboardTable({ )} + {paddingBottom > 0 && ( + + + )}
+
+
@@ -448,7 +468,7 @@ function LeaderboardTable({ ) } -interface SortableHeaderProps { +interface SortableHeaderProps extends ComponentPropsWithoutRef<'button'> { column: string label: string currentSort: string @@ -462,12 +482,19 @@ function SortableHeader({ currentSort, direction, onSort, + className, + ...rest }: SortableHeaderProps) { const isActive = currentSort === column return (