aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/components/Leaderboards.tsx289
1 files changed, 203 insertions, 86 deletions
diff --git a/frontend/src/components/Leaderboards.tsx b/frontend/src/components/Leaderboards.tsx
index fb614fa..05f01d0 100644
--- a/frontend/src/components/Leaderboards.tsx
+++ b/frontend/src/components/Leaderboards.tsx
@@ -1,15 +1,15 @@
1import React from 'react'; 1import React from "react";
2import { Link, useNavigate } from 'react-router-dom'; 2import { Link, useNavigate } from "react-router-dom";
3 3
4import { DownloadIcon, ThreedotIcon } from '@images/Images'; 4import { DownloadIcon, ThreedotIcon } from "@images/Images";
5import { MapLeaderboard } from '@customTypes/Map'; 5import { MapLeaderboard } from "@customTypes/Map";
6import { ticks_to_time, time_ago } from '@utils/Time'; 6import { ticks_to_time, time_ago } from "@utils/Time";
7import { API } from "@api/Api"; 7import { API } from "@api/Api";
8import useMessage from "@hooks/UseMessage"; 8import useMessage from "@hooks/UseMessage";
9import "@css/Maps.css" 9import "@css/Maps.css";
10 10
11interface LeaderboardsProps { 11interface LeaderboardsProps {
12 mapID: string; 12 mapID: string;
13} 13}
14 14
15const Leaderboards: React.FC<LeaderboardsProps> = ({ mapID }) => { 15const Leaderboards: React.FC<LeaderboardsProps> = ({ mapID }) => {
@@ -18,108 +18,225 @@ const Leaderboards: React.FC<LeaderboardsProps> = ({ mapID }) => {
18 const [pageNumber, setPageNumber] = React.useState<number>(1); 18 const [pageNumber, setPageNumber] = React.useState<number>(1);
19 19
20 const _fetch_map_leaderboards = async () => { 20 const _fetch_map_leaderboards = async () => {
21 const mapLeaderboards = await API.get_map_leaderboard(mapID, pageNumber.toString()); 21 const mapLeaderboards = await API.get_map_leaderboard(
22 mapID,
23 pageNumber.toString()
24 );
22 setData(mapLeaderboards); 25 setData(mapLeaderboards);
23 }; 26 };
24 27
25 const { message, MessageDialogComponent } = useMessage(); 28 const { message, MessageDialogComponent } = useMessage();
26 29
27 React.useEffect(() => { 30 React.useEffect(() => {
28 _fetch_map_leaderboards(); 31 _fetch_map_leaderboards();
29 console.log(data); 32 console.log(data);
30 }, [pageNumber, navigate]) 33 }, [pageNumber, navigate, _fetch_map_leaderboards, data]);
31 34
32 if (!data) { 35 if (!data) {
33 return ( 36 return (
34 <section id='section6' className='summary2'> 37 <section id="section6" className="summary2">
35 <h1 style={{ textAlign: "center" }}>Map is not available for competitive boards.</h1> 38 <h1 style={{ textAlign: "center" }}>
39 Map is not available for competitive boards.
40 </h1>
36 </section> 41 </section>
37 ); 42 );
38 }; 43 }
39 44
40 if (data.records.length === 0) { 45 if (data.records.length === 0) {
41 return ( 46 return (
42 <section id='section6' className='summary2'> 47 <section id="section6" className="summary2">
43 <h1 style={{ textAlign: "center" }}>No records found.</h1> 48 <h1 style={{ textAlign: "center" }}>No records found.</h1>
44 </section> 49 </section>
45 ); 50 );
46 }; 51 }
47 52
48 return ( 53 return (
49 <div> 54 <div>
50 {MessageDialogComponent} 55 {MessageDialogComponent}
51 <section id='section6' className='summary2'> 56 <section id="section6" className="summary2">
52 57 <div
53 <div id='leaderboard-top' 58 id="leaderboard-top"
54 style={data.map.is_coop ? { gridTemplateColumns: "7.5% 40% 7.5% 15% 15% 15%" } : { gridTemplateColumns: "7.5% 30% 10% 20% 17.5% 15%" }} 59 style={
55 > 60 data.map.is_coop
56 <span>Place</span> 61 ? { gridTemplateColumns: "7.5% 40% 7.5% 15% 15% 15%" }
57 62 : { gridTemplateColumns: "7.5% 30% 10% 20% 17.5% 15%" }
58 {data.map.is_coop ? ( 63 }
59 <div id='runner'> 64 >
60 <span>Blue</span> 65 <span>Place</span>
61 <span>Orange</span> 66
62 </div> 67 {data.map.is_coop ? (
63 ) : ( 68 <div id="runner">
64 <span>Runner</span> 69 <span>Blue</span>
65 )} 70 <span>Orange</span>
66 71 </div>
67 <span>Portals</span> 72 ) : (
68 <span>Time</span> 73 <span>Runner</span>
69 <span>Date</span> 74 )}
70 <div id='page-number'> 75
71 <div> 76 <span>Portals</span>
72 77 <span>Time</span>
73 <button onClick={() => pageNumber === 1 ? null : setPageNumber(prevPageNumber => prevPageNumber - 1)} 78 <span>Date</span>
74 ><i className='triangle' style={{ position: 'relative', left: '-5px', }}></i> </button> 79 <div id="page-number">
75 <span>{data.pagination.current_page}/{data.pagination.total_pages}</span> 80 <div>
76 <button onClick={() => pageNumber === data.pagination.total_pages ? null : setPageNumber(prevPageNumber => prevPageNumber + 1)} 81 <button
77 ><i className='triangle' style={{ position: 'relative', left: '5px', transform: 'rotate(180deg)' }}></i> </button> 82 onClick={() =>
83 pageNumber === 1
84 ? null
85 : setPageNumber((prevPageNumber) => prevPageNumber - 1)
86 }
87 >
88 <i
89 className="triangle"
90 style={{ position: "relative", left: "-5px" }}
91 ></i>{" "}
92 </button>
93 <span>
94 {data.pagination.current_page}/{data.pagination.total_pages}
95 </span>
96 <button
97 onClick={() =>
98 pageNumber === data.pagination.total_pages
99 ? null
100 : setPageNumber((prevPageNumber) => prevPageNumber + 1)
101 }
102 >
103 <i
104 className="triangle"
105 style={{
106 position: "relative",
107 left: "5px",
108 transform: "rotate(180deg)",
109 }}
110 ></i>{" "}
111 </button>
112 </div>
78 </div> 113 </div>
79 </div> 114 </div>
80 </div> 115 <hr />
81 <hr /> 116 <div id="leaderboard-records">
82 <div id='leaderboard-records'> 117 {data.records.map((r, index) => (
83 {data.records.map((r, index) => ( 118 <span
84 <span className='leaderboard-record' key={index} 119 className="leaderboard-record"
85 style={data.map.is_coop ? { gridTemplateColumns: "3% 4.5% 40% 4% 3.5% 15% 15% 14.5%" } : { gridTemplateColumns: "3% 4.5% 30% 4% 6% 20% 17% 15%" }} 120 key={index}
86 > 121 style={
87 <span>{r.placement}</span> 122 data.map.is_coop
88 <span> </span> 123 ? { gridTemplateColumns: "3% 4.5% 40% 4% 3.5% 15% 15% 14.5%" }
89 {r.kind === "multiplayer" ? ( 124 : { gridTemplateColumns: "3% 4.5% 30% 4% 6% 20% 17% 15%" }
90 <div> 125 }
91 <Link to={`/users/${r.host.steam_id}`}><span><img src={r.host.avatar_link} alt='' /> &nbsp; {r.host.user_name}</span></Link> 126 >
92 <Link to={`/users/${r.partner.steam_id}`}><span><img src={r.partner.avatar_link} alt='' /> &nbsp; {r.partner.user_name}</span></Link> 127 <span>{r.placement}</span>
93 </div> 128 <span> </span>
94 ) : r.kind === "singleplayer" && ( 129 {r.kind === "multiplayer" ? (
95 <div> 130 <div>
96 <Link to={`/users/${r.user.steam_id}`}><span><img src={r.user.avatar_link} alt='' /> &nbsp; {r.user.user_name}</span></Link> 131 <Link to={`/users/${r.host.steam_id}`}>
97 </div> 132 <span>
98 )} 133 <img src={r.host.avatar_link} alt="" /> &nbsp;{" "}
99 134 {r.host.user_name}
100 <span>{r.score_count}</span> 135 </span>
101 <span> </span> 136 </Link>
102 <span className='hover-popup' popup-text={(r.score_time) + " ticks"}>{ticks_to_time(r.score_time)}</span> 137 <Link to={`/users/${r.partner.steam_id}`}>
103 <span className='hover-popup' popup-text={r.record_date.replace("T", ' ').split(".")[0]}>{time_ago(new Date(r.record_date.replace("T", " ").replace("Z", "")))}</span> 138 <span>
104 139 <img src={r.partner.avatar_link} alt="" /> &nbsp;{" "}
105 {r.kind === "multiplayer" ? ( 140 {r.partner.user_name}
106 <span> 141 </span>
107 <button onClick={() => { message("Demo Information", `Host Demo ID: ${r.host_demo_id} \nParnter Demo ID: ${r.partner_demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button> 142 </Link>
108 <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.partner_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(160deg) contrast(60%) saturate(1000%)" }} /></button> 143 </div>
109 <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.host_demo_id}`}><img src={DownloadIcon} alt="download" style={{ filter: "hue-rotate(300deg) contrast(60%) saturate(1000%)" }} /></button> 144 ) : (
145 r.kind === "singleplayer" && (
146 <div>
147 <Link to={`/users/${r.user.steam_id}`}>
148 <span>
149 <img src={r.user.avatar_link} alt="" /> &nbsp;{" "}
150 {r.user.user_name}
151 </span>
152 </Link>
153 </div>
154 )
155 )}
156
157 <span>{r.score_count}</span>
158 <span> </span>
159 <span
160 className="hover-popup"
161 popup-text={r.score_time + " ticks"}
162 >
163 {ticks_to_time(r.score_time)}
110 </span> 164 </span>
111 ) : r.kind === "singleplayer" && ( 165 <span
112 166 className="hover-popup"
113 <span> 167 popup-text={r.record_date.replace("T", " ").split(".")[0]}
114 <button onClick={() => { message("Demo Information", `Demo ID: ${r.demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button> 168 >
115 <button onClick={() => window.location.href = `/api/v1/demos?uuid=${r.demo_id}`}><img src={DownloadIcon} alt="download" /></button> 169 {time_ago(
170 new Date(r.record_date.replace("T", " ").replace("Z", ""))
171 )}
116 </span> 172 </span>
117 )} 173
118 </span> 174 {r.kind === "multiplayer" ? (
119 ))} 175 <span>
120 </div> 176 <button
121 </section> 177 onClick={() => {
122 </div> 178 message(
179 "Demo Information",
180 `Host Demo ID: ${r.host_demo_id} \nParnter Demo ID: ${r.partner_demo_id}`
181 );
182 }}
183 >
184 <img src={ThreedotIcon} alt="demo_id" />
185 </button>
186 <button
187 onClick={() =>
188 (window.location.href = `/api/v1/demos?uuid=${r.partner_demo_id}`)
189 }
190 >
191 <img
192 src={DownloadIcon}
193 alt="download"
194 style={{
195 filter:
196 "hue-rotate(160deg) contrast(60%) saturate(1000%)",
197 }}
198 />
199 </button>
200 <button
201 onClick={() =>
202 (window.location.href = `/api/v1/demos?uuid=${r.host_demo_id}`)
203 }
204 >
205 <img
206 src={DownloadIcon}
207 alt="download"
208 style={{
209 filter:
210 "hue-rotate(300deg) contrast(60%) saturate(1000%)",
211 }}
212 />
213 </button>
214 </span>
215 ) : (
216 r.kind === "singleplayer" && (
217 <span>
218 <button
219 onClick={() => {
220 message("Demo Information", `Demo ID: ${r.demo_id}`);
221 }}
222 >
223 <img src={ThreedotIcon} alt="demo_id" />
224 </button>
225 <button
226 onClick={() =>
227 (window.location.href = `/api/v1/demos?uuid=${r.demo_id}`)
228 }
229 >
230 <img src={DownloadIcon} alt="download" />
231 </button>
232 </span>
233 )
234 )}
235 </span>
236 ))}
237 </div>
238 </section>
239 </div>
123 ); 240 );
124}; 241};
125 242