ActionSection initial

This commit is contained in:
Kalle (Sendou)
2021-12-06 14:48:50 +02:00
parent 873d39270c
commit a24afa2af8
7 changed files with 126 additions and 32 deletions

View File

@@ -24,6 +24,7 @@ Prerequisites: [Node.js 16.13](https://nodejs.org/en/)
- [x] Captain can remove players from roster
- [ ] Add info about architecture to README
- [ ] Make description mandatory + overview tab
- [ ] Captain can check in
- [ ] Admin can check teams in (and out)
- [ ] Admin can drop people out (show on bracket somehow that they dropped)
@@ -49,6 +50,7 @@ Prerequisites: [Node.js 16.13](https://nodejs.org/en/)
- [ ] Detailed match reports from Lanista
- [ ] Stats
- [ ] Routine to calculate Trueskill
- [ ] Markdown support for tournament description
- [ ] Can make a new tournament as org admin
- [ ] Rules tab with a good default, highlight overrides
- [ ] Friend code to add that is easily editable even before tournament starts

View File

@@ -0,0 +1,71 @@
import type { FindTournamentByNameForUrlI } from "~/services/tournament";
import { useUser } from "~/utils/hooks";
import { AlertIcon } from "../icons/Alert";
export function ActionSection({
tournament,
}: {
tournament: FindTournamentByNameForUrlI;
}) {
const user = useUser();
const ownTeam = tournament.teams.find((team) =>
team.members.some(
({ member, captain }) => captain && member.id === user?.id
)
);
// TODO: or tournament is over
if (!ownTeam) {
return null;
}
const checkInHasStarted = new Date(tournament.checkInTime) < new Date();
const teamHasEnoughMembers = true;
// const teamHasEnoughMembers =
// ownTeam.members.length >= TOURNAMENT_TEAM_ROSTER_MIN_SIZE;
if (!checkInHasStarted && !teamHasEnoughMembers) {
return (
<Wrapper icon="warning">
<AlertIcon /> You need at least 4 players in your roster to play
</Wrapper>
);
}
const differenceInMinutesBetweenCheckInAndStart = Math.floor(
(new Date(tournament.startTime).getTime() -
new Date(tournament.checkInTime).getTime()) /
(1000 * 60)
);
if (!checkInHasStarted && teamHasEnoughMembers) {
return (
<Wrapper icon="info">
<AlertIcon /> Check-in starts{" "}
{differenceInMinutesBetweenCheckInAndStart} minutes before the
tournament starts
</Wrapper>
);
}
console.error("Unexpected combination in ActionSection component");
return null;
}
function Wrapper({
children,
icon,
}: {
children: React.ReactNode;
icon: "warning" | "info";
}) {
return (
<section
className="tournament__action-section"
style={{ "--action-section-icon-color": `var(--theme-${icon})` } as any}
>
<div className="tournament__action-section__content">{children}</div>
</section>
);
}

View File

@@ -15,18 +15,7 @@ export function InfoBanner() {
return (
<>
<div
className="info-banner"
style={
{
"--background": data.bannerBackground,
// TODO: do this on backend
"--text": `hsl(${data.bannerTextHSLArgs})`,
// TODO: and this
"--text-transparent": `hsla(${data.bannerTextHSLArgs}, 0.3)`,
} as Record<string, string>
}
>
<div className="info-banner">
<div className="info-banner__top-row">
<div className="info-banner__top-row__date-name">
<time

View File

@@ -10,6 +10,7 @@ import {
useLocation,
} from "remix";
import invariant from "tiny-invariant";
import { ActionSection } from "~/components/tournament/ActionSection";
import { InfoBanner } from "~/components/tournament/InfoBanner";
import {
findTournamentByNameForUrl,
@@ -78,8 +79,21 @@ export default function TournamentPage() {
})();
return (
<div className="tournament__container">
<div
className="tournament__container"
style={
{
"--tournaments-background": data.bannerBackground,
// TODO: do this on backend
"--tournaments-text": `hsl(${data.bannerTextHSLArgs})`,
// TODO: and this
"--tournaments-text-transparent": `hsla(${data.bannerTextHSLArgs}, 0.3)`,
} as Record<string, string>
}
>
<InfoBanner />
<ActionSection tournament={data} />
<div className="tournament__container__spacer" />
{displayNavLinks && (
<div
style={{ "--tabs-count": navLinks.length } as any}

View File

@@ -15,10 +15,7 @@ import { Button } from "~/components/Button";
import ErrorMessage from "~/components/ErrorMessage";
import { MyForm } from "~/components/MyForm";
import { TeamRoster } from "~/components/tournament/TeamRoster";
import {
TOURNAMENT_TEAM_ROSTER_MAX_SIZE,
TOURNAMENT_TEAM_ROSTER_MIN_SIZE,
} from "~/constants";
import { TOURNAMENT_TEAM_ROSTER_MAX_SIZE } from "~/constants";
import {
ownTeamWithInviteCode,
OwnTeamWithInviteCodeI,
@@ -145,13 +142,6 @@ export default function ManageRosterPage() {
return (
<div className="tournament__manage-roster">
{ownTeam.members.length < TOURNAMENT_TEAM_ROSTER_MIN_SIZE && (
// TODO: show alert when team is full
<Alert type="warning" data-cy="team-size-alert">
You need at least {TOURNAMENT_TEAM_ROSTER_MIN_SIZE} players in your
roster to play (max {TOURNAMENT_TEAM_ROSTER_MAX_SIZE})
</Alert>
)}
{ownTeam.members.length >= TOURNAMENT_TEAM_ROSTER_MAX_SIZE && (
// TODO: show alert when team is full
<Alert type="info" data-cy="team-size-alert">

View File

@@ -3,7 +3,6 @@
width: 100%;
flex-direction: column;
gap: var(--s-8);
margin-block-start: var(--s-4);
}
.tournament__manage-roster__roster-container {

View File

@@ -6,12 +6,41 @@
margin: 0 auto;
}
.tournament__container__spacer {
margin-bottom: var(--s-5);
}
.tournament__action-section {
width: 100%;
padding: var(--s-1-5);
margin-top: var(--s-3);
background: var(--tournaments-background);
border-radius: var(--rounded);
}
.tournament__action-section__content {
display: flex;
width: 100%;
align-items: center;
padding: var(--s-2);
background-color: var(--bg-lighter);
border-radius: var(--rounded);
font-size: var(--fonts-sm);
font-weight: var(--semi-bold);
gap: var(--s-1-5);
}
.tournament__action-section__content > svg {
width: 1.5rem;
fill: var(--action-section-icon-color);
}
.tournament__links-container {
display: grid;
justify-content: center;
gap: var(--s-10);
grid-template-columns: repeat(2, 100px);
padding-block: var(--s-8);
padding-block-end: var(--s-8);
place-items: center;
}
@@ -46,9 +75,9 @@
.info-banner {
width: 100%;
padding: var(--s-6);
background: var(--background);
background: var(--tournaments-background);
border-radius: var(--rounded);
color: var(--text);
color: var(--tournaments-text);
}
.info-banner__top-row {
@@ -82,9 +111,9 @@
}
.info-banner__top-row__tournament-name {
border-color: var(--text);
border-color: var(--tournaments-text);
border-inline-start: 1px solid;
color: var(--text);
color: var(--tournaments-text);
font-size: var(--fonts-xl);
font-weight: var(--extra-bold);
padding-inline-start: var(--s-4);
@@ -125,7 +154,7 @@
justify-content: center;
padding: var(--s-2);
border: 1px solid;
border-color: var(--text-transparent);
border-color: var(--tournaments-text-transparent);
block-size: 2.25rem;
border-radius: 50%;
color: inherit;
@@ -142,7 +171,7 @@
align-items: center;
justify-content: center;
border: 1px solid;
border-color: var(--text-transparent);
border-color: var(--tournaments-text-transparent);
border-radius: var(--rounded);
color: inherit;
cursor: pointer;