import { useEffect, useState, useCallback } from "react"; import { useAuth } from "../contexts/AuthContext"; import { useNavigate } from "react-router"; import { NavBar } from "../components/NavBar"; import SessionExpiredPopup from "../components/SessionExpiredPopup"; import ScoreDisplay from "../components/displays/GenericScoreDisplay"; import DancerushScoreDisplay from "../components/displays/DancerushScoreDisplay"; import DivaScoreDisplay from "../components/displays/DivaScoreDisplay"; import MusicDiverDisplay from "../components/displays/MusicDiverScoreDisplay"; import SongInfoDisplay from "../components/modals/SongInfoDisplay"; import DancearoundScoreDisplay from "../components/displays/DancearoundScoreDisplay"; import NostalgiaScoreDisplay from "../components/displays/NostalgiaScoreDisplay"; import ReflecBeatScoreDisplay from "../components/displays/ReflecBeatScoreDisplay"; type SortField = string; type SortDirection = "asc" | "desc"; import { getFilterOptions } from "../types/constants"; const Chart = () => { const { user, isLoading, logout } = useAuth(); const navigate = useNavigate(); const [pbOnly, setPbOnly] = useState(false); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [scores, setScores] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [numPages, setNumPages] = useState(1); const [viewMode, setViewMode] = useState<"cards" | "table">("cards"); const [sortField, setSortField] = useState(""); const [sortDirection, setSortDirection] = useState("asc"); const [requestOrder, setRequestOrder] = useState("timestamp"); const chartIdHash = new URLSearchParams(window.location.search).get("chartId") || ""; if (!chartIdHash) { navigate("/home"); } const gameName = new URLSearchParams(window.location.search).get("game") || "dancerush"; const handleLogout = async () => { try { await logout(); navigate("/"); } catch (error) { console.error("Logout failed:", error); alert("Network error during logout. Please try again."); } }; const renderRequestFilterMenu = () => { const filterOptions = getFilterOptions(gameName); return (
{filterOptions.map((option) => ( ))}
); } // eslint-disable-next-line @typescript-eslint/no-explicit-any const flattenScoreData = (score: any) => { const flat = { ...score, ...score.data }; delete flat.data; delete flat.gameInternalName; return flat; }; const fetchScores = useCallback( async (pageNum: number) => { if (!user) return; setLoading(true); try { const url = new URL(import.meta.env.VITE_API_URL + "/scores/" + chartIdHash); url.searchParams.append("pageNum", pageNum.toString()); url.searchParams.append("sortKey", requestOrder); url.searchParams.append("direction", "asc"); url.searchParams.append("pbOnly", pbOnly.toString()); url.searchParams.append("game", gameName); const response = await fetch(url.toString(), {credentials: 'include'}); if (!response.ok) throw new Error("Failed to fetch scores"); const data = await response.json(); const flattened = data.scores.map(flattenScoreData); setScores(flattened); setNumPages(data.num_pages); setCurrentPage(pageNum); } catch (error) { console.error("Failed to load scores:", error); alert("Failed to load scores. Please refresh the page."); } finally { setLoading(false); } }, [user, requestOrder, chartIdHash, gameName, pbOnly], ); useEffect(() => { if (user) fetchScores(1); }, [user, fetchScores]); const handleSort = (field: SortField) => { if (sortField === field) { setSortDirection(sortDirection === "asc" ? "desc" : "asc"); } else { setSortField(field); setSortDirection("desc"); } }; const handleTogglePB = () => { setPbOnly(!pbOnly); }; if (!user) { return ; } if (isLoading || loading) { return (

Loading scores...

); } return (
{/* Filter Menu */}
{renderRequestFilterMenu()}
{(() => { switch (gameName) { case "dancerush": return ( ); case "dancearound": return ( ); case "diva": return ( ); case "musicdiver": return ( ); case "nostalgia": return ( ); case "reflecbeat": return ( ); default: return ( ); } })()} {numPages > 1 && (
{[...Array(numPages)].map((_, i) => ( ))}
)}

Displaying {scores.length} scores • Page {currentPage} of {numPages}

); }; export default Chart;