aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/pages/Maplist.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/pages/Maplist.tsx')
-rw-r--r--frontend/src/pages/Maplist.tsx234
1 files changed, 148 insertions, 86 deletions
diff --git a/frontend/src/pages/Maplist.tsx b/frontend/src/pages/Maplist.tsx
index 76f9a52..2f0491e 100644
--- a/frontend/src/pages/Maplist.tsx
+++ b/frontend/src/pages/Maplist.tsx
@@ -2,7 +2,6 @@ import React, { useEffect } from "react";
2import { Link, useLocation, useNavigate, useParams } from "react-router-dom"; 2import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
3import { Helmet } from "react-helmet"; 3import { Helmet } from "react-helmet";
4 4
5import "@css/Maplist.css";
6import { API } from "@api/Api"; 5import { API } from "@api/Api";
7import { Game } from "@customTypes/Game"; 6import { Game } from "@customTypes/Game";
8import { GameChapter, GamesChapters } from "@customTypes/Chapters"; 7import { GameChapter, GamesChapters } from "@customTypes/Chapters";
@@ -11,7 +10,6 @@ const Maplist: React.FC = () => {
11 const [game, setGame] = React.useState<Game | null>(null); 10 const [game, setGame] = React.useState<Game | null>(null);
12 const [catNum, setCatNum] = React.useState(0); 11 const [catNum, setCatNum] = React.useState(0);
13 const [id, setId] = React.useState(0); 12 const [id, setId] = React.useState(0);
14 const [category, setCategory] = React.useState(0);
15 const [load, setLoad] = React.useState(false); 13 const [load, setLoad] = React.useState(false);
16 const [currentlySelected, setCurrentlySelected] = React.useState<number>(0); 14 const [currentlySelected, setCurrentlySelected] = React.useState<number>(0);
17 const [hasClicked, setHasClicked] = React.useState(false); 15 const [hasClicked, setHasClicked] = React.useState(false);
@@ -21,7 +19,7 @@ const Maplist: React.FC = () => {
21 19
22 const [dropdownActive, setDropdownActive] = React.useState("none"); 20 const [dropdownActive, setDropdownActive] = React.useState("none");
23 21
24 const params = useParams<{ id: string, chapter: string }>(); 22 const params = useParams<{ id: string; chapter: string }>();
25 const location = useLocation(); 23 const location = useLocation();
26 const navigate = useNavigate(); 24 const navigate = useNavigate();
27 25
@@ -34,15 +32,15 @@ const Maplist: React.FC = () => {
34 const _fetch_chapters = async (chapter_id: string) => { 32 const _fetch_chapters = async (chapter_id: string) => {
35 const chapters = await API.get_chapters(chapter_id); 33 const chapters = await API.get_chapters(chapter_id);
36 setCurChapter(chapters); 34 setCurChapter(chapters);
37 } 35 };
38 36
39 const _handle_dropdown_click = () => { 37 const _handle_dropdown_click = () => {
40 if (dropdownActive == "none") { 38 if (dropdownActive === "none") {
41 setDropdownActive("block"); 39 setDropdownActive("block");
42 } else { 40 } else {
43 setDropdownActive("none"); 41 setDropdownActive("none");
44 } 42 }
45 } 43 };
46 44
47 // im sorry but im too lazy to fix this right now 45 // im sorry but im too lazy to fix this right now
48 useEffect(() => { 46 useEffect(() => {
@@ -54,7 +52,7 @@ const Maplist: React.FC = () => {
54 const queryParams = new URLSearchParams(location.search); 52 const queryParams = new URLSearchParams(location.search);
55 if (queryParams.get("chapter")) { 53 if (queryParams.get("chapter")) {
56 let cat = parseFloat(queryParams.get("chapter") || ""); 54 let cat = parseFloat(queryParams.get("chapter") || "");
57 if (gameId == 2) { 55 if (gameId === 2) {
58 cat += 10; 56 cat += 10;
59 } 57 }
60 _fetch_chapters(cat.toString()); 58 _fetch_chapters(cat.toString());
@@ -62,7 +60,7 @@ const Maplist: React.FC = () => {
62 60
63 const _fetch_game = async () => { 61 const _fetch_game = async () => {
64 const games = await API.get_games(); 62 const games = await API.get_games();
65 const foundGame = games.find((game) => game.id === gameId); 63 const foundGame = games.find(game => game.id === gameId);
66 // console.log(foundGame) 64 // console.log(foundGame)
67 if (foundGame) { 65 if (foundGame) {
68 setGame(foundGame); 66 setGame(foundGame);
@@ -74,111 +72,175 @@ const Maplist: React.FC = () => {
74 const games_chapters = await API.get_games_chapters(gameId.toString()); 72 const games_chapters = await API.get_games_chapters(gameId.toString());
75 setGameChapters(games_chapters); 73 setGameChapters(games_chapters);
76 setNumChapters(games_chapters.chapters.length); 74 setNumChapters(games_chapters.chapters.length);
77 } 75 };
78 76
79 setLoad(true); 77 setLoad(true);
80 _fetch_game(); 78 _fetch_game();
81 _fetch_game_chapters(); 79 _fetch_game_chapters();
82 }, []); 80 }, [location.search]);
83 81
84 useEffect(() => { 82 useEffect(() => {
85 const queryParams = new URLSearchParams(location.search); 83 const queryParams = new URLSearchParams(location.search);
86 if (gameChapters != undefined && !queryParams.get("chapter")) { 84 if (gameChapters !== undefined && !queryParams.get("chapter")) {
87 _fetch_chapters(gameChapters!.chapters[0].id.toString()); 85 _fetch_chapters(gameChapters!.chapters[0].id.toString());
88 } 86 }
89 }, [gameChapters]) 87 }, [gameChapters, location.search]);
90
91
92 88
93 return ( 89 return (
94 <main> 90 <main className="*:text-foreground w-[calc(100vw-80px)] relative left-0 ml-20 min-h-screen p-4 sm:p-8">
95 <Helmet> 91 <Helmet>
96 <title>LPHUB | Maplist</title> 92 <title>LPHUB | Maplist</title>
97 </Helmet> 93 </Helmet>
98 <section style={{ marginTop: "20px" }}> 94
99 <Link to="/games"> 95 <section className="mt-5">
100 <button className="nav-button" style={{ borderRadius: "20px" }}> 96 <Link to="/games">
101 <i className="triangle"></i> 97 <button className="nav-button rounded-[20px] h-10 bg-surface border-0 text-foreground text-lg font-[--font-barlow-semicondensed-regular] transition-colors duration-100 hover:bg-surface2 flex items-center px-2">
102 <span>Games List</span> 98 <i className="triangle mr-2"></i>
103 </button> 99 <span className="px-2">Games List</span>
104 </Link> 100 </button>
101 </Link>
105 </section> 102 </section>
103
106 {load ? ( 104 {load ? (
107 <div></div> 105 <div></div>
108 ) : ( 106 ) : (
107 <section>
108 <h1 className="font-[--font-barlow-condensed-bold] text-3xl sm:text-6xl my-0 text-foreground">
109 {game?.name}
110 </h1>
111
112 <div
113 className="text-center rounded-3xl overflow-hidden bg-cover bg-[25%] mt-3 relative"
114 style={{ backgroundImage: `url(${game?.image})` }}
115 >
116 <div className="backdrop-blur-sm flex flex-col w-full">
117 <div className="h-full flex flex-col justify-center items-center py-6">
118 <h2 className="my-5 font-[--font-barlow-semicondensed-semibold] text-4xl sm:text-8xl text-foreground">
119 {
120 game?.category_portals.find(
121 obj => obj.category.id === catNum + 1
122 )?.portal_count
123 }
124 </h2>
125 <h3 className="font-[--font-barlow-semicondensed-regular] mx-2.5 text-2xl sm:text-4xl my-0 text-foreground">
126 portals
127 </h3>
128 </div>
129
130 <div className="flex h-12 bg-surface gap-0.5">
131 {game?.category_portals.map((cat, index) => (
132 <button
133 key={index}
134 className={`border-0 text-foreground font-[--font-barlow-semicondensed-regular] text-sm sm:text-xl cursor-pointer transition-all duration-100 w-full ${
135 currentlySelected === cat.category.id ||
136 (cat.category.id - 1 === catNum && !hasClicked)
137 ? "bg-surface"
138 : "bg-surface1 hover:bg-surface"
139 }`}
140 onClick={() => {
141 setCatNum(cat.category.id - 1);
142 _update_currently_selected(cat.category.id);
143 }}
144 >
145 <span className="truncate">{cat.category.name}</span>
146 </button>
147 ))}
148 </div>
149 </div>
150 </div>
151
152 <div>
109 <section> 153 <section>
110 <h1>{game?.name}</h1> 154 <div>
155 <span className="text-lg sm:text-lg translate-y-1.5 block mt-2.5 text-foreground">
156 {curChapter?.chapter.name.split(" - ")[0]}
157 </span>
158 </div>
159 <div
160 onClick={_handle_dropdown_click}
161 className="cursor-pointer select-none flex w-fit items-center"
162 >
163 <span className="text-foreground text-base sm:text-2xl">
164 {curChapter?.chapter.name.split(" - ")[1]}
165 </span>
166 <i className="triangle translate-x-1.5 translate-y-2 -rotate-90"></i>
167 </div>
168 \
111 <div 169 <div
112 style={{ backgroundImage: `url(${game?.image})` }} 170 className={`absolute z-[1000] bg-surface1 rounded-2xl overflow-hidden p-1 animate-in fade-in duration-100 ${
113 className="game-header" 171 dropdownActive === "none" ? "hidden" : "block"
172 }`}
114 > 173 >
115 <div className="blur"> 174 {gameChapters?.chapters.map((chapter, i) => {
116 <div className="game-header-portal-count"> 175 return (
117 <h2 className="portal-count"> 176 <div
118 { 177 key={i}
119 game?.category_portals.find( 178 className="cursor-pointer text-base sm:text-xl rounded-[2000px] p-1 hover:bg-surface text-foreground"
120 (obj) => obj.category.id === catNum + 1 179 onClick={() => {
121 )?.portal_count 180 _fetch_chapters(chapter.id.toString());
122 } 181 _handle_dropdown_click();
123 </h2> 182 }}
124 <h3>portals</h3> 183 >
125 </div> 184 {chapter.name}
126 <div className="game-header-categories">
127 {game?.category_portals.map((cat, index) => (
128 <button key={index} className={currentlySelected == cat.category.id || cat.category.id - 1 == catNum && !hasClicked ? "game-cat-button selected" : "game-cat-button"} onClick={() => { setCatNum(cat.category.id - 1); _update_currently_selected(cat.category.id) }}>
129 <span>{cat.category.name}</span>
130 </button>
131 ))}
132 </div>
133 </div> 185 </div>
186 );
187 })}
134 </div> 188 </div>
189 </section>
135 190
136 <div> 191 <section className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-5 my-5">
137 <section className="chapter-select-container"> 192 {curChapter?.maps.map((map, i) => {
138 <div> 193 return (
139 <span style={{ fontSize: "18px", transform: "translateY(5px)", display: "block", marginTop: "10px" }}>{curChapter?.chapter.name.split(" - ")[0]}</span> 194 <div key={i} className="bg-surface rounded-3xl overflow-hidden">
195 <Link to={`/maps/${map.id}`}>
196 <span className="text-center text-base sm:text-xl w-full block my-1.5 text-foreground truncate">
197 {map.name}
198 </span>
199 <div
200 className="flex h-40 sm:h-48 bg-cover relative"
201 style={{ backgroundImage: `url(${map.image})` }}
202 >
203 <div className="backdrop-blur-sm w-full flex items-center justify-center">
204 <span className="text-2xl sm:text-4xl font-[--font-barlow-semicondensed-semibold] text-white mr-1.5">
205 {map.is_disabled
206 ? map.category_portals[0].portal_count
207 : map.category_portals.find(
208 obj => obj.category.id === catNum + 1
209 )?.portal_count}
210 </span>
211 <span className="text-2xl sm:text-4xl font-[--font-barlow-semicondensed-regular] text-white">
212 portals
213 </span>
140 </div> 214 </div>
141 <div onClick={_handle_dropdown_click} className="dropdown">
142 <span>{curChapter?.chapter.name.split(" - ")[1]}</span>
143 <i className="triangle"></i>
144 </div> 215 </div>
145 <div className="dropdown-elements" style={{ display: dropdownActive }}>
146 {gameChapters?.chapters.map((chapter, i) => {
147 return <div className="dropdown-element" onClick={() => { _fetch_chapters(chapter.id.toString()); _handle_dropdown_click() }}>{chapter.name}</div>
148 })
149 216
150 } 217 <div className="flex mx-2.5 my-4">
218 <div className="flex w-full items-center justify-center gap-1.5 rounded-[2000px] ml-0.5 translate-y-px">
219 {[1, 2, 3, 4, 5].map((point) => (
220 <div
221 key={point}
222 className={`flex h-0.5 w-full rounded-3xl ${
223 point <= (map.difficulty + 1)
224 ? map.difficulty === 0
225 ? "bg-green-500"
226 : map.difficulty === 1 || map.difficulty === 2
227 ? "bg-lime-500"
228 : map.difficulty === 3
229 ? "bg-red-400"
230 : "bg-red-600"
231 : "bg-surface1"
232 }`}
233 />
234 ))}
151 </div> 235 </div>
152 </section> 236 </div>
153 <section className="maplist"> 237 </Link>
154 {curChapter?.maps.map((map, i) => { 238 </div>
155 return <div className="maplist-entry"> 239 );
156 <Link to={`/maps/${map.id}`}> 240 })}
157 <span>{map.name}</span>
158 <div className="map-entry-image" style={{ backgroundImage: `url(${map.image})` }}>
159 <div className="blur map">
160 <span>{map.is_disabled ? map.category_portals[0].portal_count : map.category_portals.find(
161 (obj) => obj.category.id === catNum + 1
162 )?.portal_count}</span>
163 <span>portals</span>
164 </div>
165 </div>
166 <div className="difficulty-bar">
167 {/* <span>Difficulty:</span> */}
168 <div className={map.difficulty <= 2 ? "one" : map.difficulty <= 4 ? "two" : map.difficulty <= 6 ? "three" : map.difficulty <= 8 ? "four" : map.difficulty <= 10 ? "five" : "one"}>
169 <div className="difficulty-point"></div>
170 <div className="difficulty-point"></div>
171 <div className="difficulty-point"></div>
172 <div className="difficulty-point"></div>
173 <div className="difficulty-point"></div>
174 </div>
175 </div>
176 </Link>
177 </div>
178 })}
179 </section>
180 </div>
181 </section> 241 </section>
242 </div>
243 </section>
182 )} 244 )}
183 </main> 245 </main>
184 ); 246 );