diff --git a/pages/maps.tsx b/pages/maps.tsx index dc8585c43..8eb5365b8 100644 --- a/pages/maps.tsx +++ b/pages/maps.tsx @@ -1,24 +1,146 @@ -import { Box, Button, Checkbox, CheckboxGroup, Grid } from "@chakra-ui/react"; +import { + Alert, + AlertIcon, + Box, + Button, + Checkbox, + FormLabel, + Grid, + Input, + InputGroup, + InputRightElement, + Textarea, +} from "@chakra-ui/react"; import { Trans } from "@lingui/macro"; import { useLingui } from "@lingui/react"; +import { RankedMode } from "@prisma/client"; import Breadcrumbs from "components/common/Breadcrumbs"; import ModeImage from "components/common/ModeImage"; import MyContainer from "components/common/MyContainer"; import SubText from "components/common/SubText"; import { stages } from "lib/lists/stages"; -import { useState } from "react"; +import { useRouter } from "next/router"; +import { ChangeEvent, Fragment, useState } from "react"; -const MapsGeneratorPage = ({}) => { +const MapsGeneratorPage = () => { + const router = useRouter(); const { i18n } = useLingui(); const [stagesSelected, setStagesSelected] = useState< - Record - >({}); + Record + >(getInitialStages()); + const [maplist, setMaplist] = useState(""); + const [count, setCount] = useState(9); - console.log({ stagesSelected }); + function getInitialStages() { + return Object.entries(router.query).reduce( + (acc: Record, cur) => { + if (stages.includes(cur[0]) && typeof cur[1] === "string") { + // @ts-ignore + acc[cur[0]] = cur[1] + .split(",") + .filter((mode) => ["SZ", "TC", "RM", "CB"].includes(mode)); + } + return acc; + }, + {} + ); + } + + const poolForUrl = (stagesSelectedForUrl: Record) => { + return Object.entries(stagesSelectedForUrl).reduce( + (acc: Record, cur) => { + if (cur[1].length) acc[cur[0]] = cur[1].join(","); + + return acc; + }, + {} + ); + }; + + const handleChange = ( + e: ChangeEvent, + mode: RankedMode, + stage: string + ) => { + const oldArray = stagesSelected[stage] ?? []; + const newArray = e.target.checked + ? oldArray.concat(mode) + : oldArray.filter((modeInArray) => modeInArray !== mode); + + const newStagesSelected = { ...stagesSelected, [stage]: newArray }; + + setStagesSelected(newStagesSelected); + router.replace({ + pathname: "/maps", + query: poolForUrl(newStagesSelected), + }); + }; + + const shuffled = (array: string[]) => { + return array + .map((a) => ({ sort: Math.random(), value: a })) + .sort((a, b) => a.sort - b.sort) + .map((a) => a.value); + }; + + const generateMaps = () => { + let modeStages = Object.entries(stagesSelected).reduce( + (acc: Record, [stage, modes]) => { + modes.forEach((mode) => acc[mode].push(stage)); + return acc; + }, + { SZ: [], TC: [], RM: [], CB: [] } + ); + + modeStages = { + SZ: shuffled(modeStages.SZ), + TC: shuffled(modeStages.TC), + RM: shuffled(modeStages.RM), + CB: shuffled(modeStages.CB), + }; + + const modes = (shuffled(["SZ", "TC", "RM", "CB"]) as RankedMode[]).filter( + (mode) => modeStages[mode].length > 0 + ); + if (modes.length === 0) { + return "I can't generate a maplist without any maps in it you know."; + } + + const stagesAlreadyPicked = new Set(); + + return new Array(count) + .fill(null) + .map((_, i) => { + modes.push(modes.shift() as RankedMode); + const stageArray = modeStages[modes[0]]; + + stageArray.push(stageArray.shift() as string); + + let shifted = 0; + while ( + stagesAlreadyPicked.has(stageArray[0]) || + shifted >= stageArray.length + ) { + stageArray.push(stageArray.shift() as string); + shifted++; + } + + stagesAlreadyPicked.add(stageArray[0]); + + return `${i + 1}) ${modes[0]} on ${stageArray[0]}`; + }) + .join("\n"); + }; return ( + + + + Pro tip: bookmark this page after making your map list to save it + + @@ -35,46 +157,73 @@ const MapsGeneratorPage = ({}) => { {stages.map((stage) => ( - <> + {i18n._(stage)} - - setStagesSelected({ ...stagesSelected, [stage]: value }) - } - > - - - - - - + handleChange(e, "SZ", stage)} + /> + handleChange(e, "TC", stage)} + /> + handleChange(e, "RM", stage)} + /> + handleChange(e, "CB", stage)} + /> + ))} + + Share your map pool + + {window && ( + + + + + + + )} + + {maplist &&