From 212d3d09ac28dc7fac4fb16ab4b479b2ebca23cc Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Thu, 20 Jan 2022 21:39:03 +0200 Subject: [PATCH] Use new be style when putting player to team --- .../tournament/mutations/putPlayerToTeam.ts | 19 +++++++++++++++++ .../tournament/queries/tournamentTeamById.ts | 8 +++++++ .../$organization.$tournament/manage-team.tsx | 21 ++++++++++++++++--- app/validators/tournament.ts | 17 +++++++++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 app/db/tournament/mutations/putPlayerToTeam.ts create mode 100644 app/db/tournament/queries/tournamentTeamById.ts diff --git a/app/db/tournament/mutations/putPlayerToTeam.ts b/app/db/tournament/mutations/putPlayerToTeam.ts new file mode 100644 index 000000000..5357c7cf1 --- /dev/null +++ b/app/db/tournament/mutations/putPlayerToTeam.ts @@ -0,0 +1,19 @@ +import { db } from "~/utils/db.server"; + +export async function putPlayerToTeam({ + tournamentId, + teamId, + newPlayerId, +}: { + tournamentId: string; + teamId: string; + newPlayerId: string; +}) { + return db.tournamentTeamMember.create({ + data: { + tournamentId, + teamId, + memberId: newPlayerId, + }, + }); +} diff --git a/app/db/tournament/queries/tournamentTeamById.ts b/app/db/tournament/queries/tournamentTeamById.ts new file mode 100644 index 000000000..0662c9c46 --- /dev/null +++ b/app/db/tournament/queries/tournamentTeamById.ts @@ -0,0 +1,8 @@ +import { db } from "~/utils/db.server"; + +export function tournamentTeamById(id: string) { + return db.tournamentTeam.findUnique({ + where: { id }, + include: { tournament: true, members: true }, + }); +} diff --git a/app/routes/to/$organization.$tournament/manage-team.tsx b/app/routes/to/$organization.$tournament/manage-team.tsx index 8feff6fb6..8f705fdb6 100644 --- a/app/routes/to/$organization.$tournament/manage-team.tsx +++ b/app/routes/to/$organization.$tournament/manage-team.tsx @@ -24,17 +24,22 @@ import { roompassRegExp, roompassRegExpString, } from "~/core/tournament/utils"; +import { putPlayerToTeam } from "~/db/tournament/mutations/putPlayerToTeam"; +import { tournamentTeamById } from "~/db/tournament/queries/tournamentTeamById"; import { useBaseURL, useTimeoutState } from "~/hooks/common"; import type { FindManyByTrustReceiverId } from "~/models/TrustRelationship"; import { editTeam, ownTeamWithInviteCode, - putPlayerToTeam, removePlayerFromTeam, } from "~/services/tournament"; import { getTrustingUsers } from "~/services/user"; import styles from "~/styles/tournament-manage-team.css"; -import { parseRequestFormData, requireUser } from "~/utils"; +import { parseRequestFormData, requireUser, validate } from "~/utils"; +import { + isCaptainOfTheTeam, + tournamentTeamIsNotFull, +} from "~/validators/tournament"; export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: styles }]; @@ -83,9 +88,19 @@ export const action: ActionFunction = async ({ switch (data._action) { case "ADD_PLAYER": { try { + const tournamentTeam = await tournamentTeamById(data.teamId); + + // TODO: Validate if tournament already started / concluded (depending on if tournament allows mid-event roster additions) + validate(tournamentTeam, "Invalid tournament team id"); + validate(tournamentTeamIsNotFull(tournamentTeam), "Team is full"); + validate( + isCaptainOfTheTeam(user, tournamentTeam), + "Not captain of the team" + ); + await putPlayerToTeam({ + tournamentId: tournamentTeam.tournament.id, teamId: data.teamId, - captainId: user.id, newPlayerId: data.userId, }); } catch (e) { diff --git a/app/validators/tournament.ts b/app/validators/tournament.ts index f111926a8..f409f1f09 100644 --- a/app/validators/tournament.ts +++ b/app/validators/tournament.ts @@ -1,7 +1,9 @@ +import { TOURNAMENT_TEAM_ROSTER_MAX_SIZE } from "~/constants"; import { FindTournamentById } from "~/db/tournament/queries/findTournamentById"; /** Checks that a user is considered an admin of the tournament. An admin can perform all sorts of actions that normal users can't. */ export function isTournamentAdmin({ + // TODO: refactor to user userId, organization, }: { @@ -17,3 +19,18 @@ export function tournamentHasNotStarted( ) { return (tournament.brackets[0]?.rounds.length ?? 0) === 0; } + +/** Checks if given user is captain of the team. Captain is considered the admin of the team. */ +export function isCaptainOfTheTeam( + user: { id: string }, + team: { members: { captain: boolean; memberId: string }[] } +) { + return team.members.some( + ({ memberId, captain }) => captain && memberId === user.id + ); +} + +/** Checks tournament team's member count is below the max roster size constant. */ +export function tournamentTeamIsNotFull(team: { members: unknown[] }) { + return team.members.length < TOURNAMENT_TEAM_ROSTER_MAX_SIZE; +}