1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
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";
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<HeatmapData>({ 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 || fetchingHeatmapData) {
return <LoadingDisplay message="Loading Profile Page..." />;
}
if (!user) {
return <SessionExpiredPopup />;
}
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 <SessionExpiredPopup />;
}
return (
<div className="min-h-screen bg-slate-950">
<NavBar user={user} handleLogout={handleLogout} currentPage="" />
{/* Main Content */}
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 sm:py-8">
{/* Header */}
<div className="mb-6 sm:mb-8">
<h1 className="text-2xl sm:text-3xl font-bold text-white mb-2">
{user.username}
</h1>
<p className="text-sm sm:text-base text-slate-400">
This is a profile page for {user.username}
</p>
</div>
{isBrowser ? (
<div className="flex flex-col items-center justify-center">
<Heatmap data={heatmapData.data} />
</div>
) : null}
</div>
</div>
);
};
export default Profile;
|