Import <Bracket /> component

This commit is contained in:
Kalle (Sendou)
2021-12-23 08:47:09 +02:00
parent f811c4f56a
commit 0c659ec6af
5 changed files with 282 additions and 1 deletions

View File

@@ -62,7 +62,7 @@ You can give a variation as a flag to the seeding script changing what exactly i
- [ ] Admin can change team captain
- [x] Admin can randomize and rerandomize maps
- [x] Admin can change seeding
- [ ] Admin can start the tournament
- [x] Admin can start the tournament
- [ ] Table design to support arbitrary brackets
- [x] Generate SE bracket from seeds
- [x] Generate DE bracket from seeds

View File

@@ -0,0 +1,145 @@
import classNames from "classnames";
const rounds = [
{
title: "Round 1",
bestOf: 3,
status: "DONE",
},
{
title: "Round 2",
bestOf: 5,
status: "INPROGRESS",
},
{
title: "Semifinals",
bestOf: 5,
status: "UPCOMING",
},
{
title: "Finals",
bestOf: 7,
status: "UPCOMING",
},
] as const;
export function EliminationBracket() {
return (
<div
className="tournament-bracket__elim__container"
style={
{
"--brackets-columns": rounds.length,
"--brackets-matches": 4,
} as any
}
>
<div className="tournament-bracket__elim__bracket">
{rounds.map((round, i) => (
<RoundInfo
key={round.title}
round={round}
isLast={i === rounds.length - 1}
/>
))}
<div
className="tournament-bracket__elim__column"
style={{ "--brackets-column-matches": 4 } as any}
>
<div className="tournament-bracket__elim__matches">
<Match />
<Match />
<Match />
<Match />
</div>
<div className="tournament-bracket__elim__lines">
<div />
<div />
</div>
</div>
<div
className="tournament-bracket__elim__column"
style={{ "--brackets-column-matches": 2 } as any}
>
<div className="tournament-bracket__elim__matches">
<Match />
<Match />
</div>
<div className="tournament-bracket__elim__lines">
<div />
</div>
</div>
<div
className="tournament-bracket__elim__column"
style={
{
"--brackets-column-matches": 0,
"--brackets-bottom-border-length": 0,
} as any
}
>
<div className="tournament-bracket__elim__matches">
<Match />
</div>
<div className="tournament-bracket__elim__lines">
<div />
</div>
</div>
<div className="tournament-bracket__elim__matches">
<Match />
</div>
</div>
</div>
);
}
function RoundInfo(props: {
round: {
title: string;
bestOf: number;
status: "DONE" | "INPROGRESS" | "UPCOMING";
};
isLast?: boolean;
}) {
return (
<div
className={classNames("tournament-bracket__elim__roundInfo", {
highlighted: props.round.status === "INPROGRESS",
last: props.isLast,
})}
>
<div className="tournament-bracket__elim__roundTitle">
{props.round.title}
</div>
{props.round.status !== "DONE" && (
<div className="tournament-bracket__elim__bestOf">
Bo{props.round.bestOf}
</div>
)}
</div>
);
}
export function Match() {
return (
<div className="tournament-bracket__elim__match">
<div className="tournament-bracket__elim__roundNumber">1</div>
<div
className={classNames(
"tournament-bracket__elim__team",
"tournament-bracket__elim__teamOne"
)}
>
Team Olive <span className="tournament-bracket__elim__score">1</span>
</div>
<div
className={classNames(
"tournament-bracket__elim__team",
"tournament-bracket__elim__teamTwo"
)}
>
Chimera <span className="tournament-bracket__elim__score">1</span>
</div>
</div>
);
}

View File

@@ -8,6 +8,7 @@ import type {
UseTournamentRoundsState,
} from "./types";
// TODO: could save this to local storage but need to handle amount of rounds changing
export function useTournamentRounds(args: UseTournamentRoundsArgs) {
return React.useReducer(
(oldState: UseTournamentRoundsState, action: UseTournamentRoundsAction) => {

View File

@@ -0,0 +1,15 @@
import type { LinksFunction } from "remix";
import { EliminationBracket } from "~/components/tournament/EliminationBracket";
import styles from "~/styles/tournament-bracket.css";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export default function BracketTabWrapper() {
return (
<div className="tournament-bracket__container">
<EliminationBracket />
</div>
);
}

View File

@@ -0,0 +1,120 @@
.tournament-bracket__container {
width: 100%;
}
.tournament-bracket__elim__container {
display: flex;
width: 100%;
justify-content: center;
margin: 0 auto;
}
.tournament-bracket__elim__bracket {
display: grid;
column-gap: 2px;
grid-template-columns: repeat(var(--brackets-columns), 250px);
overflow-x: auto;
--brackets-match-height: 100px;
}
.tournament-bracket__elim__roundInfo {
padding: 1.5rem 1rem;
background-color: var(--bg-lighter);
/* TODO: transition: background-color 0.5s; */
}
.tournament-bracket__elim__roundInfo:first-of-type {
border-radius: var(--rounded) 0 0 var(--rounded);
}
.tournament-bracket__elim__roundInfo.highlighted {
background-color: var(--theme);
color: var(--button-text);
}
.tournament-bracket__elim__roundInfo.last {
border-radius: 0 var(--rounded) var(--rounded) 0;
}
.tournament-bracket__elim__roundTitle {
font-size: var(--fonts-sm);
font-weight: 500;
}
.tournament-bracket__elim__bestOf {
font-size: var(--fonts-xs);
}
.tournament-bracket__elim__match {
display: grid;
margin: 1rem 0;
column-gap: 5px;
grid-template-areas:
"round-number team-one"
"round-number team-two";
grid-template-columns: 10px 1fr;
place-items: center;
row-gap: 2px;
}
.tournament-bracket__elim__roundNumber {
font-size: var(--fonts-xs);
grid-area: round-number;
}
.tournament-bracket__elim__team {
display: flex;
width: 200px;
justify-content: space-between;
padding: 0.25rem 0.75rem;
background-color: var(--bg-lighter);
font-size: var(--fonts-sm);
place-self: flex-start;
}
.tournament-bracket__elim__teamOne {
border-radius: var(--rounded) var(--rounded) 0 0;
grid-area: team-one;
}
.tournament-bracket__elim__teamTwo {
border-radius: 0 0 var(--rounded) var(--rounded);
grid-area: team-two;
}
.tournament-bracket__elim__score {
font-weight: bold;
}
.tournament-bracket__elim__column {
display: flex;
}
.tournament-bracket__elim__matches {
display: flex;
height: calc(var(--brackets-match-height) * var(--brackets-matches));
flex-direction: column;
justify-content: space-around;
}
.tournament-bracket__elim__lines {
display: flex;
flex-direction: column;
justify-content: space-around;
padding-left: 7px;
}
.tournament-bracket__elim__lines > div {
width: calc(var(--brackets-match-height) / 4);
height: calc(
2px + var(--brackets-match-height) *
(var(--brackets-matches) / var(--brackets-column-matches))
);
border-top: 2px solid var(--theme-transparent);
border-bottom: var(--brackets-bottom-border-length, 2px) solid
var(--theme-transparent);
border-inline-end: 2px solid var(--theme-transparent);
border-radius: 0 var(--rounded) var(--rounded) 0;
}