aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/pages
diff options
context:
space:
mode:
authorFifthWit <fifthwitbusiness@gmail.com>2025-08-14 14:01:01 -0500
committerFifthWit <fifthwitbusiness@gmail.com>2025-08-14 14:01:01 -0500
commit6a8b909afbe1560be95f7ad0a3e19cfe4717aec6 (patch)
tree83cdbe3b5b7e5b83d5f0d08964634cc942264072 /frontend/src/pages
parentSwitched to Vite as build tool (diff)
downloadlphub-6a8b909afbe1560be95f7ad0a3e19cfe4717aec6.tar.gz
lphub-6a8b909afbe1560be95f7ad0a3e19cfe4717aec6.tar.bz2
lphub-6a8b909afbe1560be95f7ad0a3e19cfe4717aec6.zip
Switched to tailwind/vite
Diffstat (limited to 'frontend/src/pages')
-rw-r--r--frontend/src/pages/About.tsx4
-rw-r--r--frontend/src/pages/Games.tsx32
-rw-r--r--frontend/src/pages/Homepage.tsx12
-rw-r--r--frontend/src/pages/Maplist.tsx131
-rw-r--r--frontend/src/pages/Maps.tsx15
-rw-r--r--frontend/src/pages/Profile.tsx1
-rw-r--r--frontend/src/pages/Rules.tsx4
-rw-r--r--frontend/src/pages/User.tsx1
8 files changed, 93 insertions, 107 deletions
diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx
index 5a69bfe..a5bb291 100644
--- a/frontend/src/pages/About.tsx
+++ b/frontend/src/pages/About.tsx
@@ -2,8 +2,6 @@ import React from "react";
2import ReactMarkdown from "react-markdown"; 2import ReactMarkdown from "react-markdown";
3import { Helmet } from "react-helmet"; 3import { Helmet } from "react-helmet";
4 4
5import "@css/About.css";
6
7const About: React.FC = () => { 5const About: React.FC = () => {
8 const [aboutText, setAboutText] = React.useState<string>(""); 6 const [aboutText, setAboutText] = React.useState<string>("");
9 7
@@ -26,7 +24,7 @@ const About: React.FC = () => {
26 }, []); 24 }, []);
27 25
28 return ( 26 return (
29 <div id="about"> 27 <div className="p-8 text-foreground font-[--font-barlow-semicondensed-regular] prose prose-invert max-w-none">
30 <Helmet> 28 <Helmet>
31 <title>LPHUB | About</title> 29 <title>LPHUB | About</title>
32 </Helmet> 30 </Helmet>
diff --git a/frontend/src/pages/Games.tsx b/frontend/src/pages/Games.tsx
index d7dacde..1ef0f57 100644
--- a/frontend/src/pages/Games.tsx
+++ b/frontend/src/pages/Games.tsx
@@ -3,41 +3,23 @@ import { Helmet } from "react-helmet";
3 3
4import GameEntry from "@components/GameEntry"; 4import GameEntry from "@components/GameEntry";
5import { Game } from "@customTypes/Game"; 5import { Game } from "@customTypes/Game";
6import "@css/Maps.css";
7 6
8interface GamesProps { 7interface GamesProps {
9 games: Game[]; 8 games: Game[];
10} 9}
11 10
12const Games: React.FC<GamesProps> = ({ games }) => { 11const Games: React.FC<GamesProps> = ({ games }) => {
13 const _page_load = () => {
14 const loaders = document.querySelectorAll(".loader");
15 loaders.forEach(loader => {
16 (loader as HTMLElement).style.display = "none";
17 });
18 };
19
20 React.useEffect(() => {
21 document
22 .querySelectorAll(".games-page-item-body")
23 .forEach((game, index) => {
24 game.innerHTML = "";
25 });
26 _page_load();
27 }, []);
28
29 return ( 12 return (
30 <div className="games-page"> 13 <div className="ml-10 min-h-screen w-[calc(100%-320px)] text-foreground font-[--font-barlow-semicondensed-regular] overflow-y-auto scrollbar-thin">
31 <Helmet> 14 <Helmet>
32 <title>LPHUB | Games</title> 15 <title>LPHUB | Games</title>
33 </Helmet> 16 </Helmet>
34 <section> 17 <section className="py-12 px-12 w-full">
35 <div className="games-page-content"> 18 <h1 className="text-3xl font-bold mb-8">Games</h1>
36 <div className="games-page-item-content"> 19 <div className="flex flex-col w-full">
37 {games.map((game, index) => ( 20 {games.map((game, index) => (
38 <GameEntry game={game} key={index} /> 21 <GameEntry game={game} key={index} />
39 ))} 22 ))}
40 </div>
41 </div> 23 </div>
42 </section> 24 </section>
43 </div> 25 </div>
diff --git a/frontend/src/pages/Homepage.tsx b/frontend/src/pages/Homepage.tsx
index f0c5821..2d16b8d 100644
--- a/frontend/src/pages/Homepage.tsx
+++ b/frontend/src/pages/Homepage.tsx
@@ -3,23 +3,23 @@ import { Helmet } from "react-helmet";
3 3
4const Homepage: React.FC = () => { 4const Homepage: React.FC = () => {
5 return ( 5 return (
6 <main> 6 <main className="text-foreground font-[--font-barlow-semicondensed-regular]">
7 <Helmet> 7 <Helmet>
8 <title>LPHUB | Homepage</title> 8 <title>LPHUB | Homepage</title>
9 </Helmet> 9 </Helmet>
10 <section> 10 <section className="p-8">
11 <p /> 11 <p />
12 <h1>Welcome to Least Portals Hub!</h1> 12 <h1 className="text-5xl font-[--font-barlow-condensed-bold] mb-6 text-primary">Welcome to Least Portals Hub!</h1>
13 <p> 13 <p className="text-lg mb-4 leading-relaxed">
14 At the moment, LPHUB is in beta state. This means that the site has 14 At the moment, LPHUB is in beta state. This means that the site has
15 only the core functionalities enabled for providing both collaborative 15 only the core functionalities enabled for providing both collaborative
16 information and competitive leaderboards. 16 information and competitive leaderboards.
17 </p> 17 </p>
18 <p> 18 <p className="text-lg mb-4 leading-relaxed">
19 The website should feel intuitive to navigate around. For any type of 19 The website should feel intuitive to navigate around. For any type of
20 feedback, reach us at LPHUB Discord server. 20 feedback, reach us at LPHUB Discord server.
21 </p> 21 </p>
22 <p> 22 <p className="text-lg mb-4 leading-relaxed">
23 By using LPHUB, you agree that you have read the 'Leaderboard Rules' 23 By using LPHUB, you agree that you have read the 'Leaderboard Rules'
24 and the 'About LPHUB' pages. 24 and the 'About LPHUB' pages.
25 </p> 25 </p>
diff --git a/frontend/src/pages/Maplist.tsx b/frontend/src/pages/Maplist.tsx
index a7242ef..8343129 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";
@@ -92,44 +91,52 @@ const Maplist: React.FC = () => {
92 <Helmet> 91 <Helmet>
93 <title>LPHUB | Maplist</title> 92 <title>LPHUB | Maplist</title>
94 </Helmet> 93 </Helmet>
95 <section style={{ marginTop: "20px" }}> 94
95 <section className="mt-5">
96 <Link to="/games"> 96 <Link to="/games">
97 <button className="nav-button" style={{ borderRadius: "20px" }}> 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">
98 <i className="triangle"></i> 98 <i className="triangle mr-2"></i>
99 <span>Games List</span> 99 <span className="px-2">Games List</span>
100 </button> 100 </button>
101 </Link> 101 </Link>
102 </section> 102 </section>
103
103 {load ? ( 104 {load ? (
104 <div></div> 105 <div></div>
105 ) : ( 106 ) : (
106 <section> 107 <section>
107 <h1>{game?.name}</h1> 108 <h1 className="font-[--font-barlow-condensed-bold] text-6xl my-0 text-foreground">
109 {game?.name}
110 </h1>
111
108 <div 112 <div
113 className="text-center rounded-3xl overflow-hidden bg-cover bg-[25%] mt-3 relative"
109 style={{ backgroundImage: `url(${game?.image})` }} 114 style={{ backgroundImage: `url(${game?.image})` }}
110 className="game-header"
111 > 115 >
112 <div className="blur"> 116 <div className="backdrop-blur-sm flex flex-col w-full">
113 <div className="game-header-portal-count"> 117 <div className="h-full flex flex-col justify-center items-center">
114 <h2 className="portal-count"> 118 <h2 className="my-5 font-[--font-barlow-semicondensed-semibold] text-8xl text-foreground">
115 { 119 {
116 game?.category_portals.find( 120 game?.category_portals.find(
117 obj => obj.category.id === catNum + 1 121 obj => obj.category.id === catNum + 1
118 )?.portal_count 122 )?.portal_count
119 } 123 }
120 </h2> 124 </h2>
121 <h3>portals</h3> 125 <h3 className="font-[--font-barlow-semicondensed-regular] mx-2.5 text-4xl my-0 text-foreground">
126 portals
127 </h3>
122 </div> 128 </div>
123 <div className="game-header-categories"> 129
130 <div className="flex h-12 bg-surface gap-0.5">
124 {game?.category_portals.map((cat, index) => ( 131 {game?.category_portals.map((cat, index) => (
125 <button 132 <button
126 key={index} 133 key={index}
127 className={ 134 className={`border-0 text-foreground font-[--font-barlow-semicondensed-regular] text-xl cursor-pointer transition-all duration-100 w-full ${
128 currentlySelected === cat.category.id || 135 currentlySelected === cat.category.id ||
129 (cat.category.id - 1 === catNum && !hasClicked) 136 (cat.category.id - 1 === catNum && !hasClicked)
130 ? "game-cat-button selected" 137 ? "bg-surface"
131 : "game-cat-button" 138 : "bg-surface1 hover:bg-surface"
132 } 139 }`}
133 onClick={() => { 140 onClick={() => {
134 setCatNum(cat.category.id - 1); 141 setCatNum(cat.category.id - 1);
135 _update_currently_selected(cat.category.id); 142 _update_currently_selected(cat.category.id);
@@ -143,31 +150,32 @@ const Maplist: React.FC = () => {
143 </div> 150 </div>
144 151
145 <div> 152 <div>
146 <section className="chapter-select-container"> 153 <section>
147 <div> 154 <div>
148 <span 155 <span className="text-lg translate-y-1.5 block mt-2.5 text-foreground">
149 style={{
150 fontSize: "18px",
151 transform: "translateY(5px)",
152 display: "block",
153 marginTop: "10px",
154 }}
155 >
156 {curChapter?.chapter.name.split(" - ")[0]} 156 {curChapter?.chapter.name.split(" - ")[0]}
157 </span> 157 </span>
158 </div> 158 </div>
159 <div onClick={_handle_dropdown_click} className="dropdown"> 159 <div
160 <span>{curChapter?.chapter.name.split(" - ")[1]}</span> 160 onClick={_handle_dropdown_click}
161 <i className="triangle"></i> 161 className="cursor-pointer select-none flex w-fit items-center"
162 >
163 <span className="text-foreground text-2xl">
164 {curChapter?.chapter.name.split(" - ")[1]}
165 </span>
166 <i className="triangle translate-x-1.5 translate-y-2 -rotate-90"></i>
162 </div> 167 </div>
168 \
163 <div 169 <div
164 className="dropdown-elements" 170 className={`absolute z-[1000] bg-surface1 rounded-2xl overflow-hidden p-1 animate-in fade-in duration-100 ${
165 style={{ display: dropdownActive }} 171 dropdownActive === "none" ? "hidden" : "block"
172 }`}
166 > 173 >
167 {gameChapters?.chapters.map((chapter, i) => { 174 {gameChapters?.chapters.map((chapter, i) => {
168 return ( 175 return (
169 <div 176 <div
170 className="dropdown-element" 177 key={i}
178 className="cursor-pointer text-xl rounded-[2000px] p-1 hover:bg-surface text-foreground"
171 onClick={() => { 179 onClick={() => {
172 _fetch_chapters(chapter.id.toString()); 180 _fetch_chapters(chapter.id.toString());
173 _handle_dropdown_click(); 181 _handle_dropdown_click();
@@ -179,49 +187,52 @@ const Maplist: React.FC = () => {
179 })} 187 })}
180 </div> 188 </div>
181 </section> 189 </section>
182 <section className="maplist"> 190
191 <section className="grid grid-cols-4 gap-5 my-5">
183 {curChapter?.maps.map((map, i) => { 192 {curChapter?.maps.map((map, i) => {
184 return ( 193 return (
185 <div className="maplist-entry"> 194 <div key={i} className="bg-surface rounded-3xl overflow-hidden">
186 <Link to={`/maps/${map.id}`}> 195 <Link to={`/maps/${map.id}`}>
187 <span>{map.name}</span> 196 <span className="text-center text-xl w-full block my-1.5 text-foreground">
197 {map.name}
198 </span>
188 <div 199 <div
189 className="map-entry-image" 200 className="flex h-48 bg-cover relative"
190 style={{ backgroundImage: `url(${map.image})` }} 201 style={{ backgroundImage: `url(${map.image})` }}
191 > 202 >
192 <div className="blur map"> 203 <div className="backdrop-blur-sm w-full flex items-center justify-center">
193 <span> 204 <span className="text-4xl font-[--font-barlow-semicondensed-semibold] text-white mr-1.5">
194 {map.is_disabled 205 {map.is_disabled
195 ? map.category_portals[0].portal_count 206 ? map.category_portals[0].portal_count
196 : map.category_portals.find( 207 : map.category_portals.find(
197 obj => obj.category.id === catNum + 1 208 obj => obj.category.id === catNum + 1
198 )?.portal_count} 209 )?.portal_count}
199 </span> 210 </span>
200 <span>portals</span> 211 <span className="text-4xl font-[--font-barlow-semicondensed-regular] text-white">
212 portals
213 </span>
201 </div> 214 </div>
202 </div> 215 </div>
203 <div className="difficulty-bar"> 216
204 {/* <span>Difficulty:</span> */} 217 {/* Difficulty rating */}
205 <div 218 <div className="flex mx-2.5 my-4">
206 className={ 219 <div className="flex w-full items-center justify-center gap-1.5 rounded-[2000px] ml-0.5 translate-y-px">
207 map.difficulty === 0 220 {[1, 2, 3, 4, 5].map((point) => (
208 ? "one" 221 <div
209 : map.difficulty === 1 222 key={point}
210 ? "two" 223 className={`flex h-0.5 w-full rounded-3xl ${
211 : map.difficulty === 2 224 point <= (map.difficulty + 1)
212 ? "three" 225 ? map.difficulty === 0
213 : map.difficulty === 3 226 ? "bg-green-500"
214 ? "four" 227 : map.difficulty === 1 || map.difficulty === 2
215 : map.difficulty === 4 228 ? "bg-lime-500"
216 ? "five" 229 : map.difficulty === 3
217 : "one" 230 ? "bg-red-400"
218 } 231 : "bg-red-600"
219 > 232 : "bg-surface1"
220 <div className="difficulty-point"></div> 233 }`}
221 <div className="difficulty-point"></div> 234 />
222 <div className="difficulty-point"></div> 235 ))}
223 <div className="difficulty-point"></div>
224 <div className="difficulty-point"></div>
225 </div> 236 </div>
226 </div> 237 </div>
227 </Link> 238 </Link>
diff --git a/frontend/src/pages/Maps.tsx b/frontend/src/pages/Maps.tsx
index fbdb8f3..75753ac 100644
--- a/frontend/src/pages/Maps.tsx
+++ b/frontend/src/pages/Maps.tsx
@@ -2,14 +2,13 @@ import React from "react";
2import { Link, useLocation } from "react-router-dom"; 2import { Link, useLocation } from "react-router-dom";
3import { Helmet } from "react-helmet"; 3import { Helmet } from "react-helmet";
4 4
5import { PortalIcon, FlagIcon, ChatIcon } from "@images/Images"; 5import { PortalIcon, FlagIcon, ChatIcon } from "../images/Images";
6import Summary from "@components/Summary"; 6import Summary from "@components/Summary";
7import Leaderboards from "@components/Leaderboards"; 7import Leaderboards from "@components/Leaderboards";
8import Discussions from "@components/Discussions"; 8import Discussions from "@components/Discussions";
9import ModMenu from "@components/ModMenu"; 9import ModMenu from "@components/ModMenu";
10import { MapDiscussions, MapLeaderboard, MapSummary } from "@customTypes/Map"; 10import { MapDiscussions, MapLeaderboard, MapSummary } from "@customTypes/Map";
11import { API } from "@api/Api"; 11import { API } from "@api/Api";
12import "@css/Maps.css";
13 12
14interface MapProps { 13interface MapProps {
15 token?: string; 14 token?: string;
@@ -82,15 +81,15 @@ const Maps: React.FC<MapProps> = ({ token, isModerator }) => {
82 81
83 <section id="section2" className="summary1"> 82 <section id="section2" className="summary1">
84 <button className="nav-button"> 83 <button className="nav-button">
85 <img src={PortalIcon} alt="" /> 84 <img src={PortalIcon} alt="" className="w-6 h-6" />
86 <span>Summary</span> 85 <span>Summary</span>
87 </button> 86 </button>
88 <button className="nav-button"> 87 <button className="nav-button">
89 <img src={FlagIcon} alt="" /> 88 <img src={FlagIcon} alt="" className="w-6 h-6" />
90 <span>Leaderboards</span> 89 <span>Leaderboards</span>
91 </button> 90 </button>
92 <button className="nav-button"> 91 <button className="nav-button">
93 <img src={ChatIcon} alt="" /> 92 <img src={ChatIcon} alt="" className="w-6 h-6" />
94 <span>Discussions</span> 93 <span>Discussions</span>
95 </button> 94 </button>
96 </section> 95 </section>
@@ -151,15 +150,15 @@ const Maps: React.FC<MapProps> = ({ token, isModerator }) => {
151 150
152 <section id="section2" className="summary1"> 151 <section id="section2" className="summary1">
153 <button className="nav-button" onClick={() => setNavState(0)}> 152 <button className="nav-button" onClick={() => setNavState(0)}>
154 <img src={PortalIcon} alt="" /> 153 <img src={PortalIcon} alt="" className="w-6 h-6" />
155 <span>Summary</span> 154 <span>Summary</span>
156 </button> 155 </button>
157 <button className="nav-button" onClick={() => setNavState(1)}> 156 <button className="nav-button" onClick={() => setNavState(1)}>
158 <img src={FlagIcon} alt="" /> 157 <img src={FlagIcon} alt="" className="w-6 h-6" />
159 <span>Leaderboards</span> 158 <span>Leaderboards</span>
160 </button> 159 </button>
161 <button className="nav-button" onClick={() => setNavState(2)}> 160 <button className="nav-button" onClick={() => setNavState(2)}>
162 <img src={ChatIcon} alt="" /> 161 <img src={ChatIcon} alt="" className="w-6 h-6" />
163 <span>Discussions</span> 162 <span>Discussions</span>
164 </button> 163 </button>
165 </section> 164 </section>
diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx
index e2d6000..f44f587 100644
--- a/frontend/src/pages/Profile.tsx
+++ b/frontend/src/pages/Profile.tsx
@@ -19,7 +19,6 @@ import { UserProfile } from "@customTypes/Profile";
19import { Game, GameChapters } from "@customTypes/Game"; 19import { Game, GameChapters } from "@customTypes/Game";
20import { Map } from "@customTypes/Map"; 20import { Map } from "@customTypes/Map";
21import { ticks_to_time } from "@utils/Time"; 21import { ticks_to_time } from "@utils/Time";
22import "@css/Profile.css";
23import { API } from "@api/Api"; 22import { API } from "@api/Api";
24import useConfirm from "@hooks/UseConfirm"; 23import useConfirm from "@hooks/UseConfirm";
25import useMessage from "@hooks/UseMessage"; 24import useMessage from "@hooks/UseMessage";
diff --git a/frontend/src/pages/Rules.tsx b/frontend/src/pages/Rules.tsx
index 91027a0..7cdc08b 100644
--- a/frontend/src/pages/Rules.tsx
+++ b/frontend/src/pages/Rules.tsx
@@ -2,8 +2,6 @@ import React from "react";
2import ReactMarkdown from "react-markdown"; 2import ReactMarkdown from "react-markdown";
3import { Helmet } from "react-helmet"; 3import { Helmet } from "react-helmet";
4 4
5import "@css/Rules.css";
6
7const Rules: React.FC = () => { 5const Rules: React.FC = () => {
8 const [rulesText, setRulesText] = React.useState<string>(""); 6 const [rulesText, setRulesText] = React.useState<string>("");
9 7
@@ -27,7 +25,7 @@ const Rules: React.FC = () => {
27 }, []); 25 }, []);
28 26
29 return ( 27 return (
30 <main> 28 <main className="p-8 text-foreground font-[--font-barlow-semicondensed-regular] prose prose-invert max-w-none">
31 <Helmet> 29 <Helmet>
32 <title>LPHUB | Rules</title> 30 <title>LPHUB | Rules</title>
33 </Helmet> 31 </Helmet>
diff --git a/frontend/src/pages/User.tsx b/frontend/src/pages/User.tsx
index 0198034..4b8a456 100644
--- a/frontend/src/pages/User.tsx
+++ b/frontend/src/pages/User.tsx
@@ -19,7 +19,6 @@ import { Game, GameChapters } from "@customTypes/Game";
19import { Map } from "@customTypes/Map"; 19import { Map } from "@customTypes/Map";
20import { API } from "@api/Api"; 20import { API } from "@api/Api";
21import { ticks_to_time } from "@utils/Time"; 21import { ticks_to_time } from "@utils/Time";
22import "@css/Profile.css";
23import useMessage from "@hooks/UseMessage"; 22import useMessage from "@hooks/UseMessage";
24 23
25interface UserProps { 24interface UserProps {