')) {
-// return
-// }
-// const title = e.getAttribute("title");
-
-// const titleDiv = document.createElement("div");
-// const titleSpan = document.createElement("span");
-
-// titleDiv.classList.add("homepage-panel-title-div")
-
-// titleSpan.innerText = title
-
-// titleDiv.appendChild(titleSpan)
-// e.insertBefore(titleDiv, e.firstChild)
-// });
-// }
-// try {
-// home();
-// } catch (e) {
-// console.log("error while setting up home page:", e);
-// }
-
-// }, [token]);
-
-const newsList = [
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
- {
- "title": "Portal Saved on Container Ride",
- "short_description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vehicula facilisis quam, non ultrices nisl aliquam at. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas."
- },
-]
-
-return (
-
-
- Home
- {profile ?
-
- Welcome back,
-
- Wolfboy248
-
- : null}
-
-
-
-
- {/* Column 1 */}
- {profile ?
-
-
-
- Overall rank
- {profile.rankings.overall.rank > 0 ? "#" + profile.rankings.overall.rank : "No rank"}
-
-
- Singleplayer
- {profile.rankings.singleplayer.rank > 0 ? "#" + profile.rankings.singleplayer.rank : "No rank"} {profile.rankings.singleplayer.rank > 0 ? "(" + profile.rankings.singleplayer.completion_count + "/" + profile.rankings.singleplayer.completion_total + ")" : ""}
-
-
- Cooperative rank
- {profile.rankings.cooperative.rank > 0 ? "#" + profile.rankings.cooperative.rank : "No rank"} {profile.rankings.cooperative.rank > 0 ? "(" + profile.rankings.cooperative.completion_count + "/" + profile.rankings.cooperative.completion_total + ")" : ""}
-
-
-
- : null}
- {profile ?
-
-
-
-
-
Container Ride
-
Your Record: 4 portals
-
World Record: 2 portals
-
-
-
-
- : null}
-
-
-
- Place
- Runner
- Portals
- Time
- Date
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Column 2 */}
-
-
-
- {newsList.map((newsList, index) => (
-
- ))}
-
-
-
-
-
-
-
-
-)
-}
\ No newline at end of file
diff --git a/frontend/src/components/pages/maplist.css b/frontend/src/components/pages/maplist.css
deleted file mode 100644
index b56aacc..0000000
--- a/frontend/src/components/pages/maplist.css
+++ /dev/null
@@ -1,403 +0,0 @@
-.maplist-page {
- position: relative;
- left: 350px;
- height: 100vh;
- color: #cdcfdf;
- width: calc(100% - 380px);
- font-family: BarlowSemiCondensed-Regular;
- overflow-y: scroll;
- overflow-x: hidden;
- padding-right: 30px;
-}
-
-a {
- color: inherit;
- width: fit-content;
-}
-
-.maplist-page-content {
- position: absolute;
- left: 0px;
- width: calc(100% - 50px);
-}
-
-.maplist-page-header {
- margin-top: 33px;
- display: grid;
- margin-bottom: 10px;
-}
-
-.nav-btn {
- height: 40px;
- background-color: #2b2e46;
- color: inherit;
- font-size: 18px;
- font-family: inherit;
- border: none;
- border-radius: 20px;
- transition: background-color .1s;
- cursor: default;
- width: fit-content;
-}
-
-.nav-btn>span {
- padding: 0 8px 0 8px;
-}
-
-.nav-btn:hover {
- background-color: #202232;
- cursor: pointer;
-}
-
-.game {
- width: 100%;
- height: 192px;
- /* background: #202232; */
- border-radius: 24px;
- overflow: hidden;
-}
-
-.game-header {
- width: 100%;
- height: 144px;
- display: flex;
- justify-content: center;
- align-items: center;
- overflow: hidden;
-}
-
-.game-header-text {
- display: flex;
- justify-content: center;
- align-items: center;
- position: absolute;
-}
-
-.game-img {
- width: 100%;
- height: 100%;
- background-size: cover;
- filter: blur(4px);
-}
-
-.game-header-text>span {
- font-size: 42px;
- font-weight: 500;
- margin: 5px;
-}
-
-.game-header-text span>b {
- font-size: 96px;
- font-weight: 600;
-}
-
-.game-nav {
- display: flex;
- height: 48px;
-}
-
-.game-nav-btn {
- width: 100%;
- height: 100%;
- border: none;
- border-radius: 0px;
- color: inherit;
- font-family: inherit;
- font-size: 22px;
- background: #2B2E46;
- transition: background-color .1s;
- margin: 0 1px;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.game-nav-btn:hover {
- cursor: pointer;
-}
-
-.selected {
- background-color: #202232;
-}
-
-.gameview-nav {
- margin-top: 20px;
- display: flex;
- height: 56px;
- border-radius: 24px;
- overflow: hidden;
- gap: 0.06em;
- /* background-color: #202232; */
-}
-
-.maplist {
- width: 100%;
- margin-top: 20px;
- margin-bottom: 40px;
-}
-
-.chapter-name {
- font-size: 30px;
-}
-
-.chapter-page-div {
- display: flex;
- justify-content: right;
- transform: translateY(-30px);
-}
-
-.chapter-page-div button {
- background-color: #00000000;
- border: 0;
- cursor: pointer;
- height: 30px;
- padding: 0;
- width: 30px;
-}
-
-.chapter-page-div span {
- color: #cdcfdf;
- font-family: BarlowSemiCondensed-Regular;
- font-size: 20px;
-}
-
-.maplist-maps {
- display: grid;
- grid-template-columns: 25% 25% 25% 25%;
- margin-top: 10px;
- transform: translateY(-30px);
-}
-
-.maplist-item {
- background: #202232;
- border-radius: 24px;
- overflow: hidden;
- margin: 10px 10px;
- /* padding: 10px 15px; */
- cursor: pointer;
- user-select: none;
-}
-
-.loader-map {
- border-radius: 24px;
- overflow: hidden;
- margin: 10px 10px;
- /* padding: 10px 15px; */
- user-select: none;
- width: calc(100% - 20px);
- height: calc(223px);
-}
-
-.maplist-img-div {
- height: 150px;
- overflow: hidden;
-}
-
-.maplist-img {
- width: 100%;
- height: 100%;
- background-size: cover;
- filter: blur(4px);
- opacity: 0.7;
-}
-
-.maplist-portalcount-div {
- display: flex;
- justify-content: center;
- align-items: center;
- text-align: center;
- height: 100%;
- transform: translateY(-100%);
- overflow: hidden;
-}
-
-.maplist-title {
- font-size: 22px;
- text-align: center;
- width: 100%;
- display: inherit;
- padding: 5px 0px;
- color: #CDCFDF;
-}
-
-.maplist-portals {
- margin-left: 5px;
- font-size: 32px;
-}
-
-.difficulty-div {
- display: flex;
- padding: 7px 10px;
-}
-
-.difficulty-label {
- font-size: 18px;
-}
-
-.difficulty-bar {
- width: 100%;
- display: grid;
- grid-template-columns: 20% 20% 20% 20% 20%;
- align-items: center;
- margin: 5px;
-}
-
-.difficulty-point {
- background: #2B2E46;
- height: 3px;
- margin: 5px;
- border-radius: 10px;
-}
-
-.stats {
- margin-top: 30px;
-}
-
-.portalcount-over-time-div {
- width: 100%;
- height: 450px;
- position: relative;
- background-color: #202232;
- border-radius: 20px;
-}
-
-.graph-title {
- width: 100%;
- display: inherit;
- font-size: 24px;
- margin-top: 5px;
- text-align: center;
- font-family: BarlowSemiCondensed-SemiBold;
- padding-top: 7px;
-}
-
-.portalcount-graph {
- height: calc(100% - 30px);
- width: calc(100% - 80px);
-}
-
-.chart {
- height: calc(100% - 80px);
- width: 100%;
- position: relative;
- padding: 0px 0px;
- scrollbar-width: thin;
-}
-
-.line-chart {
- list-style: none;
- margin: 0;
- padding: 0;
- height: 100%;
- border-bottom: 2px solid #2B2E46;
-}
-
-.data-point {
- background-color: #202232;
- border: 4px solid #006FDE;
- border-radius: 50%;
- height: 6px;
- position: absolute;
- width: 6px;
- bottom: calc(var(--y) - 4.5px);
- left: calc(var(--x) - 6.5px);
- transition: all 0.2s cubic-bezier(0.075, 0.82, 0.165, 1);
- z-index: 1;
- animation: point_intro 0.2s cubic-bezier(0.075, 0.82, 0.165, 1.8);
- animation-fill-mode: backwards;
-}
-
-.data-point:hover, .data-point-active {
- background-color: #006FDE;
- box-shadow: 0px 0px 10px #006FDE;
-}
-
-.line-segment {
- background-color: #006FDE;
- bottom: var(--y);
- height: 4px;
- left: var(--x);
- position: absolute;
- transform: rotate(calc(var(--angle) * -1deg));
- width: calc(var(--hypotenuse) * 1px);
- transform-origin: left bottom;
- border-radius: 20px;
- z-index: 1;
- animation: line_intro 0.05s cubic-bezier(0, 1, 0.31, 0.96);
- animation-fill-mode: backwards;
-}
-
-#dataPointInfo {
- position: absolute;
- width: 400px;
- height: 85px;
- background: #202232;
- box-shadow: 0px 4px 16px 0px #00000080;
- transition: all 0.3s cubic-bezier(0.075, 0.82, 0.165, 1);
- z-index: 1000;
- opacity: 0;
- left: auto;
- border-radius: 20px;
- padding: 15px 7px;
-}
-
-.section-header {
- display: flex;
- text-align: center;
- font-family: BarlowSemiCondensed-SemiBold;
- font-size: 18px;
- height: 40%;
- justify-content: space-evenly;
- align-items: center;
-}
-
-.section-header span, .section-data span {
- flex: 1;
-}
-
-.divider {
- width: 100%;
- height: 2px;
- background-color: #2B2E46;
- display: flex;
- margin: 5px 0px 8px 0px;
-}
-
-.section-data {
- display: flex;
- grid-template-columns: 25% 25% 25% 25%;
- text-align: center;
- background-color: #2B2E46;
- height: 52%;
- border-radius: 200px;
- align-items: center;
- justify-content: space-evenly;
- flex-grow: 1;
- font-family: BarlowSemiCondensed-Regular;
- font-size: 18px;
- padding: 0px 5px;
-}
-
-@keyframes line_intro {
- 0% {
- width: 0;
- }
- 100% {
- width: calc(var(--hypotenuse) * 1px);
- }
-}
-
-@keyframes point_intro {
- 0% {
- opacity: 0;
- width: 0;
- height: 0;
- transform: translate(3px, -3px);
- }
- 100% {
- width: 6px;
- height: 6px;
- transform: translate(0px, 0px);
- opacity: 1;
- }
-}
diff --git a/frontend/src/components/pages/maplist.js b/frontend/src/components/pages/maplist.js
deleted file mode 100644
index a5c6c19..0000000
--- a/frontend/src/components/pages/maplist.js
+++ /dev/null
@@ -1,890 +0,0 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { useLocation, Link } from "react-router-dom";
-import { BrowserRouter as Router, Route, Routes, useNavigate } from 'react-router-dom';
-
-import "./maplist.css"
-import img5 from "../../imgs/5.png"
-import img6 from "../../imgs/6.png"
-
-export default function Maplist(prop) {
- const { token, setToken } = prop
- const scrollRef = useRef(null)
- const [games, setGames] = React.useState(null);
- const [hasOpenedStatistics, setHasOpenedStatistics] = React.useState(false);
- const [totalPortals, setTotalPortals] = React.useState(0);
- const [loading, setLoading] = React.useState(true)
- const location = useLocation();
-
- const [gameTitle, setGameTitle] = React.useState("");
- const [catPortalCount, setCatPortalCount] = React.useState(0);
- let minPage;
- let maxPage;
- let currentPage;
- let add = 0;
- let gameState;
- let catState = 0;
- async function detectGame() {
- const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
-
- const url = new URL(window.location.href)
-
- const params = new URLSearchParams(url.search)
- gameState = parseFloat(location.pathname.split("/")[2])
-
- if (gameState == 1) {
- setGameTitle(data.data[0].name);
-
- maxPage = 9;
- minPage = 1;
- createCategories(1);
- } else if (gameState == 2) {
- setGameTitle(data.data[1].name);
-
- maxPage = 16;
- minPage = 10;
- add = 10
- createCategories(2);
- }
-
- let chapterParam = params.get("chapter")
-
- currentPage = minPage;
-
- if (chapterParam) {
- currentPage = +chapterParam + add
- }
-
- changePage(currentPage);
-
- // if (!loading) {
-
- // document.querySelector("#catPortalCount").innerText = data.data[gameState - 1].category_portals[0].portal_count;
-
- // }
-
- setCatPortalCount(data.data[gameState - 1].category_portals[0].portal_count);
-
- // if (chapterParam) {
- // document.querySelector("#pageNumbers").innerText = `${chapterParam - minPage + 1}/${maxPage - minPage + 1}`
- // }
- }
-
- function changeMaplistOrStatistics(index, name) {
- const maplistBtns = document.querySelectorAll("#maplistBtn");
- maplistBtns.forEach((btn, i) => {
- if (i == index) {
- btn.className = "game-nav-btn selected"
-
- if (name == "maplist") {
- document.querySelector(".stats").style.display = "none";
- document.querySelector(".maplist").style.display = "block";
- document.querySelector(".maplist").setAttribute("currentTab", "maplist");
- } else {
- document.querySelector(".stats").style.display = "block";
- document.querySelector(".maplist").style.display = "none";
-
- document.querySelector(".maplist-page").scrollTo({ top: 372, behavior: "smooth" })
- document.querySelector(".maplist").setAttribute("currentTab", "stats");
- setHasOpenedStatistics(true);
- }
- } else {
- btn.className = "game-nav-btn";
- }
- });
- }
-
- async function createCategories(gameID) {
- const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
- let categoriesArr = data.data[gameID - 1].category_portals;
-
- if (document.querySelector(".maplist-maps") == null) {
- return;
- }
- const gameNav = document.querySelector(".game-nav");
- gameNav.innerHTML = "";
- categoriesArr.forEach((category) => {
- createCategory(category);
- });
-
- setLoading(false);
- }
-
- let categoryNum = 0;
- function createCategory(category) {
- const gameNav = document.querySelector(".game-nav");
-
- categoryNum++;
- const gameNavBtn = document.createElement("button");
- if (categoryNum == 1) {
- gameNavBtn.className = "game-nav-btn selected";
- } else {
- gameNavBtn.className = "game-nav-btn";
- }
- gameNavBtn.id = "catBtn"
- gameNavBtn.innerText = category.category.name;
-
- gameNavBtn.addEventListener("click", (e) => {
- changeCategory(category, e);
- changePage(currentPage);
- })
-
- gameNav.appendChild(gameNavBtn);
- }
-
- async function changeCategory(category, btn) {
- const navBtns = document.querySelectorAll("#catBtn");
- navBtns.forEach((btns) => {
- btns.classList.remove("selected");
- });
-
- btn.srcElement.classList.add("selected");
- const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
- catState = category.category.id - 1;
- // console.log(catState)
- document.querySelector("#catPortalCount").innerText = category.portal_count;
- }
-
- async function changePage(page) {
- const pageNumbers = document.querySelector("#pageNumbers");
-
- pageNumbers.innerText = `${currentPage - minPage + 1}/${maxPage - minPage + 1}`;
-
- const maplistMaps = document.querySelector(".maplist-maps");
- maplistMaps.innerHTML = "";
- for (let index = 0; index < 8; index++) {
- const loadingAnimation = document.createElement("div");
- loadingAnimation.classList.add("loader");
- loadingAnimation.classList.add("loader-map")
- maplistMaps.appendChild(loadingAnimation);
- }
- const data = await fetchMaps(page);
- const maps = data.data.maps;
- const name = data.data.chapter.name;
-
- let chapterName = "Chapter";
- const chapterNumberOld = name.split(" - ")[0];
- let chapterNumber1 = chapterNumberOld.split("Chapter ")[1];
- if (chapterNumber1 == undefined) {
- chapterName = "Course"
- chapterNumber1 = chapterNumberOld.split("Course ")[1];
- }
- const chapterNumber = chapterNumber1.toString().padStart(2, "0");
- const chapterTitle = name.split(" - ")[1];
-
- if (document.querySelector(".maplist-maps") == null) {
- return;
- }
- const chapterNumberElement = document.querySelector(".chapter-num")
- const chapterTitleElement = document.querySelector(".chapter-name")
- chapterNumberElement.innerText = chapterName + " " + chapterNumber;
- chapterTitleElement.innerText = chapterTitle;
-
- maplistMaps.innerHTML = "";
- maps.forEach(map => {
- let portalCount;
- if (map.category_portals[catState] != undefined) {
- portalCount = map.category_portals[catState].portal_count;
- } else {
- portalCount = map.category_portals[0].portal_count;
- }
- addMap(map.name, portalCount, map.image, map.difficulty + 1, map.id);
- });
-
- const url = new URL(window.location.href)
-
- const params = new URLSearchParams(url.search)
-
- let chapterParam = params.get("chapter")
-
- try {
- const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
-
- const gameImg = document.querySelector(".game-img");
-
- gameImg.style.backgroundImage = `url(${data.data[0].image})`;
-
- // const mapImg = document.querySelectorAll(".maplist-img");
- // mapImg.forEach((map) => {
- // map.style.backgroundImage = `url(${data.data[0].image})`;
- // });
-
- } catch (error) {
- console.log("error fetching games:", error);
- }
-
- asignDifficulties();
- }
-
- async function addMap(mapName, mapPortalCount, mapImage, difficulty, mapID) {
- // jesus christ
- const maplistItem = document.createElement("div");
- const maplistTitle = document.createElement("span");
- const maplistImgDiv = document.createElement("div");
- const maplistImg = document.createElement("div");
- const maplistPortalcountDiv = document.createElement("div");
- const maplistPortalcount = document.createElement("span");
- const b = document.createElement("b");
- const maplistPortalcountPortals = document.createElement("span");
- const difficultyDiv = document.createElement("div");
- const difficultyLabel = document.createElement("span");
- const difficultyBar = document.createElement("div");
- const difficultyPoint1 = document.createElement("div");
- const difficultyPoint2 = document.createElement("div");
- const difficultyPoint3 = document.createElement("div");
- const difficultyPoint4 = document.createElement("div");
- const difficultyPoint5 = document.createElement("div");
-
- maplistItem.className = "maplist-item";
- maplistTitle.className = "maplist-title";
- maplistImgDiv.className = "maplist-img-div";
- maplistImg.className = "maplist-img";
- maplistPortalcountDiv.className = "maplist-portalcount-div";
- maplistPortalcount.className = "maplist-portalcount";
- maplistPortalcountPortals.className = "maplist-portals";
- difficultyDiv.className = "difficulty-div";
- difficultyLabel.className = "difficulty-label";
- difficultyBar.className = "difficulty-bar";
- difficultyPoint1.className = "difficulty-point";
- difficultyPoint2.className = "difficulty-point";
- difficultyPoint3.className = "difficulty-point";
- difficultyPoint4.className = "difficulty-point";
- difficultyPoint5.className = "difficulty-point";
-
-
- maplistTitle.innerText = mapName;
- difficultyLabel.innerText = "Difficulty: "
- maplistPortalcountPortals.innerText = "portals"
- b.innerText = mapPortalCount;
- maplistImg.style.backgroundImage = `url(${mapImage})`;
- difficultyBar.setAttribute("difficulty", difficulty)
- maplistItem.setAttribute("id", mapID)
- maplistItem.addEventListener("click", () => {
- console.log(mapID)
- window.location.href = "/maps/" + mapID
- })
-
- // appends
- // maplist item
- maplistItem.appendChild(maplistTitle);
- maplistImgDiv.appendChild(maplistImg);
- maplistImgDiv.appendChild(maplistPortalcountDiv);
- maplistPortalcountDiv.appendChild(maplistPortalcount);
- maplistPortalcount.appendChild(b);
- maplistPortalcountDiv.appendChild(maplistPortalcountPortals);
- maplistItem.appendChild(maplistImgDiv);
- maplistItem.appendChild(difficultyDiv);
- difficultyDiv.appendChild(difficultyLabel);
- difficultyDiv.appendChild(difficultyBar);
- difficultyBar.appendChild(difficultyPoint1);
- difficultyBar.appendChild(difficultyPoint2);
- difficultyBar.appendChild(difficultyPoint3);
- difficultyBar.appendChild(difficultyPoint4);
- difficultyBar.appendChild(difficultyPoint5);
-
- // display in place
- const maplistMaps = document.querySelector(".maplist-maps");
- maplistMaps.appendChild(maplistItem);
- }
-
- async function fetchMaps(chapterID) {
- try {
- const response = await fetch(`https://lp.ardapektezol.com/api/v1/chapters/${chapterID}`, {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
- return data;
- } catch (err) {
- console.log(err)
- }
- }
-
- // difficulty stuff
- function asignDifficulties() {
- const difficulties = document.querySelectorAll(".difficulty-bar");
- difficulties.forEach((difficultyElement) => {
- let difficulty = difficultyElement.getAttribute("difficulty");
- if (difficulty == "1") {
- difficultyElement.childNodes[0].style.backgroundColor = "#51C355";
- } else if (difficulty == "2") {
- difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A";
- difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A";
- } else if (difficulty == "3") {
- difficultyElement.childNodes[0].style.backgroundColor = "#8AC93A";
- difficultyElement.childNodes[1].style.backgroundColor = "#8AC93A";
- difficultyElement.childNodes[2].style.backgroundColor = "#8AC93A";
- } else if (difficulty == "4") {
- difficultyElement.childNodes[0].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[1].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[2].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[3].style.backgroundColor = "#C35F51";
- } else if (difficulty == "5") {
- difficultyElement.childNodes[0].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[1].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[2].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[3].style.backgroundColor = "#C35F51";
- difficultyElement.childNodes[4].style.backgroundColor = "#C35F51";
- }
- });
- }
-
- const divRef = useRef(null);
-
- React.useEffect(() => {
-
- const lineChart = document.querySelector(".line-chart")
- let tempTotalPortals = 0
- fetch("https://lp.ardapektezol.com/api/v1/games/1/maps", {
- headers: {
- 'Authorization': token
- }
- })
- .then(r => r.json())
- .then(d => {
- d.data.maps.forEach((map, i) => {
- tempTotalPortals += map.portal_count
- })
- })
- .then(() => {
- setTotalPortals(tempTotalPortals)
- })
- async function createGraph() {
- console.log(totalPortals)
- // max
- let items = [
- {
- record: "100",
- date: new Date(2011, 4, 4),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "98",
- date: new Date(2012, 6, 4),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "94",
- date: new Date(2013, 0, 1),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "90",
- date: new Date(2014, 0, 1),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "88",
- date: new Date(2015, 6, 14),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "84",
- date: new Date(2016, 8, 19),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "82",
- date: new Date(2017, 3, 20),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "81",
- date: new Date(2018, 2, 25),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "80",
- date: new Date(2019, 3, 4),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "78",
- date: new Date(2020, 11, 21),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "77",
- date: new Date(2021, 10, 25),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "76",
- date: new Date(2022, 4, 17),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "75",
- date: new Date(2023, 9, 31),
- map: "Container Ride",
- first: "tiny zach"
- },
- {
- record: "74",
- date: new Date(2024, 4, 4),
- map: "Container Ride",
- first: "tiny zach"
- },
- ]
-
- function calculatePosition(date, startDate, endDate, maxWidth) {
- const totalMilliseconds = endDate - startDate + 10000000000;
- const millisecondsFromStart = date - startDate + 5000000000;
- return (millisecondsFromStart / totalMilliseconds) * maxWidth
- }
-
- const minDate = items.reduce((min, dp) => dp.date < min ? dp.date : min, items[0].date)
- const maxDate = items.reduce((max, dp) => dp.date > max ? dp.date : max, items[0].date)
-
- const graph_width = document.querySelector(".portalcount-over-time-div").clientWidth
- // console.log(graph_width)
-
- const uniqueYears = new Set()
- items.forEach(dp => uniqueYears.add(dp.date.getFullYear()))
- let minYear = Infinity;
- let maxYear = -Infinity;
-
- items.forEach(dp => {
- const year = dp.date.getFullYear();
- minYear = Math.min(minYear, year);
- maxYear = Math.max(maxYear, year);
- });
-
- // Add missing years to the set
- for (let year = minYear; year <= maxYear; year++) {
- uniqueYears.add(year);
- }
- const uniqueYearsArr = Array.from(uniqueYears)
-
- items = items.map(dp => ({
- record: dp.record,
- date: dp.date,
- x: calculatePosition(dp.date, minDate, maxDate, lineChart.clientWidth),
- map: dp.map,
- first: dp.first
- }))
-
- const yearInterval = lineChart.clientWidth / uniqueYears.size
- for (let index = 1; index < (uniqueYears.size); index++) {
- const placeholderlmao = document.createElement("div")
- const yearSpan = document.createElement("span")
- yearSpan.style.position = "absolute"
- placeholderlmao.style.height = "100%"
- placeholderlmao.style.width = "2px"
- placeholderlmao.style.backgroundColor = "#00000080"
- placeholderlmao.style.position = `absolute`
- const thing = calculatePosition(new Date(uniqueYearsArr[index], 0, 0), minDate, maxDate, lineChart.clientWidth)
- placeholderlmao.style.left = `${thing}px`
- yearSpan.style.left = `${thing}px`
- yearSpan.style.bottom = "-34px"
- yearSpan.innerText = uniqueYearsArr[index]
- yearSpan.style.fontFamily = "BarlowSemiCondensed-Regular"
- yearSpan.style.fontSize = "22px"
- yearSpan.style.opacity = "0.8"
- lineChart.appendChild(yearSpan)
-
- }
-
- let maxPortals;
- let minPortals;
- let precision;
- let multiplier = 1;
- for (let index = 0; index < items.length; index++) {
- precision = Math.floor((items[0].record - items[items.length - 1].record))
- if (precision > 20) {
- precision = 20
- }
- minPortals = Math.floor((items[items.length - 1].record) / 10) * 10
- if (index == 0) {
- maxPortals = items[index].record - minPortals
- }
- }
- function calculateMultiplier(value) {
- while (value > precision) {
- multiplier += 1;
- value -= precision;
- }
- }
- calculateMultiplier(items[0].record);
- // if (items[0].record > 10) {
- // multiplier = 2;
- // }
-
- // Original cubic bezier control points
- const P0 = { x: 0, y: 0 };
- const P1 = { x: 0.26, y: 1 };
- const P2 = { x: 0.74, y: 1 };
- const P3 = { x: 1, y: 0 };
-
- function calculateIntermediateControlPoints(t, P0, P1, P2, P3) {
- const x = (1 - t) ** 3 * P0.x +
- 3 * (1 - t) ** 2 * t * P1.x +
- 3 * (1 - t) * t ** 2 * P2.x +
- t ** 3 * P3.x;
-
- const y = (1 - t) ** 3 * P0.y +
- 3 * (1 - t) ** 2 * t * P1.y +
- 3 * (1 - t) * t ** 2 * P2.y +
- t ** 3 * P3.y;
-
- return { x, y };
- }
-
-
- let delay = 0;
- for (let index = 0; index < items.length; index++) {
- let chart_height = 340;
- const item = items[index];
- delay += 0.05;
- // console.log(lineChart.clientWidth)
-
- // maxPortals++;
- // maxPortals++;
-
- let point_height = (chart_height / maxPortals)
-
- for (let index = 0; index < (maxPortals / multiplier); index++) {
- // console.log((index + 1) * multiplier)
- let current_portal_count = (index + 1);
-
- const placeholderDiv = document.createElement("div")
- const numPortalsText = document.createElement("span")
- const numPortalsTextBottom = document.createElement("span")
- numPortalsText.innerText = (current_portal_count * multiplier) + minPortals
- numPortalsTextBottom.innerText = minPortals
- placeholderDiv.style.position = "absolute"
- numPortalsText.style.position = "absolute"
- numPortalsTextBottom.style.position = "absolute"
- numPortalsText.style.left = "-37px"
- numPortalsText.style.opacity = "0.2"
- numPortalsTextBottom.style.opacity = "0.2"
- numPortalsText.style.fontFamily = "BarlowSemiCondensed-Regular"
- numPortalsTextBottom.style.fontFamily = "BarlowSemiCondensed-Regular"
- numPortalsText.style.fontSize = "22px"
- numPortalsTextBottom.style.left = "-37px"
- numPortalsTextBottom.style.fontSize = "22px"
- numPortalsTextBottom.style.fontWeight = "400"
- numPortalsText.style.color = "#CDCFDF"
- numPortalsTextBottom.style.color = "#CDCFDF"
- numPortalsText.style.fontFamily = "inherit"
- numPortalsTextBottom.style.fontFamily = "inherit"
- numPortalsText.style.textAlign = "right"
- numPortalsTextBottom.style.textAlign = "right"
- numPortalsText.style.width = "30px"
- numPortalsTextBottom.style.width = "30px"
- placeholderDiv.style.bottom = `${(point_height * current_portal_count * multiplier) - 2}px`
- numPortalsText.style.bottom = `${(point_height * current_portal_count * multiplier) - 2 - 9}px`
- numPortalsTextBottom.style.bottom = `${0 - 2 - 8}px`
- placeholderDiv.id = placeholderDiv.style.bottom
- placeholderDiv.style.width = "100%"
- placeholderDiv.style.height = "2px"
- placeholderDiv.style.backgroundColor = "#2B2E46"
- placeholderDiv.style.zIndex = "0"
-
- if (index == 0) {
- lineChart.appendChild(numPortalsTextBottom)
- }
- lineChart.appendChild(numPortalsText)
- lineChart.appendChild(placeholderDiv)
- }
-
- const li = document.createElement("li");
- const lineSeg = document.createElement("div");
- const dataPoint = document.createElement("div");
-
- li.style = `--y: ${point_height * (item.record - minPortals) - 3}px; --x: ${item.x}px`;
- lineSeg.className = "line-segment";
- dataPoint.className = "data-point";
-
- if (items[index + 1] !== undefined) {
- const hypotenuse = Math.sqrt(
- Math.pow(items[index + 1].x - items[index].x, 2) +
- Math.pow((point_height * items[index + 1].record) - point_height * item.record, 2)
- );
- const angle = Math.asin(
- ((point_height * item.record) - (point_height * items[index + 1].record)) / hypotenuse
- );
-
- lineSeg.style = `--hypotenuse: ${hypotenuse}; --angle: ${angle * (-180 / Math.PI)}`;
- const t0 = index / items.length;
- const t1 = (index + 1) / items.length
-
- const P0t0 = calculateIntermediateControlPoints(t0, P0, P1, P2, P3);
- const P1t1 = calculateIntermediateControlPoints(t1, P0, P1, P2, P3);
- const bezierStyle = `cubic-bezier(${P0t0.x.toFixed(3)}, ${P0t0.y.toFixed(3)}, ${P1t1.x.toFixed(3)}, ${P1t1.y.toFixed(3)})`
- lineSeg.style.animationTimingFunction = bezierStyle
- lineSeg.style.animationDelay = delay + "s"
- }
- dataPoint.style.animationDelay = delay + "s"
-
- let isHoveringOverData = true;
- let isDataActive = false;
- document.querySelector("#dataPointInfo").style.left = item.x + "px";
- document.querySelector("#dataPointInfo").style.bottom = (point_height * item.record - 3) + "px";
- dataPoint.addEventListener("mouseenter", (e) => {
- isDataActive = true;
- isHoveringOverData = true;
- const dataPoints = document.querySelectorAll(".data-point")
- dataPoints.forEach(point => {
- point.classList.remove("data-point-active")
- });
- dataPoint.classList.add("data-point-active")
- document.querySelector("#dataPointRecord").innerText = item.record;
- document.querySelector("#dataPointMap").innerText = item.map;
- document.querySelector("#dataPointDate").innerText = item.date.toLocaleDateString("en-GB");
- document.querySelector("#dataPointFirst").innerText = item.first;
- if ((lineChart.clientWidth - 400) < item.x) {
- document.querySelector("#dataPointInfo").style.left = item.x - 400 + "px";
- } else {
- document.querySelector("#dataPointInfo").style.left = item.x + "px";
- }
- if ((lineChart.clientHeight - 115) < (point_height * (item.record - minPortals) - 3)) {
- document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) - 3) - 115 + "px";
- } else {
- document.querySelector("#dataPointInfo").style.bottom = (point_height * (item.record - minPortals) - 3) + "px";
- }
- document.querySelector("#dataPointInfo").style.opacity = "1";
- document.querySelector("#dataPointInfo").style.zIndex = "10";
- });
- document.querySelector("#dataPointInfo").addEventListener("mouseenter", (e) => {
- isHoveringOverData = true;
- })
- document.querySelector("#dataPointInfo").addEventListener("mouseleave", (e) => {
- isHoveringOverData = false;
- })
- document.addEventListener("mousedown", () => {
- if (!isHoveringOverData) {
- isDataActive = false
- dataPoint.classList.remove("data-point-active")
- document.querySelector("#dataPointInfo").style.opacity = "0";
- document.querySelector("#dataPointInfo").style.zIndex = "0";
- }
- })
- dataPoint.addEventListener("mouseenter", (e) => {
- isHoveringOverData = false;
- })
- document.querySelector(".chart").addEventListener("mouseleave", () => {
- isDataActive = false
- // fuck you
- isHoveringOverData = true;
- dataPoint.classList.remove("data-point-active")
- document.querySelector("#dataPointInfo").style.opacity = "0";
- document.querySelector("#dataPointInfo").style.zIndex = "0";
- })
-
- li.appendChild(lineSeg);
- li.appendChild(dataPoint);
- lineChart.appendChild(li);
- }
- }
-
- async function fetchGames() {
- try {
- const response = await fetch("https://lp.ardapektezol.com/api/v1/games", {
- headers: {
- 'Authorization': token
- }
- });
-
- const data = await response.json();
-
- const gameImg = document.querySelector(".game-img");
-
- gameImg.style.backgroundImage = `url(${data.data[0].image})`;
-
- // const mapImg = document.querySelectorAll(".maplist-img");
- // mapImg.forEach((map) => {
- // map.style.backgroundImage = `url(${data.data[0].image})`;
- // });
-
- } catch (error) {
- console.log("error fetching games:", error);
- }
- }
-
- detectGame();
-
- const maplistImg = document.querySelector("#maplistImg");
- maplistImg.src = img5;
- const statisticsImg = document.querySelector("#statisticsImg");
- statisticsImg.src = img6;
-
- fetchGames();
-
- const handleResize = (entries) => {
- for (let entry of entries) {
- if (hasOpenedStatistics) {
- lineChart.innerHTML = ""
- createGraph()
- }
- if (document.querySelector(".maplist").getAttribute("currentTab") == "stats") {
- document.querySelector(".stats").style.display = "block"
- } else {
- document.querySelector(".stats").style.display = "none"
- }
- }
- };
-
- const resizeObserver = new ResizeObserver(handleResize);
-
- // if (scrollRef.current) {
- // //hi
- // if (new URLSearchParams(new URL(window.location.href).search).get("chapter")) {
- // setTimeout(() => {
- // scrollRef.current.scrollIntoView({ behavior: "smooth", block: "start" })
- // }, 200);
- // }
-
- // }
-
- if (divRef.current) {
- resizeObserver.observe(divRef.current);
- }
-
- return () => {
- if (divRef.current) {
- resizeObserver.unobserve(divRef.current);
- }
- resizeObserver.disconnect();
- };
-
-
- })
- return (
-
-
-
-
- {!loading ?
- {gameTitle}
- :
- LOADINGLOADING}
-
-
-
- {!loading ?
-
-
-
- {catPortalCount}
- portals
-
-
- :
}
- {!loading ?
-
-
- :
-
}
-
-
-
-
-
-
-
-
-
-
undefined
-
undefined
-
-
-
- 0/0
-
-
-
-
-
-
-
-
-
-
-
Portal count over time
-
-
-
-
-
-
- Date
- Map
- Record
- First completion
-
-
-
-
-
-
- Hello
-
-
-
-
-
-
-
-
-
- )
-}
\ No newline at end of file
diff --git a/frontend/src/components/pages/profile.css b/frontend/src/components/pages/profile.css
deleted file mode 100644
index 4944ade..0000000
--- a/frontend/src/components/pages/profile.css
+++ /dev/null
@@ -1,239 +0,0 @@
-#section1.profile{
- margin: 20px;
- background: linear-gradient(0deg, #202232 50%, #2b2e46 50%);
- border-radius: 24px;
- height: 200px;
-
- display: grid;
- grid-template-columns: 250px 1fr;
-
-}
-#section1.profile>div:first-child{
- overflow: hidden;
- border-radius: 100%;
- display: grid;
-
- place-items: center;
-
- margin: 8px 33px 8px 33px;
- scale: 0.9;
- grid-row: 1 / 3;
-
-
-}
-#profile-image>img{
- border-radius: 100%;
- transition: filter 0.3s;
- cursor: pointer;
-}
-
-#profile-image>span{
- z-index: 1;
- position: absolute;
- opacity: 0;
- color:white;
- transition: opacity 0.3s;
- cursor: pointer;
-}
-
-#profile-image:hover > img{filter: blur(5px) brightness(60%);z-index: 1;}
-#profile-image:hover > span{opacity: 1;}
-
-#profile-top{
- height: 100px;
- display: grid;
- grid-template-columns: 80% 20%;
-}
-#profile-top>div:nth-child(1)>div>img{
- margin: 12px;
- border-radius: 10px;
-}
-
-#profile-top>div:nth-child(1){
- display: flex;
- place-items: center;
- font-size: 50px;
- font-weight: bold;
- color: white;
-}
-#profile-top>div:nth-child(1)>div{
- display: flex;
- height: 60px;
-}
-span.titles{
- margin: 12px 12px 12px 0;
-
- font-size: 18px;
- font-weight: 100;
-
- padding: 6px 20px 0px 20px;
- border-radius: 10px;
-}
-
-#profile-top>div:nth-child(2){
- display: flex;
- flex-direction: row-reverse;
- align-items: center;
- padding-right: 10px;
-}
-#profile-top>div:nth-child(2)>a>img{
- height: 50px;
- padding: 0 5px 0 5px;
- scale: 0.9;
- filter: brightness(200%);
-
-}
-
-
-#profile-bottom{
- height: 100px;
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
-}
-#profile-bottom>div{
- margin: 12px;
- background-color: #2b2e46;
- border-radius: 20px;
- display: grid;
- place-items: center;
- grid-template-rows: 40% 50%;
-}
-#profile-bottom>div>span:nth-child(1){
- color: inherit;
- font-size: 18px;
-}
-#profile-bottom>div>span:nth-child(2){
- color: white;
- font-size: 40px;
-}
-#profile-bottom>div>span:nth-child(2)>span{
- color: white;
- font-size: 20px;
-}
-/* #section1.profile>div>div{outline: red 1px dashed;} */
-
-
-#section2.profile{
- margin: 20px;
- height: 60px;
- display: grid;
- grid-template-columns: 1fr 1fr;
-}
-#section2.profile>button{
- display: flex;
- justify-content: center;
- align-items: center;
-
- background-color: #2b2e46;
- border: 0;
- color: inherit;
- font-family: inherit;
- font-size: 24px;
- cursor: pointer;
-
- transition: background-color .1s;
-}
-#section2.profile>button:nth-child(1){border-radius: 24px 0 0 24px;}
-#section2.profile>button:nth-child(2){border-radius: 0 24px 24px 0;}
-
-#section3.profile1>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
-#section3.profile1{
- margin: 20px;
- display: block;
-
- background-color: #202232;
- border-radius: 24px;
-}
-
-#profileboard-nav{
- display: grid;
- grid-template-columns: 1fr 1fr;
-}
-
-#profileboard-nav>select{
-
- /* appearance: none; */
- margin: 10px 20px 20px 20px;
- height: 50px;
-
- border-radius: 24px;
- text-align: center;
-
- color: inherit;
- font-family: inherit;
- font-size: 24px;
- border: 0;
-
- background-color: #2b2e46;
-}
-
-
-#profileboard-top>span>img{height: 20px;scale: .8;}
-#profileboard-top>span>img,#profileboard-top>span>span{cursor: pointer;}
-#profileboard-top{
- height: 34px;
- display: grid;
- font-size: 20px;
- padding-left: 40px;
- margin: 0 20px;
- grid-template-columns: 15% 15% 5% 15% 5% 15% 15% 15%;
-}
-
-#profileboard-top>span{
- display: flex;
- place-items: flex-end;
-}
-
-#profileboard-records{
- padding-bottom: 10px;
-}
-
-.profileboard-record{
- width: calc(100% - 40px);
- margin: 10px 20px 0px 20px;
- height: 44px;
-
- border-radius: 20px;
- padding: 0 0 0 40px;
- font-size: 20px;
-
- color: inherit;
- font-family: inherit;
- border: 0;
- transition: background-color .1s;
- background-color: #2b2e46;
- display: grid;
- grid-template-columns: 15% 15% 5% 15% 5% 15% 15% 15%;
- overflow: hidden;
- white-space: nowrap;
-
- transition: height .2s
-}
-
-/* this right here should be illegal */
-.profileboard-record>span:nth-child(-n+8){filter: brightness(100%);}
-.profileboard-record>span{
- display: flex;
- place-items: flex-end;
- filter: brightness(65%);
-}
-
-.profileboard-record>hr{
- margin: 0 0 0 -60px;
- border: 0;
- height: 2px;
- background-color: #202232;
-}
-
-.profileboard-record>span:nth-child(4){display: grid;}
-.profileboard-record>span{
-
- display: flex;
- place-items: center;
- height: 44px;
-}
-.profileboard-record>span>button{
- background-color: #0000;
- border: 0;
- cursor: pointer;
-}
diff --git a/frontend/src/components/pages/profile.js b/frontend/src/components/pages/profile.js
deleted file mode 100644
index 7c45320..0000000
--- a/frontend/src/components/pages/profile.js
+++ /dev/null
@@ -1,382 +0,0 @@
-import React from 'react';
-import { useLocation } from "react-router-dom";
-
-import img4 from "../../imgs/4.png"
-import img5 from "../../imgs/5.png"
-import img12 from "../../imgs/12.png"
-import img13 from "../../imgs/13.png"
-import img14 from "../../imgs/14.png"
-import img15 from "../../imgs/15.png"
-import img16 from "../../imgs/16.png"
-import img17 from "../../imgs/17.png"
-import img18 from "../../imgs/18.png"
-import img19 from "../../imgs/19.png"
-import "./profile.css";
-
-export default function Profile(props) {
-const {token} = props
-
-
-const location = useLocation()
-
-
-const [profileData, setProfileData] = React.useState(null)
-React.useEffect(()=>{
- setProfileData(null)
- setChapterData(null)
- setMaps(null)
- setPageNumber(1)
-
- if(location.pathname==="/profile"){
- fetch(`https://lp.ardapektezol.com/api/v1/${location.pathname}`,{
- headers: {
- 'Authorization': token
- }})
- .then(r=>r.json())
- .then(d=>{
- setProfileData(d.data)
- setPageMax(Math.ceil(d.data.records.length/20))
- })
- }else{
- fetch(`https://lp.ardapektezol.com/api/v1/${location.pathname}`)
- .then(r=>r.json())
- .then(d=>{
- setProfileData(d.data)
- setPageMax(Math.ceil(d.data.records.length/20))
- })
- }
-},[location.pathname])
-
-
-
-const [game,setGame] = React.useState(0)
-const [gameData,setGameData] = React.useState(null)
-const [chapter,setChapter] = React.useState("0")
-const [chapterData,setChapterData] = React.useState(null)
-const [maps,setMaps] = React.useState(null)
-
-React.useEffect(()=>{
- fetch("https://lp.ardapektezol.com/api/v1/games")
- .then(r=>r.json())
- .then(d=>{
- setGameData(d.data)
- setGame(0)
- })
-
-},[location])
-
-React.useEffect(()=>{
- if(game!==null && game!= 0){
- fetch(`https://lp.ardapektezol.com/api/v1/games/${game}`)
- .then(r=>r.json())
- .then(d=>{
- setChapterData(d.data)
- setChapter("0")
- document.querySelector('#select-chapter').value=0
- })
-
- } else if (game!==null && game==0 && profileData!== null){
- setPageMax(Math.ceil(profileData.records.length/20))
- setPageNumber(1)
- }
-
-},[game,location])
-
-React.useEffect(()=>{
- if(chapter!==null){
- if(chapter==0){
- setMaps(null)
- fetch(`https://lp.ardapektezol.com/api/v1/games/${game}/maps`)
- .then(r=>r.json())
- .then(d=>{
- setMaps(d.data.maps);
- setPageMax(Math.ceil(d.data.maps.length/20))
- setPageNumber(1)
- })
- }else{
- setMaps(null)
- fetch(`https://lp.ardapektezol.com/api/v1/chapters/${chapter}`)
- .then(r=>r.json())
- .then(d=>{
- setMaps(d.data.maps);
- setPageMax(Math.ceil(d.data.maps.length/20))
- setPageNumber(1)
- })
-
- }
- }
-},[chapter,chapterData])
-
-
-
-const [pageNumber, setPageNumber] = React.useState(1);
-const [pageMax, setPageMax] = React.useState(0);
-const [navState, setNavState] = React.useState(0); // eslint-disable-next-line
-React.useEffect(() => {NavClick();}, [[],navState]);
-function NavClick() {
- if(profileData!==null){
- const btn = document.querySelectorAll("#section2 button");
- btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"});
- btn[navState].style.backgroundColor = "#202232";
-
- document.querySelectorAll("section").forEach((e,i)=>i>=2?e.style.display="none":"")
- if(navState === 0){document.querySelectorAll(".profile1").forEach((e) => {e.style.display = "block"});}
- if(navState === 1){document.querySelectorAll(".profile2").forEach((e) => {e.style.display = "block"});}
-}
-}
-function UpdateProfile(){
- fetch(`https://lp.ardapektezol.com/api/v1/profile`,{
- method: 'POST',
- headers: {Authorization: token}
- }).then(r=>r.json())
- .then(d=>d.success?window.alert("profile updated"):window.alert(`Error: ${d.message}`))
-}
-
-function TimeAgo(date) {
- const seconds = Math.floor((new Date() - date) / 1000);
-
- let interval = Math.floor(seconds / 31536000);
- if (interval > 1) {return interval + ' years ago';}
-
- interval = Math.floor(seconds / 2592000);
- if (interval > 1) {return interval + ' months ago';}
-
- interval = Math.floor(seconds / 86400);
- if (interval > 1) {return interval + ' days ago';}
-
- interval = Math.floor(seconds / 3600);
- if (interval > 1) {return interval + ' hours ago';}
-
- interval = Math.floor(seconds / 60);
- if (interval > 1) {return interval + ' minutes ago';}
-
- if(seconds < 10) return 'just now';
-
- return Math.floor(seconds) + ' seconds ago';
- };
-
-function TicksToTime(ticks) {
-
- let seconds = Math.floor(ticks/60)
- let minutes = Math.floor(seconds/60)
- let hours = Math.floor(minutes/60)
-
- let milliseconds = Math.floor((ticks%60)*1000/60)
- seconds = seconds % 60;
- minutes = minutes % 60;
-
- return `${hours===0?"":hours+":"}${minutes===0?"":hours>0?minutes.toString().padStart(2, '0')+":":(minutes+":")}${minutes>0?seconds.toString().padStart(2, '0'):seconds}.${milliseconds.toString().padStart(3, '0')} (${ticks})`;
-}
-
-
-if(profileData!==null){
-return (
-
-
-
- {profileData.profile?(
- UpdateProfile()}>
-

-
Refresh
-
- ):(
-
-

-
- )}
-
-
-
-
{profileData.user_name}
-
- {profileData.country_code==="XX"?"":
}.jpg`})
}
-
-
- {profileData.titles.map(e=>(
-
- {e.name}
-
- ))}
-
-
-
- {profileData.links.p2sr==="-"?"":

}
- {profileData.links.p2sr==="-"?"":

}
- {profileData.links.p2sr==="-"?"":

}
- {profileData.links.p2sr==="-"?"":

}
-
-
-
-
-
- Overall
- {profileData.rankings.overall.rank===0?"N/A ":"#"+profileData.rankings.overall.rank+" "}
- ({profileData.rankings.overall.completion_count}/{profileData.rankings.overall.completion_total})
-
-
-
- Singleplayer
- {profileData.rankings.singleplayer.rank===0?"N/A ":"#"+profileData.rankings.singleplayer.rank+" "}
- ({profileData.rankings.singleplayer.completion_count}/{profileData.rankings.singleplayer.completion_total})
-
-
-
- Cooperative
- {profileData.rankings.cooperative.rank===0?"N/A ":"#"+profileData.rankings.cooperative.rank+" "}
- ({profileData.rankings.cooperative.completion_count}/{profileData.rankings.cooperative.completion_total})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {gameData===null?:
-
-
- }
-
- {game==0?
-
- :chapterData===null?:
-
-
- }
-
-
-
Map Name
-
Portals
-
WRΔ 
-
Time
-
-
Rank
-
Date
-
-
-
- {pageNumber}/{pageMax}
-
-
-
-
-
-
-
- {game == 0 && profileData !== null
- ? (
-
- profileData.records.sort((a,b)=>a.map_id - b.map_id)
- .map((r, index) => (
-
- Math.ceil((index+1)/20)===pageNumber ? (
-
- ) : ""
- ))) : maps !== null ?
-
- maps.filter(e=>e.is_disabled===false).sort((a,b)=>a.id - b.id)
- .map((r, index) => {
- if(Math.ceil((index+1)/20)===pageNumber){
- let record = profileData.records.find((e) => e.map_id === r.id);
- return record === undefined ? (
-
- {r.name}
- N/A
- N/A
- N/A
-
- N/A
- N/A
-
-
- ) : (
-
- {record.scores.map((e,i)=>(<>
- {i!==0?
:""}
- {r.name}
- {record.scores[i].score_count}
- {record.scores[i].score_count-record.map_wr_count}
- {TicksToTime(record.scores[i].score_time)}
-
- {i===0?#{record.placement}: }
- {record.scores[i].date.split("T")[0]}
-
-
- {window.alert(`Demo ID: ${e.demo_id}`)}}>
- window.location.href=`https://lp.ardapektezol.com/api/v1/demos?uuid=${e.demo_id}`}>
- {i===0&&record.scores.length>1?
- {
- document.querySelectorAll(".profileboard-record")[index%20].style.height==="44px"||
- document.querySelectorAll(".profileboard-record")[index%20].style.height===""?
- document.querySelectorAll(".profileboard-record")[index%20].style.height=`${record.scores.length*46}px`:
- document.querySelectorAll(".profileboard-record")[index%20].style.height="44px"
- }
- }>
:""}
-
-
- >))}
-
-
- )
- }else{return null}
- }):(<>{console.warn(maps)}>)}
-
-
-
-
-)}
-}
-
-
diff --git a/frontend/src/components/pages/summary.css b/frontend/src/components/pages/summary.css
deleted file mode 100644
index 8c6ec35..0000000
--- a/frontend/src/components/pages/summary.css
+++ /dev/null
@@ -1,720 +0,0 @@
-#background-image{
- z-index: -1;
- position: absolute;
- opacity: 10%;
- height: 50%;
- width: 100%
-}
-#background-image>img{
- object-fit: cover;
- width: 100%;
- height: 100%;
-}
-#background-image::before{
- content: "";
- position: absolute;
- width: 100%;
- height: 100%;
- background: linear-gradient(to top, #161723, #0000);
-}
-
-/* Section 1: map name*/
-
-#section1{
- margin: 20px 0 0 0;
- cursor: default;
-}
-
-.nav-button{
- height: 40px;
- background-color: #2b2e46;
-
- color: inherit;
- font-size: 18px;
- font-family: inherit;
- border: none;
- transition: background-color .1s;
-}
-/* #section1>div>.nav-button:nth-child(1){border-radius: 0px;}:nth-child(1){border-radius: 20px 0 0 20px;}
-#section1>div>.nav-button:nth-child(2){border-radius: 0 20px 20px 0;margin-left: 2px;} */
-.nav-button>span{padding: 0 8px 0 8px;}
-.nav-button:hover{background-color: #202232;cursor: pointer;}
-
-/* Section 2: navbar */
-#section2{
- margin: 40px 0 0 0;
-
- display: grid; gap: 2px;
- grid-template-columns: 1fr 1fr 1fr;
-}
-
-#section2>.nav-button{
- height: 50px;
- font-size: 22px;
- display: flex;
- justify-content: center;
- place-items: center;
-}
-#section2>.nav-button>img{scale: 1.2;}
-#section2>.nav-button:nth-child(1){border-radius: 30px 0 0 30px;}
-#section2>.nav-button:nth-child(3){border-radius: 0 30px 30px 0;}
-
-
-/* Section 3: category + history */
-
-#section3{
- margin: 40px 0 0 0;
-
- display: none;
- grid-template-columns: 1fr 1fr;
- gap: 20px;
-}
-
-#category{
- display: grid;
- height: 350px;
- border-radius: 24px;
- overflow: hidden;
-
-}
-#category>p{
- margin-bottom: 20px;
- text-align: center;
- font-size: 50px;
- cursor: default;
- color: white;
-}
-
-p>span.portal-count{font-weight: bold;font-size: 100px;vertical-align: -15%;}
-
-#category-image{
- transform: translate(-20%, -15%);
- z-index: -1;
- overflow: hidden;
- width: 125%;
- margin: 22px;
- filter: blur(4px) contrast(80%) brightness(80%);
-}
-
-#category>span{
- margin-top: 70px;
- background-color: #202232;
-
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr;
- gap: 2px;
-}
-#category>span>button{
- font-family: inherit;
- font-size: 18px;
- border: none;
- height: 40px;
- color: inherit;
-
- cursor: pointer;
- transition: background-color .1s;
-}
-
-
-
-#history>div>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
-#history{
- min-width: 560px;
- background-color: #202232;
- border-radius: 24px;
-
-}
-
-#records{overflow-y: auto; height: 256px;}
-#records::-webkit-scrollbar{display: none;}
-
-.record-top, .record{
- font-size: 18px;
- display: grid;
- text-align: center;
- grid-template-columns: 1fr 1fr 1fr;
-}
-.record-top{font-weight: bold;margin: 20px 20px 0 20px;cursor: default;}
-.record{
- margin: 10px 20px 10px 20px;
- height: 44px; width: calc(100% - 40px);
-
- color: inherit;
- border-radius: 40px;
- place-items: center;
-
- border: 0;
- cursor: pointer;
- transition: background-color .1s;
-}
-#history>span{
- border-top: #202232 solid 2px;
- display: grid;
- grid-template-columns: 1fr 1fr;
-}
-#history>span>button{
- width: 100%; height: 40px;
- font-family: inherit;
- font-size: 18px;
- border: none;
- color: inherit;
-
- cursor: pointer;
- transition: background-color .1s;
-}
-#history>span>button:nth-child(1){border-radius: 0 0 0 24px;}
-#history>span>button:nth-child(2){border-radius: 0 0 24px 0;}
-
-#graph{
- display: grid;
- grid-template-columns: 20px 1fr;
- grid-template-rows: 1fr 20px;
- height: 293px;
-
- margin: 10px 10px 5px 10px;
- overflow: hidden;
-}
-#graph>div:nth-child(1){ /* numbers */
- width: 20px;
- display: grid;
- place-items: center;
- /* background-color: blue; */
-}
-#graph>div:nth-child(1)>span{
- font-size: 12px;
- line-height: 0;
-}
-
-#graph>div:nth-child(2){ /* big graph */
- position: relative;
- display: grid;
-}
-#graph>div:nth-child(2)>tr{
- display: flex;
- align-items: center;
- grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));
-}
-#graph>div:nth-child(2)>tr>td.graph_hor{
- width: 100%;
- height: 0;
- padding: 0;
-
- outline: 1px solid red;
-}
-#graph>div:nth-child(2)>tr>td.graph_ver{
- width: 0;
- height: 100%;
- padding: 0;
-
- outline: 1px solid blue;
- transform: translateY(50%);
- z-index: 0;
- overflow: hidden;
-}
-
-#graph>div:nth-child(3){ /* dates */
- padding-right: 20px;
- z-index: 1;
- height: 16px;
- background-color: #202232;
- grid-column: 1 /3;
- font-size: 12px;
- display: grid;
- padding-top: 8px;
- grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));
-}
-
-.graph-button{
- position: absolute;
- padding: 0;
- border: 5px solid white;
- border-radius: 20px;
- cursor: pointer;
- transform: translateX(-50%);
-}
-
-#history>div>h5{text-align: center;height: 197px;}
-
-
-/* Section 4: Difficulty + count */
-
-#section4{
- display: none;
- grid-template-columns: 1fr 1fr;
- gap: 20px;
- margin: 40px 0 0 0;
-}
-
-#difficulty,
-#count {
- background-color: #202232;
- min-width: 250px;
- text-align: center;
- cursor: default;
-
- border-radius: 24px;
- display: grid;
- grid-template-rows: 20px 40px 40px;
-}
-#difficulty>span:nth-child(1),
-#count>span:nth-child(1){
- padding-top:10px;
- font-size: 18px;
- color:#cdcfdf
-}
-#difficulty>span:nth-child(2){
- font-size: 40px;
-}
-#difficulty>div{
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
- padding: 0 calc(50% - 125px) 0 calc(50% - 125px);
- place-items: center;
-}
-
-.difficulty-rating{
- border-radius: 24px;
- width: 40px; height: 3px;
- background-color: #2b2e46;
-}
-
-#count>div{
- padding-top:10px;
- font-size: 50px;
- color:white
-}
-
-/* Section 5: route desc + video */
-#section5{
- margin: 40px 0 20px 0;
- width: 100%;
-}
-
-#description{
- width: 100%; height: auto;
- min-height: 342px;
-}
-
-
-
-
-#description>iframe{
- margin: 4px;
- float:right;
- border: 0;
- border-radius: 24px;
- width: 608px; height: 342px;
-}
-
-#description>h3{margin: 0 0 10px 0; color: white;}
-#description-text{
- display: block;
- font-size: 21px;
- word-wrap: break-word;
-}
-#description-text>b{font-size: inherit;}
-#description-text>a{font-size: inherit;color: #3c91e6;}
-
-
-/* Section 6: leaderboards */
-#section6{
- margin: 40px 0 20px 0;
- min-height: 600px;
- background-color: #202232;
-
- border-radius: 24px;
- padding: 10px 10px 0 10px;
-
-}
-
-
-#section6>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
-#leaderboard-top{
- display: grid;
- font-size: 20px;
- height: 34px;
- padding-left: 60px;
- margin: 0 20px 0 20px;
-}
-#leaderboard-top>span{
-
- display: flex;
- place-items: flex-end;
-}
-
-#runner{
- display: grid;
- grid-template-columns: 50% 50%;
- align-items: end;
-}
-
-#page-number{
- display: flex;
- width: auto;
- flex-direction: row-reverse;
-}
-#page-number>div{
-width: 100px;
-place-items: center;
-display: grid;
-grid-template-columns: 1fr 1fr 1fr;
-text-align: center;
-}
-#page-number>div>button{
- width: 30px;
- height: 30px;
- background-color: #202232;
- border: 0;
- padding: 0;
- cursor: pointer;
-}
-
-.leaderboard-record{
- margin: 10px 20px 0px 20px;
- height: 44px; width: calc(100% - 40px);
- width: auto;
-
- color: inherit;
- border-radius: 40px;
- text-align: left;
- padding: 0 0 0 60px;
- font-size: 20px;
- font-family: inherit;
-
- grid-template-columns: 3% 4.5% 40% 4% 3.5% 15% 15% 15%;
- display: grid;
-
- border: 0;
- transition: background-color .1s;
- background-color: #2b2e46;
-}
-
-.leaderboard-record>span:nth-child(1){display: grid;}
-.leaderboard-record>span:nth-child(4){display: grid;}
-.leaderboard-record>span:last-child{flex-direction: row-reverse;}
-.leaderboard-record>span{
- display: flex;
- place-items: center;
- height: 44px;
-}
-
-.leaderboard-record>div>span>img{
- height: 36px;
- border-radius: 50px;
- padding: 0;
- scale: .95;
-}
-.leaderboard-record>div{
- display: grid;
- grid-template-columns: 50% 50%;
- place-items: left;
-}
-.leaderboard-record>div>span{
- display: flex;
- place-items: center;
- height: 44px;
-}
-
-.leaderboard-record>span>button{
- background-color: #0000;
- border: 0;
- cursor: pointer;
- transition: opacity 0.1s;
-}
-
-.hover-popup {
- position: relative;
- }
-
- .hover-popup::after {
- content: attr(popup-text);
- position: absolute;
- /* top: 0%; */
- /* left: 80%; */
- /* transform: translateX(-100%); */
- /* padding: 5px; */
- background-color: #2b2e46;
- /* border: 1px solid #161723; */
- border-radius: 8px;
- visibility: hidden;
- opacity: 0;
- /* transition: visibility 0s, opacity 0.3s ease; */
- }
-
- .hover-popup:hover::after {
- visibility: visible;
- opacity: 1;
- }
-
-.leaderboard-record:last-child{margin: 10px 20px 10px 20px;}
-
-
-#section7{
- margin: 40px 0 20px 0;
- background-color: #202232;
- border-radius: 24px;
- padding: 10px;
-}
-
-#discussion-search{
- height: 46px;
- width: 100%;
- display: grid;
- grid-template-columns: 1fr 100px;
- margin: 0 0 20px 0;
-}
-#discussion-search>input::placeholder{color: #aaa;}
-#discussion-search>input{
- background-color: #2b2e46;
- font-size: 20px;
- padding-left: 10px;
- color: white;
- border: 0;
- border-radius: 16px 0 0 16px;
- font-family: inherit;
-}
-#discussion-search>div>button:hover{filter: brightness(75%);}
-#discussion-search>div>button{
- padding: 7px 16px;
- margin: 8px 0;
- border: 0;
- font-size: 16px;
- border-radius: 24px;
- display: block;
- background-color:#3c91e6;
- font-family: inherit;
- font-weight: bold;
- cursor: pointer;
- color: white;
-
- transition: filter .2s;
-}
-#discussion-search>div{
- background-color: #2b2e46;
- border-radius: 0 16px 16px 0;
-}
-#discussion-post>button:nth-child(1)>span>b{font-size: 18px;color:#cdcfdf;font-weight: lighter;}
-#discussion-post>button:nth-child(1){
- background-color: #2b2e46;
- display: grid;
- grid-template-columns: minmax(0, 1fr) 150px;
-
- border-radius: 16px;
- padding: 16px 12px;
- margin: 8px 0 0 0;
- border: 0;
- width: 100%; height: 100px;
- text-align: start;
- white-space: nowrap;
- color: #cdcfdf;
- cursor: pointer;
- overflow: hidden;
-}
-#discussion-post>button:nth-child(1)>span:nth-child(1){font-size: 32px;}
-#discussion-post>button:nth-child(1)>span:nth-child(3){color: #aaa; font-size: 18px;}
-#discussion-post>button:nth-child(1)>span:nth-child(4){
- opacity: .7;
- height: 40px;
- display: flex;
- place-items: end;
- justify-content: end;
-}
-
-#discussion-post{height: 100px;}
-#discussion-post>button>button:hover{filter: brightness(75%); }
-#discussion-post>button>button{
- padding: 7px 16px;
-
- border: 0;
- font-size: 16px;
- border-radius: 24px;
- background-color:#e52d04;
- font-family: BarlowSemiCondensed-Regular;
- font-weight: bold;
- cursor: pointer;
- color: white;
-
- transition: filter .2s;
-}
-
-
-#discussion-create>div{
- display: grid;
- text-align: start;
-}
-#discussion-create{
- display: grid;
- grid-template-columns: 1fr 40px;
- height: auto;
- word-wrap: break-word;
-}
-
-#discussion-create>span{padding-left: 20px;}
-#discussion-create>div>input::placeholder{color: #aaa;}
-#discussion-create>div>input{
- background-color: #2b2e46;
- font-size: 20px;
- padding-left: 10px;
- margin-top: 10px;
- height: 32px;
- color: white;
- border: 0;
- font-family: inherit;
-}
-#discussion-create>div>input:nth-child(2){font-size: 16px;}
-
-#discussion-create-button:hover{filter: brightness(75%);}
-#discussion-create-button{
- padding: 7px 16px;
- margin: 8px 0 0 0;
- border: 0;
- font-size: 16px;
- border-radius: 24px;
-
- background-color:#3c91e6;
- font-family: inherit;
- font-weight: bold;
- cursor: pointer;
- color: white;
- width: min-content;
- grid-column: 1 / span 2;
-
-
- transition: filter .2s;
-}
-
-
-#discussion-thread>div:nth-child(1){
- display: grid;
- grid-template-columns: 1fr 40px;
- height: auto;
- padding: 0 0 10px 20px;
- word-wrap: break-word;
-}
-
-#discussion-create>button:nth-child(2),
-#discussion-thread>div>button{
- height: 40px;
- float:inline-end;
- color:#cdcfdf;
- background-color: #0000;
- border: 0;
- font-size: 38px;
- cursor: pointer;
-}
-
-
-#discussion-thread>div:nth-child(2)>img{
- width: 60px; height: 60px;
- border-radius: 100px;
- margin: 20px 0 0 0;
-}
-#discussion-thread>div:nth-child(2)>div{
- height: max-content;
- padding: 20px 0 0 10px;
- display: inline-grid;
- grid-template-columns: min-content 1fr ;
- overflow: hidden;
-
-}
-#discussion-thread>div:nth-child(2)>div>span:nth-child(1){font-weight: bold;height: 30px;}
-#discussion-thread>div:nth-child(2)>div>span:nth-child(2){
- opacity: 0.6;
- height: 30px;
- font-size: 80%;
- padding-left: 10px;
-}
-#discussion-thread>div:nth-child(2)>div>span:nth-child(3){
- grid-column: 1 / span 2;
- height: max-content;
- word-wrap: break-word;
-}
-#discussion-thread>div:nth-child(2){
- display: grid;
- grid-template-columns: 60px 1fr;
- font-size: 20px;
- max-height: 522px;
- overflow-y: auto;
-}
-
-
-#discussion-send{
- height: 48px;
- width: 100%;
- display: grid;
- grid-template-columns: 1fr 80px;
- margin: 10px 0 0 0;
-}
-#discussion-send>input::placeholder{color: #aaa;}
-#discussion-send>input{
- background-color: #2b2e46;
- padding-left: 10px;
- color: white;
- border: 0;
- font-size: 20px;
- border-radius: 16px 0 0 16px;
- font-family: inherit;
-}
-#discussion-send>div{
- background-color: #2b2e46;
- border-radius: 0 16px 16px 0;
-
-}
-#discussion-send>div>button:hover{ filter: brightness(75%);}
-#discussion-send>div>button{
- padding: 7px 20px;
- margin: 8px 0;
- font-size: 16px;
- border: 0;
- border-radius: 24px;
- display: block;
- background-color:#3c91e6;
- font-family: inherit;
- font-weight: bold;
- cursor: pointer;
- color: white;
-
- transition: filter .2s;
-}
-
-
-
-.triangle{
- display: inline-block;
- width: 8px; height: 0;
- border-top: 7px solid transparent;
- border-right: 8px solid #cdcfdf;
- border-bottom: 7px solid transparent;
-}
-
- /* such responsive, very mobile */
-@media screen and (max-width: 1480px) {
- #section3.summary1{grid-template-columns: auto;}
- #category{min-width: 608px;}
- #history{min-width: 608px;}
- #description{min-width: 608px;}
- #section4.summary1{min-width: 588px;}
-
- #description>iframe{
- padding: 0 0 0 calc(50% - 304px);
- float:none;
- justify-content: center;
- align-items: center;
- }
-
- #section1.summary1{
- grid-template-columns: auto;
- place-items: center;
- text-align: center;
-
- }
-
- #section2.summary1{
- grid-template-columns: auto;
- width: 450px;
- margin: 40px auto 0 auto;
- }
- #section2.summary1>.nav-button:nth-child(1){border-radius: 30px 30px 0 0;}
- #section2.summary1>.nav-button:nth-child(2){border-radius: 0;}
- #section2.summary1>.nav-button:nth-child(3){border-radius: 0 0 30px 30px;}
-}
\ No newline at end of file
diff --git a/frontend/src/components/pages/summary.js b/frontend/src/components/pages/summary.js
deleted file mode 100644
index d276408..0000000
--- a/frontend/src/components/pages/summary.js
+++ /dev/null
@@ -1,650 +0,0 @@
-import React, { useEffect } from 'react';
-import { useLocation, Link } from "react-router-dom";
-import ReactMarkdown from 'react-markdown'
-
-import "./summary.css";
-
-import img4 from "../../imgs/4.png"
-import img5 from "../../imgs/5.png"
-import img6 from "../../imgs/6.png"
-import img12 from "../../imgs/12.png"
-import img13 from "../../imgs/13.png"
-import Modview from "./summary_modview.js"
-
-export default function Summary(prop) {
-const {token,mod} = prop
-const fakedata={} //for debug
-
- const location = useLocation()
-
- //fetching data
- const [data, setData] = React.useState(null);
- React.useEffect(() => {
- setData(null)
- setDiscussionThread(null)
- setCreatePostState(0)
- setSelectedRun(0)
- setCatState(1)
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/summary`)
- .then(r => r.json())
- .then(d => {
- if(Object.keys(fakedata).length!==0){setData(fakedata)}
- else{setData(d.data)}
- if(d.data.summary.routes.length===0){d.data.summary.routes[0]={"category": "","history": {"score_count": 0,},"rating": 0,"description": "","showcase": ""}}
- })
- // eslint-disable-next-line
- }, [location.pathname]);
-
- const [pageNumber, setPageNumber] = React.useState(1);
- const [lbData, setLbData] = React.useState(null);
- React.useEffect(() => {
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/leaderboards?page=${pageNumber}`)
- .then(r => r.json())
- .then(d => setLbData(d))
- // eslint-disable-next-line
- }, [pageNumber,location.pathname]);
-
- const [discussions,setDiscussions] = React.useState(null)
- function fetchDiscussions() {
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions`)
- .then(r=>r.json())
- .then(d=>setDiscussions(d.data.discussions))
- }
-
- React.useEffect(()=>{
- fetchDiscussions()
- },[location.pathname])
-
-
-
-const [discussionThread,setDiscussionThread] = React.useState(null)
-function openDiscussion(x){
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${x}`)
- .then(r=>r.json())
- .then(d=>setDiscussionThread(d.data.discussion))
-}
-const [discussionSearch, setDiscussionSearch] = React.useState("")
-
-
-
-
-const [navState, setNavState] = React.useState(0); // eslint-disable-next-line
-React.useEffect(() => {NavClick();}, [[],navState]);
-
-function NavClick() {
- if(data!==null){
- const btn = document.querySelectorAll("#section2 button.nav-button");
- btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"});
- btn[navState].style.backgroundColor = "#202232";
-
- document.querySelectorAll("section").forEach((e,i)=>i>=2?e.style.display="none":"")
- if(navState === 0){document.querySelectorAll(".summary1").forEach((e) => {e.style.display = "grid"});}
- if(navState === 1){document.querySelectorAll(".summary2").forEach((e) => {e.style.display = "block"});}
- if(navState === 2){document.querySelectorAll(".summary3").forEach((e) => {e.style.display = "block"});}
-}}
-
-
-const [catState, setCatState] = React.useState(1); // eslint-disable-next-line
-React.useEffect(() => {CatClick();}, [[],catState]);
-
-function CatClick() {
- if(data!==null){
- const btn = document.querySelectorAll("#section3 #category span button");
- btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"});
- btn[catState-1].style.backgroundColor = "#202232";
-}}
-React.useEffect(()=>{
- if(data!==null && data.summary.routes.filter(e=>e.category.id===catState).length!==0){
- selectRun(0,catState)} // eslint-disable-next-line
-},[catState,data])
-
-
-const [hisState, setHisState] = React.useState(0); // eslint-disable-next-line
-React.useEffect(() => {HisClick();}, [[],hisState]);
-
-function HisClick() {
- if(data!==null){
- const btn = document.querySelectorAll("#section3 #history span button");
- btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"});
- btn[hisState].style.backgroundColor = "#202232";
-
-}}
-
-const [selectedRun,setSelectedRun] = React.useState(0)
-
-function selectRun(x,y){
- let r = document.querySelectorAll("button.record")
- r.forEach(e=>e.style.backgroundColor="#2b2e46")
- r[x].style.backgroundColor="#161723"
-
-
- if(data!==null && data.summary.routes.length!==0 && data.summary.routes.length!==0){
- if(y===2){x+=data.summary.routes.filter(e=>e.category.id<2).length}
- if(y===3){x+=data.summary.routes.filter(e=>e.category.id<3).length}
- if(y===4){x+=data.summary.routes.filter(e=>e.category.id<4).length}
- setSelectedRun(x)
- }
-}
-
-function graph(state) {
- // this is such a mess
- let graph = data.summary.routes.filter(e=>e.category.id===catState)
- let graph_score = []
- data.summary.routes.filter(e=>e.category.id===catState).forEach(e=>graph_score.push(e.history.score_count))
- let graph_dates = []
- data.summary.routes.filter(e=>e.category.id===catState).forEach(e=>graph_dates.push(e.history.date.split("T")[0]))
- let graph_max = graph[graph.length-1].history.score_count
- let graph_numbers = []
- for (let i=graph_max;i>=0;i--){
- graph_numbers[i]=i
- }
-
- switch (state) {
- case 1: //numbers
- return graph_numbers
- .reverse().map(e=>(
- graph_score.includes(e) || e===0 ?
-
{e}
- :
-
- ))
- case 2: // graph
- let g = 0
- let h = 0
- return graph_numbers.map((e,j)=>(
-
- {
- graph_score.map((e,i)=>(
- <>
- | =h ? "1px dashed white" : "0" }}
- > |
-
- {g===h && graph_score.includes(graph_max-j) ?
- {
- selectRun(graph_dates.length-(i-1),catState);
- }}
- style={{left: `calc(100% / ${graph_dates.length} * ${h-1})`}}
- >
- : ""}
-
- =h ?
- g-1>=h ? "1px dashed #2b2e46" : "1px solid white" : "0"
- : "0"}}
- > |
-
-
-
- =h ?
- g-1>=h ? "1px dashed #2b2e46" : "1px solid white" : "0"
- : "0"}}
- > |
-
- >
- ))
-
- }
-
-
- ))
-
- case 3: // dates
- return graph_dates
- .reverse().map(e=>(
-
{e}
- ))
- default:
- break;
-
- }
-
-}
-
-const [vid,setVid] = React.useState("")
-React.useEffect(()=>{
- if(data!==null){
- let showcase = data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].showcase
- showcase.length>6 ? setVid("https://www.youtube.com/embed/"+YouTubeGetID(showcase))
- : setVid("")
- } // eslint-disable-next-line
-},[[],selectedRun])
-
-function YouTubeGetID(url){
- url = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
- return (url[2] !== undefined) ? url[2].split(/[^0-9a-z_]/i)[0] : url[0];
- }
-
-function TimeAgo(date) {
- // const seconds = Math.floor((new Date() - date) / 1000);
-
- const seconds = Math.floor(((new Date(new Date() - (date.getTimezoneOffset()*-60000))) - date) / 1000);
-
- let interval = Math.floor(seconds / 31536000);
- if (interval === 1) {return interval + ' year ago';}
- if (interval > 1) {return interval + ' years ago';}
-
- interval = Math.floor(seconds / 2592000);
- if (interval === 1) {return interval + ' month ago';}
- if (interval > 1) {return interval + ' months ago';}
-
- interval = Math.floor(seconds / 86400);
- if (interval === 1) {return interval + ' day ago';}
- if (interval > 1) {return interval + ' days ago';}
-
- interval = Math.floor(seconds / 3600);
- if (interval === 1) {return interval + ' hour ago';}
- if (interval > 1) {return interval + ' hours ago';}
-
- interval = Math.floor(seconds / 60);
- if (interval === 1) {return interval + ' minute ago';}
- if (interval > 1) {return interval + ' minutes ago';}
-
- if(seconds < 10) return 'just now';
-
- return Math.floor(seconds) + ' seconds ago';
- };
-
-function TicksToTime(ticks) {
-
- let seconds = Math.floor(ticks/60)
- let minutes = Math.floor(seconds/60)
- let hours = Math.floor(minutes/60)
-
- let milliseconds = Math.floor((ticks%60)*1000/60)
- seconds = seconds % 60;
- minutes = minutes % 60;
-
- return `${hours===0?"":hours+":"}${minutes===0?"":hours>0?minutes.toString().padStart(2, '0')+":":(minutes+":")}${minutes>0?seconds.toString().padStart(2, '0'):seconds}.${milliseconds.toString().padStart(3, '0')} (${ticks})`;
-}
-
-function PostComment() {
-
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${discussionThread.id}`,{
- method:"POST",
- headers:{authorization:token},
- body:JSON.stringify({"comment":document.querySelector("#discussion-send>input").value})
-})
-.then(r=>r.json())
-.then(d=>{
- document.querySelector("#discussion-send>input").value=""
- openDiscussion(discussionThread.id)
-})
-}
-
-
-const [createPostState,setCreatePostState] = React.useState(0)
-function CreatePost() {
-
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions`,{
- method:"POST",
- headers:{authorization:token},
- body:JSON.stringify({"title":document.querySelector("#discussion-create-title").value,"content":document.querySelector("#discussion-create-content").value})
- })
- .then(r=>r.json())
- .then(d=>{
- setCreatePostState(0)
- fetchDiscussions()
- })
-}
-
-function DeletePost(post) {
-if(window.confirm(`Are you sure you want to remove post: ${post.title}?`)){
- console.log("deleted",post.id)
- fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${post.id}`,{
- method:"DELETE",
- headers:{authorization:token},
- })
- .then(r=>r.json())
- .then(d=>{
- fetchDiscussions()
- })
-}
-}
-
-
-if(data!==null){
- console.log(data)
-
-let current_chapter = data.map.chapter_name
-let isCoop = false;
-if (data.map.game_name == "Portal 2 - Cooperative") {
- isCoop = true
-}
-
-current_chapter = data.map.chapter_name.split(" ")
-// current_chapter = current_chapter.split("-")
-current_chapter = current_chapter[1]
-
-return (
- <>
- {token!==null?mod===true?
:"":""}
-
-
-

-
-
-
-
- Games list
- {data.map.chapter_name}
-
{data.map.map_name}
-
-
-
-
-
-
- setNavState(0)}>
Summary
- setNavState(1)}>
Leaderboards
- setNavState(2)}>
Discussions
-
-
-
-

-
{data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].history.score_count}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].history.score_count === 1 ? ` portal` : ` portals` }
-
- setCatState(1)}>CM
- setCatState(2)}>NoSLA
- {data.map.is_coop?setCatState(3)}>SLA
- :setCatState(3)}>Inbounds SLA}
- setCatState(4)}>Any%
-
-
-
-
-
-
-
- {data.summary.routes.filter(e=>e.category.id===catState).length===0 ?
There are no records for this map.
:
- <>
-
- Date
- Record
- First completion
-
-
-
-
- {data.summary.routes
- .sort((a, b) => a.history.score_count - b.history.score_count)
- .filter(e=>e.category.id===catState)
- .map((r, index) => (
- {
- selectRun(index,r.category.id);
- }}>
- { new Date(r.history.date).toLocaleDateString(
- "en-US", { month: 'long', day: 'numeric', year: 'numeric' }
- )}
- {r.history.score_count}
- {r.history.runner_name}
-
- ))}
-
- >
- }
-
-
-
- {data.summary.routes.filter(e=>e.category.id===catState).length===0 ?
There are no records for this map.
:
-
-
{graph(1)}
-
{graph(2)}
-
{graph(3)}
-
- }
-
-
- setHisState(0)}>List
- setHisState(1)}>Graph
-
-
-
-
-
-
-
-
Difficulty
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 0 ? (
N/A):null}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 1 ? (
Very easy):null}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 2 ? (
Easy):null}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 3 ? (
Medium):null}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 4 ? (
Hard):null}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 5 ? (
Very hard):null}
-
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 1 ? (
) : (
)}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 2 ? (
) : (
)}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 3 ? (
) : (
)}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 4 ? (
) : (
)}
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 5 ? (
) : (
)}
-
-
-
-
Completion count
-
{catState===1?data.summary.routes[selectedRun].completion_count:"N/A"}
-
-
-
-
-
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].showcase!=="" ?
-
- : ""}
-
Route description
-
-
- {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].description}
-
-
-
-
-
- {/* Leaderboards */}
-
- {lbData===null?"":lbData.success===false?(
-
- Map is not available for competitive boards.
-
- ):lbData.data.records.length===0?(
-
- ):(
-
-
-
-
Place
-
- {lbData.data.map.is_coop?(
-
- Host
- Partner
-
- ):(
-
Runner
- )}
-
-
Portals
-
Time
-
Date
-
-
-
- pageNumber === 1 ? null : setPageNumber(prevPageNumber => prevPageNumber - 1)}
- >
- {lbData.data.pagination.current_page}/{lbData.data.pagination.total_pages}
- pageNumber === lbData.data.pagination.total_pages ? null : setPageNumber(prevPageNumber => prevPageNumber + 1)}
- >
-
-
-
-
-
-
- )}
-
-
- {/* Discussions */}
-
-
- {discussionThread === null ? (
- createPostState === 0 ? (
- discussions !== null ? (
- // Main screen
- <>
-
-
setDiscussionSearch(document.querySelector("#discussion-search>input").value)} />
-
setCreatePostState(1)}>New Post
-
- {discussions.filter(f=>f.title.includes(discussionSearch)).sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))
- .map((e, i) => (
-
-
- openDiscussion(e.id)}>
- {e.title}
-
- {token!==null?e.creator.steam_id===JSON.parse(atob(token.split(".")[1])).sub?
- DeletePost(e)}>Delete Post
- ::}
- {e.creator.user_name}: {e.content}
- last updated: {TimeAgo(new Date(e.updated_at.replace("T"," ").replace("Z","")))}
-
-
- ))}
- >
- ):(
-
- // Main screen (no posts)
- <>
-
-
setDiscussionSearch(document.querySelector("#discussion-search>input").value)} />
-
setCreatePostState(1)}>New Post
-
- no discussions
->
- )
- ):(
- // Creating post
-
-
Create post
-
setCreatePostState(0)}>X
-
-
-
-
-
- CreatePost()}>Post
-
-
-
-
- )):(
- // Post screen
-
-
- {discussionThread.title}
- setDiscussionThread(null)}>X
-
-
-
-

-
- {discussionThread.creator.user_name}
- {TimeAgo(new Date(discussionThread.created_at.replace("T"," ").replace("Z","")))}
- {discussionThread.content}
-
- {discussionThread.comments!==null?
- discussionThread.comments.sort((a, b) => new Date(a.date) - new Date(b.date))
- .map(e=>(
- <>
-

-
- {e.user.user_name}
- {TimeAgo(new Date(e.date.replace("T"," ").replace("Z","")))}
- {e.comment}
-
- >
-
- )):""}
-
-
-
-
-
e.key==="Enter"?PostComment():""}/>
-
PostComment()}>Send
-
-
-
-
-
- )}
-
-
-
-
- >
- )
-}else{
- return (
-
- )
-}
-
-
-}
-
-
diff --git a/frontend/src/components/pages/summary_modview.css b/frontend/src/components/pages/summary_modview.css
deleted file mode 100644
index c6d3d8d..0000000
--- a/frontend/src/components/pages/summary_modview.css
+++ /dev/null
@@ -1,112 +0,0 @@
-div#modview{
- position: absolute;
- left: 50%;
- z-index: 20;
- width: 320px; height: auto;
- /* background-color: red; */
-
- transform: translateY(-68%);
-}
-div#modview>div>button{
- height: 30px;
-}
-
-div#modview>div:nth-child(1){
- display: grid;
- grid-template-columns: 50% 50%;
-}
-
-div#modview>div:nth-child(2){
- display: grid;
- place-items: center;
-}
-
-#modview-menu{
- position: absolute;
- left: calc(50% + 160px); top: 130px;
- transform: translateX(-50%);
- background-color: #2b2e46;
- z-index: 2; color: white;
-}
-
-#modview-menu-image{
- box-shadow: 0 0 40px 16px black;
- outline: 8px solid #2b2e46;
- border-radius: 20px;
- font-size: 40px;
- display: grid;
- grid-template-columns: 50% 50%;
- /* place-items: center; */
-
-}
-#modview-menu-image>div:nth-child(1){
- height: 400px; width: 500px;
- display: grid;
- grid-template-rows: 30% 70%;
-}
-#modview-menu-image>div:nth-child(2){
- height: 400px; width: 500px;
- display: grid;
- grid-template-rows: 20% 10%;
-}
-
-#modview-menu-image>div>button{width: 300px;margin-left:100px;}
-#modview-menu-image>div>img{width: 500px;}
-#modview-menu-image>div>button{font-size: 20px;}
-#modview-menu-image>div>span>input[type="file"]{font-size: 15px;}
-
-
-#modview-menu-add,
-#modview-menu-edit{
- box-shadow: 0 0 40px 16px black;
- outline: 8px solid #2b2e46;
- border-radius: 20px;
- font-size: 40px;
- display: grid;
- grid-template-columns: 20% 20% 20% 20% 20%;
-}
-
-#modview-menu-add>div,
-#modview-menu-edit>div{
- display: grid;
- margin: 20px;
- width: 200px;
- font-size: 20px;
-}
-#modview-route-description>textarea{
- resize: none;
- height: 160px;
- width: 1160px;
-}
-#modview-route-showcase>input::placeholder{opacity: .5;}
-#modview_block{
- position: absolute;
- background-color: black;
- opacity: .3;
- left: 320px;
- width: calc(100% - 320px);
- height: 100%;
- z-index: 2;
- cursor: no-drop;
-}
-#modview-md{
- box-shadow: 0 0 40px 16px black;
- background-color: #2b2e46;
- outline: 8px solid #2b2e46;
-
- border-radius: 20px;
- position: absolute;
- padding: 10px; top: 400px;
- width: 1180px; height: 300px;
- overflow-y: auto;
- word-wrap: break-word;
-}
-#modview-md>span>a{
- padding-left: 20px;
- color:aqua;
-}
-#modview-md>p{
- font-family: BarlowSemiCondensed-Regular;
- color: #cdcfdf;
- font-size: 21px;
-}
\ No newline at end of file
diff --git a/frontend/src/components/pages/summary_modview.js b/frontend/src/components/pages/summary_modview.js
deleted file mode 100644
index 3541c48..0000000
--- a/frontend/src/components/pages/summary_modview.js
+++ /dev/null
@@ -1,254 +0,0 @@
-import React from 'react';
-import { useLocation } from "react-router-dom";
-import ReactMarkdown from 'react-markdown'
-
-import "./summary_modview.css";
-
-
-export default function Modview(prop) {
-const {selectedRun,data,token} = prop
-
-const [menu,setMenu] = React.useState(0)
-React.useEffect(()=>{
-if(menu===3){ // add
- document.querySelector("#modview-route-name>input").value=""
- document.querySelector("#modview-route-score>input").value=""
- document.querySelector("#modview-route-date>input").value=""
- document.querySelector("#modview-route-showcase>input").value=""
- document.querySelector("#modview-route-description>textarea").value=""
- }
-if(menu===2){ // edit
- document.querySelector("#modview-route-id>input").value=data.summary.routes[selectedRun].route_id
- document.querySelector("#modview-route-name>input").value=data.summary.routes[selectedRun].history.runner_name
- document.querySelector("#modview-route-score>input").value=data.summary.routes[selectedRun].history.score_count
- document.querySelector("#modview-route-date>input").value=data.summary.routes[selectedRun].history.date.split("T")[0]
- document.querySelector("#modview-route-showcase>input").value=data.summary.routes[selectedRun].showcase
- document.querySelector("#modview-route-description>textarea").value=data.summary.routes[selectedRun].description
-} // eslint-disable-next-line
-},[menu])
-
-function compressImage(file) {
- const reader = new FileReader();
- reader.readAsDataURL(file);
- return new Promise(resolve => {
- reader.onload = () => {
- const img = new Image();
- img.src = reader.result;
- img.onload = () => {
- let {width, height} = img;
- if (width > 550) {
- height *= 550 / width;
- width = 550;
- }
- if (height > 320) {
- width *= 320 / height;
- height = 320;
- }
- const canvas = document.createElement('canvas');
- canvas.width = width;
- canvas.height = height;
- canvas.getContext('2d').drawImage(img, 0, 0, width, height);
- resolve(canvas.toDataURL(file.type, 0.6));
- };
- };
- });
-}
-const [image,setImage] = React.useState(null)
-function uploadImage(){
- if(window.confirm("Are you sure you want to submit this to the database?")){
- fetch(`/api/v1/maps/${location.pathname.split('/')[2]}/image`,{
- method: 'PUT',
- headers: {Authorization: token},
- body: JSON.stringify({"image": image})
- }).then(r=>window.location.reload())
- }
-}
-const location = useLocation()
-function editRoute(){
-if(window.confirm("Are you sure you want to submit this to the database?")){
- let payload = {
- "description": document.querySelector("#modview-route-description>textarea").value===""?"No description available.":document.querySelector("#modview-route-description>textarea").value,
- "record_date": document.querySelector("#modview-route-date>input").value+"T00:00:00Z",
- "route_id": parseInt(document.querySelector("#modview-route-id>input").value),
- "score_count": parseInt(document.querySelector("#modview-route-score>input").value),
- "showcase": document.querySelector("#modview-route-showcase>input").value,
- "user_name": document.querySelector("#modview-route-name>input").value
- }
- fetch(`/api/v1/maps/${location.pathname.split('/')[2]}/summary`,{
- method: 'PUT',
- headers: {Authorization: token},
- body: JSON.stringify(payload)
- }).then(r=>window.location.reload())
- }
-}
-
-
-function addRoute(){
- if(window.confirm("Are you sure you want to submit this to the database?")){
- let payload = {
- "category_id": parseInt(document.querySelector("#modview-route-category>select").value),
- "description": document.querySelector("#modview-route-description>textarea").value===""?"No description available.":document.querySelector("#modview-route-description>textarea").value,
- "record_date": document.querySelector("#modview-route-date>input").value+"T00:00:00Z",
- "score_count": parseInt(document.querySelector("#modview-route-score>input").value),
- "showcase": document.querySelector("#modview-route-showcase>input").value,
- "user_name": document.querySelector("#modview-route-name>input").value
- }
- fetch(`/api/v1/maps/${location.pathname.split('/')[2]}/summary`,{
- method: 'POST',
- headers: {Authorization: token},
- body: JSON.stringify(payload)
- }).then(r=>window.location.reload())
- }
-}
-
-function deleteRoute(){
-if(data.summary.routes[0].category==='')
-{window.alert("no run selected")}else{
-if(window.confirm(`Are you sure you want to delete this run from the database?
-${data.summary.routes[selectedRun].category.name} ${data.summary.routes[selectedRun].history.score_count} portals ${data.summary.routes[selectedRun].history.runner_name}`)===true){
- console.log("deleted:",selectedRun)
- fetch(`/api/v1/maps/${location.pathname.split('/')[2]}/summary`,{
- method: 'DELETE',
- headers: {Authorization: token},
- body: JSON.stringify({"route_id":data.summary.routes[selectedRun].route_id})
- }).then(r=>window.location.reload())
-}}
-
-}
-
-const [showButton, setShowButton] = React.useState(1)
-const modview = document.querySelector("div#modview")
-React.useEffect(()=>{
- if(modview!==null){
- showButton ? modview.style.transform="translateY(-68%)"
- : modview.style.transform="translateY(0%)"
- }
- let modview_block = document.querySelector("#modview_block")
- showButton===1?modview_block.style.display="none":modview_block.style.display="block"// eslint-disable-next-line
-},[showButton])
-
-const [md,setMd] = React.useState("")
-
-return (
- <>
-
-
-
- setMenu(1)}>edit image
- window.alert("no run selected"):()=>setMenu(2)}>edit selected route
- setMenu(3)}>add new route
- deleteRoute()}>delete selected route
-
-
- {showButton ?(
- setShowButton(0)}>Show
- ) : (
- {setShowButton(1);setMenu(0)}}>Hide
- )}
-
-
- {menu!==0? (
- ):""}
-
- >
-)
-}
-
diff --git a/frontend/src/components/record.css b/frontend/src/components/record.css
deleted file mode 100644
index 60d47ee..0000000
--- a/frontend/src/components/record.css
+++ /dev/null
@@ -1,15 +0,0 @@
-.record-container {
- --padding: 20px;
- width: calc(100% - calc(var(--padding * 2)));
- height: 42px;
- background-color: #2B2E46;
- border-radius: 200px;
- font-size: 18px;
- display: grid;
- grid-template-columns: 20% 25% 15% 15% 25%;
- text-align: center;
- padding: 0px var(--padding);
- vertical-align: middle;
- align-items: center;
- margin-bottom: 6px;
-}
\ No newline at end of file
diff --git a/frontend/src/components/record.js b/frontend/src/components/record.js
deleted file mode 100644
index 80e084d..0000000
--- a/frontend/src/components/record.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { useLocation, Link } from "react-router-dom";
-
-import "./record.css"
-
-export default function Record({ name, place, portals, time, date }) {
- // const {token} = prop;
- const [record, setRecord] = useState(null);
- const location = useLocation();
-
- // useEffect(() => {
- // console.log(name, place, portals, time, date);
- // })
-
- function timeSince() {
- const now = new Date();
- const dateNew = new Date(date);
-
- const secondsPast = Math.floor((now - dateNew) / 1000);
-
- if (secondsPast < 60) {
- return `${secondsPast} seconds ago`;
- }
- if (secondsPast < 3600) {
- const minutes = Math.floor(secondsPast / 60);
- return `${minutes} minutes ago`;
- }
- if (secondsPast < 86400) {
- const hours = Math.floor(secondsPast / 3600);
- return `${hours} hours ago`;
- }
- if (secondsPast < 2592000) {
- const days = Math.floor(secondsPast / 86400);
- return `${days} days ago`;
- }
- if (secondsPast < 31536000) {
- const months = Math.floor(secondsPast / 2592000);
- return `${months} months ago`;
- }
- const years = Math.floor(secondsPast / 31536000);
- return `${years} years ago`;
- }
-
- return(
-
-
{place}
-
-

-
{name}
-
-
{portals}
-
{time}
-
{timeSince()}
-
- )
-}
diff --git a/frontend/src/components/sidebar.css b/frontend/src/components/sidebar.css
deleted file mode 100644
index 34ede80..0000000
--- a/frontend/src/components/sidebar.css
+++ /dev/null
@@ -1,208 +0,0 @@
-#sidebar {
- overflow: hidden;
- position: absolute;
- background-color: #2b2e46;
- width: 320px; height: 100vh;
- min-height: 670px;
-
-}
-
- /* logo */
-#logo{
- display: grid;
- grid-template-columns: 60px 200px;
-
-
- height: 80px;
- padding: 20px 0 20px 30px;
- cursor: pointer;
- user-select: none;
-}
-
-#logo-text{
- font-family: BarlowCondensed-Regular;
- font-size: 42px;
- color: #FFF;
- line-height: 38px;
-}
-span>b{
- font-family: BarlowCondensed-Bold;
- font-size: 56px;
-}
-
- /* Sidelist */
-#sidebar-list{
- z-index: 2;
- background-color: #2b2e46;
- position: relative;
- height: calc(100vh - 120px);
- width: 320px;
- /* min-height: 670px; */
- transition: width .3s;
-}
-#sidebar-toplist>button:nth-child(1){margin-top: 5px;}
-#sidebar-toplist{
- display: grid;
-
- margin: 0 5px 0 5px;
- justify-items: left;
- height: 400px;
- grid-template-rows: 45px 50px 50px 50px 50px 50px 50px 50px auto;
-}
-
-#sidebar-bottomlist{
- display: grid;
-
- margin: 0 5px 0 5px;
- justify-items: left;
- grid-template-rows: calc(100vh - 670px) 50px 50px 50px;
-}
-.sidebar-button>span{
- font-family: BarlowSemiCondensed-Regular;
- font-size: 18px;
- color: #CDCFDF;
- height: 32px;
- line-height: 28px;
- transition: opacity .1s;
-}
-.sidebar-button{
- display: grid;
- grid-template-columns: 50px auto;
- place-items: left;
- text-align: left;
-
- background-color: inherit;
- cursor: pointer;
- border: none;
- width: 310px;
- height: 40px;
- border-radius: 20px;
- padding: 0.4em 0 0 11px;
-
- transition:
- width .3s,
- background-color .15s,
- padding .3s;
-}
-
-.sidebar-button-selected {
- background-color: #202232;
-}
-
-.sidebar-button-deselected {
- background-color: #20223200;
-}
-
-.sidebar-button-deselected:hover {
- background-color: #202232aa;
-}
-
-button>img {
- scale: 1.1;
- width: 20px;
- padding: 5px;
-}
-
- /* Maplist */
-#sidebar>div:nth-child(3){
- position: relative;
- background-color: #202232;
- color: #424562;
- z-index: 1;
-
- left: 52px;
- top: calc(-100vh + 120px);
- width: 268px; height: calc(100vh - 120px);
- min-height: 550px;
-}
-input#searchbar[type=text]{
- margin: 10px 0 0 6px;
- padding: 1px 0px 1px 16px;
- width: 240px;
- height: 30px;
-
- font-family: BarlowSemiCondensed-Regular;
- font-size: 20px;
-
- background-color: #161723;
- color:#CDCFDF;
-
- border: 0;
- border-radius: 20px;
-
-}
-input[type=text]::placeholder{color:#2b2e46}
-input[type=text]:focus{outline: inherit;}
-a{text-decoration: none;height: 40px;}
-
-
-#search-data{
- margin: 8px 0 8px 0;
- overflow-y: auto;
- max-height: calc(100vh - 172px);
- scrollbar-width: thin;
-}
-#search-data::-webkit-scrollbar{display: none;}
-.search-map{
- margin: 10px 6px 0 6px;
- height: 80px;
-
- border-radius: 20px;
- text-align: center;
-
- display: grid;
-
- border: 0;
- transition: background-color .1s;
- background-color: #2b2e46;
- grid-template-rows: 20% 20% 60%;
- width: calc(100% - 15px);
-}
-.search-map>span{
- color: #888;
- font-size: 16px;
- font-family: BarlowSemiCondensed-Regular;
-}
-.search-map>span:nth-child(3){
- font-size: 30px;
- color: #CDCFDF;
-}
-
-.search-player{
- overflow: hidden;
- margin: 10px 6px 0 6px;
- height: 80px;
-
- border-radius: 20px;
- text-align: center;
- color: #CDCFDF;
- font-family: BarlowSemiCondensed-Regular;
-
- display: grid;
- place-items: center;
- grid-template-columns: 20% 80%;
- padding: 0 16px 0 16px;
-
- border: 0;
- transition: background-color .1s;
- background-color: #2b2e46;
-}
-.search-player>img{
- height: 60px;
- border-radius: 20px;
-}
-.search-player>span{
- width:154px;
- font-size: 26px;
-}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/components/sidebar.js b/frontend/src/components/sidebar.js
deleted file mode 100644
index 1ca17e6..0000000
--- a/frontend/src/components/sidebar.js
+++ /dev/null
@@ -1,203 +0,0 @@
-import React, { useEffect } from 'react';
-import { Link, useLocation } from "react-router-dom";
-
-import "../App.css"
-import "./sidebar.css";
-import logo from "../imgs/logo.png"
-import img1 from "../imgs/1.png"
-import img2 from "../imgs/2.png"
-import img3 from "../imgs/3.png"
-import img4 from "../imgs/4.png"
-import img5 from "../imgs/5.png"
-import img6 from "../imgs/6.png"
-import img7 from "../imgs/7.png"
-import img8 from "../imgs/8.png"
-import img9 from "../imgs/9.png"
-import Login from "./login.js"
-
-export default function Sidebar(prop) {
-const {token,setToken} = prop
-const [profile, setProfile] = React.useState(null);
-
-React.useEffect(() => {
- fetch(`https://lp.ardapektezol.com/api/v1/profile`,{
- headers: {
- 'Content-Type': 'application/json',
- Authorization: token
- }})
- .then(r => r.json())
- .then(d => setProfile(d.data))
- }, [token]);
-
-// Locks search button for 300ms before it can be clicked again, prevents spam
-const [isLocked, setIsLocked] = React.useState(false);
-function HandleLock(arg) {
-if (!isLocked) {
- setIsLocked(true);
- setTimeout(() => setIsLocked(false), 300);
- SidebarHide(arg)
- }
-}
-
-
-// The menu button
-const [sidebar, setSidebar] = React.useState();
-
-// Clicked buttons
-function SidebarClick(x){
-const btn = document.querySelectorAll("button.sidebar-button");
-
-if(sidebar===1){setSidebar(0);SidebarHide()}
-
-// clusterfuck
-btn.forEach((e,i) =>{
- btn[i].classList.remove("sidebar-button-selected")
- btn[i].classList.add("sidebar-button-deselected")
-})
-btn[x].classList.add("sidebar-button-selected")
-btn[x].classList.remove("sidebar-button-deselected")
-
-}
-
-function SidebarHide(){
-const btn = document.querySelectorAll("button.sidebar-button")
-const span = document.querySelectorAll("button.sidebar-button>span");
-const side = document.querySelector("#sidebar-list");
-const login = document.querySelectorAll(".login>button")[1];
-const searchbar = document.querySelector("#searchbar");
-
-if(sidebar===1){
- setSidebar(0)
- side.style.width="320px"
- btn.forEach((e, i) =>{
- e.style.width="310px"
- e.style.padding = "0.4em 0 0 11px"
- setTimeout(() => {
- span[i].style.opacity="1"
- login.style.opacity="1"
-
- }, 100)
- })
- side.style.zIndex="2"
-} else {
- side.style.width="40px";
- searchbar.focus();
- setSearch(searchbar.value)
- setSidebar(1)
- btn.forEach((e,i) =>{
- e.style.width="40px"
- e.style.padding = "0.4em 0 0 5px"
- span[i].style.opacity="0"
- })
- login.style.opacity="0"
- setTimeout(() => {
- side.style.zIndex="0"
- }, 300);
- }
-}
-// Links
-const location = useLocation()
-React.useEffect(()=>{
- if(location.pathname==="/"){SidebarClick(1)}
- if(location.pathname.includes("news")){SidebarClick(2)}
- if(location.pathname.includes("games")){SidebarClick(3)}
- if(location.pathname.includes("leaderboards")){SidebarClick(4)}
- if(location.pathname.includes("scorelog")){SidebarClick(5)}
- if(location.pathname.includes("profile")){SidebarClick(6)}
- if(location.pathname.includes("rules")){SidebarClick(8)}
- if(location.pathname.includes("about")){SidebarClick(9)}
-
- // eslint-disable-next-line react-hooks/exhaustive-deps
-}, [location.pathname])
-
-const [search,setSearch] = React.useState(null)
-const [searchData,setSearchData] = React.useState(null)
-
-React.useEffect(()=>{
- fetch(`https://lp.ardapektezol.com/api/v1/search?q=${search}`)
- .then(r=>r.json())
- .then(d=>setSearchData(d.data))
-
-}, [search])
-
-
-return (
-
- )
-}
-
-
diff --git a/frontend/src/css/Games.css b/frontend/src/css/Games.css
new file mode 100644
index 0000000..ec57a71
--- /dev/null
+++ b/frontend/src/css/Games.css
@@ -0,0 +1,99 @@
+.games-page {
+ position: absolute;
+ left: 320px;
+ color: white;
+ width: calc(100% - 320px);
+ height: 100%;
+ font-family: BarlowSemiCondensed-Regular;
+ color: #ffffff;
+ overflow-y: scroll;
+ scrollbar-width: thin;
+}
+
+.games-page-item-content {
+ position: absolute;
+ left: 50px;
+ width: calc(100% - 100px);
+}
+
+.games-page-item-content a {
+ color: inherit;
+}
+
+.games-page-header {
+ margin-top: 50px;
+ margin-left: 50px;
+}
+
+span>b {
+ font-size: 56px;
+ font-family: BarlowCondensed-Bold;
+}
+
+.loader-game {
+ width: 100%;
+ height: 256px;
+ border-radius: 24px;
+ overflow: hidden;
+ margin: 25px 0px;
+}
+
+.games-page-item {
+ width: 100%;
+ height: 256px;
+ background: #202232;
+ border-radius: 24px;
+ overflow: hidden;
+ margin: 25px 0px;
+}
+
+.games-page-item-header {
+ width: 100%;
+ height: 50%;
+ background-size: cover;
+ overflow: hidden;
+}
+
+.games-page-item-header-img {
+ width: 100%;
+ height: 100%;
+ backdrop-filter: blur(4px);
+ filter: blur(4px);
+ background-size: cover;
+}
+
+.games-page-item-header span>b {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+ transform: translateY(-100%);
+}
+
+.games-page-item-body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 50%;
+}
+
+.games-page-item-body-item {
+ background: #2B2E46;
+ text-align: center;
+ width: max-content;
+ width: calc(100% - 24px);
+ height: 100px;
+ border-radius: 24px;
+ color: #CDCFDF;
+ margin: 12px;
+}
+
+.games-page-item-body-item-title {
+ margin-top: 0px;
+ font-size: 26px;
+}
+
+.games-page-item-body-item-num {
+ font-size: 50px;
+ font-family: BarlowCondensed-Bold;
+}
\ No newline at end of file
diff --git a/frontend/src/css/Login.css b/frontend/src/css/Login.css
new file mode 100644
index 0000000..aa75f98
--- /dev/null
+++ b/frontend/src/css/Login.css
@@ -0,0 +1,26 @@
+span>img {
+ scale: 1.1;
+ padding: 4px 0 0 8px;
+}
+.login>button>span{
+ max-width: 22ch;
+ overflow: hidden;
+}
+.login>button:nth-child(2){
+ position: relative;
+ left: 210px;
+ width: 50px !important;
+
+ padding-left: 10px;
+ background-color: #00000000 !important;
+ /* transition: opacity .1s; */
+}
+
+.login{
+ display: grid;
+ grid-template-columns: 50px auto 200px ;
+}
+
+button:disabled {
+ display: none;
+}
\ No newline at end of file
diff --git a/frontend/src/css/Maps.css b/frontend/src/css/Maps.css
new file mode 100644
index 0000000..d164d3b
--- /dev/null
+++ b/frontend/src/css/Maps.css
@@ -0,0 +1,726 @@
+#background-image{
+ z-index: -1;
+ position: absolute;
+ opacity: 10%;
+ height: 50%;
+ width: 100%
+}
+#background-image>img{
+ object-fit: cover;
+ width: 100%;
+ height: 100%;
+}
+#background-image::before{
+ content: "";
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(to top, #161723, #0000);
+}
+
+/* Section 1: map name*/
+
+#section1{
+ margin: 20px 0 0 0;
+ cursor: default;
+}
+
+.nav-button{
+ height: 40px;
+ background-color: #2b2e46;
+
+ color: inherit;
+ font-size: 18px;
+ font-family: inherit;
+ border: none;
+ transition: background-color .1s;
+}
+/* #section1>div>.nav-button:nth-child(1){border-radius: 0px;}:nth-child(1){border-radius: 20px 0 0 20px;}
+#section1>div>.nav-button:nth-child(2){border-radius: 0 20px 20px 0;margin-left: 2px;} */
+.nav-button>span{padding: 0 8px 0 8px;}
+.nav-button:hover{background-color: #202232;cursor: pointer;}
+
+/* Section 2: navbar */
+#section2{
+ margin: 40px 0 0 0;
+
+ display: grid; gap: 2px;
+ grid-template-columns: 1fr 1fr 1fr;
+}
+
+#section2>.nav-button{
+ height: 50px;
+ font-size: 22px;
+ display: flex;
+ justify-content: center;
+ place-items: center;
+}
+#section2>.nav-button>img{scale: 1.2;}
+#section2>.nav-button:nth-child(1){border-radius: 30px 0 0 30px;}
+#section2>.nav-button:nth-child(3){border-radius: 0 30px 30px 0;}
+
+
+/* Section 3: category + history */
+
+#section3{
+ margin: 40px 0 0 0;
+
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+}
+
+#category{
+ display: grid;
+ height: 350px;
+ border-radius: 24px;
+ overflow: hidden;
+
+}
+#category>p{
+ margin-bottom: 20px;
+ text-align: center;
+ font-size: 50px;
+ cursor: default;
+ color: white;
+}
+
+p>span.portal-count{font-weight: bold;font-size: 100px;vertical-align: -15%;}
+
+#category-image{
+ transform: translate(-20%, -15%);
+ z-index: -1;
+ overflow: hidden;
+ width: 125%;
+ margin: 22px;
+ filter: blur(4px) contrast(80%) brightness(80%);
+}
+
+#category>span{
+ margin-top: 70px;
+ background-color: #202232;
+
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ gap: 2px;
+}
+#category>span>button{
+ font-family: inherit;
+ font-size: 18px;
+ border: none;
+ height: 40px;
+ color: inherit;
+
+ cursor: pointer;
+ transition: background-color .1s;
+}
+
+
+
+#history>div>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
+#history{
+ min-width: 560px;
+ background-color: #202232;
+ border-radius: 24px;
+
+}
+
+#records{overflow-y: auto; height: 256px;}
+#records::-webkit-scrollbar{display: none;}
+
+.record-top, .record{
+ font-size: 18px;
+ display: grid;
+ text-align: center;
+ grid-template-columns: 1fr 1fr 1fr;
+}
+.record-top{font-weight: bold;margin: 20px 20px 0 20px;cursor: default;}
+.record{
+ margin: 10px 20px 10px 20px;
+ height: 44px; width: calc(100% - 40px);
+
+ color: inherit;
+ border-radius: 40px;
+ place-items: center;
+
+ border: 0;
+ cursor: pointer;
+ transition: background-color .1s;
+}
+#history>span{
+ border-top: #202232 solid 2px;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+}
+#history>span>button{
+ width: 100%; height: 40px;
+ font-family: inherit;
+ font-size: 18px;
+ border: none;
+ color: inherit;
+
+ cursor: pointer;
+ transition: background-color .1s;
+}
+#history>span>button:nth-child(1){border-radius: 0 0 0 24px;}
+#history>span>button:nth-child(2){border-radius: 0 0 24px 0;}
+
+#graph{
+ display: grid;
+ grid-template-columns: 20px 1fr;
+ grid-template-rows: 1fr 20px;
+ height: 293px;
+
+ margin: 10px 10px 5px 10px;
+ overflow: hidden;
+}
+#graph>div:nth-child(1){ /* numbers */
+ width: 20px;
+ display: grid;
+ place-items: center;
+ /* background-color: blue; */
+}
+#graph>div:nth-child(1)>span{
+ font-size: 12px;
+ line-height: 0;
+}
+
+#graph>div:nth-child(2){ /* big graph */
+ position: relative;
+ display: grid;
+}
+#graph>div:nth-child(2)>tr{
+ display: flex;
+ align-items: center;
+ grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));
+}
+#graph>div:nth-child(2)>tr>td.graph_hor{
+ width: 100%;
+ height: 0;
+ padding: 0;
+
+ outline: 1px solid red;
+}
+#graph>div:nth-child(2)>tr>td.graph_ver{
+ width: 0;
+ height: 100%;
+ padding: 0;
+
+ outline: 1px solid blue;
+ transform: translateY(50%);
+ z-index: 0;
+ overflow: hidden;
+}
+
+#graph>div:nth-child(3){ /* dates */
+ padding-right: 20px;
+ z-index: 1;
+ height: 16px;
+ background-color: #202232;
+ grid-column: 1 /3;
+ font-size: 12px;
+ display: grid;
+ padding-top: 8px;
+ grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));
+}
+
+.graph-button{
+ position: absolute;
+ padding: 0;
+ border: 5px solid white;
+ border-radius: 20px;
+ cursor: pointer;
+ transform: translateX(-50%);
+}
+
+#history>div>h5{text-align: center;height: 197px;}
+
+
+/* Section 4: Difficulty + count */
+
+#section4{
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+ margin: 40px 0 0 0;
+}
+
+#difficulty,
+#count {
+ background-color: #202232;
+ min-width: 250px;
+ text-align: center;
+ cursor: default;
+
+ border-radius: 24px;
+ display: grid;
+ grid-template-rows: 20px 40px 40px;
+}
+#difficulty>span:nth-child(1),
+#count>span:nth-child(1){
+ padding-top:10px;
+ font-size: 18px;
+ color:#cdcfdf
+}
+#difficulty>span:nth-child(2){
+ font-size: 40px;
+}
+#difficulty>div{
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
+ padding: 0 calc(50% - 125px) 0 calc(50% - 125px);
+ place-items: center;
+}
+
+.difficulty-rating{
+ border-radius: 24px;
+ width: 40px; height: 3px;
+ background-color: #2b2e46;
+}
+
+#count>div{
+ padding-top:10px;
+ font-size: 50px;
+ color:white
+}
+
+/* Section 5: route desc + video */
+#section5{
+ margin: 40px 0 20px 0;
+ width: 100%;
+}
+
+#description{
+ width: 100%; height: auto;
+ min-height: 342px;
+}
+
+
+
+
+#description>iframe{
+ margin: 4px;
+ float:right;
+ border: 0;
+ border-radius: 24px;
+ width: 608px; height: 342px;
+}
+
+#description>h3{margin: 0 0 10px 0; color: white;}
+#description-text{
+ display: block;
+ font-size: 21px;
+ word-wrap: break-word;
+}
+#description-text>b{font-size: inherit;}
+#description-text>a{font-size: inherit;color: #3c91e6;}
+
+
+/* Section 6: leaderboards */
+#section6{
+ margin: 40px 0 20px 0;
+ min-height: 600px;
+ background-color: #202232;
+
+ border-radius: 24px;
+ padding: 10px 10px 0 10px;
+
+}
+
+
+#section6>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
+#leaderboard-top{
+ display: grid;
+ font-size: 20px;
+ height: 34px;
+ padding-left: 60px;
+ margin: 0 20px 0 20px;
+}
+#leaderboard-top>span{
+
+ display: flex;
+ place-items: flex-end;
+}
+
+#runner{
+ display: grid;
+ grid-template-columns: 50% 50%;
+ align-items: end;
+}
+
+#page-number{
+ display: flex;
+ width: auto;
+ flex-direction: row-reverse;
+}
+#page-number>div{
+width: 100px;
+place-items: center;
+display: grid;
+grid-template-columns: 1fr 1fr 1fr;
+text-align: center;
+}
+#page-number>div>button{
+ width: 30px;
+ height: 30px;
+ background-color: #202232;
+ border: 0;
+ padding: 0;
+ cursor: pointer;
+}
+
+.leaderboard-record{
+ margin: 10px 20px 0px 20px;
+ height: 44px; width: calc(100% - 40px);
+ width: auto;
+
+ color: inherit;
+ border-radius: 40px;
+ text-align: left;
+ padding: 0 0 0 60px;
+ font-size: 20px;
+ font-family: inherit;
+
+ grid-template-columns: 3% 4.5% 40% 4% 3.5% 15% 15% 15%;
+ display: grid;
+
+ border: 0;
+ transition: background-color .1s;
+ background-color: #2b2e46;
+}
+
+.leaderboard-record>span:nth-child(1){display: grid;}
+.leaderboard-record>span:nth-child(4){display: grid;}
+.leaderboard-record>span:last-child{flex-direction: row-reverse;}
+.leaderboard-record>span{
+ display: flex;
+ place-items: center;
+ height: 44px;
+}
+
+.leaderboard-record>div>span>img{
+ height: 36px;
+ border-radius: 50px;
+ padding: 0;
+ scale: .95;
+}
+.leaderboard-record>div{
+ display: grid;
+ grid-template-columns: 50% 50%;
+ place-items: left;
+}
+.leaderboard-record>div>span{
+ display: flex;
+ place-items: center;
+ height: 44px;
+}
+
+.leaderboard-record>span>button{
+ background-color: #0000;
+ border: 0;
+ cursor: pointer;
+ transition: opacity 0.1s;
+}
+
+.hover-popup {
+ position: relative;
+ display: inline-block;
+ }
+
+ .hover-popup::after {
+ content: attr(popup-text);
+ position: absolute;
+ /* top: 0%; */
+ /* left: 80%; */
+ /* transform: translateX(-100%); */
+ /* padding: 5px; */
+ background-color: #2b2e46;
+ /* border: 1px solid #161723; */
+ border-radius: 8px;
+ visibility: hidden;
+ opacity: 0;
+ color: #cdcfdf;
+ /* transition: visibility 0s, opacity 0.3s ease; */
+ }
+
+ .hover-popup:hover {
+ color: transparent;
+ }
+
+ .hover-popup:hover::after {
+ visibility: visible;
+ opacity: 1;
+ }
+
+.leaderboard-record:last-child{margin: 10px 20px 10px 20px;}
+
+
+#section7{
+ margin: 40px 0 20px 0;
+ background-color: #202232;
+ border-radius: 24px;
+ padding: 10px;
+}
+
+#discussion-search{
+ height: 46px;
+ width: 100%;
+ display: grid;
+ grid-template-columns: 1fr 100px;
+ margin: 0 0 20px 0;
+}
+#discussion-search>input::placeholder{color: #aaa;}
+#discussion-search>input{
+ background-color: #2b2e46;
+ font-size: 20px;
+ padding-left: 10px;
+ color: white;
+ border: 0;
+ border-radius: 16px 0 0 16px;
+ font-family: inherit;
+}
+#discussion-search>div>button:hover{filter: brightness(75%);}
+#discussion-search>div>button{
+ padding: 7px 16px;
+ margin: 8px 0;
+ border: 0;
+ font-size: 16px;
+ border-radius: 24px;
+ display: block;
+ background-color:#3c91e6;
+ font-family: inherit;
+ font-weight: bold;
+ cursor: pointer;
+ color: white;
+
+ transition: filter .2s;
+}
+#discussion-search>div{
+ background-color: #2b2e46;
+ border-radius: 0 16px 16px 0;
+}
+#discussion-post>button:nth-child(1)>span>b{font-size: 18px;color:#cdcfdf;font-weight: lighter;}
+#discussion-post>button:nth-child(1){
+ background-color: #2b2e46;
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) 150px;
+
+ border-radius: 16px;
+ padding: 16px 12px;
+ margin: 8px 0 0 0;
+ border: 0;
+ width: 100%; height: 100px;
+ text-align: start;
+ white-space: nowrap;
+ color: #cdcfdf;
+ cursor: pointer;
+ overflow: hidden;
+}
+#discussion-post>button:nth-child(1)>span:nth-child(1){font-size: 32px;}
+#discussion-post>button:nth-child(1)>span:nth-child(3){color: #aaa; font-size: 18px;}
+#discussion-post>button:nth-child(1)>span:nth-child(4){
+ opacity: .7;
+ height: 40px;
+ display: flex;
+ place-items: end;
+ justify-content: end;
+}
+
+#discussion-post{height: 100px;}
+#discussion-post>button>button:hover{filter: brightness(75%); }
+#discussion-post>button>button{
+ padding: 7px 16px;
+
+ border: 0;
+ font-size: 16px;
+ border-radius: 24px;
+ background-color:#e52d04;
+ font-family: BarlowSemiCondensed-Regular;
+ font-weight: bold;
+ cursor: pointer;
+ color: white;
+
+ transition: filter .2s;
+}
+
+
+#discussion-create>div{
+ display: grid;
+ text-align: start;
+}
+#discussion-create{
+ display: grid;
+ grid-template-columns: 1fr 40px;
+ height: auto;
+ word-wrap: break-word;
+}
+
+#discussion-create>span{padding-left: 20px;}
+#discussion-create>div>input::placeholder{color: #aaa;}
+#discussion-create>div>input{
+ background-color: #2b2e46;
+ font-size: 20px;
+ padding-left: 10px;
+ margin-top: 10px;
+ height: 32px;
+ color: white;
+ border: 0;
+ font-family: inherit;
+}
+#discussion-create>div>input:nth-child(2){font-size: 16px;}
+
+#discussion-create-button:hover{filter: brightness(75%);}
+#discussion-create-button{
+ padding: 7px 16px;
+ margin: 8px 0 0 0;
+ border: 0;
+ font-size: 16px;
+ border-radius: 24px;
+
+ background-color:#3c91e6;
+ font-family: inherit;
+ font-weight: bold;
+ cursor: pointer;
+ color: white;
+ width: min-content;
+ grid-column: 1 / span 2;
+
+
+ transition: filter .2s;
+}
+
+
+#discussion-thread>div:nth-child(1){
+ display: grid;
+ grid-template-columns: 1fr 40px;
+ height: auto;
+ padding: 0 0 10px 20px;
+ word-wrap: break-word;
+}
+
+#discussion-create>button:nth-child(2),
+#discussion-thread>div>button{
+ height: 40px;
+ float:inline-end;
+ color:#cdcfdf;
+ background-color: #0000;
+ border: 0;
+ font-size: 38px;
+ cursor: pointer;
+}
+
+
+#discussion-thread>div:nth-child(2)>img{
+ width: 60px; height: 60px;
+ border-radius: 100px;
+ margin: 20px 0 0 0;
+}
+#discussion-thread>div:nth-child(2)>div{
+ height: max-content;
+ padding: 20px 0 0 10px;
+ display: inline-grid;
+ grid-template-columns: min-content 1fr ;
+ overflow: hidden;
+
+}
+#discussion-thread>div:nth-child(2)>div>span:nth-child(1){font-weight: bold;height: 30px;}
+#discussion-thread>div:nth-child(2)>div>span:nth-child(2){
+ opacity: 0.6;
+ height: 30px;
+ font-size: 80%;
+ padding-left: 10px;
+}
+#discussion-thread>div:nth-child(2)>div>span:nth-child(3){
+ grid-column: 1 / span 2;
+ height: max-content;
+ word-wrap: break-word;
+}
+#discussion-thread>div:nth-child(2){
+ display: grid;
+ grid-template-columns: 60px 1fr;
+ font-size: 20px;
+ max-height: 522px;
+ overflow-y: auto;
+}
+
+
+#discussion-send{
+ height: 48px;
+ width: 100%;
+ display: grid;
+ grid-template-columns: 1fr 80px;
+ margin: 10px 0 0 0;
+}
+#discussion-send>input::placeholder{color: #aaa;}
+#discussion-send>input{
+ background-color: #2b2e46;
+ padding-left: 10px;
+ color: white;
+ border: 0;
+ font-size: 20px;
+ border-radius: 16px 0 0 16px;
+ font-family: inherit;
+}
+#discussion-send>div{
+ background-color: #2b2e46;
+ border-radius: 0 16px 16px 0;
+
+}
+#discussion-send>div>button:hover{ filter: brightness(75%);}
+#discussion-send>div>button{
+ padding: 7px 20px;
+ margin: 8px 0;
+ font-size: 16px;
+ border: 0;
+ border-radius: 24px;
+ display: block;
+ background-color:#3c91e6;
+ font-family: inherit;
+ font-weight: bold;
+ cursor: pointer;
+ color: white;
+
+ transition: filter .2s;
+}
+
+
+
+.triangle{
+ display: inline-block;
+ width: 8px; height: 0;
+ border-top: 7px solid transparent;
+ border-right: 8px solid #cdcfdf;
+ border-bottom: 7px solid transparent;
+}
+
+ /* such responsive, very mobile */
+@media screen and (max-width: 1480px) {
+ #section3.summary1{grid-template-columns: auto;}
+ #category{min-width: 608px;}
+ #history{min-width: 608px;}
+ #description{min-width: 608px;}
+ #section4.summary1{min-width: 588px;}
+
+ #description>iframe{
+ padding: 0 0 0 calc(50% - 304px);
+ float:none;
+ justify-content: center;
+ align-items: center;
+ }
+
+ #section1.summary1{
+ grid-template-columns: auto;
+ place-items: center;
+ text-align: center;
+
+ }
+
+ #section2.summary1{
+ grid-template-columns: auto;
+ width: 450px;
+ margin: 40px auto 0 auto;
+ }
+ #section2.summary1>.nav-button:nth-child(1){border-radius: 30px 30px 0 0;}
+ #section2.summary1>.nav-button:nth-child(2){border-radius: 0;}
+ #section2.summary1>.nav-button:nth-child(3){border-radius: 0 0 30px 30px;}
+}
\ No newline at end of file
diff --git a/frontend/src/css/ModMenu.css b/frontend/src/css/ModMenu.css
new file mode 100644
index 0000000..c6d3d8d
--- /dev/null
+++ b/frontend/src/css/ModMenu.css
@@ -0,0 +1,112 @@
+div#modview{
+ position: absolute;
+ left: 50%;
+ z-index: 20;
+ width: 320px; height: auto;
+ /* background-color: red; */
+
+ transform: translateY(-68%);
+}
+div#modview>div>button{
+ height: 30px;
+}
+
+div#modview>div:nth-child(1){
+ display: grid;
+ grid-template-columns: 50% 50%;
+}
+
+div#modview>div:nth-child(2){
+ display: grid;
+ place-items: center;
+}
+
+#modview-menu{
+ position: absolute;
+ left: calc(50% + 160px); top: 130px;
+ transform: translateX(-50%);
+ background-color: #2b2e46;
+ z-index: 2; color: white;
+}
+
+#modview-menu-image{
+ box-shadow: 0 0 40px 16px black;
+ outline: 8px solid #2b2e46;
+ border-radius: 20px;
+ font-size: 40px;
+ display: grid;
+ grid-template-columns: 50% 50%;
+ /* place-items: center; */
+
+}
+#modview-menu-image>div:nth-child(1){
+ height: 400px; width: 500px;
+ display: grid;
+ grid-template-rows: 30% 70%;
+}
+#modview-menu-image>div:nth-child(2){
+ height: 400px; width: 500px;
+ display: grid;
+ grid-template-rows: 20% 10%;
+}
+
+#modview-menu-image>div>button{width: 300px;margin-left:100px;}
+#modview-menu-image>div>img{width: 500px;}
+#modview-menu-image>div>button{font-size: 20px;}
+#modview-menu-image>div>span>input[type="file"]{font-size: 15px;}
+
+
+#modview-menu-add,
+#modview-menu-edit{
+ box-shadow: 0 0 40px 16px black;
+ outline: 8px solid #2b2e46;
+ border-radius: 20px;
+ font-size: 40px;
+ display: grid;
+ grid-template-columns: 20% 20% 20% 20% 20%;
+}
+
+#modview-menu-add>div,
+#modview-menu-edit>div{
+ display: grid;
+ margin: 20px;
+ width: 200px;
+ font-size: 20px;
+}
+#modview-route-description>textarea{
+ resize: none;
+ height: 160px;
+ width: 1160px;
+}
+#modview-route-showcase>input::placeholder{opacity: .5;}
+#modview_block{
+ position: absolute;
+ background-color: black;
+ opacity: .3;
+ left: 320px;
+ width: calc(100% - 320px);
+ height: 100%;
+ z-index: 2;
+ cursor: no-drop;
+}
+#modview-md{
+ box-shadow: 0 0 40px 16px black;
+ background-color: #2b2e46;
+ outline: 8px solid #2b2e46;
+
+ border-radius: 20px;
+ position: absolute;
+ padding: 10px; top: 400px;
+ width: 1180px; height: 300px;
+ overflow-y: auto;
+ word-wrap: break-word;
+}
+#modview-md>span>a{
+ padding-left: 20px;
+ color:aqua;
+}
+#modview-md>p{
+ font-family: BarlowSemiCondensed-Regular;
+ color: #cdcfdf;
+ font-size: 21px;
+}
\ No newline at end of file
diff --git a/frontend/src/css/Profile.css b/frontend/src/css/Profile.css
new file mode 100644
index 0000000..4944ade
--- /dev/null
+++ b/frontend/src/css/Profile.css
@@ -0,0 +1,239 @@
+#section1.profile{
+ margin: 20px;
+ background: linear-gradient(0deg, #202232 50%, #2b2e46 50%);
+ border-radius: 24px;
+ height: 200px;
+
+ display: grid;
+ grid-template-columns: 250px 1fr;
+
+}
+#section1.profile>div:first-child{
+ overflow: hidden;
+ border-radius: 100%;
+ display: grid;
+
+ place-items: center;
+
+ margin: 8px 33px 8px 33px;
+ scale: 0.9;
+ grid-row: 1 / 3;
+
+
+}
+#profile-image>img{
+ border-radius: 100%;
+ transition: filter 0.3s;
+ cursor: pointer;
+}
+
+#profile-image>span{
+ z-index: 1;
+ position: absolute;
+ opacity: 0;
+ color:white;
+ transition: opacity 0.3s;
+ cursor: pointer;
+}
+
+#profile-image:hover > img{filter: blur(5px) brightness(60%);z-index: 1;}
+#profile-image:hover > span{opacity: 1;}
+
+#profile-top{
+ height: 100px;
+ display: grid;
+ grid-template-columns: 80% 20%;
+}
+#profile-top>div:nth-child(1)>div>img{
+ margin: 12px;
+ border-radius: 10px;
+}
+
+#profile-top>div:nth-child(1){
+ display: flex;
+ place-items: center;
+ font-size: 50px;
+ font-weight: bold;
+ color: white;
+}
+#profile-top>div:nth-child(1)>div{
+ display: flex;
+ height: 60px;
+}
+span.titles{
+ margin: 12px 12px 12px 0;
+
+ font-size: 18px;
+ font-weight: 100;
+
+ padding: 6px 20px 0px 20px;
+ border-radius: 10px;
+}
+
+#profile-top>div:nth-child(2){
+ display: flex;
+ flex-direction: row-reverse;
+ align-items: center;
+ padding-right: 10px;
+}
+#profile-top>div:nth-child(2)>a>img{
+ height: 50px;
+ padding: 0 5px 0 5px;
+ scale: 0.9;
+ filter: brightness(200%);
+
+}
+
+
+#profile-bottom{
+ height: 100px;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+}
+#profile-bottom>div{
+ margin: 12px;
+ background-color: #2b2e46;
+ border-radius: 20px;
+ display: grid;
+ place-items: center;
+ grid-template-rows: 40% 50%;
+}
+#profile-bottom>div>span:nth-child(1){
+ color: inherit;
+ font-size: 18px;
+}
+#profile-bottom>div>span:nth-child(2){
+ color: white;
+ font-size: 40px;
+}
+#profile-bottom>div>span:nth-child(2)>span{
+ color: white;
+ font-size: 20px;
+}
+/* #section1.profile>div>div{outline: red 1px dashed;} */
+
+
+#section2.profile{
+ margin: 20px;
+ height: 60px;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+}
+#section2.profile>button{
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ background-color: #2b2e46;
+ border: 0;
+ color: inherit;
+ font-family: inherit;
+ font-size: 24px;
+ cursor: pointer;
+
+ transition: background-color .1s;
+}
+#section2.profile>button:nth-child(1){border-radius: 24px 0 0 24px;}
+#section2.profile>button:nth-child(2){border-radius: 0 24px 24px 0;}
+
+#section3.profile1>hr{border: 1px solid #2b2e46;margin: 8px 20px 0px 20px;}
+#section3.profile1{
+ margin: 20px;
+ display: block;
+
+ background-color: #202232;
+ border-radius: 24px;
+}
+
+#profileboard-nav{
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+}
+
+#profileboard-nav>select{
+
+ /* appearance: none; */
+ margin: 10px 20px 20px 20px;
+ height: 50px;
+
+ border-radius: 24px;
+ text-align: center;
+
+ color: inherit;
+ font-family: inherit;
+ font-size: 24px;
+ border: 0;
+
+ background-color: #2b2e46;
+}
+
+
+#profileboard-top>span>img{height: 20px;scale: .8;}
+#profileboard-top>span>img,#profileboard-top>span>span{cursor: pointer;}
+#profileboard-top{
+ height: 34px;
+ display: grid;
+ font-size: 20px;
+ padding-left: 40px;
+ margin: 0 20px;
+ grid-template-columns: 15% 15% 5% 15% 5% 15% 15% 15%;
+}
+
+#profileboard-top>span{
+ display: flex;
+ place-items: flex-end;
+}
+
+#profileboard-records{
+ padding-bottom: 10px;
+}
+
+.profileboard-record{
+ width: calc(100% - 40px);
+ margin: 10px 20px 0px 20px;
+ height: 44px;
+
+ border-radius: 20px;
+ padding: 0 0 0 40px;
+ font-size: 20px;
+
+ color: inherit;
+ font-family: inherit;
+ border: 0;
+ transition: background-color .1s;
+ background-color: #2b2e46;
+ display: grid;
+ grid-template-columns: 15% 15% 5% 15% 5% 15% 15% 15%;
+ overflow: hidden;
+ white-space: nowrap;
+
+ transition: height .2s
+}
+
+/* this right here should be illegal */
+.profileboard-record>span:nth-child(-n+8){filter: brightness(100%);}
+.profileboard-record>span{
+ display: flex;
+ place-items: flex-end;
+ filter: brightness(65%);
+}
+
+.profileboard-record>hr{
+ margin: 0 0 0 -60px;
+ border: 0;
+ height: 2px;
+ background-color: #202232;
+}
+
+.profileboard-record>span:nth-child(4){display: grid;}
+.profileboard-record>span{
+
+ display: flex;
+ place-items: center;
+ height: 44px;
+}
+.profileboard-record>span>button{
+ background-color: #0000;
+ border: 0;
+ cursor: pointer;
+}
diff --git a/frontend/src/css/Sidebar.css b/frontend/src/css/Sidebar.css
new file mode 100644
index 0000000..34ede80
--- /dev/null
+++ b/frontend/src/css/Sidebar.css
@@ -0,0 +1,208 @@
+#sidebar {
+ overflow: hidden;
+ position: absolute;
+ background-color: #2b2e46;
+ width: 320px; height: 100vh;
+ min-height: 670px;
+
+}
+
+ /* logo */
+#logo{
+ display: grid;
+ grid-template-columns: 60px 200px;
+
+
+ height: 80px;
+ padding: 20px 0 20px 30px;
+ cursor: pointer;
+ user-select: none;
+}
+
+#logo-text{
+ font-family: BarlowCondensed-Regular;
+ font-size: 42px;
+ color: #FFF;
+ line-height: 38px;
+}
+span>b{
+ font-family: BarlowCondensed-Bold;
+ font-size: 56px;
+}
+
+ /* Sidelist */
+#sidebar-list{
+ z-index: 2;
+ background-color: #2b2e46;
+ position: relative;
+ height: calc(100vh - 120px);
+ width: 320px;
+ /* min-height: 670px; */
+ transition: width .3s;
+}
+#sidebar-toplist>button:nth-child(1){margin-top: 5px;}
+#sidebar-toplist{
+ display: grid;
+
+ margin: 0 5px 0 5px;
+ justify-items: left;
+ height: 400px;
+ grid-template-rows: 45px 50px 50px 50px 50px 50px 50px 50px auto;
+}
+
+#sidebar-bottomlist{
+ display: grid;
+
+ margin: 0 5px 0 5px;
+ justify-items: left;
+ grid-template-rows: calc(100vh - 670px) 50px 50px 50px;
+}
+.sidebar-button>span{
+ font-family: BarlowSemiCondensed-Regular;
+ font-size: 18px;
+ color: #CDCFDF;
+ height: 32px;
+ line-height: 28px;
+ transition: opacity .1s;
+}
+.sidebar-button{
+ display: grid;
+ grid-template-columns: 50px auto;
+ place-items: left;
+ text-align: left;
+
+ background-color: inherit;
+ cursor: pointer;
+ border: none;
+ width: 310px;
+ height: 40px;
+ border-radius: 20px;
+ padding: 0.4em 0 0 11px;
+
+ transition:
+ width .3s,
+ background-color .15s,
+ padding .3s;
+}
+
+.sidebar-button-selected {
+ background-color: #202232;
+}
+
+.sidebar-button-deselected {
+ background-color: #20223200;
+}
+
+.sidebar-button-deselected:hover {
+ background-color: #202232aa;
+}
+
+button>img {
+ scale: 1.1;
+ width: 20px;
+ padding: 5px;
+}
+
+ /* Maplist */
+#sidebar>div:nth-child(3){
+ position: relative;
+ background-color: #202232;
+ color: #424562;
+ z-index: 1;
+
+ left: 52px;
+ top: calc(-100vh + 120px);
+ width: 268px; height: calc(100vh - 120px);
+ min-height: 550px;
+}
+input#searchbar[type=text]{
+ margin: 10px 0 0 6px;
+ padding: 1px 0px 1px 16px;
+ width: 240px;
+ height: 30px;
+
+ font-family: BarlowSemiCondensed-Regular;
+ font-size: 20px;
+
+ background-color: #161723;
+ color:#CDCFDF;
+
+ border: 0;
+ border-radius: 20px;
+
+}
+input[type=text]::placeholder{color:#2b2e46}
+input[type=text]:focus{outline: inherit;}
+a{text-decoration: none;height: 40px;}
+
+
+#search-data{
+ margin: 8px 0 8px 0;
+ overflow-y: auto;
+ max-height: calc(100vh - 172px);
+ scrollbar-width: thin;
+}
+#search-data::-webkit-scrollbar{display: none;}
+.search-map{
+ margin: 10px 6px 0 6px;
+ height: 80px;
+
+ border-radius: 20px;
+ text-align: center;
+
+ display: grid;
+
+ border: 0;
+ transition: background-color .1s;
+ background-color: #2b2e46;
+ grid-template-rows: 20% 20% 60%;
+ width: calc(100% - 15px);
+}
+.search-map>span{
+ color: #888;
+ font-size: 16px;
+ font-family: BarlowSemiCondensed-Regular;
+}
+.search-map>span:nth-child(3){
+ font-size: 30px;
+ color: #CDCFDF;
+}
+
+.search-player{
+ overflow: hidden;
+ margin: 10px 6px 0 6px;
+ height: 80px;
+
+ border-radius: 20px;
+ text-align: center;
+ color: #CDCFDF;
+ font-family: BarlowSemiCondensed-Regular;
+
+ display: grid;
+ place-items: center;
+ grid-template-columns: 20% 80%;
+ padding: 0 16px 0 16px;
+
+ border: 0;
+ transition: background-color .1s;
+ background-color: #2b2e46;
+}
+.search-player>img{
+ height: 60px;
+ border-radius: 20px;
+}
+.search-player>span{
+ width:154px;
+ font-size: 26px;
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/images/Images.tsx b/frontend/src/images/Images.tsx
new file mode 100644
index 0000000..d2f6dfb
--- /dev/null
+++ b/frontend/src/images/Images.tsx
@@ -0,0 +1,44 @@
+import logo from "./png/logo.png"
+import login from "./png/login.png"
+import img1 from './png/1.png';
+import img2 from './png/2.png';
+import img3 from './png/3.png';
+import img4 from './png/4.png';
+import img5 from './png/5.png';
+import img6 from './png/6.png';
+import img7 from './png/7.png';
+import img8 from './png/8.png';
+import img9 from './png/9.png';
+import img10 from './png/10.png';
+import img11 from './png/11.png';
+import img12 from './png/12.png';
+import img13 from './png/13.png';
+import img14 from './png/14.png';
+import img15 from './png/15.png';
+import img16 from './png/16.png';
+import img17 from './png/17.png';
+import img18 from './png/18.png';
+import img19 from './png/19.png';
+
+export const LogoIcon = logo;
+export const LoginIcon = login;
+
+export const SearchIcon = img1;
+export const HomeIcon = img2;
+export const NewsIcon = img3;
+export const PortalIcon = img4;
+export const FlagIcon = img5;
+export const ChatIcon = img6;
+export const TableIcon = img7;
+export const BookIcon = img8;
+export const HelpIcon = img9;
+export const UserIcon = img10;
+export const ExitIcon = img11;
+export const DownloadIcon = img12;
+export const ThreedotIcon = img13;
+export const StatisticsIcon = img14;
+export const TwitchIcon = img15;
+export const YouTubeIcon = img16;
+export const SteamIcon = img17;
+export const HistoryIcon = img18;
+export const SortIcon = img19;
\ No newline at end of file
diff --git a/frontend/src/images/png/1.png b/frontend/src/images/png/1.png
new file mode 100644
index 0000000..ea59d2f
Binary files /dev/null and b/frontend/src/images/png/1.png differ
diff --git a/frontend/src/images/png/10.png b/frontend/src/images/png/10.png
new file mode 100644
index 0000000..d4b0863
Binary files /dev/null and b/frontend/src/images/png/10.png differ
diff --git a/frontend/src/images/png/11.png b/frontend/src/images/png/11.png
new file mode 100644
index 0000000..b493059
Binary files /dev/null and b/frontend/src/images/png/11.png differ
diff --git a/frontend/src/images/png/12.png b/frontend/src/images/png/12.png
new file mode 100644
index 0000000..abb7717
Binary files /dev/null and b/frontend/src/images/png/12.png differ
diff --git a/frontend/src/images/png/13.png b/frontend/src/images/png/13.png
new file mode 100644
index 0000000..28a67c5
Binary files /dev/null and b/frontend/src/images/png/13.png differ
diff --git a/frontend/src/images/png/14.png b/frontend/src/images/png/14.png
new file mode 100644
index 0000000..7be6359
Binary files /dev/null and b/frontend/src/images/png/14.png differ
diff --git a/frontend/src/images/png/15.png b/frontend/src/images/png/15.png
new file mode 100644
index 0000000..e5ae8aa
Binary files /dev/null and b/frontend/src/images/png/15.png differ
diff --git a/frontend/src/images/png/16.png b/frontend/src/images/png/16.png
new file mode 100644
index 0000000..bf3ae0c
Binary files /dev/null and b/frontend/src/images/png/16.png differ
diff --git a/frontend/src/images/png/17.png b/frontend/src/images/png/17.png
new file mode 100644
index 0000000..85e39f0
Binary files /dev/null and b/frontend/src/images/png/17.png differ
diff --git a/frontend/src/images/png/18.png b/frontend/src/images/png/18.png
new file mode 100644
index 0000000..048cda9
Binary files /dev/null and b/frontend/src/images/png/18.png differ
diff --git a/frontend/src/images/png/19.png b/frontend/src/images/png/19.png
new file mode 100644
index 0000000..0d97d16
Binary files /dev/null and b/frontend/src/images/png/19.png differ
diff --git a/frontend/src/images/png/2.png b/frontend/src/images/png/2.png
new file mode 100644
index 0000000..b8d108e
Binary files /dev/null and b/frontend/src/images/png/2.png differ
diff --git a/frontend/src/images/png/3.png b/frontend/src/images/png/3.png
new file mode 100644
index 0000000..cfda6a4
Binary files /dev/null and b/frontend/src/images/png/3.png differ
diff --git a/frontend/src/images/png/4.png b/frontend/src/images/png/4.png
new file mode 100644
index 0000000..bbc01c4
Binary files /dev/null and b/frontend/src/images/png/4.png differ
diff --git a/frontend/src/images/png/5.png b/frontend/src/images/png/5.png
new file mode 100644
index 0000000..b63d2c3
Binary files /dev/null and b/frontend/src/images/png/5.png differ
diff --git a/frontend/src/images/png/6.png b/frontend/src/images/png/6.png
new file mode 100644
index 0000000..6ced542
Binary files /dev/null and b/frontend/src/images/png/6.png differ
diff --git a/frontend/src/images/png/7.png b/frontend/src/images/png/7.png
new file mode 100644
index 0000000..c20bcf4
Binary files /dev/null and b/frontend/src/images/png/7.png differ
diff --git a/frontend/src/images/png/8.png b/frontend/src/images/png/8.png
new file mode 100644
index 0000000..d640522
Binary files /dev/null and b/frontend/src/images/png/8.png differ
diff --git a/frontend/src/images/png/9.png b/frontend/src/images/png/9.png
new file mode 100644
index 0000000..3cd602a
Binary files /dev/null and b/frontend/src/images/png/9.png differ
diff --git a/frontend/src/images/png/login.png b/frontend/src/images/png/login.png
new file mode 100644
index 0000000..6456c21
Binary files /dev/null and b/frontend/src/images/png/login.png differ
diff --git a/frontend/src/images/png/logo.png b/frontend/src/images/png/logo.png
new file mode 100644
index 0000000..774d55a
Binary files /dev/null and b/frontend/src/images/png/logo.png differ
diff --git a/frontend/src/imgs/1.png b/frontend/src/imgs/1.png
deleted file mode 100644
index ea59d2f..0000000
Binary files a/frontend/src/imgs/1.png and /dev/null differ
diff --git a/frontend/src/imgs/10.png b/frontend/src/imgs/10.png
deleted file mode 100644
index d4b0863..0000000
Binary files a/frontend/src/imgs/10.png and /dev/null differ
diff --git a/frontend/src/imgs/11.png b/frontend/src/imgs/11.png
deleted file mode 100644
index b493059..0000000
Binary files a/frontend/src/imgs/11.png and /dev/null differ
diff --git a/frontend/src/imgs/12.png b/frontend/src/imgs/12.png
deleted file mode 100644
index abb7717..0000000
Binary files a/frontend/src/imgs/12.png and /dev/null differ
diff --git a/frontend/src/imgs/13.png b/frontend/src/imgs/13.png
deleted file mode 100644
index 28a67c5..0000000
Binary files a/frontend/src/imgs/13.png and /dev/null differ
diff --git a/frontend/src/imgs/14.png b/frontend/src/imgs/14.png
deleted file mode 100644
index 7be6359..0000000
Binary files a/frontend/src/imgs/14.png and /dev/null differ
diff --git a/frontend/src/imgs/15.png b/frontend/src/imgs/15.png
deleted file mode 100644
index e5ae8aa..0000000
Binary files a/frontend/src/imgs/15.png and /dev/null differ
diff --git a/frontend/src/imgs/16.png b/frontend/src/imgs/16.png
deleted file mode 100644
index bf3ae0c..0000000
Binary files a/frontend/src/imgs/16.png and /dev/null differ
diff --git a/frontend/src/imgs/17.png b/frontend/src/imgs/17.png
deleted file mode 100644
index 85e39f0..0000000
Binary files a/frontend/src/imgs/17.png and /dev/null differ
diff --git a/frontend/src/imgs/18.png b/frontend/src/imgs/18.png
deleted file mode 100644
index 048cda9..0000000
Binary files a/frontend/src/imgs/18.png and /dev/null differ
diff --git a/frontend/src/imgs/19.png b/frontend/src/imgs/19.png
deleted file mode 100644
index 0d97d16..0000000
Binary files a/frontend/src/imgs/19.png and /dev/null differ
diff --git a/frontend/src/imgs/2.png b/frontend/src/imgs/2.png
deleted file mode 100644
index b8d108e..0000000
Binary files a/frontend/src/imgs/2.png and /dev/null differ
diff --git a/frontend/src/imgs/3.png b/frontend/src/imgs/3.png
deleted file mode 100644
index cfda6a4..0000000
Binary files a/frontend/src/imgs/3.png and /dev/null differ
diff --git a/frontend/src/imgs/4.png b/frontend/src/imgs/4.png
deleted file mode 100644
index bbc01c4..0000000
Binary files a/frontend/src/imgs/4.png and /dev/null differ
diff --git a/frontend/src/imgs/5.png b/frontend/src/imgs/5.png
deleted file mode 100644
index b63d2c3..0000000
Binary files a/frontend/src/imgs/5.png and /dev/null differ
diff --git a/frontend/src/imgs/6.png b/frontend/src/imgs/6.png
deleted file mode 100644
index 6ced542..0000000
Binary files a/frontend/src/imgs/6.png and /dev/null differ
diff --git a/frontend/src/imgs/7.png b/frontend/src/imgs/7.png
deleted file mode 100644
index c20bcf4..0000000
Binary files a/frontend/src/imgs/7.png and /dev/null differ
diff --git a/frontend/src/imgs/8.png b/frontend/src/imgs/8.png
deleted file mode 100644
index d640522..0000000
Binary files a/frontend/src/imgs/8.png and /dev/null differ
diff --git a/frontend/src/imgs/9.png b/frontend/src/imgs/9.png
deleted file mode 100644
index 3cd602a..0000000
Binary files a/frontend/src/imgs/9.png and /dev/null differ
diff --git a/frontend/src/imgs/login.png b/frontend/src/imgs/login.png
deleted file mode 100644
index 6456c21..0000000
Binary files a/frontend/src/imgs/login.png and /dev/null differ
diff --git a/frontend/src/imgs/logo.png b/frontend/src/imgs/logo.png
deleted file mode 100644
index 774d55a..0000000
Binary files a/frontend/src/imgs/logo.png and /dev/null differ
diff --git a/frontend/src/index.js b/frontend/src/index.js
deleted file mode 100644
index f648298..0000000
--- a/frontend/src/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom/client';
-import App from './App';
-
-const root = ReactDOM.createRoot(document.getElementById('root'));
-root.render(
-
-);
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
new file mode 100644
index 0000000..eec2ff4
--- /dev/null
+++ b/frontend/src/index.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import { BrowserRouter } from "react-router-dom";
+
+import App from './App';
+
+const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement
+);
+
+root.render(
+
+
+
+
+
+);
diff --git a/frontend/src/pages/Games.tsx b/frontend/src/pages/Games.tsx
new file mode 100644
index 0000000..e4b33e5
--- /dev/null
+++ b/frontend/src/pages/Games.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+
+import GameEntry from '../components/GameEntry';
+import { Game } from '../types/Game';
+import { API } from '../api/Api';
+import "../css/Maps.css"
+
+const Games: React.FC = () => {
+ const [games, setGames] = React.useState([]);
+
+ const _fetch_games = async () => {
+ const games = await API.get_games();
+ setGames(games);
+ };
+
+ const _page_load = () => {
+ const loaders = document.querySelectorAll(".loader");
+ loaders.forEach((loader) => {
+ (loader as HTMLElement).style.display = "none";
+ });
+ }
+
+ React.useEffect(() => {
+ document.querySelectorAll(".games-page-item-body").forEach((game, index) => {
+ game.innerHTML = "";
+ });
+
+ _fetch_games();
+ _page_load();
+ }, []);
+
+ return (
+
+
+
+
+
+
+ {games.map((game, index) => (
+
+ ))}
+
+
+
+
+ );
+};
+
+export default Games;
diff --git a/frontend/src/pages/Maps.tsx b/frontend/src/pages/Maps.tsx
new file mode 100644
index 0000000..707d865
--- /dev/null
+++ b/frontend/src/pages/Maps.tsx
@@ -0,0 +1,91 @@
+import React from 'react';
+import { Link, useLocation } from 'react-router-dom';
+
+import { PortalIcon, FlagIcon, ChatIcon } from '../images/Images';
+import Summary from '../components/Summary';
+import Leaderboards from '../components/Leaderboards';
+import Discussions from '../components/Discussions';
+import ModMenu from '../components/ModMenu';
+import { MapDiscussions, MapLeaderboard, MapSummary } from '../types/Map';
+import { API } from '../api/Api';
+import "../css/Maps.css";
+
+interface MapProps {
+ isModerator: boolean;
+};
+
+const Maps: React.FC = ({ isModerator }) => {
+
+ const [selectedRun, setSelectedRun] = React.useState(0);
+
+ const [mapSummaryData, setMapSummaryData] = React.useState(undefined);
+ const [mapLeaderboardData, setMapLeaderboardData] = React.useState(undefined);
+ const [mapDiscussionsData, setMapDiscussionsData] = React.useState(undefined)
+
+
+ const [navState, setNavState] = React.useState(0);
+
+ const location = useLocation();
+
+ const mapID = location.pathname.split("/")[2];
+
+ const _fetch_map_summary = async () => {
+ const mapSummary = await API.get_map_summary(mapID);
+ setMapSummaryData(mapSummary);
+ };
+
+ const _fetch_map_leaderboards = async () => {
+ const mapLeaderboards = await API.get_map_leaderboard(mapID);
+ setMapLeaderboardData(mapLeaderboards);
+ };
+
+ const _fetch_map_discussions = async () => {
+ const mapDiscussions = await API.get_map_discussions(mapID);
+ setMapDiscussionsData(mapDiscussions);
+ };
+
+ React.useEffect(() => {
+ _fetch_map_summary();
+ _fetch_map_leaderboards();
+ _fetch_map_discussions();
+ }, []);
+
+ if (!mapSummaryData) {
+ return (
+ <>>
+ );
+ }
+
+ return (
+ <>
+ {isModerator && }
+
+
+

+
+
+
+
+ Games list
+ {mapSummaryData.map.chapter_name}
+
{mapSummaryData.map.map_name}
+
+
+
+
+
+
+ setNavState(0)}>
Summary
+ setNavState(1)}>
Leaderboards
+ setNavState(2)}>
Discussions
+
+
+ {navState === 0 && }
+ {navState === 1 && }
+ {navState === 2 && _fetch_map_discussions()} />}
+
+ >
+ );
+};
+
+export default Maps;
diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx
new file mode 100644
index 0000000..8654a03
--- /dev/null
+++ b/frontend/src/pages/Profile.tsx
@@ -0,0 +1,326 @@
+import React from 'react';
+import { useLocation, useNavigate } from 'react-router-dom';
+
+import { SteamIcon, TwitchIcon, YouTubeIcon, PortalIcon, FlagIcon, StatisticsIcon, SortIcon, ThreedotIcon, DownloadIcon, HistoryIcon } from '../images/Images';
+import { UserProfile } from '../types/Profile';
+import { Game, GameChapters } from '../types/Game';
+import { Map } from '../types/Map';
+import "../css/Profile.css";
+
+interface ProfileProps {
+ profile: UserProfile;
+}
+
+const Profile: React.FC = ({ profile }) => {
+
+
+ const location = useLocation();
+ const navigate = useNavigate();
+
+ React.useEffect(() => {
+ if (!profile) {
+ navigate("/");
+ };
+ }, [profile]);
+
+ const [navState, setNavState] = React.useState(0);
+ const [pageNumber, setPageNumber] = React.useState(1);
+ const [pageMax, setPageMax] = React.useState(0);
+
+ const [game, setGame] = React.useState("0")
+ const [gameData, setGameData] = React.useState([]);
+ const [chapter, setChapter] = React.useState("0")
+ const [chapterData, setChapterData] = React.useState(null);
+ const [maps, setMaps] = React.useState