diff --git a/app/features/tournament-bracket/queries/findMatchById.server.ts b/app/features/tournament-bracket/queries/findMatchById.server.ts index f37ccbea2..25ba1c151 100644 --- a/app/features/tournament-bracket/queries/findMatchById.server.ts +++ b/app/features/tournament-bracket/queries/findMatchById.server.ts @@ -24,7 +24,13 @@ const stm = sql.prepare(/* sql */ ` 'tournamentTeamId', "TournamentTeamMember"."tournamentTeamId", 'inGameName', - "User"."inGameName" + "User"."inGameName", + 'discordId', + "User"."discordId", + 'customUrl', + "User"."customUrl", + 'discordAvatar', + "User"."discordAvatar" ) ) as "players" from "TournamentMatch" @@ -58,6 +64,9 @@ export const findMatchById = (id: number) => { discordName: User["discordName"]; tournamentTeamId: TournamentTeamMember["tournamentTeamId"]; inGameName: User["inGameName"]; + discordId: User["discordId"]; + customUrl: User["customUrl"]; + discordAvatar: User["discordAvatar"]; }>, }; }; diff --git a/app/features/tournament-bracket/routes/to.$id.matches.$mid.tsx b/app/features/tournament-bracket/routes/to.$id.matches.$mid.tsx index 118a72fcd..36459ecc3 100644 --- a/app/features/tournament-bracket/routes/to.$id.matches.$mid.tsx +++ b/app/features/tournament-bracket/routes/to.$id.matches.$mid.tsx @@ -4,6 +4,7 @@ import type { LoaderArgs, } from "@remix-run/node"; import { + Link, useLoaderData, useOutletContext, useRevalidator, @@ -28,6 +29,8 @@ import { assertUnreachable } from "~/utils/types"; import { tournamentBracketsPage, tournamentMatchSubscribePage, + tournamentTeamPage, + userPage, } from "~/utils/urls"; import { findByIdentifier } from "../../tournament/queries/findByIdentifier.server"; import { findTeamsByTournamentId } from "../../tournament/queries/findTeamsByTournamentId.server"; @@ -47,6 +50,8 @@ import { matchSubscriptionKey, } from "../tournament-bracket-utils"; import bracketStyles from "../tournament-bracket.css"; +import clsx from "clsx"; +import { Avatar } from "~/components/Avatar"; export const links: LinksFunction = () => [ { @@ -323,6 +328,7 @@ export const loader = ({ params }: LoaderArgs) => { }; export default function TournamentMatchPage() { + const user = useUser(); const visibility = useVisibilityChange(); const { revalidate } = useRevalidator(); const parentRouteData = useOutletContext(); @@ -332,16 +338,33 @@ export default function TournamentMatchPage() { data.match.opponentOne?.result === "win" || data.match.opponentTwo?.result === "win"; - const matchHasTwoTeams = Boolean( - data.match.opponentOne?.id && data.match.opponentTwo?.id - ); - React.useEffect(() => { if (visibility !== "visible" || matchIsOver) return; revalidate(); }, [visibility, revalidate, matchIsOver]); + const isMemberOfATeam = data.match.players.some((p) => p.id === user?.id); + + const type = canReportTournamentScore({ + event: parentRouteData.event, + match: data.match, + ownedTeamId: parentRouteData.ownTeam?.id, + user, + }) + ? "EDIT" + : isMemberOfATeam + ? "MEMBER" + : "OTHER"; + + const showRosterPeek = () => { + if (matchIsOver) return false; + + if (!data.match.opponentOne?.id || !data.match.opponentTwo?.id) return true; + + return type !== "EDIT"; + }; + return (
{!matchIsOver && visibility !== "hidden" ? : null} @@ -359,17 +382,18 @@ export default function TournamentMatchPage() { Back to bracket
- {!matchHasTwoTeams ? ( -
- Waiting for teams -
- ) : null} {matchIsOver ? : null} {!matchIsOver && typeof data.match.opponentOne?.id === "number" && typeof data.match.opponentTwo?.id === "number" ? ( + ) : null} + {showRosterPeek() ? ( + ) : null} @@ -403,8 +427,13 @@ function useAutoRefresh() { }, [lastEventId, revalidate]); } -function MapListSection({ teams }: { teams: [id: number, id: number] }) { - const user = useUser(); +function MapListSection({ + teams, + type, +}: { + teams: [id: number, id: number]; + type: "EDIT" | "MEMBER" | "OTHER"; +}) { const data = useLoaderData(); const parentRouteData = useOutletContext(); @@ -416,27 +445,12 @@ function MapListSection({ teams }: { teams: [id: number, id: number] }) { invariant(data.currentMap, "No map found for this score"); invariant(data.modes, "No modes found for this map list"); - const isMemberOfATeam = - teamOne.members.some((m) => m.userId === user?.id) || - teamTwo.members.some((m) => m.userId === user?.id); - return ( ); } @@ -482,3 +496,100 @@ function ResultsSection() { /> ); } + +function Rosters({ + teams, +}: { + teams: [id: number | null | undefined, id: number | null | undefined]; +}) { + const data = useLoaderData(); + const parentRouteData = useOutletContext(); + + const teamOne = parentRouteData.teams.find((team) => team.id === teams[0]); + const teamTwo = parentRouteData.teams.find((team) => team.id === teams[1]); + const teamOnePlayers = data.match.players.filter( + (p) => p.tournamentTeamId === teamOne?.id + ); + const teamTwoPlayers = data.match.players.filter( + (p) => p.tournamentTeamId === teamTwo?.id + ); + + return ( +
+
+
+
+ Team 1 +
+

+ {teamOne ? ( + + {teamOne.name} + + ) : ( + "Waiting on team" + )} +

+ {teamOnePlayers.length > 0 ? ( +
    + {teamOnePlayers.map((p) => { + return ( +
  • + + + {p.discordName} + +
  • + ); + })} +
+ ) : null} +
+
+
+
+ Team 2 +
+

+ {teamTwo ? ( + + {teamTwo.name} + + ) : ( + "Waiting on team" + )} +

+ {teamTwoPlayers.length > 0 ? ( +
    + {teamTwoPlayers.map((p) => { + return ( +
  • + + + {p.discordName} + +
  • + ); + })} +
+ ) : null} +
+
+ ); +} diff --git a/app/features/tournament-bracket/tournament-bracket.css b/app/features/tournament-bracket/tournament-bracket.css index d92f7e9bc..7cf7cd56d 100644 --- a/app/features/tournament-bracket/tournament-bracket.css +++ b/app/features/tournament-bracket/tournament-bracket.css @@ -209,6 +209,27 @@ font-weight: var(--bold); } +.tournament-bracket__rosters { + display: flex; + flex-wrap: wrap; + gap: var(--s-8); + font-size: var(--fonts-xs); + font-weight: var(--semi-bold); + flex-direction: column; +} + +.tournament-bracket__rosters ul { + padding: 0; + list-style: none; +} + +@media screen and (min-width: 640px) { + .tournament-bracket__rosters { + justify-content: space-evenly; + flex-direction: row; + } +} + .tournament-bracket__mode-progress { display: flex; margin-bottom: var(--s-4);