From 732f3873354863a4dec591d4d6a425edb7b47c61 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Mon, 27 Oct 2025 22:25:44 -0700 Subject: add heatmap api endpoints and heatmap to stub profile page --- frontend/src/pages/Profile.tsx | 88 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'frontend/src/pages') diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx index 184681d..4ab5995 100644 --- a/frontend/src/pages/Profile.tsx +++ b/frontend/src/pages/Profile.tsx @@ -1,19 +1,74 @@ -import { useNavigate } from 'react-router'; -import LoadingDisplay from "../components/LoadingDisplay"; +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 { NavBar } from "../components/NavBar"; import { useAuth } from "../contexts/AuthContext"; - - +import Heatmap from "../components/Heatmap"; +import type { HeatmapData } from "../components/Heatmap"; const Profile = () => { const { user, isLoading, logout } = useAuth(); + const targetUser = + new URLSearchParams(window.location.search).get("userId") || ""; // looking at profile of this user const navigate = useNavigate(); + const [fetchingHeatmapData, setFetchingHeatmapData] = useState(false); + const [heatmapData, setHeatmapData] = useState({ data: [] }); + + 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 (!targetUser) { + navigate("/"); + } - if (isLoading) { + if (isLoading || fetchingHeatmapData) { return ; } + if (!user) { + return ; + } + const handleLogout = async () => { try { await logout(); @@ -30,8 +85,25 @@ const Profile = () => { return (
- -

Profile

+ + + {/* Main Content */} +
+ {/* Header */} +
+

+ {user.username} +

+

+ This is a profile page for {user.username} +

+
+ {isBrowser ? ( +
+ +
+ ) : null} +
); }; -- cgit v1.2.3