From c71ababd5bbc7ab31f9f74eb2794e4cd04ba8d08 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Tue, 4 Nov 2025 18:35:54 -0800 Subject: add recently played games to profile page --- frontend/src/pages/Profile.tsx | 28 +++++++++++++++++++++++----- frontend/src/pages/Score.tsx | 19 +++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'frontend/src') diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx index cc8fc99..bffc710 100644 --- a/frontend/src/pages/Profile.tsx +++ b/frontend/src/pages/Profile.tsx @@ -9,8 +9,15 @@ import Heatmap from "../components/Heatmap"; import type { HeatmapData } from "../components/Heatmap"; import type { User } from "../utils/authApi"; +interface recentPlayedGame { + gameInternalName: string; + formattedName: string; + timestamp: number; +} + interface UserData { user: User; + recentPlayedGames: recentPlayedGame[]; isAdmin: boolean; } @@ -91,14 +98,14 @@ const Profile = () => { navigate("/"); } - if (isLoading || fetchingHeatmapData || fetchingUserData) { - return ; - } - if (!user) { return ; } + if (isLoading || fetchingHeatmapData || fetchingUserData) { + return ; + } + const handleLogout = async () => { try { await logout(); @@ -125,9 +132,20 @@ const Profile = () => { {user.username}

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

+
+

Recently Played Games

+
    + {userData?.recentPlayedGames.map((game, index) => ( +
  • + {game.formattedName} + {new Date(game.timestamp).toLocaleString()} +
  • + ))} +
+
{isBrowser ? (
diff --git a/frontend/src/pages/Score.tsx b/frontend/src/pages/Score.tsx index cf2b09c..3701b1f 100644 --- a/frontend/src/pages/Score.tsx +++ b/frontend/src/pages/Score.tsx @@ -23,6 +23,8 @@ const Score = () => { const [formattedGameName, setFormattedGameName] = useState(""); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [scores, setScores] = useState([]); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const [username, setUsername] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [numPages, setNumPages] = useState(1); @@ -30,6 +32,7 @@ const Score = () => { const [sortField, setSortField] = useState(""); const [sortDirection, setSortDirection] = useState("asc"); const [requestOrder, setRequestOrder] = useState("timestamp"); + const [viewingOwnScores, setViewingOwnScores] = useState(true); const gameName = new URLSearchParams(window.location.search).get("game") || "dancerush"; @@ -95,7 +98,18 @@ const Score = () => { setLoading(true); try { const url = new URL(import.meta.env.VITE_API_URL + "/scores"); - url.searchParams.append("userId", user.id.toString()); + const targetUserId = new URLSearchParams(window.location.search).get("userId"); + if (targetUserId) { + url.searchParams.append("userId", targetUserId); + } else { + url.searchParams.append("userId", user.id.toString()); + } + if(targetUserId !== user.id.toString()){ + setViewingOwnScores(false); + } + else{ + setViewingOwnScores(true); + } url.searchParams.append("internalGameName", gameName); url.searchParams.append("pageNum", pageNum.toString()); url.searchParams.append("sortKey", requestOrder); @@ -104,6 +118,7 @@ const Score = () => { const response = await fetch(url.toString(), {credentials: 'include'}); if (!response.ok) throw new Error("Failed to fetch scores"); const data = await response.json(); + setUsername(data.user); const flattened = data.scores.map(flattenScoreData); setScores(flattened); setNumPages(data.num_pages); @@ -175,7 +190,7 @@ const Score = () => {

- Your Scores for {formattedGameName} + {viewingOwnScores ? "Your Scores" : `${username}'s Scores`} for {formattedGameName}