import { useState, useEffect } from 'react'; import { Trophy, Medal, Clock, TrendingUp } from 'lucide-react'; import { useGameStore } from '@/store'; import { formatMoney, formatNumber } from '@ai-tycoon/shared'; import { api, getAuthToken } from '@/lib/api'; interface LeaderboardEntry { companyName: string; score: number; era: string; tickCount: number; } const CATEGORIES = [ { id: 'revenue', label: 'Highest Revenue', icon: TrendingUp }, { id: 'fastest-agi', label: 'Fastest to AGI', icon: Clock }, { id: 'capability', label: 'Best Model', icon: Trophy }, ] as const; export function LeaderboardPage() { const [category, setCategory] = useState('revenue'); const [entries, setEntries] = useState([]); const [loading, setLoading] = useState(false); const [submitted, setSubmitted] = useState(false); const companyName = useGameStore((s) => s.meta.companyName); const totalRevenue = useGameStore((s) => s.economy.totalRevenue); const era = useGameStore((s) => s.meta.currentEra); const tickCount = useGameStore((s) => s.meta.tickCount); const bestModel = useGameStore((s) => s.models.trainedModels.reduce((best, m) => Math.max(best, m.benchmarkScore), 0), ); useEffect(() => { setLoading(true); api.leaderboard.get(category) .then(data => setEntries(data.entries)) .catch(() => setEntries([])) .finally(() => setLoading(false)); }, [category]); const handleSubmit = async () => { if (!getAuthToken()) return; const scoreMap: Record = { revenue: Math.floor(totalRevenue), 'fastest-agi': era === 'agi' ? tickCount : 0, capability: Math.floor(bestModel * 10), }; const score = scoreMap[category]; if (score <= 0) return; try { await api.leaderboard.submit({ companyName, category, score, era, tickCount }); setSubmitted(true); const data = await api.leaderboard.get(category); setEntries(data.entries); } catch { /* ignore */ } }; return (

Leaderboard

{CATEGORIES.map(cat => ( ))}
{getAuthToken() && !submitted && ( )} {submitted &&

Score submitted!

}
{loading ? (
Loading...
) : entries.length === 0 ? (

No entries yet. Be the first!

) : ( {entries.map((entry, i) => ( ))}
# Company Score Era
{i < 3 ? : i + 1} {entry.companyName} {formatNumber(entry.score)} {entry.era}
)}
); }