diff --git a/app/routes/to/$organization.$tournament/map-pool.tsx b/app/routes/to/$organization.$tournament/map-pool.tsx index a964f6212..cdfdd84c2 100644 --- a/app/routes/to/$organization.$tournament/map-pool.tsx +++ b/app/routes/to/$organization.$tournament/map-pool.tsx @@ -1,4 +1,4 @@ -import mapPoolStylesUrl from "~/styles/map-pool.css"; +import stylesUrl from "~/styles/map-pool.css"; import type { Mode } from ".prisma/client"; import classNames from "classnames"; import { modesShort, stages } from "~/utils"; @@ -6,7 +6,7 @@ import { LinksFunction, useMatches } from "remix"; import { FindTournamentByNameForUrlI } from "../../../../services/tournament"; export const links: LinksFunction = () => { - return [{ rel: "stylesheet", href: mapPoolStylesUrl }]; + return [{ rel: "stylesheet", href: stylesUrl }]; }; export default function MapPoolTab() { diff --git a/app/routes/to/$organization.$tournament/teams.tsx b/app/routes/to/$organization.$tournament/teams.tsx new file mode 100644 index 000000000..085482be9 --- /dev/null +++ b/app/routes/to/$organization.$tournament/teams.tsx @@ -0,0 +1,88 @@ +import { useMatches, LinksFunction } from "remix"; +import { FindTournamentByNameForUrlI } from "../../../../services/tournament"; +import stylesUrl from "~/styles/teams.css"; +import { Fragment } from "react"; + +export const links: LinksFunction = () => { + return [{ rel: "stylesheet", href: stylesUrl }]; +}; + +export default function TeamsTab() { + const [, parentRoute] = useMatches(); + const { teams } = parentRoute.data as FindTournamentByNameForUrlI; + + if (!teams.length) return null; + + const sortedTeams = teams + // TODO: user id here + .sort(sortOwnTeamsAndFullTeamsFirst(-1)) + .map((team) => { + return { + ...team, + members: team.members.sort(sortCaptainFirst), + }; + }); + + return ( +
+
+
+ {sortedTeams.map((team) => ( + +
{team.name}
+
+ {team.members.map(({ member, captain }, i) => ( +
+
+ {captain ? "C" : i + 1} +
+
+
+ {member.discordAvatar && ( + + )} +
+
{member.discordName}
+
+
+ ))} +
+
+ ))} +
+
+
+ ); +} + +function sortCaptainFirst(a: { captain: boolean }, b: { captain: boolean }) { + return Number(b.captain) - Number(a.captain); +} + +function sortOwnTeamsAndFullTeamsFirst(userId?: number) { + return function ( + a: { members: { member: { id: number } }[] }, + b: { members: { member: { id: number } }[] } + ) { + if (userId) { + const aSortValue = Number( + a.members.some(({ member }) => userId === member.id) + ); + const bSortValue = Number( + b.members.some(({ member }) => userId === member.id) + ); + + if (aSortValue !== bSortValue) return bSortValue - aSortValue; + } + + const aSortValue = a.members.length >= 4 ? 1 : 0; + const bSortValue = b.members.length >= 4 ? 1 : 0; + + return bSortValue - aSortValue; + }; +} diff --git a/app/styles/teams.css b/app/styles/teams.css new file mode 100644 index 000000000..aa0d4691d --- /dev/null +++ b/app/styles/teams.css @@ -0,0 +1,77 @@ +.teams-tab { + display: flex; + flex-direction: column; + gap: var(--s-10); +} + +.teams-tab__teams-container { + display: grid; + column-gap: var(--s-6); + grid-template-columns: 1fr; + row-gap: var(--s-10); +} + +.teams-tab__team-name { + display: flex; + align-self: center; + border-block-end: 2px solid var(--theme); + font-size: var(--fonts-lg); + font-weight: var(--extra-bold); + justify-self: center; +} + +.teams-tab__members-container { + display: flex; + flex-direction: column; + gap: var(--s-4); +} + +.teams-tab__member { + display: flex; + align-items: center; + gap: var(--s-3); +} + +.teams-tab__member__order-number { + color: var(--theme-secondary); + font-size: var(--fonts-sm); + font-weight: bold; +} + +.teams-tab__member__container { + display: flex; + align-items: center; + font-weight: var(--semi-bold); + gap: var(--s-3); +} + +.teams-tab__member__avatar { + block-size: 2.5rem; + border-radius: var(--rounded); + filter: none; + inline-size: 2.5rem; + text-indent: -10000px; +} + +.teams-tab__member__placeholder { + background-image: url("/svg/background-pattern.svg"); + block-size: 2.5rem; + border-radius: var(--rounded); + inline-size: 2.5rem; +} + +@media screen and (min-width: 640px) { + .teams-tab__teams-container { + grid-template-columns: 1fr 1fr; + } + + .teams-tab__team-name { + border-bottom: none; + justify-self: flex-end; + } + + .teams-tab__members-container { + border-inline-start: 2px solid var(--theme); + padding-inline-start: var(--s-6); + } +}