"use client"; import { useState, useEffect } from "react"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; export default function AdminLeaderboardPage() { const { data: session, status } = useSession(); const [teams, setTeams] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const router = useRouter(); // Add state for expanded team details const [expandedTeam, setExpandedTeam] = useState(null); const [teamDetails, setTeamDetails] = useState({}); const [loadingDetails, setLoadingDetails] = useState(false); // Check if user is admin useEffect(() => { if (status === "authenticated") { if (session?.user?.role !== "admin") { router.push("/team-selection"); } else { fetchLeaderboardData(); } } else if (status === "unauthenticated") { router.push("/login"); } }, [session, status, router]); // Fetch leaderboard data const fetchLeaderboardData = async () => { try { setLoading(true); setError(""); const response = await fetch("/api/admin/leaderboard", { method: "GET", headers: { "Content-Type": "application/json", "Cache-Control": "no-cache, no-store, must-revalidate", }, credentials: "include", }); if (!response.ok) { throw new Error("Failed to fetch leaderboard data"); } const data = await response.json(); setTeams(data); } catch (err) { console.error("Error fetching leaderboard data:", err); setError(err.message); } finally { setLoading(false); } }; // Handle resetting a team's progress const handleResetTeamProgress = async (teamId, teamName) => { if ( !confirm( `Are you sure you want to reset progress for team "${teamName}"?` ) ) { return; } try { setLoading(true); const response = await fetch( `/api/admin/teams/${teamId}/reset-progress`, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", } ); if (!response.ok) { throw new Error("Failed to reset team progress"); } // Refresh the data after successful reset fetchLeaderboardData(); } catch (err) { console.error("Error resetting team progress:", err); setError(err.message); setLoading(false); } }; // Auto refresh data every 30 seconds useEffect(() => { if (session?.user?.role === "admin") { const interval = setInterval(() => { fetchLeaderboardData(); }, 30000); return () => clearInterval(interval); } }, [session]); // New function to toggle team details dropdown and fetch data const toggleTeamDetails = async (teamId) => { if (expandedTeam === teamId) { // Close dropdown if already open setExpandedTeam(null); } else { // Open dropdown for this team setExpandedTeam(teamId); // Only fetch if we don't already have data for this team if (!teamDetails[teamId]) { setLoadingDetails(true); try { const response = await fetch(`/api/admin/teams/${teamId}/stats`, { headers: { "Content-Type": "application/json", "Cache-Control": "no-cache, no-store, must-revalidate", }, credentials: "include", }); if (!response.ok) { throw new Error("Failed to fetch team details"); } const data = await response.json(); setTeamDetails((prev) => ({ ...prev, [teamId]: data, })); } catch (err) { console.error("Error fetching team details:", err); } finally { setLoadingDetails(false); } } } }; if (status === "loading" || loading) { return
Loading...
; } if (status === "unauthenticated") { return null; // Will redirect via useEffect } return (
Admin Leaderboard
{error &&

{error}

}

Team Progress

{teams.length === 0 ? (

No teams currently participating.

) : (
{teams.map((team, index) => ( <> {/* Team details dropdown */} {expandedTeam === team.id && ( )} ))}
Rank Team Name Members Progress Last Activity Actions
{index + 1} {team.name} ({team.code}) {team.memberCount}
{team.cluesFound} / {team.totalClues} ( {team.progress}%)
{team.lastActivity ? new Date(team.lastActivity).toLocaleString() : "Never"}
{loadingDetails && !teamDetails[team.id] ? (
Loading team details...
) : teamDetails[team.id] ? ( <>

Team Stats for {team.name}

{/* Found clues section */}

Found Clues ( {teamDetails[team.id].foundClues.length})

{teamDetails[team.id].foundClues.length > 0 ? ( {teamDetails[team.id].foundClues.map( (clue) => ( ) )}
Title Found At
{clue.title} {new Date( clue.found_at ).toLocaleString()}
) : (

No clues found yet

)}
{/* Skipped clues section */}

Skipped Clues ( {teamDetails[team.id].skippedClues.length} )

{teamDetails[team.id].skippedClues.length > 0 ? ( {teamDetails[ team.id ].skippedClues.map((clue) => ( ))}
Title Skipped At
{clue.title} {new Date( clue.found_at ).toLocaleString()}
) : (

No clues skipped

)}
) : (
Error loading team details
)}
)}
{/* Admin Navigation Bar */}
); }