import React, { useState, useEffect } from 'react'; import { Trophy, Medal, Award, TrendingUp, Star, CheckSquare } from 'lucide-react'; import { motion } from 'framer-motion'; import Card from '../components/ui/Card'; import Tag from '../components/ui/Tag'; import { useApp } from '../store/AppContext'; import * as db from '../lib/db'; const BADGE_RULES = [ { id: 'first_test', icon: Star, label: 'First Steps', condition: (u) => u.tests_completed > 0 }, { id: 'perfectionist', icon: Award, label: 'Perfectionist', condition: (u) => u.perfectScores > 0 }, { id: 'veteran', icon: Medal, label: 'Veteran', condition: (u) => u.tests_completed >= 5 }, ]; const Leaderboard = () => { const { state } = useApp(); const [board, setBoard] = useState([]); useEffect(() => { const load = async () => { const [leaderboardData, allUsers] = await Promise.all([ db.getLeaderboard(), db.getTeamMembers(), ]); const nonAdminIds = allUsers.filter(u => u.role !== 'admin').map(u => u.id); let data = leaderboardData.filter(entry => nonAdminIds.includes(entry.user_id)); // Ensure all non-admin users appear even if they have no points yet const inBoard = new Set(data.map(e => e.user_id)); for (const user of allUsers) { if (!inBoard.has(user.id) && user.role !== 'admin') { data.push({ user_id: user.id, name: user.name, points: 0, tests_completed: 0, perfectScores: 0 }); } } // Compute perfect scores per user data = await Promise.all(data.map(async entry => { let perfectScores = 0; for (let w = 1; w <= state.weekNumber; w++) { const result = await db.getQuizResult(entry.user_id, w); if (result && result.percentage === 100) perfectScores++; } return { ...entry, perfectScores }; })); data.sort((a, b) => b.points - a.points); setBoard(data); }; load(); }, [state.weekNumber]); return (
Compete, learn, and earn badges based on your weekly knowledge tests.
{board[1].name}
{board[1].points} pts
{board[0].name}
{board[0].points} pts
{board[2].name}
{board[2].points} pts
{user.name}
{isMe &&