aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/pages/Profile.tsx
blob: 4ab5995ff20fc15453de9c097a209bea5f3155c6 (plain) (blame)
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;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage