aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/components/pages/maplist.js
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/pages/maplist.js')
-rw-r--r--frontend/src/components/pages/maplist.js844
1 files changed, 844 insertions, 0 deletions
diff --git a/frontend/src/components/pages/maplist.js b/frontend/src/components/pages/maplist.js
new file mode 100644
index 0000000..dca76d6
--- /dev/null
+++ b/frontend/src/components/pages/maplist.js
@@ -0,0 +1,844 @@
1import React, { useEffect, useRef, useState } from 'react';
2import { useLocation, Link } from "react-router-dom";
3import { BrowserRouter as Router, Route, Routes, useNavigate } from 'react-router-dom';
4
5import "./maplist.css"
6import img5 from "../../imgs/5.png"
7import img6 from "../../imgs/6.png"
8
9export default function Maplist(prop) {
10 const {token,setToken} = prop
11 const scrollRef = useRef(null)
12 const [games, setGames] = React.useState(null);
13 const location = useLocation();
14
15 let gameTitle;
16 let minPage;
17 let maxPage;
18 let currentPage;
19 let add = 0;
20 let gameState;
21 let catState = 0;
22 async function detectGame() {
23 const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
24 headers: {
25 'Authorization': token
26 }
27 });
28
29 const data = await response.json();
30
31 const url = new URL(window.location.href)
32
33 const params = new URLSearchParams(url.search)
34 gameState = parseFloat(params.get("game"))
35
36 document.querySelector("#catPortalCount").innerText = data.data[gameState - 1].category_portals[0].portal_count;
37
38 if (gameState == 1){
39 gameTitle = data.data[0].name;
40
41 maxPage = 9;
42 minPage = 1;
43 createCategories(1);
44 } else if (gameState == 2){
45 gameTitle = data.data[1].name;
46
47 maxPage = 16;
48 minPage = 10;
49 add = 10
50 createCategories(2);
51 }
52
53 let chapterParam = params.get("chapter")
54
55 currentPage = minPage;
56
57 if (chapterParam) {
58 currentPage = +chapterParam + add
59 }
60
61 changePage(currentPage);
62
63 // if (chapterParam) {
64 // document.querySelector("#pageNumbers").innerText = `${chapterParam - minPage + 1}/${maxPage - minPage + 1}`
65 // }
66 }
67
68 function changeMaplistOrStatistics(index, name) {
69 const maplistBtns = document.querySelectorAll("#maplistBtn");
70 maplistBtns.forEach((btn, i) => {
71 if (i == index) {
72 btn.className = "game-nav-btn selected"
73
74 if (name == "maplist") {
75 document.querySelector(".stats").style.display = "none";
76 document.querySelector(".maplist").style.display = "block";
77 document.querySelector(".maplist").setAttribute("currentTab", "maplist");
78 } else {
79 document.querySelector(".stats").style.display = "block";
80 document.querySelector(".maplist").style.display = "none";
81
82 document.querySelector(".maplist-page").scrollTo({ top: 372, behavior: "smooth" })
83 document.querySelector(".maplist").setAttribute("currentTab", "stats");
84 }
85 } else {
86 btn.className = "game-nav-btn";
87 }
88 });
89 }
90
91 async function createCategories(gameID) {
92 const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
93 headers: {
94 'Authorization': token
95 }
96 });
97
98 const data = await response.json();
99 let categoriesArr = data.data[gameID - 1].category_portals;
100
101 const gameNav = document.querySelector(".game-nav");
102 gameNav.innerHTML = "";
103 categoriesArr.forEach((category) => {
104 createCategory(category);
105 });
106 }
107
108 let categoryNum = 0;
109 function createCategory(category) {
110 const gameNav = document.querySelector(".game-nav");
111
112 categoryNum++;
113 const gameNavBtn = document.createElement("button");
114 if (categoryNum == 1) {
115 gameNavBtn.className = "game-nav-btn selected";
116 } else {
117 gameNavBtn.className = "game-nav-btn";
118 }
119 gameNavBtn.id = "catBtn"
120 gameNavBtn.innerText = category.category.name;
121
122 gameNavBtn.addEventListener("click", (e) => {
123 changeCategory(category, e);
124 changePage(currentPage);
125 })
126
127 gameNav.appendChild(gameNavBtn);
128 }
129
130 async function changeCategory(category, btn) {
131 const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
132 headers: {
133 'Authorization': token
134 }
135 });
136
137 const data = await response.json();
138 catState = category.category.id - 1;
139 console.log(catState)
140 const navBtns = document.querySelectorAll("#catBtn");
141 navBtns.forEach((btns) => {
142 btns.classList.remove("selected");
143 });
144
145 btn.srcElement.classList.add("selected");
146 document.querySelector("#catPortalCount").innerText = category.portal_count;
147 }
148
149 async function changePage(page) {
150
151 const pageNumbers = document.querySelector("#pageNumbers");
152
153 pageNumbers.innerText = `${currentPage - minPage + 1}/${maxPage - minPage + 1}`;
154
155 const maplistMaps = document.querySelector(".maplist-maps");
156 maplistMaps.innerHTML = "";
157 for (let index = 0; index < 8; index++) {
158 const loadingAnimation = document.createElement("div");
159 loadingAnimation.classList.add("loader");
160 loadingAnimation.classList.add("loader-map")
161 maplistMaps.appendChild(loadingAnimation);
162 }
163 const data = await fetchMaps(page);
164 const maps = data.data.maps;
165 const name = data.data.chapter.name;
166
167 let chapterName = "Chapter";
168 const chapterNumberOld = name.split(" - ")[0];
169 let chapterNumber1 = chapterNumberOld.split("Chapter ")[1];
170 if (chapterNumber1 == undefined) {
171 chapterName = "Course"
172 chapterNumber1 = chapterNumberOld.split("Course ")[1];
173 }
174 const chapterNumber = chapterNumber1.toString().padStart(2, "0");
175 const chapterTitle = name.split(" - ")[1];
176
177 const chapterNumberElement = document.querySelector(".chapter-num")
178 const chapterTitleElement = document.querySelector(".chapter-name")
179 chapterNumberElement.innerText = chapterName + " " + chapterNumber;
180 chapterTitleElement.innerText = chapterTitle;
181
182 maplistMaps.innerHTML = "";
183 maps.forEach(map => {
184 let portalCount;
185 if (map.category_portals[catState] != undefined) {
186 portalCount = map.category_portals[catState].portal_count;
187 } else {
188 portalCount = map.category_portals[0].portal_count;
189 }
190 addMap(map.name, portalCount, map.image, map.difficulty + 1, map.id);
191 });
192
193 const gameTitleElement = document.querySelector("#gameTitle");
194 gameTitleElement.innerText = gameTitle;
195
196 const url = new URL(window.location.href)
197
198 const params = new URLSearchParams(url.search)
199
200 let chapterParam = params.get("chapter")
201
202 try {
203 const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
204 headers: {
205 'Authorization': token
206 }
207 });
208
209 const data = await response.json();
210
211 const gameImg = document.querySelector(".game-img");
212
213 gameImg.style.backgroundImage = `url(${data.data[0].image})`;
214
215 // const mapImg = document.querySelectorAll(".maplist-img");
216 // mapImg.forEach((map) => {
217 // map.style.backgroundImage = `url(${data.data[0].image})`;
218 // });
219
220 } catch (error) {
221 console.log("error fetching games:", error);
222 }
223
224 asignDifficulties();
225 }
226
227 async function addMap(mapName, mapPortalCount, mapImage, difficulty, mapID) {
228 // jesus christ
229 const maplistItem = document.createElement("div");
230 const maplistTitle = document.createElement("span");
231 const maplistImgDiv = document.createElement("div");
232 const maplistImg = document.createElement("div");
233 const maplistPortalcountDiv = document.createElement("div");
234 const maplistPortalcount = document.createElement("span");
235 const b = document.createElement("b");
236 const maplistPortalcountPortals = document.createElement("span");
237 const difficultyDiv = document.createElement("div");
238 const difficultyLabel = document.createElement("span");
239 const difficultyBar = document.createElement("div");
240 const difficultyPoint1 = document.createElement("div");
241 const difficultyPoint2 = document.createElement("div");
242 const difficultyPoint3 = document.createElement("div");
243 const difficultyPoint4 = document.createElement("div");
244 const difficultyPoint5 = document.createElement("div");
245
246 maplistItem.className = "maplist-item";
247 maplistTitle.className = "maplist-title";
248 maplistImgDiv.className = "maplist-img-div";
249 maplistImg.className = "maplist-img";
250 maplistPortalcountDiv.className = "maplist-portalcount-div";
251 maplistPortalcount.className = "maplist-portalcount";
252 maplistPortalcountPortals.className = "maplist-portals";
253 difficultyDiv.className = "difficulty-div";
254 difficultyLabel.className = "difficulty-label";
255 difficultyBar.className = "difficulty-bar";
256 difficultyPoint1.className = "difficulty-point";
257 difficultyPoint2.className = "difficulty-point";
258 difficultyPoint3.className = "difficulty-point";
259 difficultyPoint4.className = "difficulty-point";
260 difficultyPoint5.className = "difficulty-point";
261
262
263 maplistTitle.innerText = mapName;
264 difficultyLabel.innerText = "Difficulty: "
265 maplistPortalcountPortals.innerText = "portals"
266 b.innerText = mapPortalCount;
267 maplistImg.style.backgroundImage = `url(${mapImage})`;
268 difficultyBar.setAttribute("difficulty", difficulty)
269 maplistItem.setAttribute("id", mapID)
270 maplistItem.addEventListener("click", () => {
271 console.log(mapID)
272 window.location.href = "/maps/" + mapID
273 })
274
275 // appends
276 // maplist item
277 maplistItem.appendChild(maplistTitle);
278 maplistImgDiv.appendChild(maplistImg);
279 maplistImgDiv.appendChild(maplistPortalcountDiv);
280 maplistPortalcountDiv.appendChild(maplistPortalcount);
281 maplistPortalcount.appendChild(b);
282 maplistPortalcountDiv.appendChild(maplistPortalcountPortals);
283 maplistItem.appendChild(maplistImgDiv);
284 maplistItem.appendChild(difficultyDiv);
285 difficultyDiv.appendChild(difficultyLabel);
286 difficultyDiv.appendChild(difficultyBar);
287 difficultyBar.appendChild(difficultyPoint1);
288 difficultyBar.appendChild(difficultyPoint2);
289 difficultyBar.appendChild(difficultyPoint3);
290 difficultyBar.appendChild(difficultyPoint4);
291 difficultyBar.appendChild(difficultyPoint5);
292
293 // display in place
294 const maplistMaps = document.querySelector(".maplist-maps");
295 maplistMaps.appendChild(maplistItem);
296 }
297
298 async function fetchMaps(chapterID) {
299 try{
300 const response = await fetch(`https://lp.ardapektezol.com/api/v1/chapters/${chapterID}`, {
301 headers: {
302 'Authorization': token
303 }
304 });
305
306 const data = await response.json();
307 return data;
308 } catch (err) {
309 console.log(err)
310 }
311 }
312
313 // difficulty stuff
314 function asignDifficulties() {
315 const difficulties = document.querySelectorAll(".difficulty-bar");
316 difficulties.forEach((difficultyElement) => {
317 let difficulty = difficultyElement.getAttribute("difficulty");
318 if (difficulty == "1") {
319 difficultyElement.childNodes[0].style.backgroundColor = "#51C355";
320 } else if (difficulty == "2") {
321 difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A";
322 difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A";
323 } else if (difficulty == "3") {
324 difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A";
325 difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A";
326 difficultyElement.childNodes[2].style.backgroundColor = "#8AC93A";
327 } else if (difficulty == "4") {
328 difficultyElement.childNodes[0].style.backgroundColor = "#C35F51";
329 difficultyElement.childNodes[1].style.backgroundColor = "#C35F51";
330 difficultyElement.childNodes[2].style.backgroundColor = "#C35F51";
331 difficultyElement.childNodes[3].style.backgroundColor = "#C35F51";
332 } else if (difficulty == "5") {
333 difficultyElement.childNodes[0].style.backgroundColor = "#C35F51";
334 difficultyElement.childNodes[1].style.backgroundColor = "#C35F51";
335 difficultyElement.childNodes[2].style.backgroundColor = "#C35F51";
336 difficultyElement.childNodes[3].style.backgroundColor = "#C35F51";
337 difficultyElement.childNodes[4].style.backgroundColor = "#C35F51";
338 }
339 });
340 }
341
342 const divRef = useRef(null);
343
344 React.useEffect(() => {
345
346 const lineChart = document.querySelector(".line-chart")
347 function createGraph() {
348 // max
349 let items = [
350 {
351 record: "100",
352 date: new Date(2011, 4, 4),
353 map: "Container Ride",
354 first: "tiny zach"
355 },
356 {
357 record: "98",
358 date: new Date(2012, 6, 4),
359 map: "Container Ride",
360 first: "tiny zach"
361 },
362 {
363 record: "94",
364 date: new Date(2013, 0, 1),
365 map: "Container Ride",
366 first: "tiny zach"
367 },
368 {
369 record: "90",
370 date: new Date(2014, 0, 1),
371 map: "Container Ride",
372 first: "tiny zach"
373 },
374 {
375 record: "88",
376 date: new Date(2015, 6, 14),
377 map: "Container Ride",
378 first: "tiny zach"
379 },
380 {
381 record: "84",
382 date: new Date(2016, 8, 19),
383 map: "Container Ride",
384 first: "tiny zach"
385 },
386 {
387 record: "82",
388 date: new Date(2017, 3, 20),
389 map: "Container Ride",
390 first: "tiny zach"
391 },
392 {
393 record: "81",
394 date: new Date(2018, 2, 25),
395 map: "Container Ride",
396 first: "tiny zach"
397 },
398 {
399 record: "80",
400 date: new Date(2019, 3, 4),
401 map: "Container Ride",
402 first: "tiny zach"
403 },
404 {
405 record: "78",
406 date: new Date(2020, 11, 21),
407 map: "Container Ride",
408 first: "tiny zach"
409 },
410 {
411 record: "77",
412 date: new Date(2021, 10, 25),
413 map: "Container Ride",
414 first: "tiny zach"
415 },
416 {
417 record: "76",
418 date: new Date(2022, 4, 17),
419 map: "Container Ride",
420 first: "tiny zach"
421 },
422 {
423 record: "75",
424 date: new Date(2023, 9, 31),
425 map: "Container Ride",
426 first: "tiny zach"
427 },
428 {
429 record: "74",
430 date: new Date(2024, 4, 4),
431 map: "Container Ride",
432 first: "tiny zach"
433 },
434 ]
435
436 function calculatePosition(date, startDate, endDate, maxWidth) {
437 const totalMilliseconds = endDate - startDate + 10000000000;
438 const millisecondsFromStart = date - startDate + 5000000000;
439 return (millisecondsFromStart / totalMilliseconds) * maxWidth
440 }
441
442 const minDate = items.reduce((min, dp) => dp.date < min ? dp.date : min, items[0].date)
443 const maxDate = items.reduce((max, dp) => dp.date > max ? dp.date : max, items[0].date)
444
445 const graph_width = document.querySelector(".portalcount-over-time-div").clientWidth
446 // console.log(graph_width)
447
448 const uniqueYears = new Set()
449 items.forEach(dp => uniqueYears.add(dp.date.getFullYear()))
450 let minYear = Infinity;
451 let maxYear = -Infinity;
452
453 items.forEach(dp => {
454 const year = dp.date.getFullYear();
455 minYear = Math.min(minYear, year);
456 maxYear = Math.max(maxYear, year);
457 });
458
459 // Add missing years to the set
460 for (let year = minYear; year <= maxYear; year++) {
461 uniqueYears.add(year);
462 }
463 const uniqueYearsArr = Array.from(uniqueYears)
464
465 items = items.map(dp => ({
466 record: dp.record,
467 date: dp.date,
468 x: calculatePosition(dp.date, minDate, maxDate, lineChart.clientWidth),
469 map: dp.map,
470 first: dp.first
471 }))
472
473 const yearInterval = lineChart.clientWidth / uniqueYears.size
474 for (let index = 1; index < (uniqueYears.size); index++) {
475 const placeholderlmao = document.createElement("div")
476 const yearSpan = document.createElement("span")
477 yearSpan.style.position = "absolute"
478 placeholderlmao.style.height = "100%"
479 placeholderlmao.style.width = "2px"
480 placeholderlmao.style.backgroundColor = "#00000080"
481 placeholderlmao.style.position = `absolute`
482 const thing = calculatePosition(new Date(uniqueYearsArr[index], 0, 0), minDate, maxDate, lineChart.clientWidth)
483 placeholderlmao.style.left = `${thing}px`
484 yearSpan.style.left = `${thing}px`
485 yearSpan.style.bottom = "-34px"
486 yearSpan.innerText = uniqueYearsArr[index]
487 yearSpan.style.fontFamily = "BarlowSemiCondensed-Regular"
488 yearSpan.style.fontSize = "22px"
489 yearSpan.style.opacity = "0.8"
490 lineChart.appendChild(yearSpan)
491
492 }
493
494 let maxPortals;
495 let minPortals;
496 let precision;
497 let multiplier = 1;
498 for (let index = 0; index < items.length; index++) {
499 precision = Math.floor((items[0].record - items[items.length - 1].record))
500 if (precision > 20) {
501 precision = 20
502 }
503 minPortals = Math.floor((items[items.length - 1].record) / 10) * 10
504 if (index == 0) {
505 maxPortals = items[index].record - minPortals
506 }
507 }
508 function calculateMultiplier(value) {
509 while (value > precision) {
510 multiplier += 1;
511 value -= precision;
512 }
513 }
514 calculateMultiplier(items[0].record);
515 // if (items[0].record > 10) {
516 // multiplier = 2;
517 // }
518
519 // Original cubic bezier control points
520 const P0 = { x: 0, y: 0 };
521 const P1 = { x: 0.26, y: 1 };
522 const P2 = { x: 0.74, y: 1 };
523 const P3 = { x: 1, y: 0 };
524
525 function calculateIntermediateControlPoints(t, P0, P1, P2, P3) {
526 const x = (1 - t) ** 3 * P0.x +
527 3 * (1 - t) ** 2 * t * P1.x +
528 3 * (1 - t) * t ** 2 * P2.x +
529 t ** 3 * P3.x;
530
531 const y = (1 - t) ** 3 * P0.y +
532 3 * (1 - t) ** 2 * t * P1.y +
533 3 * (1 - t) * t ** 2 * P2.y +
534 t ** 3 * P3.y;
535
536 return { x, y };
537 }
538
539
540 let delay = 0;
541 for (let index = 0; index < items.length; index++) {
542 let chart_height = 340;
543 const item = items[index];
544 delay += 0.05;
545 // console.log(lineChart.clientWidth)
546
547 // maxPortals++;
548 // maxPortals++;
549
550 let point_height = (chart_height / maxPortals)
551
552 for (let index = 0; index < (maxPortals / multiplier); index++) {
553 // console.log((index + 1) * multiplier)
554 let current_portal_count = (index + 1);
555
556 const placeholderDiv = document.createElement("div")
557 const numPortalsText = document.createElement("span")
558 const numPortalsTextBottom = document.createElement("span")
559 numPortalsText.innerText = (current_portal_count * multiplier) + minPortals
560 numPortalsTextBottom.innerText = minPortals
561 placeholderDiv.style.position = "absolute"
562 numPortalsText.style.position = "absolute"
563 numPortalsTextBottom.style.position = "absolute"
564 numPortalsText.style.left = "-37px"
565 numPortalsText.style.opacity = "0.2"
566 numPortalsTextBottom.style.opacity = "0.2"
567 numPortalsText.style.fontFamily = "BarlowSemiCondensed-Regular"
568 numPortalsTextBottom.style.fontFamily = "BarlowSemiCondensed-Regular"
569 numPortalsText.style.fontSize = "22px"
570 numPortalsTextBottom.style.left = "-37px"
571 numPortalsTextBottom.style.fontSize = "22px"
572 numPortalsTextBottom.style.fontWeight = "400"
573 numPortalsText.style.color = "#CDCFDF"
574 numPortalsTextBottom.style.color = "#CDCFDF"
575 numPortalsText.style.fontFamily = "inherit"
576 numPortalsTextBottom.style.fontFamily = "inherit"
577 numPortalsText.style.textAlign = "right"
578 numPortalsTextBottom.style.textAlign = "right"
579 numPortalsText.style.width = "30px"
580 numPortalsTextBottom.style.width = "30px"
581 placeholderDiv.style.bottom = `${(point_height * current_portal_count * multiplier) - 2}px`
582 numPortalsText.style.bottom = `${(point_height * current_portal_count * multiplier) - 2 - 9}px`
583 numPortalsTextBottom.style.bottom = `${0 - 2 - 8}px`
584 placeholderDiv.id = placeholderDiv.style.bottom
585 placeholderDiv.style.width = "100%"
586 placeholderDiv.style.height = "2px"
587 placeholderDiv.style.backgroundColor = "#2B2E46"
588 placeholderDiv.style.zIndex = "0"
589
590 if (index == 0) {
591 lineChart.appendChild(numPortalsTextBottom)
592 }
593 lineChart.appendChild(numPortalsText)
594 lineChart.appendChild(placeholderDiv)
595 }
596
597 const li = document.createElement("li");
598 const lineSeg = document.createElement("div");
599 const dataPoint = document.createElement("div");
600
601 li.style = `--y: ${point_height * (item.record - minPortals) - 3}px; --x: ${item.x}px`;
602 lineSeg.className = "line-segment";
603 dataPoint.className = "data-point";
604
605 if (items[index + 1] !== undefined) {
606 const hypotenuse = Math.sqrt(
607 Math.pow(items[index + 1].x - items[index].x, 2) +
608 Math.pow((point_height * items[index + 1].record) - point_height * item.record, 2)
609 );
610 const angle = Math.asin(
611 ((point_height * item.record) - (point_height * items[index + 1].record)) / hypotenuse
612 );
613
614 lineSeg.style = `--hypotenuse: ${hypotenuse}; --angle: ${angle * (-180 / Math.PI)}`;
615 const t0 = index / items.length;
616 const t1 = (index + 1) / items.length
617
618 const P0t0 = calculateIntermediateControlPoints(t0, P0, P1, P2, P3);
619 const P1t1 = calculateIntermediateControlPoints(t1, P0, P1, P2, P3);
620 const bezierStyle = `cubic-bezier(${P0t0.x.toFixed(3)}, ${P0t0.y.toFixed(3)}, ${P1t1.x.toFixed(3)}, ${P1t1.y.toFixed(3)})`
621 lineSeg.style.animationTimingFunction = bezierStyle
622 lineSeg.style.animationDelay = delay + "s"
623 }
624 dataPoint.style.animationDelay = delay + "s"
625
626 let isHoveringOverData = false;
627 let isDataActive = false;
628 document.querySelector("#dataPointInfo").style.left = item.x + "px";
629 document.querySelector("#dataPointInfo").style.bottom = (point_height * item.record -3) + "px";
630 dataPoint.addEventListener("mouseenter", (e) => {
631 isDataActive = true;
632 isHoveringOverData = true;
633 const dataPoints = document.querySelectorAll(".data-point")
634 dataPoints.forEach(point => {
635 point.classList.remove("data-point-active")
636 });
637 dataPoint.classList.add("data-point-active")
638 document.querySelector("#dataPointRecord").innerText = item.record;
639 document.querySelector("#dataPointMap").innerText = item.map;
640 document.querySelector("#dataPointDate").innerText = item.date.toLocaleDateString("en-GB");
641 document.querySelector("#dataPointFirst").innerText = item.first;
642 if ((lineChart.clientWidth - 400) < item.x) {
643 document.querySelector("#dataPointInfo").style.left = item.x - 400 + "px";
644 } else {
645 document.querySelector("#dataPointInfo").style.left = item.x + "px";
646 }
647 if ((lineChart.clientHeight - 115) < (point_height * (item.record - minPortals) -3)) {
648 document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) -3) - 115 + "px";
649 } else {
650 document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) -3) + "px";
651 }
652 document.querySelector("#dataPointInfo").style.opacity = "1";
653 document.querySelector("#dataPointInfo").style.zIndex = "10";
654 });
655 document.querySelector("#dataPointInfo").addEventListener("mouseenter", (e) => {
656 isHoveringOverData = true;
657 })
658 document.querySelector("#dataPointInfo").addEventListener("mouseleave", (e) => {
659 isHoveringOverData = false;
660 })
661 document.addEventListener("mousedown", () => {
662 if (!isHoveringOverData) {
663 isDataActive = false
664 dataPoint.classList.remove("data-point-active")
665 document.querySelector("#dataPointInfo").style.opacity = "0";
666 document.querySelector("#dataPointInfo").style.zIndex = "0";
667 }
668 })
669 dataPoint.addEventListener("mouseenter", (e) => {
670 isHoveringOverData = false;
671 })
672 document.querySelector(".chart").addEventListener("mouseleave", () => {
673 isDataActive = false
674 dataPoint.classList.remove("data-point-active")
675 document.querySelector("#dataPointInfo").style.opacity = "0";
676 document.querySelector("#dataPointInfo").style.zIndex = "0";
677 })
678
679 li.appendChild(lineSeg);
680 li.appendChild(dataPoint);
681 lineChart.appendChild(li);
682 }
683 }
684
685 createGraph()
686
687 async function fetchGames() {
688 try {
689 const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
690 headers: {
691 'Authorization': token
692 }
693 });
694
695 const data = await response.json();
696
697 const gameImg = document.querySelector(".game-img");
698
699 gameImg.style.backgroundImage = `url(${data.data[0].image})`;
700
701 // const mapImg = document.querySelectorAll(".maplist-img");
702 // mapImg.forEach((map) => {
703 // map.style.backgroundImage = `url(${data.data[0].image})`;
704 // });
705
706 } catch (error) {
707 console.log("error fetching games:", error);
708 }
709 }
710
711 detectGame();
712
713 const maplistImg = document.querySelector("#maplistImg");
714 maplistImg.src = img5;
715 const statisticsImg = document.querySelector("#statisticsImg");
716 statisticsImg.src = img6;
717
718 fetchGames();
719
720 const handleResize = (entries) => {
721 for (let entry of entries) {
722 lineChart.innerHTML = ""
723 createGraph()
724 if (document.querySelector(".maplist").getAttribute("currentTab") == "stats") {
725 document.querySelector(".stats").style.display = "block"
726 } else {
727 document.querySelector(".stats").style.display = "none"
728 }
729 }
730 };
731
732 const resizeObserver = new ResizeObserver(handleResize);
733
734 // if (scrollRef.current) {
735 // //hi
736 // if (new URLSearchParams(new URL(window.location.href).search).get("chapter")) {
737 // setTimeout(() => {
738 // scrollRef.current.scrollIntoView({ behavior: "smooth", block: "start" })
739 // }, 200);
740 // }
741
742 // }
743
744 if (divRef.current) {
745 resizeObserver.observe(divRef.current);
746 }
747
748 return () => {
749 if (divRef.current) {
750 resizeObserver.unobserve(divRef.current);
751 }
752 resizeObserver.disconnect();
753 };
754
755
756 })
757 return (
758 <div ref={divRef} className='maplist-page'>
759 <div className='maplist-page-content'>
760 <section className='maplist-page-header'>
761 <Link to='/games'><button className='nav-btn'>
762 <i className='triangle'></i>
763 <span>Games list</span>
764 </button></Link>
765 <span><b id='gameTitle'>&nbsp;</b></span>
766 </section>
767
768 <div className='game'>
769 <div className='game-header'>
770 <div className='game-img'></div>
771 <div className='game-header-text'>
772 <span><b id='catPortalCount'>0</b></span>
773 <span>portals</span>
774 </div>
775 </div>
776
777 <div className='game-nav'>
778 </div>
779 </div>
780
781 <div className='gameview-nav'>
782 <button id='maplistBtn' onClick={() => {changeMaplistOrStatistics(0, "maplist")}} className='game-nav-btn selected'>
783 <img id='maplistImg'/>
784 <span>Map List</span>
785 </button>
786 <button id='maplistBtn' onClick={() => changeMaplistOrStatistics(1, "stats")} className='game-nav-btn'>
787 <img id='statisticsImg'/>
788 <span>Statistics</span>
789 </button>
790 </div>
791
792 <div ref={scrollRef} className='maplist'>
793 <div className='chapter'>
794 <span className='chapter-num'>undefined</span><br/>
795 <span className='chapter-name'>undefined</span>
796
797 <div className='chapter-page-div'>
798 <button id='pageChanger' onClick={() => { currentPage--; currentPage < minPage ? currentPage = minPage : changePage(currentPage); }}>
799 <i className='triangle'></i>
800 </button>
801 <span id='pageNumbers'>0/0</span>
802 <button id='pageChanger' onClick={() => { currentPage++; currentPage > maxPage ? currentPage = maxPage : changePage(currentPage); }}>
803 <i style={{ transform: "rotate(180deg)" }} className='triangle'></i>
804 </button>
805 </div>
806
807 <div className='maplist-maps'>
808 </div>
809 </div>
810 </div>
811
812 <div style={{display: "block"}} className='stats'>
813 <div className='portalcount-over-time-div'>
814 <span className='graph-title'>Portal count over time</span><br/>
815
816 <div className='portalcount-graph'>
817 <figure className='chart'>
818 <div style={{display: "block"}}></div>
819 <div id="dataPointInfo">
820 <div className='section-header'>
821 <span className='header-title'>Date</span>
822 <span className='header-title'>Map</span>
823 <span className='header-title'>Record</span>
824 <span className='header-title'>First completion</span>
825 </div>
826 <div className='divider'></div>
827 <div className='section-data'>
828 <span id='dataPointDate'></span>
829 <span id='dataPointMap'></span>
830 <span id='dataPointRecord'></span>
831 <span id='dataPointFirst'>Hello</span>
832 </div>
833 </div>
834 <ul className='line-chart'>
835
836 </ul>
837 </figure>
838 </div>
839 </div>
840 </div>
841 </div>
842 </div>
843 )
844} \ No newline at end of file