import { useState, useEffect } from "react"; import { useNavigate } from "react-router"; import { isBrowser } from "react-device-detect"; import LoadingDisplay from "../components/LoadingDisplay"; import SessionExpiredPopup from "../components/SessionExpiredPopup"; import { NavBar } from "../components/NavBar"; import { useAuth } from "../contexts/AuthContext"; import Heatmap from "../components/Heatmap"; import type { HeatmapData } from "../components/Heatmap"; import type { User } from "../utils/authApi"; interface ScoreCountByGame { gameInternalName: string; formattedName: string; count: number; } interface RecentPlayedGame { gameInternalName: string; formattedName: string; timestamp: number; } interface UserData { user: User; recentPlayedGames: RecentPlayedGame[]; scoreCountByGame: ScoreCountByGame[]; isAdmin: boolean; } const Profile = () => { const { user, isLoading, logout } = useAuth(); let targetUser = new URLSearchParams(window.location.search).get("userId") || ""; // looking at profile of this user const navigate = useNavigate(); const [fetchingHeatmapData, setFetchingHeatmapData] = useState(true); const [fetchingUserData, setFetchingUserData] = useState(true); const [heatmapData, setHeatmapData] = useState({ data: [] }); const [userData, setUserData] = useState(null); useEffect(() => { if (targetUser) { setFetchingUserData(true); const fetchUserData = async () => { try { const response = await fetch( new URL( import.meta.env.VITE_API_URL + "/me?userId=" + targetUser, ), { credentials: "include" }, ); const data = await response.json(); setUserData(data); setFetchingUserData(false); } catch (error) { console.error("Failed to fetch user data:", error); } }; fetchUserData(); } }, [targetUser]); useEffect(() => { if (targetUser) { setFetchingHeatmapData(true); const fetchHeatmapData = async () => { try { const response = await fetch( new URL( import.meta.env.VITE_API_URL + "/heatmap?userId=" + targetUser, ), { credentials: "include" }, ); const data = await response.json(); return data; } catch (error) { setFetchingHeatmapData(false); console.error("Failed to fetch heatmap data:", error); throw error; } }; fetchHeatmapData().then((data) => { const heatmapDates: { [key: string]: number } = {}; for (let i = 0; i < data.scores.length; i++) { const date = new Date(data.scores[i].timestamp); const dateString = date.toDateString(); if (!heatmapDates[dateString]) { heatmapDates[dateString] = 1; } else { heatmapDates[dateString] += 1; } } setHeatmapData({ data: Object.entries(heatmapDates).map(([date, count]) => ({ date, count, })), }); setFetchingHeatmapData(false); }); } }, [targetUser]); if (!user) { return ; } if (!targetUser) { targetUser = user.id.toString(); } if (isLoading || fetchingHeatmapData || fetchingUserData) { return ; } const handleLogout = async () => { try { await logout(); navigate("/"); } catch (error) { console.error("Logout failed:", error); alert("Network error during logout. Please try again."); } }; if (!user) { return ; } return (
{/* Main Content */}
{/* Header */}

{user.username}

{userData?.user?.bio ? userData.user.bio.replace(//g, '>') : "I'm a fairly non-descript person"}

{isBrowser ? (
) : null}

Recently Played Games

    {userData?.recentPlayedGames.map((game, index) => (
  • {game.formattedName} {new Date(game.timestamp).toLocaleString()}
  • ))}

Total Scores

{userData?.scoreCountByGame .sort((a, b) => b.count - a.count) .map((score, index) => ( ))}
Game Total Scores Uploaded
{score.formattedName} {score.count}
); }; export default Profile;