"use client" import { useEffect, useState } from "react" import { getApiUrl } from "@/lib/api-config" import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import Link from "next/link" import { Star, MapPin, Music, User, Trophy, Calendar, Sparkles } from "lucide-react" import { Badge } from "@/components/ui/badge" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { motion, AnimatePresence } from "framer-motion" interface TopShow { show: { id: number; date: string; venue_id: number; slug: string } venue: { id: number; name: string; city: string; state: string } avg_score: number review_count: number } interface TopVenue { venue: { id: number; name: string; city: string; state: string; slug: string } avg_score: number review_count: number } interface TopPerformance { performance: { id: number; show_id: number; song_id: number; notes: string | null; slug: string } song: { id: number; title: string; original_artist: string | null; slug: string } show: { id: number; date: string; slug: string } venue: { id: number; name: string; city: string; state: string; slug: string } avg_score: number rating_count: number } interface TopUser { profile: { id: number; user_id: number } review_count: number } export default function LeaderboardsPage() { const [topShows, setTopShows] = useState([]) const [topVenues, setTopVenues] = useState([]) const [topPerformances, setTopPerformances] = useState([]) const [topUsers, setTopUsers] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const fetchData = async () => { try { const [showsRes, venuesRes, perfsRes, usersRes] = await Promise.all([ fetch(`${getApiUrl()}/leaderboards/shows/top`), fetch(`${getApiUrl()}/leaderboards/venues/top`), fetch(`${getApiUrl()}/leaderboards/performances/top`), fetch(`${getApiUrl()}/leaderboards/users/active`) ]) setTopShows(await showsRes.json()) setTopVenues(await venuesRes.json()) setTopPerformances(await perfsRes.json()) setTopUsers(await usersRes.json()) } catch (error) { console.error("Failed to fetch leaderboards:", error) } finally { setLoading(false) } } fetchData() }, []) const RankIcon = ({ rank }: { rank: number }) => { if (rank === 1) return if (rank === 2) return if (rank === 3) return return {rank} } if (loading) { return (

Computing Heady Stats...

) } return (

Leaderboards

Discover the highest rated shows, legendary jams, and top contributors.

Heady Jams Top Shows Venues Contributors {/* HEADY JAMS CONTENT */}
{topPerformances.map((item, i) => (
{item.song.title} {item.performance.notes && ( {item.performance.notes} )}
{new Date(item.show.date).toLocaleDateString(undefined, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' })} {item.venue.name}
{item.avg_score.toFixed(2)}
{item.rating_count} votes
))} {topPerformances.length === 0 && (
No ranked jams yet. Start rating performances!
)}
{/* TOP SHOWS CONTENT */} {topShows.map((item, i) => (
{i + 1}
{new Date(item.show.date).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}

{item.venue.name} • {item.venue.city}, {item.venue.state}

{item.avg_score.toFixed(2)}
{item.review_count} ratings
))}
{/* VENUES CONTENT */} {topVenues.map((item, i) => (
{i + 1}
{item.venue.name}

{item.venue.city}, {item.venue.state}

{item.avg_score.toFixed(2)}
))}
{/* USERS CONTENT */} {topUsers.map((item, i) => ( U
User {item.profile.user_id}

Top Contributor

{item.review_count} Reviews
))} {topUsers.length === 0 &&

No active users yet.

}
) }