@@ -422,6 +445,127 @@ function TournamentProgressPrompt({ ownedTeamId }: { ownedTeamId: number }) {
);
}
+function FinalStandings({ standings }: { standings: FinalStanding[] }) {
+ const [viewAll, setViewAll] = React.useState(false);
+
+ if (standings.length < 3) {
+ console.error("Unexpectedly few standings");
+ return null;
+ }
+
+ const [first, second, third, ...rest] = standings;
+
+ const nonTopThreePlacements = viewAll
+ ? removeDuplicates(rest.map((s) => s.placement))
+ : [];
+
+ return (
+
+ {[third, first, second].map((standing) => {
+ return (
+
+
+
+ {standing.tournamentTeam.name}
+
+
+ {standing.players.map((player) => {
+ return (
+
+
+
+ );
+ })}
+
+
+ {standing.players.map((player) => {
+ return (
+
+ {player.discordName}
+
+ );
+ })}
+
+
+ );
+ })}
+ {nonTopThreePlacements.map((placement) => {
+ return (
+
+
+
+
+
+ {standings
+ .filter((s) => s.placement === placement)
+ .map((standing) => {
+ return (
+
+
+ {standing.tournamentTeam.name}
+
+
+ {standing.players.map((player) => {
+ return (
+
+
+
+ );
+ })}
+
+
+ {standing.players.map((player) => {
+ return (
+
+ {player.discordName}
+
+ );
+ })}
+
+
+ );
+ })}
+
+
+ );
+ })}
+
+
+
+ );
+}
+
function TournamentProgressContainer({
children,
}: {
diff --git a/app/features/tournament-bracket/tournament-bracket-utils.ts b/app/features/tournament-bracket/tournament-bracket-utils.ts
index e2cd89176..c2ae3d85d 100644
--- a/app/features/tournament-bracket/tournament-bracket-utils.ts
+++ b/app/features/tournament-bracket/tournament-bracket-utils.ts
@@ -16,6 +16,7 @@ import type {
} from "~/features/tournament";
import type { Params } from "@remix-run/react";
import invariant from "tiny-invariant";
+import type { DataTypes, ValueToArray } from "~/modules/brackets-manager/types";
export function matchIdFromParams(params: Params
) {
const result = Number(params["mid"]);
@@ -144,3 +145,31 @@ export function fillWithNullTillPowerOfTwo(arr: T[]) {
return [...arr, ...new Array(nullsToAdd).fill(null)];
}
+
+export function everyMatchIsOver(bracket: ValueToArray) {
+ let lastWinner = -1;
+ for (const [i, match] of bracket.match.entries()) {
+ // special case - bracket reset might not be played depending on who wins in the grands
+ if (
+ match.group_id === 3 &&
+ i === bracket.match.length - 1 &&
+ lastWinner === 1
+ ) {
+ continue;
+ }
+ // BYE
+ if (match.opponent1 === null || match.opponent2 === null) {
+ continue;
+ }
+ if (
+ match.opponent1?.result !== "win" &&
+ match.opponent2?.result !== "win"
+ ) {
+ return false;
+ }
+
+ lastWinner = match.opponent1?.result === "win" ? 1 : 2;
+ }
+
+ return true;
+}
diff --git a/app/features/tournament-bracket/tournament-bracket.css b/app/features/tournament-bracket/tournament-bracket.css
index 2cc31cfe7..71a63a3bf 100644
--- a/app/features/tournament-bracket/tournament-bracket.css
+++ b/app/features/tournament-bracket/tournament-bracket.css
@@ -251,6 +251,42 @@
gap: var(--s-3);
}
+.tournament-bracket__standings {
+ background-color: var(--bg-lighter-transparent);
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ border-radius: var(--rounded);
+ padding: var(--s-3);
+ gap: var(--s-2);
+ max-width: max-content;
+ margin: 0 auto;
+}
+.tournament-bracket__stadings__full-row-taker {
+ grid-column: 1 / 4;
+}
+
+.tournament-bracket__standing {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ gap: var(--s-2);
+}
+
+.tournament-bracket__standing__team-name {
+ font-weight: var(--semi-bold);
+ text-align: center;
+ font-size: var(-fonts-sm);
+}
+
+.tournament-bracket__standing__team-name__big {
+ font-size: var(--fonts-lg);
+}
+
+.tournament-bracket__standings__show-more {
+ margin-block-start: var(--s-2);
+ margin-inline: auto;
+}
+
@media screen and (min-width: 480px) {
.tournament-bracket__infos {
flex-direction: row;
diff --git a/app/modules/brackets-manager/types.ts b/app/modules/brackets-manager/types.ts
index 4f06b58d1..e8762dee0 100644
--- a/app/modules/brackets-manager/types.ts
+++ b/app/modules/brackets-manager/types.ts
@@ -84,7 +84,7 @@ export type DeepPartial = T extends object
/**
* Converts all value types to array types.
*/
-type ValueToArray = {
+export type ValueToArray = {
[K in keyof T]: Array;
};
diff --git a/app/styles/common.css b/app/styles/common.css
index 585f33b2a..337249e2e 100644
--- a/app/styles/common.css
+++ b/app/styles/common.css
@@ -759,6 +759,10 @@ dialog::backdrop {
gap: var(--s-8);
}
+.stack.xl {
+ gap: var(--s-12);
+}
+
.stack.horizontal {
flex-direction: row;
}