mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-09 12:13:10 -05:00
MatchActionPickBanTab
This commit is contained in:
parent
646cc04899
commit
7ad37d6882
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
& > label {
|
||||
margin: 0;
|
||||
text-box: trim-start cap alphabetic;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
185
app/components/match-page/MatchActionPickBanTab.module.css
Normal file
185
app/components/match-page/MatchActionPickBanTab.module.css
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
.root {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"options"
|
||||
"prompt"
|
||||
"submit";
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
gap: var(--s-6);
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.title {
|
||||
grid-area: header;
|
||||
font-size: var(--font-md);
|
||||
font-weight: var(--weight-semi);
|
||||
text-align: center;
|
||||
text-box: trim-start cap alphabetic;
|
||||
}
|
||||
|
||||
.options {
|
||||
grid-area: options;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-6);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
grid-area: prompt;
|
||||
margin: 0;
|
||||
font-size: var(--font-sm);
|
||||
color: var(--color-text-lighter);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.verbPick {
|
||||
color: var(--color-success);
|
||||
font-weight: var(--weight-semi);
|
||||
}
|
||||
|
||||
.verbBan {
|
||||
color: var(--color-error);
|
||||
font-weight: var(--weight-semi);
|
||||
}
|
||||
|
||||
.submit {
|
||||
grid-area: submit;
|
||||
}
|
||||
|
||||
.modeGroup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-2);
|
||||
}
|
||||
|
||||
.divider {
|
||||
font-size: var(--font-xs);
|
||||
font-weight: var(--weight-semi);
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
gap: var(--s-2);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-bottom: 2px dotted var(--color-bg-higher);
|
||||
}
|
||||
}
|
||||
|
||||
.stageGrid {
|
||||
--tile-width: 90px;
|
||||
--tile-height: 50px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--s-4) var(--s-3);
|
||||
}
|
||||
|
||||
.modeGrid {
|
||||
--tile-width: 90px;
|
||||
--tile-height: 90px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--s-4) var(--s-3);
|
||||
}
|
||||
|
||||
.tileContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: var(--tile-width);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tileWrapper {
|
||||
position: relative;
|
||||
width: var(--tile-width);
|
||||
height: var(--tile-height);
|
||||
}
|
||||
|
||||
.tile {
|
||||
height: var(--tile-height);
|
||||
width: var(--tile-width);
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
transition:
|
||||
filter,
|
||||
opacity 0.2s;
|
||||
border-radius: var(--radius-box);
|
||||
cursor: pointer;
|
||||
|
||||
&:active {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.stageTile {
|
||||
background-image: var(--map-image-url);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.modeTile {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--color-bg-higher);
|
||||
}
|
||||
|
||||
.tileSelected {
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.tileIcon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tileIconPick {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.tileIconBan {
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.tileNumber {
|
||||
position: absolute;
|
||||
background-color: var(--color-text-accent);
|
||||
border-radius: 100%;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: var(--color-text-inverse);
|
||||
font-size: var(--font-2xs);
|
||||
font-weight: var(--weight-semi);
|
||||
top: -5px;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tileFrom {
|
||||
font-size: var(--font-2xs);
|
||||
font-weight: var(--weight-bold);
|
||||
text-transform: uppercase;
|
||||
line-height: 1;
|
||||
margin-block-start: var(--s-0-5);
|
||||
}
|
||||
|
||||
.tileLabel {
|
||||
font-size: var(--font-2xs);
|
||||
color: var(--color-text-high);
|
||||
font-weight: var(--weight-semi);
|
||||
margin-block-start: var(--s-1);
|
||||
}
|
||||
347
app/components/match-page/MatchActionPickBanTab.tsx
Normal file
347
app/components/match-page/MatchActionPickBanTab.tsx
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
import clsx from "clsx";
|
||||
import { Check, X } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SendouButton } from "~/components/elements/Button";
|
||||
import { shortStageName } from "~/modules/in-game-lists/stage-ids";
|
||||
import type { ModeShort, StageId } from "~/modules/in-game-lists/types";
|
||||
import { stageImageUrl } from "~/utils/urls";
|
||||
import { Divider } from "../Divider";
|
||||
import { SendouTabPanel } from "../elements/Tabs";
|
||||
import { ModeImage } from "../Image";
|
||||
import styles from "./MatchActionPickBanTab.module.css";
|
||||
import { TAB_KEYS } from "./MatchTabs";
|
||||
import { WeaponReporter, type WeaponReporterProps } from "./WeaponReporter";
|
||||
|
||||
interface PickBanMapOption {
|
||||
stageId?: StageId;
|
||||
mode?: ModeShort;
|
||||
picker?: "US" | "THEM" | "BOTH";
|
||||
nth?: number;
|
||||
}
|
||||
|
||||
interface PickBanSubmission {
|
||||
type: "PICK" | "BAN";
|
||||
map: PickBanMapOption;
|
||||
}
|
||||
|
||||
interface MatchActionPickBanTabProps {
|
||||
options: PickBanMapOption[];
|
||||
type: "PICK" | "BAN";
|
||||
onSubmit?: (data: PickBanSubmission) => void;
|
||||
isSubmitting?: boolean;
|
||||
weaponReport?: WeaponReporterProps;
|
||||
}
|
||||
|
||||
export function MatchActionPickBanTab({
|
||||
options,
|
||||
type,
|
||||
onSubmit,
|
||||
isSubmitting,
|
||||
weaponReport,
|
||||
}: MatchActionPickBanTabProps) {
|
||||
const { t } = useTranslation(["q", "common", "game-misc"]);
|
||||
const [selected, setSelected] = useState<PickBanMapOption>();
|
||||
|
||||
const hasStage = options.every((option) => option.stageId !== undefined);
|
||||
const hasMode = options.every((option) => option.mode !== undefined);
|
||||
const layout: "STAGE_BY_MODE" | "STAGE_ONLY" | "MODE_ONLY" =
|
||||
hasStage && hasMode
|
||||
? "STAGE_BY_MODE"
|
||||
: hasStage
|
||||
? "STAGE_ONLY"
|
||||
: "MODE_ONLY";
|
||||
|
||||
const titleKey =
|
||||
layout === "MODE_ONLY"
|
||||
? type === "PICK"
|
||||
? "q:match.action.pickMode"
|
||||
: "q:match.action.banMode"
|
||||
: type === "PICK"
|
||||
? "q:match.action.pickStage"
|
||||
: "q:match.action.banStage";
|
||||
|
||||
const selectedLabel = (() => {
|
||||
if (!selected) return null;
|
||||
const stageName =
|
||||
selected.stageId !== undefined
|
||||
? t(`game-misc:STAGE_${selected.stageId}`)
|
||||
: null;
|
||||
const modeName =
|
||||
selected.mode !== undefined
|
||||
? t(
|
||||
selected.stageId !== undefined
|
||||
? `game-misc:MODE_SHORT_${selected.mode}`
|
||||
: `game-misc:MODE_LONG_${selected.mode}`,
|
||||
)
|
||||
: null;
|
||||
if (stageName && modeName) return `${stageName} (${modeName})`;
|
||||
return stageName ?? modeName;
|
||||
})();
|
||||
|
||||
return (
|
||||
<SendouTabPanel id={TAB_KEYS.ACTION}>
|
||||
<div className={styles.root}>
|
||||
<div className={styles.title}>{t(titleKey)}</div>
|
||||
|
||||
<div className={styles.options}>
|
||||
{layout === "STAGE_BY_MODE" ? (
|
||||
<StageByModeGrid
|
||||
options={options}
|
||||
type={type}
|
||||
selected={selected}
|
||||
onSelect={setSelected}
|
||||
/>
|
||||
) : layout === "STAGE_ONLY" ? (
|
||||
<StageOnlyGrid
|
||||
options={options}
|
||||
type={type}
|
||||
selected={selected}
|
||||
onSelect={setSelected}
|
||||
/>
|
||||
) : (
|
||||
<ModeOnlyGrid
|
||||
options={options}
|
||||
type={type}
|
||||
selected={selected}
|
||||
onSelect={setSelected}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className={styles.prompt}>
|
||||
{selectedLabel ? (
|
||||
<>
|
||||
<span
|
||||
className={type === "PICK" ? styles.verbPick : styles.verbBan}
|
||||
>
|
||||
{type === "PICK"
|
||||
? t("q:match.action.picking")
|
||||
: t("q:match.action.banning")}
|
||||
</span>{" "}
|
||||
{selectedLabel}
|
||||
</>
|
||||
) : (
|
||||
t("q:match.action.pickBanPrompt")
|
||||
)}
|
||||
</p>
|
||||
|
||||
<SendouButton
|
||||
variant="primary"
|
||||
className={styles.submit}
|
||||
isDisabled={!selected || isSubmitting}
|
||||
onPress={() => {
|
||||
if (!selected) return;
|
||||
onSubmit?.({ type, map: selected });
|
||||
}}
|
||||
>
|
||||
{t("common:actions.submit")}
|
||||
</SendouButton>
|
||||
</div>
|
||||
{weaponReport ? <WeaponReporter {...weaponReport} /> : null}
|
||||
</SendouTabPanel>
|
||||
);
|
||||
}
|
||||
|
||||
function StageByModeGrid({
|
||||
options,
|
||||
type,
|
||||
selected,
|
||||
onSelect,
|
||||
}: {
|
||||
options: PickBanMapOption[];
|
||||
type: "PICK" | "BAN";
|
||||
selected?: PickBanMapOption;
|
||||
onSelect: (option: PickBanMapOption) => void;
|
||||
}) {
|
||||
const modesInOrder: ModeShort[] = [];
|
||||
const byMode = new Map<ModeShort, PickBanMapOption[]>();
|
||||
for (const option of options) {
|
||||
const mode = option.mode!;
|
||||
if (!byMode.has(mode)) {
|
||||
byMode.set(mode, []);
|
||||
modesInOrder.push(mode);
|
||||
}
|
||||
byMode.get(mode)!.push(option);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{modesInOrder.map((mode) => (
|
||||
<div key={mode} className={styles.modeGroup}>
|
||||
<Divider className={styles.divider}>
|
||||
<ModeImage mode={mode} size={32} />
|
||||
</Divider>
|
||||
<div className={styles.stageGrid}>
|
||||
{byMode.get(mode)!.map((option) => (
|
||||
<StageTile
|
||||
key={`${option.stageId}-${option.mode}`}
|
||||
option={option}
|
||||
type={type}
|
||||
isSelected={isSameOption(option, selected)}
|
||||
onSelect={() => onSelect(option)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function StageOnlyGrid({
|
||||
options,
|
||||
type,
|
||||
selected,
|
||||
onSelect,
|
||||
}: {
|
||||
options: PickBanMapOption[];
|
||||
type: "PICK" | "BAN";
|
||||
selected?: PickBanMapOption;
|
||||
onSelect: (option: PickBanMapOption) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.stageGrid}>
|
||||
{options.map((option) => (
|
||||
<StageTile
|
||||
key={option.stageId}
|
||||
option={option}
|
||||
type={type}
|
||||
isSelected={isSameOption(option, selected)}
|
||||
onSelect={() => onSelect(option)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ModeOnlyGrid({
|
||||
options,
|
||||
type,
|
||||
selected,
|
||||
onSelect,
|
||||
}: {
|
||||
options: PickBanMapOption[];
|
||||
type: "PICK" | "BAN";
|
||||
selected?: PickBanMapOption;
|
||||
onSelect: (option: PickBanMapOption) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.modeGrid}>
|
||||
{options.map((option) => (
|
||||
<ModeTile
|
||||
key={option.mode}
|
||||
option={option}
|
||||
type={type}
|
||||
isSelected={isSameOption(option, selected)}
|
||||
onSelect={() => onSelect(option)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// xxx: maybe we should just have a shared custom component for stage image + label
|
||||
function StageTile({
|
||||
option,
|
||||
type,
|
||||
isSelected,
|
||||
onSelect,
|
||||
}: {
|
||||
option: PickBanMapOption;
|
||||
type: "PICK" | "BAN";
|
||||
isSelected: boolean;
|
||||
onSelect: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation(["q", "game-misc"]);
|
||||
|
||||
return (
|
||||
<div className={styles.tileContainer}>
|
||||
<div className={styles.tileWrapper}>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(styles.tile, styles.stageTile, {
|
||||
[styles.tileSelected]: isSelected,
|
||||
})}
|
||||
style={{
|
||||
"--map-image-url": `url("${stageImageUrl(option.stageId!)}.avif")`,
|
||||
}}
|
||||
onClick={onSelect}
|
||||
/>
|
||||
{isSelected ? (
|
||||
type === "PICK" ? (
|
||||
<Check className={clsx(styles.tileIcon, styles.tileIconPick)} />
|
||||
) : (
|
||||
<X className={clsx(styles.tileIcon, styles.tileIconBan)} />
|
||||
)
|
||||
) : null}
|
||||
{option.nth ? (
|
||||
<span className={styles.tileNumber}>{option.nth}</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.tileLabel}>
|
||||
{shortStageName(t(`game-misc:STAGE_${option.stageId!}`))}
|
||||
</div>
|
||||
{option.picker ? (
|
||||
<span
|
||||
className={clsx(styles.tileFrom, {
|
||||
"text-theme": option.picker === "BOTH",
|
||||
"text-success": option.picker === "US",
|
||||
"text-error": option.picker === "THEM",
|
||||
})}
|
||||
>
|
||||
{option.picker === "US"
|
||||
? t("q:match.action.pickerUs")
|
||||
: option.picker === "THEM"
|
||||
? t("q:match.action.pickerThem")
|
||||
: t("q:match.action.pickerBoth")}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ModeTile({
|
||||
option,
|
||||
type,
|
||||
isSelected,
|
||||
onSelect,
|
||||
}: {
|
||||
option: PickBanMapOption;
|
||||
type: "PICK" | "BAN";
|
||||
isSelected: boolean;
|
||||
onSelect: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation(["game-misc"]);
|
||||
|
||||
return (
|
||||
<div className={styles.tileContainer}>
|
||||
<div className={styles.tileWrapper}>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(styles.tile, styles.modeTile, {
|
||||
[styles.tileSelected]: isSelected,
|
||||
})}
|
||||
onClick={onSelect}
|
||||
>
|
||||
<ModeImage mode={option.mode!} size={48} />
|
||||
</button>
|
||||
{isSelected ? (
|
||||
type === "PICK" ? (
|
||||
<Check className={clsx(styles.tileIcon, styles.tileIconPick)} />
|
||||
) : (
|
||||
<X className={clsx(styles.tileIcon, styles.tileIconBan)} />
|
||||
)
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.tileLabel}>
|
||||
{t(`game-misc:MODE_LONG_${option.mode!}`)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function isSameOption(a: PickBanMapOption, b: PickBanMapOption | undefined) {
|
||||
if (!b) return false;
|
||||
return a.stageId === b.stageId && a.mode === b.mode;
|
||||
}
|
||||
|
|
@ -4,25 +4,22 @@
|
|||
grid-template-areas:
|
||||
"header header header"
|
||||
"actions actions actions"
|
||||
"alpha stage bravo"
|
||||
". label ."
|
||||
"selection selection selection"
|
||||
"points-alpha ko points-bravo"
|
||||
". submit .";
|
||||
"submit submit submit";
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
gap: var(--s-4);
|
||||
gap: var(--s-5);
|
||||
container-type: inline-size;
|
||||
|
||||
@container (max-width: 599px) {
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"actions actions"
|
||||
"stage alpha"
|
||||
"stage bravo"
|
||||
"label ."
|
||||
"points points"
|
||||
"submit submit";
|
||||
"header"
|
||||
"actions"
|
||||
"selection"
|
||||
"points"
|
||||
"submit";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +28,7 @@
|
|||
font-size: var(--font-md);
|
||||
font-weight: var(--weight-semi);
|
||||
text-align: center;
|
||||
text-box: trim-start cap alphabetic;
|
||||
}
|
||||
|
||||
.actionButtons {
|
||||
|
|
@ -41,7 +39,26 @@
|
|||
}
|
||||
|
||||
.selectionRow {
|
||||
display: contents;
|
||||
grid-area: selection;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
grid-template-areas:
|
||||
"alpha stage bravo"
|
||||
". text .";
|
||||
column-gap: var(--s-4);
|
||||
row-gap: var(--s-1);
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
@container (max-width: 599px) {
|
||||
column-gap: var(--s-2);
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-areas:
|
||||
"stage alpha"
|
||||
"stage bravo"
|
||||
"text .";
|
||||
}
|
||||
}
|
||||
|
||||
.teamRadioContainer {
|
||||
|
|
@ -96,14 +113,13 @@
|
|||
}
|
||||
|
||||
.stageLabel {
|
||||
grid-area: label;
|
||||
grid-area: text;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--s-1);
|
||||
font-size: var(--font-3xs);
|
||||
font-weight: var(--weight-semi);
|
||||
color: var(--color-text-high);
|
||||
margin-block-start: -11px;
|
||||
}
|
||||
|
||||
.pointsRow {
|
||||
|
|
@ -129,7 +145,6 @@
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--s-1);
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.pointsBravo {
|
||||
|
|
@ -139,7 +154,6 @@
|
|||
|
||||
.submit {
|
||||
grid-area: submit;
|
||||
margin-block-start: calc(-1 * var(--s-2));
|
||||
}
|
||||
|
||||
.checkCircle {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
& [class*="tabPanel"] {
|
||||
background-color: var(--color-bg-high);
|
||||
border-radius: 0 0 var(--radius-box) var(--radius-box);
|
||||
padding: var(--s-4) var(--s-4);
|
||||
padding: var(--s-6) var(--s-4);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
import { ArrowLeft, Ban } from "lucide-react";
|
||||
import { ArrowLeft, Ban, Undo2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SendouButton } from "~/components/elements/Button";
|
||||
import {
|
||||
SendouTab,
|
||||
SendouTabList,
|
||||
SendouTabs,
|
||||
} from "~/components/elements/Tabs";
|
||||
import { Main } from "~/components/Main";
|
||||
import { MatchActionPickBanTab } from "~/components/match-page/MatchActionPickBanTab";
|
||||
import { MatchActionTab } from "~/components/match-page/MatchActionTab";
|
||||
import {
|
||||
IconBanner,
|
||||
|
|
@ -18,12 +25,21 @@ import { MatchTabs } from "~/components/match-page/MatchTabs";
|
|||
import { logger } from "~/utils/logger";
|
||||
import type { SendouRouteHandle } from "~/utils/remix.server";
|
||||
|
||||
type ActionVariant =
|
||||
| "winner"
|
||||
| "counterpick-stage"
|
||||
| "ban-stage"
|
||||
| "ban-stage-only"
|
||||
| "pick-mode"
|
||||
| "ban-mode";
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["q"],
|
||||
};
|
||||
|
||||
export default function MatchPageTestRoute() {
|
||||
const { t } = useTranslation(["q"]);
|
||||
const [actionVariant, setActionVariant] = useState<ActionVariant>("winner");
|
||||
|
||||
return (
|
||||
<Main>
|
||||
|
|
@ -39,6 +55,22 @@ export default function MatchPageTestRoute() {
|
|||
Round 2.1
|
||||
</MatchPageHeader>
|
||||
|
||||
<SendouTabs
|
||||
selectedKey={actionVariant}
|
||||
onSelectionChange={(key) => setActionVariant(key as ActionVariant)}
|
||||
disappearing={false}
|
||||
padded={false}
|
||||
>
|
||||
<SendouTabList>
|
||||
<SendouTab id="winner">Winner</SendouTab>
|
||||
<SendouTab id="counterpick-stage">Counterpick</SendouTab>
|
||||
<SendouTab id="ban-stage">Ban stage</SendouTab>
|
||||
<SendouTab id="ban-stage-only">Ban stage (any mode)</SendouTab>
|
||||
<SendouTab id="pick-mode">Pick mode</SendouTab>
|
||||
<SendouTab id="ban-mode">Ban mode</SendouTab>
|
||||
</SendouTabList>
|
||||
</SendouTabs>
|
||||
|
||||
<MatchBannerContainer>
|
||||
<MatchBannerTopRow
|
||||
score={{
|
||||
|
|
@ -239,16 +271,94 @@ export default function MatchPageTestRoute() {
|
|||
},
|
||||
]}
|
||||
/>
|
||||
<MatchActionTab
|
||||
teams={[
|
||||
{ id: 1, name: "Chimera" },
|
||||
{ id: 2, name: "Koopa Clan" },
|
||||
]}
|
||||
ownTeamId={1}
|
||||
stageId={4}
|
||||
mode="SZ"
|
||||
withPoints={true}
|
||||
/>
|
||||
{actionVariant === "winner" ? (
|
||||
<MatchActionTab
|
||||
teams={[
|
||||
{ id: 1, name: "Chimera" },
|
||||
{ id: 2, name: "Koopa Clan" },
|
||||
]}
|
||||
ownTeamId={1}
|
||||
stageId={4}
|
||||
mode="SZ"
|
||||
withPoints={true}
|
||||
actionButtons={
|
||||
<SendouButton
|
||||
variant="minimal-destructive"
|
||||
size="miniscule"
|
||||
icon={<Undo2 size={16} />}
|
||||
>
|
||||
{t("q:match.undoReport")}
|
||||
</SendouButton>
|
||||
}
|
||||
/>
|
||||
) : actionVariant === "counterpick-stage" ? (
|
||||
<MatchActionPickBanTab
|
||||
type="PICK"
|
||||
options={[
|
||||
{ stageId: 1, mode: "SZ", picker: "US" },
|
||||
{ stageId: 2, mode: "SZ", picker: "BOTH" },
|
||||
{ stageId: 3, mode: "SZ", picker: "THEM" },
|
||||
{ stageId: 4, mode: "TC", picker: "US" },
|
||||
{ stageId: 5, mode: "TC", picker: "THEM" },
|
||||
{ stageId: 6, mode: "RM", picker: "BOTH" },
|
||||
{ stageId: 7, mode: "RM", picker: "US" },
|
||||
]}
|
||||
onSubmit={(data) => logger.info("pick submit", data)}
|
||||
/>
|
||||
) : actionVariant === "ban-stage" ? (
|
||||
<MatchActionPickBanTab
|
||||
type="BAN"
|
||||
options={[
|
||||
{ stageId: 1, mode: "SZ", nth: 1 },
|
||||
{ stageId: 2, mode: "SZ", nth: 2 },
|
||||
{ stageId: 4, mode: "TC", nth: 3 },
|
||||
{ stageId: 5, mode: "TC", nth: 4 },
|
||||
{ stageId: 6, mode: "RM", nth: 5 },
|
||||
{ stageId: 7, mode: "RM", nth: 6 },
|
||||
{ stageId: 8, mode: "CB", nth: 7 },
|
||||
{ stageId: 9, mode: "CB", nth: 8 },
|
||||
]}
|
||||
onSubmit={(data) => logger.info("ban submit", data)}
|
||||
/>
|
||||
) : actionVariant === "ban-stage-only" ? (
|
||||
<MatchActionPickBanTab
|
||||
type="BAN"
|
||||
options={[
|
||||
{ stageId: 1 },
|
||||
{ stageId: 2 },
|
||||
{ stageId: 3 },
|
||||
{ stageId: 4 },
|
||||
{ stageId: 5 },
|
||||
{ stageId: 6 },
|
||||
{ stageId: 7 },
|
||||
{ stageId: 8 },
|
||||
{ stageId: 9 },
|
||||
]}
|
||||
onSubmit={(data) => logger.info("ban stage-only submit", data)}
|
||||
/>
|
||||
) : actionVariant === "pick-mode" ? (
|
||||
<MatchActionPickBanTab
|
||||
type="PICK"
|
||||
options={[
|
||||
{ mode: "SZ" },
|
||||
{ mode: "TC" },
|
||||
{ mode: "RM" },
|
||||
{ mode: "CB" },
|
||||
]}
|
||||
onSubmit={(data) => logger.info("pick mode submit", data)}
|
||||
/>
|
||||
) : (
|
||||
<MatchActionPickBanTab
|
||||
type="BAN"
|
||||
options={[
|
||||
{ mode: "SZ" },
|
||||
{ mode: "TC" },
|
||||
{ mode: "RM" },
|
||||
{ mode: "CB" },
|
||||
]}
|
||||
onSubmit={(data) => logger.info("ban mode submit", data)}
|
||||
/>
|
||||
)}
|
||||
<MatchResultTab
|
||||
teams={{
|
||||
alpha: { name: "me in japan" },
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "This score will end the set. Please confirm below.",
|
||||
"match.action.requestCancel": "Request cancel",
|
||||
"match.action.acceptCancelingSet": "Accept canceling the set?",
|
||||
"match.action.pickStage": "Pick a stage",
|
||||
"match.action.banStage": "Ban a stage",
|
||||
"match.action.pickMode": "Pick a mode",
|
||||
"match.action.banMode": "Ban a mode",
|
||||
"match.action.pickerUs": "Us",
|
||||
"match.action.pickerThem": "Them",
|
||||
"match.action.pickerBoth": "Both",
|
||||
"match.action.pickBanPrompt": "Make your selection above",
|
||||
"match.action.picking": "Picking",
|
||||
"match.action.banning": "Banning",
|
||||
"match.cancelRequested.subtitle": "{{teamName}} has requested to cancel the set",
|
||||
"match.timeline.win": "Win",
|
||||
"match.timeline.loss": "Loss",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
|
|
@ -184,6 +184,16 @@
|
|||
"match.action.confirmSetEnding": "",
|
||||
"match.action.requestCancel": "",
|
||||
"match.action.acceptCancelingSet": "",
|
||||
"match.action.pickStage": "",
|
||||
"match.action.banStage": "",
|
||||
"match.action.pickMode": "",
|
||||
"match.action.banMode": "",
|
||||
"match.action.pickerUs": "",
|
||||
"match.action.pickerThem": "",
|
||||
"match.action.pickerBoth": "",
|
||||
"match.action.pickBanPrompt": "",
|
||||
"match.action.picking": "",
|
||||
"match.action.banning": "",
|
||||
"match.cancelRequested.subtitle": "",
|
||||
"match.timeline.win": "",
|
||||
"match.timeline.loss": "",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user