Port Map Pool Tab over
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## Commands
|
||||
|
||||
### Convert .png to .webp
|
||||
|
||||
`cwebp -q 80 image.png -o image.webp`
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Routes as SolidAppRoutes, Route } from "solid-app-router";
|
||||
import { lazy } from "solid-js";
|
||||
import { MapPoolTab } from "./scenes/tournament/components/MapPoolTab";
|
||||
import TournamentData from "./scenes/tournament/TournamentPage.data";
|
||||
|
||||
const TournamentsPage = lazy(
|
||||
@@ -15,11 +16,11 @@ export function Routes() {
|
||||
// TODO: fix type error
|
||||
data={TournamentData as any}
|
||||
>
|
||||
<Route path="/*all" element={() => <>overview</>} />
|
||||
<Route path="/map-pool" element={() => <>map pool</>} />
|
||||
<Route path="/map-pool" element={<MapPoolTab />} />
|
||||
<Route path="/bracket" element={() => <>bracket</>} />
|
||||
<Route path="/teams" element={() => <>teams</>} />
|
||||
<Route path="/streams" element={() => <>streams</>} />
|
||||
<Route path="/*all" element={() => <>overview</>} />
|
||||
</Route>
|
||||
<Route path="/" element={() => <>home!</>} />
|
||||
<Route path="/*all" element={() => <>Not found</>} />
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB |
BIN
public/img/modes/CB.webp
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
public/img/modes/RM.webp
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 20 KiB |
BIN
public/img/modes/SZ.webp
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 19 KiB |
BIN
public/img/modes/TC.webp
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
public/img/modes/TW.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 626 KiB |
BIN
public/img/stages/ancho-v-games.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 634 KiB |
BIN
public/img/stages/arowana-mall.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 738 KiB |
BIN
public/img/stages/blackbelly-skatepark.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 768 KiB |
BIN
public/img/stages/camp-triggerfish.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 735 KiB |
BIN
public/img/stages/goby-arena.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 767 KiB |
BIN
public/img/stages/humpback-pump-track.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 653 KiB |
BIN
public/img/stages/inkblot-art-academy.webp
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 857 KiB |
BIN
public/img/stages/kelp-dome.webp
Normal file
|
After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 782 KiB |
BIN
public/img/stages/makomart.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 744 KiB |
BIN
public/img/stages/manta-maria.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 749 KiB |
BIN
public/img/stages/moray-towers.webp
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 843 KiB |
BIN
public/img/stages/musselforge-fitness.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 706 KiB |
BIN
public/img/stages/new-albacore-hotel.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 634 KiB |
BIN
public/img/stages/piranha-pit.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 656 KiB |
BIN
public/img/stages/port-mackerel.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 717 KiB |
BIN
public/img/stages/shellendorf-institute.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 657 KiB |
BIN
public/img/stages/skipper-pavilion.webp
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 759 KiB |
BIN
public/img/stages/snapper-canal.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 749 KiB |
BIN
public/img/stages/starfish-mainstage.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 648 KiB |
BIN
public/img/stages/sturgeon-shipyard.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 800 KiB |
BIN
public/img/stages/the-reef.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 659 KiB |
BIN
public/img/stages/wahoo-world.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 747 KiB |
BIN
public/img/stages/walleye-warehouse.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
70
scenes/tournament/components/MapPoolTab.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { For, Show } from "solid-js";
|
||||
import { modesShort, stages } from "../../../utils/constants";
|
||||
import { useTournamentData } from "../TournamentPage.data";
|
||||
import s from "../styles/MapPoolTab.module.css";
|
||||
import type { Mode } from ".prisma/client";
|
||||
|
||||
export function MapPoolTab() {
|
||||
const tournament = useTournamentData(1);
|
||||
|
||||
return (
|
||||
<Show when={tournament?.()}>
|
||||
{({ mapPool }) => (
|
||||
<div class={s.container}>
|
||||
<div class={s.infoSquare}>
|
||||
<span class={s.emphasizedText}>{mapPool.length} maps</span>
|
||||
</div>
|
||||
<For each={stages}>
|
||||
{(stage) => (
|
||||
<div class={s.stageImageContainer}>
|
||||
<img
|
||||
class={s.stageImage}
|
||||
classList={{ [s.disabled]: !modesPerStage(mapPool)[stage] }}
|
||||
loading="lazy"
|
||||
alt={stage}
|
||||
src={`/img/stages/${stage
|
||||
.replaceAll(" ", "-")
|
||||
.toLowerCase()}.webp`}
|
||||
/>
|
||||
{modesPerStage(mapPool)[stage] && (
|
||||
<div class={s.modeImagesContainer}>
|
||||
{modesShort.map((mode) => {
|
||||
if (
|
||||
!modesPerStage(mapPool)[stage]?.includes(mode as Mode)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<img
|
||||
class={s.modeImage}
|
||||
src={`/img/modes/${mode}.webp`}
|
||||
alt={mode}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
||||
export function modesPerStage(
|
||||
mapPool: {
|
||||
name: string;
|
||||
mode: Mode;
|
||||
}[]
|
||||
) {
|
||||
return mapPool.reduce((acc: Record<string, Mode[]>, { name, mode }) => {
|
||||
if (!acc[name]) {
|
||||
acc[name] = [];
|
||||
}
|
||||
|
||||
acc[name].push(mode);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
62
scenes/tournament/styles/MapPoolTab.module.css
Normal file
@@ -0,0 +1,62 @@
|
||||
.infoSquare {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-weight: var(--semi-bold);
|
||||
font-size: var(--fonts-xl);
|
||||
background-image: url(/svg/background-pattern.svg);
|
||||
background-color: var(--bg-lighter);
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 480px) {
|
||||
.container {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 640px) {
|
||||
.container {
|
||||
grid-template-columns: repeat(4, minmax(1px, 200px));
|
||||
}
|
||||
}
|
||||
|
||||
.emphasizedText {
|
||||
font-weight: var(--bold);
|
||||
}
|
||||
|
||||
.stageImageContainer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.stageImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.modeImage {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.modeImagesContainer {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
backdrop-filter: blur(5px) grayscale(25%);
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
padding: var(--s-1);
|
||||
gap: var(--s-2);
|
||||
border-start-start-radius: var(--rounded);
|
||||
border-end-end-radius: var(--rounded);
|
||||
}
|
||||