diff --git a/scenes/tournament/components/TeamsTab.tsx b/scenes/tournament/components/TeamsTab.tsx
new file mode 100644
index 000000000..7385e02ea
--- /dev/null
+++ b/scenes/tournament/components/TeamsTab.tsx
@@ -0,0 +1,83 @@
+import { createMemo, For, Show } from "solid-js";
+import { useTournamentData } from "../TournamentPage.data";
+import s from "../styles/TeamsTab.module.css";
+import { AvatarWithName } from "../../../components/AvatarWithName";
+import type { InferQueryOutput } from "../../../utils/trpc-client";
+
+export function TeamsTab() {
+ const tournament = useTournamentData(1);
+
+ const sortCaptainFirst = (
+ a: { captain: boolean },
+ b: { captain: boolean }
+ ) => {
+ return Number(b.captain) - Number(a.captain);
+ };
+
+ const completeTeams = createMemo(() =>
+ tournament()
+ ?.teams.filter((team) => team.members.length >= 4)
+ .map((team) => {
+ return {
+ ...team,
+ members: team.members.sort(sortCaptainFirst),
+ };
+ })
+ );
+
+ const inCompleteTeams = createMemo(() =>
+ tournament()
+ ?.teams.filter((team) => team.members.length < 4)
+ .map((team) => {
+ return {
+ ...team,
+ members: team.members.sort(sortCaptainFirst),
+ };
+ })
+ );
+
+ return (
+
+
+ {(teams) => }
+
+
+ {(teams) => }
+
+
+ );
+}
+
+function TeamsList(p: {
+ teams: NonNullable
>["teams"];
+ title: string;
+}) {
+ if (!p.teams.length) return null;
+
+ return (
+
+
+ {p.title} ({p.teams.length})
+
+
+
+ {(team) => (
+ <>
+ {team.name}
+
+
+ {({ member, captain }, i) => (
+
+
{captain ? "C" : i()}
+
+
+ )}
+
+
+ >
+ )}
+
+
+
+ );
+}
diff --git a/scenes/tournament/components/TournamentPage.tsx b/scenes/tournament/components/TournamentPage.tsx
index 25c001ab9..1dfaf524f 100644
--- a/scenes/tournament/components/TournamentPage.tsx
+++ b/scenes/tournament/components/TournamentPage.tsx
@@ -1,28 +1,36 @@
import { NavLink, Outlet } from "solid-app-router";
import { InfoBanner } from "./InfoBanner";
import s from "../styles/TournamentPage.module.css";
+import { useTournamentData } from "../TournamentPage.data";
+import { Show } from "solid-js";
export default function TournamentsPage() {
+ const tournament = useTournamentData();
+
return (
-
-
- Overview
-
-
- Map Pool
-
-
- Bracket
-
-
- Teams (23)
-
-
- Streams (4)
-
-
+
+ {(tournament) => (
+
+
+ Overview
+
+
+ Map Pool
+
+
+ Bracket
+
+
+ Teams ({tournament.teams.length})
+
+
+ Streams (4)
+
+
+ )}
+
);
diff --git a/scenes/tournament/service.ts b/scenes/tournament/service.ts
index 3d52f5c97..caa2b4e58 100644
--- a/scenes/tournament/service.ts
+++ b/scenes/tournament/service.ts
@@ -32,6 +32,26 @@ export async function findTournamentByNameForUrl({
name: true,
},
},
+ teams: {
+ select: {
+ checkedIn: true,
+ id: true,
+ name: true,
+ members: {
+ select: {
+ captain: true,
+ member: {
+ select: {
+ discordAvatar: true,
+ discordName: true,
+ discordId: true,
+ discordDiscriminator: true,
+ },
+ },
+ },
+ },
+ },
+ },
},
});
diff --git a/scenes/tournament/styles/TeamsTab.module.css b/scenes/tournament/styles/TeamsTab.module.css
new file mode 100644
index 000000000..025ca94c9
--- /dev/null
+++ b/scenes/tournament/styles/TeamsTab.module.css
@@ -0,0 +1,44 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ gap: var(--s-10);
+}
+
+.teamsContainer {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ row-gap: var(--s-10);
+}
+
+.teamName {
+ display: flex;
+ align-items: center;
+ font-weight: var(--extra-bold);
+ font-size: var(--fonts-lg);
+}
+
+.membersContainer {
+ display: flex;
+ flex-direction: column;
+ gap: var(--s-4);
+ border-inline-start: 2px solid var(--theme);
+ padding-inline-start: var(--s-3);
+}
+
+.member {
+ display: flex;
+ align-items: center;
+ gap: var(--s-3);
+}
+
+.orderNumber {
+ color: var(--theme-secondary);
+ font-weight: bold;
+ font-size: var(--fonts-sm);
+}
+
+.teamListTitle {
+ margin-block-end: var(--s-8);
+ text-align: center;
+ margin-block-start: 0;
+}
diff --git a/scenes/tournament/styles/TournamentPage.module.css b/scenes/tournament/styles/TournamentPage.module.css
index c542a5d22..9ea31847a 100644
--- a/scenes/tournament/styles/TournamentPage.module.css
+++ b/scenes/tournament/styles/TournamentPage.module.css
@@ -10,7 +10,7 @@
place-items: center;
gap: var(--s-10);
grid-template-columns: repeat(2, 100px);
- padding-block: var(--s-6);
+ padding-block: var(--s-8);
}
.navLink {
diff --git a/styles/AvatarWithName.module.css b/styles/AvatarWithName.module.css
new file mode 100644
index 000000000..78bfcd7b2
--- /dev/null
+++ b/styles/AvatarWithName.module.css
@@ -0,0 +1,21 @@
+.container {
+ display: flex;
+ align-items: center;
+ gap: var(--s-3);
+ font-weight: var(--semi-bold);
+}
+
+.avatar {
+ border-radius: var(--rounded);
+ block-size: 2.5rem;
+ inline-size: 2.5rem;
+ text-indent: -10000px;
+ filter: none;
+}
+
+.placeholder {
+ border-radius: var(--rounded);
+ block-size: 2.5rem;
+ inline-size: 2.5rem;
+ background-image: url(/svg/background-pattern.svg);
+}
diff --git a/styles/global.css b/styles/global.css
index c5863bac0..896b08ada 100644
--- a/styles/global.css
+++ b/styles/global.css
@@ -3,8 +3,9 @@
--bg-lighter: hsl(237.3, 42.3%, 35.6%);
--text: rgba(255, 255, 255, 0.95);
--text-lighter: rgba(255, 255, 255, 0.55);
- --theme: rgba(103, 65, 217);
- --theme-transparent: rgba(103, 65, 217, 0.4);
+ --theme: hsl(255, 66.7%, 55.3%);
+ --theme-transparent: hsla(255, 66.7%, 55.3%, 0.4);
+ --theme-secondary: hsl(85, 66.7%, 55.3%);
--rounded: 16px;
diff --git a/utils/types.ts b/utils/types.ts
new file mode 100644
index 000000000..9db8f9f7b
--- /dev/null
+++ b/utils/types.ts
@@ -0,0 +1 @@
+export type UseDataResult = () => Data;