mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-30 23:27:55 -05:00
Map list stage banner initial
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import React, { useState } from "react";
|
||||
import { useMatches } from "remix";
|
||||
import invariant from "tiny-invariant";
|
||||
import { modesShortToLong } from "~/constants";
|
||||
import { resolveHostInfo } from "~/core/tournament/utils";
|
||||
import type {
|
||||
BracketModified,
|
||||
FindTournamentByNameForUrlI,
|
||||
} from "~/services/tournament";
|
||||
import { Unpacked } from "~/utils";
|
||||
import { modeToImageUrl, Unpacked } from "~/utils";
|
||||
import { Button } from "../Button";
|
||||
import { ActionSectionWrapper } from "./ActionSectionWrapper";
|
||||
import { DuringMatchActionsRosters } from "./DuringMatchActionsRosters";
|
||||
@@ -52,17 +53,29 @@ export function DuringMatchActions({
|
||||
["Room pass", `${roomPass} (${weHost ? "We" : "They"} host)`],
|
||||
["Friend code to add", friendCodeToAdd],
|
||||
["Score", currentMatch.score?.join("-")],
|
||||
["Current map", `${stage.mode} ${stage.name}`],
|
||||
["Best of", currentRound.stages.length],
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex gap-2.5 flex-wrap w-100">
|
||||
<div className="tournament-bracket__stage-banner">
|
||||
<div className="tournament-bracket__stage-banner__top-bar">
|
||||
<h4 className="tournament-bracket__stage-banner__top-bar__header">
|
||||
<img
|
||||
className="tournament-bracket__stage-banner__top-bar__mode-image"
|
||||
src={modeToImageUrl(stage.mode)}
|
||||
/>
|
||||
{modesShortToLong[stage.mode]} on {stage.name}
|
||||
</h4>
|
||||
<h4>Stage 1</h4>
|
||||
</div>
|
||||
</div>
|
||||
<ActionSectionWrapper>
|
||||
<div className="flex flex-wrap">
|
||||
<div className="grid grid-cols-2 gap-y-2 gap-x-4">
|
||||
{roundInfo.map(([title, value]) => (
|
||||
<React.Fragment key={title}>
|
||||
<label className="plain font-bold">{title}</label>
|
||||
<label className="font-bold plain">{title}</label>
|
||||
<div>{value}</div>
|
||||
</React.Fragment>
|
||||
))}
|
||||
@@ -82,7 +95,7 @@ export function DuringMatchActions({
|
||||
|
||||
return (
|
||||
<ActionSectionWrapper>
|
||||
<h4 className="font-bold mr-6">Opponent: {opponentTeam.name}</h4>
|
||||
<h4 className="mr-6 font-bold">Opponent: {opponentTeam.name}</h4>
|
||||
<ol className="list-decimal">
|
||||
<li>Add FC: {friendCodeToAdd}</li>
|
||||
{weHost ? (
|
||||
|
||||
@@ -4,6 +4,7 @@ import classNames from "classnames";
|
||||
import { modesShort, stages } from "~/constants";
|
||||
import { LinksFunction, useMatches } from "remix";
|
||||
import { FindTournamentByNameForUrlI } from "~/services/tournament";
|
||||
import { modeToImageUrl, stageNameToImageUrl } from "~/utils";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
@@ -28,7 +29,7 @@ export default function MapPoolTab() {
|
||||
})}
|
||||
loading="lazy"
|
||||
alt={stage}
|
||||
src={`/img/stages/${stage.replaceAll(" ", "-").toLowerCase()}.webp`}
|
||||
src={stageNameToImageUrl(stage)}
|
||||
/>
|
||||
{modesPerStage(mapPool)[stage] && (
|
||||
<div className="map-pool__mode-images-container">
|
||||
@@ -38,7 +39,7 @@ export default function MapPoolTab() {
|
||||
<img
|
||||
key={mode}
|
||||
className="map-pool__mode-image"
|
||||
src={`/img/modes/${mode}.webp`}
|
||||
src={modeToImageUrl(mode)}
|
||||
alt={mode}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -5,6 +5,37 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tournament-bracket__stage-banner {
|
||||
/* TODO: */
|
||||
background-image: url("https://pbs.twimg.com/media/DoAV42MXsAAtHCh?format=jpg&name=large");
|
||||
height: 10rem;
|
||||
width: 100%;
|
||||
background-position: center;
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.tournament-bracket__stage-banner__top-bar {
|
||||
padding: var(--s-2);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
backdrop-filter: blur(5px);
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border-start-end-radius: var(--rounded);
|
||||
border-start-start-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.tournament-bracket__stage-banner__top-bar__header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--s-2);
|
||||
}
|
||||
|
||||
.tournament-bracket__stage-banner__top-bar__mode-image {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.tournament-bracket__elim__bracket {
|
||||
display: grid;
|
||||
column-gap: 2px;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Mode } from "@prisma/client";
|
||||
import type { CSSProperties } from "react";
|
||||
import { json, useLocation } from "remix";
|
||||
import { z } from "zod";
|
||||
@@ -31,6 +32,14 @@ export function getLogInUrl(location: ReturnType<typeof useLocation>) {
|
||||
)}`;
|
||||
}
|
||||
|
||||
export function stageNameToImageUrl(name: string) {
|
||||
return `/img/stages/${name.replaceAll(" ", "-").toLowerCase()}.webp`;
|
||||
}
|
||||
|
||||
export function modeToImageUrl(mode: Mode) {
|
||||
return `/img/modes/${mode}.webp`;
|
||||
}
|
||||
|
||||
/** Parse formData of a request with the given schema. Throws HTTP 400 response if fails. */
|
||||
export async function parseRequestFormData<T extends z.ZodTypeAny>({
|
||||
request,
|
||||
|
||||
Reference in New Issue
Block a user