mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-24 12:11:56 -05:00
Match modal renders correct info
This commit is contained in:
parent
7c7140f046
commit
487f0e27fb
|
|
@ -26,8 +26,8 @@ export function DuringMatchActionsRosters({
|
|||
<Form method="post" className="width-full">
|
||||
<div>
|
||||
<TeamRosterInputs
|
||||
teamOne={ownTeam}
|
||||
teamTwo={opponentTeam}
|
||||
teamUpper={ownTeam}
|
||||
teamLower={opponentTeam}
|
||||
winnerId={winnerId}
|
||||
setWinnerId={setWinnerId}
|
||||
checkedPlayers={checkedPlayers}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export interface TeamRosterInputTeam {
|
|||
}[];
|
||||
}
|
||||
|
||||
export type TeamRosterInputsType = "DEFAULT" | "DISABLED" | "PRESENTATIONAL";
|
||||
|
||||
/** Inputs to select who played for teams in a match as well as the winner. Can also be used in a presentational way. */
|
||||
export function TeamRosterInputs({
|
||||
teamUpper,
|
||||
|
|
@ -25,7 +27,7 @@ export function TeamRosterInputs({
|
|||
setWinnerId,
|
||||
checkedPlayers,
|
||||
setCheckedPlayers,
|
||||
interactable = true,
|
||||
presentational = false,
|
||||
}: {
|
||||
teamUpper: TeamRosterInputTeam;
|
||||
teamLower: TeamRosterInputTeam;
|
||||
|
|
@ -33,8 +35,21 @@ export function TeamRosterInputs({
|
|||
setWinnerId: (newId: string) => void;
|
||||
checkedPlayers: [string[], string[]];
|
||||
setCheckedPlayers: React.Dispatch<React.SetStateAction<[string[], string[]]>>;
|
||||
interactable?: boolean;
|
||||
presentational?: boolean;
|
||||
}) {
|
||||
const inputMode = (team: TeamRosterInputTeam): TeamRosterInputsType => {
|
||||
if (presentational) return "PRESENTATIONAL";
|
||||
|
||||
// Disabled in this case because we expect a result to have exactly
|
||||
// TOURNAMENT_TEAM_ROSTER_MIN_SIZE members per team when reporting it
|
||||
// so there is no point to let user to change them around
|
||||
if (team.members.length <= TOURNAMENT_TEAM_ROSTER_MIN_SIZE) {
|
||||
return "DISABLED";
|
||||
}
|
||||
|
||||
return "DEFAULT";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="tournament-bracket__during-match-actions__rosters">
|
||||
{[teamUpper, teamLower].map((team, teamI) => (
|
||||
|
|
@ -44,7 +59,6 @@ export function TeamRosterInputs({
|
|||
<input
|
||||
type="radio"
|
||||
id={team.id}
|
||||
name="winnerTeamId"
|
||||
onChange={() => setWinnerId(team.id)}
|
||||
checked={winnerId === team.id}
|
||||
/>
|
||||
|
|
@ -55,7 +69,7 @@ export function TeamRosterInputs({
|
|||
<TeamRosterInputsCheckboxes
|
||||
team={team}
|
||||
checkedPlayers={checkedPlayers[teamI]}
|
||||
disabled={team.members.length <= TOURNAMENT_TEAM_ROSTER_MIN_SIZE}
|
||||
mode={inputMode(team)}
|
||||
handlePlayerClick={(playerId: string) =>
|
||||
setCheckedPlayers((players) => {
|
||||
const newPlayers = clone(players);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import clsx from "clsx";
|
||||
import { TOURNAMENT_TEAM_ROSTER_MIN_SIZE } from "~/constants";
|
||||
import { Label } from "../Label";
|
||||
import { TeamRosterInputTeam } from "./TeamRosterInputs";
|
||||
import { TeamRosterInputsType, TeamRosterInputTeam } from "./TeamRosterInputs";
|
||||
|
||||
export function TeamRosterInputsCheckboxes({
|
||||
team,
|
||||
checkedPlayers,
|
||||
handlePlayerClick,
|
||||
disabled,
|
||||
mode,
|
||||
}: {
|
||||
team: TeamRosterInputTeam;
|
||||
checkedPlayers: string[];
|
||||
handlePlayerClick: (playerId: string) => void;
|
||||
disabled: boolean;
|
||||
/** DEFAULT = inputs work, DISABLED = inputs disabled and look disabled, PRESENTATION = inputs disabled but look like in DEFAULT (without hover styles) */
|
||||
mode: TeamRosterInputsType;
|
||||
}) {
|
||||
return (
|
||||
<div className="tournament-bracket__during-match-actions__team-players">
|
||||
|
|
@ -21,7 +21,8 @@ export function TeamRosterInputsCheckboxes({
|
|||
key={member.id}
|
||||
className={clsx(
|
||||
"tournament-bracket__during-match-actions__checkbox-name",
|
||||
{ "disabled-opaque": disabled }
|
||||
{ "disabled-opaque": mode === "DISABLED" },
|
||||
{ presentational: mode === "PRESENTATIONAL" }
|
||||
)}
|
||||
>
|
||||
<input
|
||||
|
|
@ -29,7 +30,7 @@ export function TeamRosterInputsCheckboxes({
|
|||
type="checkbox"
|
||||
id={member.id}
|
||||
name="playerName"
|
||||
disabled={team.members.length === TOURNAMENT_TEAM_ROSTER_MIN_SIZE}
|
||||
disabled={mode === "DISABLED" || mode === "PRESENTATIONAL"}
|
||||
value={member.id}
|
||||
checked={checkedPlayers.flat().includes(member.id)}
|
||||
onChange={() => handlePlayerClick(member.id)}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type {
|
||||
Mode,
|
||||
TeamOrder,
|
||||
TournamentMatchGameResult,
|
||||
TournamentTeamMember,
|
||||
User,
|
||||
|
|
@ -19,7 +18,7 @@ export type FindMatchModalInfoByNumber =
|
|||
idForReact: string;
|
||||
teamUpper: TeamRosterInputTeam;
|
||||
teamLower: TeamRosterInputTeam;
|
||||
winner?: TeamOrder;
|
||||
winnerId?: string;
|
||||
stage: { name: string; mode: Mode };
|
||||
}[];
|
||||
}
|
||||
|
|
@ -92,7 +91,11 @@ export async function findMatchModalInfoByNumber({
|
|||
id: lowerTeam.teamId,
|
||||
members: membersWithPlayedInfo.lowerTeamMembers,
|
||||
},
|
||||
winner: stageResult?.winner,
|
||||
winnerId: stageResult
|
||||
? stageResult.winner === "UPPER"
|
||||
? upperTeam.teamId
|
||||
: lowerTeam.teamId
|
||||
: undefined,
|
||||
stage: {
|
||||
name: tournamentRoundStage.stage.name,
|
||||
mode: tournamentRoundStage.stage.mode,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
import { json, LoaderFunction, useLoaderData, useLocation } from "remix";
|
||||
import {
|
||||
json,
|
||||
LinksFunction,
|
||||
LoaderFunction,
|
||||
useLoaderData,
|
||||
useLocation,
|
||||
} from "remix";
|
||||
import { z } from "zod";
|
||||
import Modal from "~/components/Modal";
|
||||
import { TeamRosterInputs } from "~/components/tournament/TeamRosterInputs";
|
||||
|
|
@ -7,6 +13,11 @@ import {
|
|||
findMatchModalInfoByNumber,
|
||||
} from "~/db/tournament/queries/findMatchModalInfoByNumber";
|
||||
import { Unpacked } from "~/utils";
|
||||
import styles from "~/styles/tournament-match.css";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
|
||||
const typedJson = (args: NonNullable<FindMatchModalInfoByNumber>) => json(args);
|
||||
|
||||
|
|
@ -28,20 +39,24 @@ export default function MatchModal() {
|
|||
return (
|
||||
<Modal title={data.title} closeUrl={location.pathname.split("/match")[0]}>
|
||||
<h4>{data.roundName}</h4>
|
||||
{data.matchInfos
|
||||
.filter((matchInfo) => matchInfo.winner)
|
||||
.map((matchInfo) => {
|
||||
return (
|
||||
<TeamRosterInputs
|
||||
key={matchInfo.idForReact}
|
||||
teamUpper={matchInfo.teamUpper}
|
||||
teamLower={matchInfo.teamLower}
|
||||
checkedPlayers={matchInfoToCheckedPlayers(matchInfo)}
|
||||
setCheckedPlayers={() => null}
|
||||
setWinnerId={() => null}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div className="tournament-match-modal__rounds">
|
||||
{data.matchInfos
|
||||
.filter((matchInfo) => matchInfo.winnerId)
|
||||
.map((matchInfo) => {
|
||||
return (
|
||||
<TeamRosterInputs
|
||||
key={matchInfo.idForReact}
|
||||
teamUpper={matchInfo.teamUpper}
|
||||
teamLower={matchInfo.teamLower}
|
||||
checkedPlayers={matchInfoToCheckedPlayers(matchInfo)}
|
||||
setCheckedPlayers={() => null}
|
||||
setWinnerId={() => null}
|
||||
winnerId={matchInfo.winnerId}
|
||||
presentational
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,11 +152,11 @@
|
|||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tournament-bracket__during-match-actions__checkbox-name:not(.disabled-opaque):hover {
|
||||
.tournament-bracket__during-match-actions__checkbox-name:not(.disabled-opaque):not(.presentational):hover {
|
||||
border-radius: var(--rounded);
|
||||
cursor: pointer;
|
||||
outline: 2px solid var(--theme-transparent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
|
|
|||
6
app/styles/tournament-match.css
Normal file
6
app/styles/tournament-match.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.tournament-match-modal__rounds {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-8);
|
||||
margin-block-start: var(--s-4);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user