aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/pages/Rankings
diff options
context:
space:
mode:
authorWolfboy248 <georgejvindkarlsen@gmail.com>2025-08-19 13:23:17 +0200
committerWolfboy248 <georgejvindkarlsen@gmail.com>2025-08-19 13:23:17 +0200
commitc04bc9a36ebfcdf6d8e2db8a6cdeb44062b66bec (patch)
tree42dfa70f41f701b561455aac01b45ec72f816184 /frontend/src/pages/Rankings
parentfix/frontend: smol syntax fix (diff)
downloadlphub-c04bc9a36ebfcdf6d8e2db8a6cdeb44062b66bec.tar.gz
lphub-c04bc9a36ebfcdf6d8e2db8a6cdeb44062b66bec.tar.bz2
lphub-c04bc9a36ebfcdf6d8e2db8a6cdeb44062b66bec.zip
organised pages, started work on theme
Diffstat (limited to 'frontend/src/pages/Rankings')
-rw-r--r--frontend/src/pages/Rankings/Rankings.tsx203
1 files changed, 203 insertions, 0 deletions
diff --git a/frontend/src/pages/Rankings/Rankings.tsx b/frontend/src/pages/Rankings/Rankings.tsx
new file mode 100644
index 0000000..57b875f
--- /dev/null
+++ b/frontend/src/pages/Rankings/Rankings.tsx
@@ -0,0 +1,203 @@
1import React, { useEffect } from "react";
2import { Helmet } from "react-helmet";
3
4import RankingEntry from "@components/RankingEntry.tsx";
5import {
6 Ranking,
7 SteamRanking,
8 RankingType,
9 SteamRankingType,
10} from "@customTypes/Ranking.ts";
11import { API } from "@api/Api.ts";
12
13import "@css/Rankings.css";
14
15enum LeaderboardTypes {
16 official,
17 unofficial,
18}
19
20enum RankingCategories {
21 rankings_overall,
22 rankings_multiplayer,
23 rankings_singleplayer,
24}
25
26const Rankings: React.FC = () => {
27 const [leaderboardData, setLeaderboardData] = React.useState<
28 Ranking | SteamRanking
29 >();
30 const [currentLeaderboard, setCurrentLeaderboard] = React.useState<
31 RankingType[] | SteamRankingType[]
32 >();
33 const [currentRankingType, setCurrentRankingType] =
34 React.useState<LeaderboardTypes>(LeaderboardTypes.official);
35
36 const [leaderboardLoad, setLeaderboardLoad] = React.useState<boolean>(false);
37
38 const [currentLeaderboardType, setCurrentLeaderboardType] =
39 React.useState<RankingCategories>(RankingCategories.rankings_singleplayer);
40 const [load, setLoad] = React.useState<boolean>(false);
41
42 const _fetch_rankings = React.useCallback(async () => {
43 setLeaderboardLoad(false);
44 const rankings = await API.get_official_rankings();
45 setLeaderboardData(rankings);
46 if (currentLeaderboardType === RankingCategories.rankings_singleplayer) {
47 setCurrentLeaderboard(rankings.rankings_singleplayer);
48 } else if (
49 currentLeaderboardType === RankingCategories.rankings_multiplayer
50 ) {
51 setCurrentLeaderboard(rankings.rankings_multiplayer);
52 } else {
53 setCurrentLeaderboard(rankings.rankings_overall);
54 }
55 setLoad(true);
56 setLeaderboardLoad(true);
57 }, [currentLeaderboardType]);
58
59 const __dev_fetch_unofficial_rankings = async () => {
60 try {
61 setLeaderboardLoad(false);
62 const rankings = await API.get_unofficial_rankings();
63 setLeaderboardData(rankings);
64 if (currentLeaderboardType === RankingCategories.rankings_singleplayer) {
65 // console.log(_sort_rankings_steam(unofficialRanking.rankings_singleplayer))
66 setCurrentLeaderboard(rankings.rankings_singleplayer);
67 } else if (
68 currentLeaderboardType === RankingCategories.rankings_multiplayer
69 ) {
70 setCurrentLeaderboard(rankings.rankings_multiplayer);
71 } else {
72 setCurrentLeaderboard(rankings.rankings_overall);
73 }
74 setLeaderboardLoad(true);
75 } catch (e) {
76 console.log(e);
77 }
78 };
79
80 const _set_current_leaderboard = React.useCallback(
81 (ranking_cat: RankingCategories) => {
82 if (ranking_cat === RankingCategories.rankings_singleplayer) {
83 setCurrentLeaderboard(leaderboardData!.rankings_singleplayer);
84 } else if (ranking_cat === RankingCategories.rankings_multiplayer) {
85 setCurrentLeaderboard(leaderboardData!.rankings_multiplayer);
86 } else {
87 setCurrentLeaderboard(leaderboardData!.rankings_overall);
88 }
89
90 setCurrentLeaderboardType(ranking_cat);
91 },
92 [leaderboardData]
93 );
94
95 // unused func
96 // const _set_leaderboard_type = (leaderboard_type: LeaderboardTypes) => {
97 // if (leaderboard_type === LeaderboardTypes.official) {
98 // _fetch_rankings();
99 // } else {
100 // }
101 // };
102
103 useEffect(() => {
104 _fetch_rankings();
105 }, [_fetch_rankings]);
106
107 return (
108 <main className="*:text-foreground">
109 <Helmet>
110 <title>LPHUB | Rankings</title>
111 </Helmet>
112 <section className="nav-container nav-1">
113 <div>
114 <button
115 onClick={() => {
116 _fetch_rankings();
117 setCurrentRankingType(LeaderboardTypes.official);
118 }}
119 className={`nav-1-btn ${currentRankingType === LeaderboardTypes.official ? "selected" : ""}`}
120 >
121 <span>Official (LPHUB)</span>
122 </button>
123 <button
124 onClick={() => {
125 __dev_fetch_unofficial_rankings();
126 setCurrentRankingType(LeaderboardTypes.unofficial);
127 }}
128 className={`nav-1-btn ${currentRankingType === LeaderboardTypes.unofficial ? "selected" : ""}`}
129 >
130 <span>Unofficial (Steam)</span>
131 </button>
132 </div>
133 </section>
134 <section className="nav-container nav-2">
135 <div>
136 <button
137 onClick={() =>
138 _set_current_leaderboard(RankingCategories.rankings_singleplayer)
139 }
140 className={`nav-2-btn ${currentLeaderboardType === RankingCategories.rankings_singleplayer ? "selected" : ""}`}
141 >
142 <span>Singleplayer</span>
143 </button>
144 <button
145 onClick={() =>
146 _set_current_leaderboard(RankingCategories.rankings_multiplayer)
147 }
148 className={`nav-2-btn ${currentLeaderboardType === RankingCategories.rankings_multiplayer ? "selected" : ""}`}
149 >
150 <span>Cooperative</span>
151 </button>
152 <button
153 onClick={() =>
154 _set_current_leaderboard(RankingCategories.rankings_overall)
155 }
156 className={`nav-2-btn ${currentLeaderboardType === RankingCategories.rankings_overall ? "selected" : ""}`}
157 >
158 <span>Overall</span>
159 </button>
160 </div>
161 </section>
162
163 {load ? (
164 <section className="rankings-leaderboard">
165 <div className="ranks-container">
166 <div className="leaderboard-entry header">
167 <span>Rank</span>
168 <span>Player</span>
169 <span>Portals</span>
170 </div>
171
172 <div className="splitter"></div>
173
174 {leaderboardLoad &&
175 currentLeaderboard?.map((curRankingData, i) => {
176 return (
177 <RankingEntry
178 currentLeaderboardType={currentLeaderboardType}
179 curRankingData={curRankingData}
180 key={i}
181 ></RankingEntry>
182 );
183 })}
184
185 {leaderboardLoad ? null : (
186 <div
187 style={{
188 display: "flex",
189 justifyContent: "center",
190 margin: "30px 0px",
191 }}
192 >
193 <span className="loader"></span>
194 </div>
195 )}
196 </div>
197 </section>
198 ) : null}
199 </main>
200 );
201};
202
203export default Rankings;