"use client"; import { useEffect, useState } from "react"; interface LeaderboardEntry { id: string; username: string; points: number; badgeCount: number; rank: number; isCurrentUser?: boolean; } export default function LeaderboardTable() { const [entries, setEntries] = useState([]); const [loading, setLoading] = useState(true); const [timeframe, setTimeframe] = useState<"daily" | "weekly" | "alltime">("alltime"); useEffect(() => { fetchLeaderboard(); }, [timeframe]); const fetchLeaderboard = async () => { try { const token = localStorage.getItem("token"); const response = await fetch(`/api/leaderboard?timeframe=${timeframe}`, { headers: { Authorization: `Bearer ${token}` }, }); const data = await response.json(); if (data.success && data.data) { // API returns { entries: LeaderboardEntry[], userRank } const leaderboardEntries = (data.data.entries || []).map((entry: { userId: string; userName: string; points: number; badgesEarned: number; rank: number }) => ({ id: entry.userId, username: entry.userName, points: entry.points, badgeCount: entry.badgesEarned, rank: entry.rank, })); setEntries(leaderboardEntries); } else if (Array.isArray(data)) { setEntries(data); } } catch (error) { console.error("Failed to fetch leaderboard:", error); } finally { setLoading(false); } }; const getRankIcon = (rank: number) => { switch (rank) { case 1: return 🥇; case 2: return 🥈; case 3: return 🥉; default: return #{rank}; } }; if (loading) { return (
); } return (
{(["daily", "weekly", "alltime"] as const).map(tf => ( ))}
{entries.map(entry => ( ))}
Rank Player Points Badges
{getRankIcon(entry.rank)}
{entry.username[0].toUpperCase()}
{entry.username} {entry.isCurrentUser && ( You )}
{entry.points.toLocaleString()}
{entry.badgeCount}
); }