mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-14 07:06:14 -05:00
Rename <ActionSection />
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
import { useLoaderData } from "remix";
|
||||
import type { FindTournamentByNameForUrlI } from "~/services/tournament";
|
||||
import { useUser } from "~/utils/hooks";
|
||||
import { ActionSectionBeforeStartContent } from "./ActionSectionBeforeStartContent";
|
||||
|
||||
// TODO: warning when not registered but check in is open
|
||||
// TODO: rename, refactor
|
||||
export function ActionSection() {
|
||||
const tournament = useLoaderData<FindTournamentByNameForUrlI>();
|
||||
const user = useUser();
|
||||
|
||||
const ownTeam = tournament.teams.find((team) =>
|
||||
team.members.some(
|
||||
({ member, captain }) => captain && member.id === user?.id
|
||||
)
|
||||
);
|
||||
|
||||
const tournamentHasStarted = tournament.brackets.some((b) => b.rounds.length);
|
||||
if (!ownTeam || tournamentHasStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <ActionSectionBeforeStartContent ownTeam={ownTeam} />;
|
||||
}
|
||||
153
app/components/tournament/CheckinActions.tsx
Normal file
153
app/components/tournament/CheckinActions.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
// TODO: Warning: Text content did not match. Server: "57" Client: "56"
|
||||
import * as React from "react";
|
||||
import { Form, useLoaderData, useTransition } from "remix";
|
||||
import {
|
||||
checkInClosesDate,
|
||||
TOURNAMENT_TEAM_ROSTER_MIN_SIZE,
|
||||
} from "~/constants";
|
||||
import { TournamentAction } from "~/routes/to/$organization.$tournament";
|
||||
import type { FindTournamentByNameForUrlI } from "~/services/tournament";
|
||||
import { useUser } from "~/utils/hooks";
|
||||
import { Button } from "../Button";
|
||||
import { AlertIcon } from "../icons/Alert";
|
||||
import { CheckInIcon } from "../icons/CheckIn";
|
||||
import { ErrorIcon } from "../icons/Error";
|
||||
import { SuccessIcon } from "../icons/Success";
|
||||
import { ActionSectionWrapper } from "./ActionSectionWrapper";
|
||||
|
||||
// TODO: warning when not registered but check in is open
|
||||
export function CheckinActions() {
|
||||
const tournament = useLoaderData<FindTournamentByNameForUrlI>();
|
||||
const user = useUser();
|
||||
const transition = useTransition();
|
||||
|
||||
const ownTeam = tournament.teams.find((team) =>
|
||||
team.members.some(
|
||||
({ member, captain }) => captain && member.id === user?.id
|
||||
)
|
||||
);
|
||||
|
||||
const tournamentHasStarted = tournament.brackets.some((b) => b.rounds.length);
|
||||
if (!ownTeam || tournamentHasStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const timeInMinutesBeforeCheckInCloses = () => {
|
||||
return Math.floor(
|
||||
(checkInClosesDate(tournament.startTime).getTime() -
|
||||
new Date().getTime()) /
|
||||
(1000 * 60)
|
||||
);
|
||||
};
|
||||
|
||||
const [minutesTillCheckInCloses, setMinutesTillCheckInCloses] =
|
||||
React.useState(timeInMinutesBeforeCheckInCloses());
|
||||
|
||||
React.useEffect(() => {
|
||||
const timeout = setInterval(() => {
|
||||
setMinutesTillCheckInCloses(timeInMinutesBeforeCheckInCloses());
|
||||
}, 1000 * 15);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, []);
|
||||
|
||||
if (ownTeam.checkedInTime) {
|
||||
return (
|
||||
<ActionSectionWrapper icon="success" data-cy="checked-in-alert">
|
||||
<SuccessIcon /> Your team is checked in!
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const checkInHasStarted = new Date(tournament.checkInStartTime) < new Date();
|
||||
const teamHasEnoughMembers =
|
||||
ownTeam.members.length >= TOURNAMENT_TEAM_ROSTER_MIN_SIZE;
|
||||
|
||||
if (!checkInHasStarted && !teamHasEnoughMembers) {
|
||||
return (
|
||||
<ActionSectionWrapper icon="warning" data-cy="team-size-alert">
|
||||
<AlertIcon /> You need at least 4 players in your roster to play
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const differenceInMinutesBetweenCheckInAndStart = Math.floor(
|
||||
(new Date(tournament.startTime).getTime() -
|
||||
new Date(tournament.checkInStartTime).getTime()) /
|
||||
(1000 * 60)
|
||||
);
|
||||
|
||||
if (!checkInHasStarted && teamHasEnoughMembers) {
|
||||
return (
|
||||
<ActionSectionWrapper icon="info">
|
||||
<AlertIcon /> Check-in starts{" "}
|
||||
{differenceInMinutesBetweenCheckInAndStart} minutes before the
|
||||
tournament starts
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
checkInHasStarted &&
|
||||
!teamHasEnoughMembers &&
|
||||
minutesTillCheckInCloses > 0
|
||||
) {
|
||||
return (
|
||||
<ActionSectionWrapper icon="warning" data-cy="not-enough-players-warning">
|
||||
<AlertIcon /> You need at least 4 players in your roster to play.
|
||||
Check-in is open for {minutesTillCheckInCloses} more{" "}
|
||||
{minutesTillCheckInCloses > 1 ? "minutes" : "minute"}
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
checkInHasStarted &&
|
||||
teamHasEnoughMembers &&
|
||||
minutesTillCheckInCloses > 0
|
||||
) {
|
||||
return (
|
||||
<ActionSectionWrapper
|
||||
icon={minutesTillCheckInCloses <= 1 ? "warning" : "info"}
|
||||
data-cy="check-in-alert"
|
||||
>
|
||||
{minutesTillCheckInCloses > 1 ? (
|
||||
<>
|
||||
<AlertIcon /> Check-in is open for {minutesTillCheckInCloses} more
|
||||
minutes
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<AlertIcon /> Check-in closes in less than a minute
|
||||
</>
|
||||
)}
|
||||
<Form
|
||||
method="post"
|
||||
className="tournament__action-section__button-container"
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
name="_action"
|
||||
value={TournamentAction.CHECK_IN}
|
||||
/>
|
||||
<input type="hidden" name="teamId" value={ownTeam.id} />
|
||||
<Button
|
||||
variant="outlined"
|
||||
type="submit"
|
||||
loading={transition.state !== "idle"}
|
||||
icon={<CheckInIcon />}
|
||||
data-cy="check-in-button"
|
||||
>
|
||||
Check-in
|
||||
</Button>
|
||||
</Form>
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionSectionWrapper icon="error">
|
||||
<ErrorIcon /> Check-in has closed. Your team is not checked in
|
||||
</ActionSectionWrapper>
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "remix";
|
||||
import invariant from "tiny-invariant";
|
||||
import { AdminIcon } from "~/components/icons/Admin";
|
||||
import { ActionSection } from "~/components/tournament/ActionSection";
|
||||
import { CheckinActions } from "~/components/tournament/CheckinActions";
|
||||
import { InfoBanner } from "~/components/tournament/InfoBanner";
|
||||
import { isTournamentAdmin } from "~/core/tournament/permissions";
|
||||
import { tournamentHasStarted } from "~/core/tournament/utils";
|
||||
@@ -149,7 +149,7 @@ export default function TournamentPage() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="tournament__container__spacer" />
|
||||
<ActionSection />
|
||||
<CheckinActions />
|
||||
<div className="tournament__outlet-spacer" />
|
||||
{/* TODO: pass context instead of useMatches */}
|
||||
<Outlet />
|
||||
|
||||
Reference in New Issue
Block a user