+
{match.away?.seed ? (
match.away.team ? (
- {match.away.team.name}
+ {match.away.team.name}
) : (
- Team {match.away.seed}
+
+ Team {match.away.seed}
+
)
- ) : (match.away?.parent_lid !== null && match.away?.parent_lid !== undefined) ? (
-
- {match.away.loser ? 'Loser' : 'Winner'} of Match {getParentMatchOrder(match.away.parent_lid)}
+ ) : match.away?.parent_lid !== null &&
+ match.away?.parent_lid !== undefined ? (
+
+ {match.away.loser ? "Loser" : "Winner"} of Match{" "}
+ {getParentMatchOrder(match.away.parent_lid)}
) : match.away ? (
- TBD
+
+ TBD
+
) : null}
{match.reset && (
-
IF NECESSARY
)}
{onAnnounce && match.home?.team && match.away?.team && (
{
onAnnounce(match.home.team, match.away.team);
}}
- bd='none'
- style={{ boxShadow: 'none' }}
- size='xs'
+ bd="none"
+ style={{ boxShadow: "none" }}
+ size="xs"
>
@@ -172,4 +209,4 @@ const BracketView: React.FC
= ({ bracket, bracketMaps, onAnnou
);
};
-export default BracketView;
\ No newline at end of file
+export default BracketView;
diff --git a/src/features/bracket/components/bracket.tsx b/src/features/bracket/components/bracket.tsx
new file mode 100644
index 0000000..a19b6d1
--- /dev/null
+++ b/src/features/bracket/components/bracket.tsx
@@ -0,0 +1,46 @@
+import { ScrollArea, Text } from "@mantine/core";
+import BracketView from "./bracket-view";
+import { Match } from "../types";
+import useAppShellHeight from "@/hooks/use-appshell-height";
+import { BracketMaps } from "../utils/bracket-maps";
+
+interface BracketProps {
+ winners: Match[][],
+ losers?: Match[][],
+ bracketMaps: BracketMaps | null
+}
+
+const Bracket: React.FC = ({ winners, losers, bracketMaps }) => {
+ const height = useAppShellHeight();
+
+ if (!bracketMaps) return Data not available.
+
+ return (
+
+
+
+ Winners Bracket
+
+
+
+ {
+ losers &&
+
+ Losers Bracket
+
+
+
+ }
+
+ );
+};
+
+export default Bracket;
diff --git a/src/features/bracket/components/preview.tsx b/src/features/bracket/components/preview.tsx
new file mode 100644
index 0000000..7674a29
--- /dev/null
+++ b/src/features/bracket/components/preview.tsx
@@ -0,0 +1,119 @@
+import {
+ Text,
+ Container,
+ Flex,
+ NumberInput,
+ Group,
+ Loader,
+} from "@mantine/core";
+import { useEffect, useState } from "react";
+import { bracketQueries } from "../queries";
+import { useQuery } from "@tanstack/react-query";
+import { createBracketMaps, BracketMaps } from "../utils/bracket-maps";
+import { BracketData, Match, Team } from "../types";
+import Bracket from "./bracket";
+import "./styles.module.css";
+
+export const PreviewBracket: React.FC = () => {
+ const [teamCount, setTeamCount] = useState(20);
+ const { data, isLoading, error } = useQuery(
+ bracketQueries.preview(teamCount)
+ );
+
+ const [teams, setTeams] = useState([]);
+
+ useEffect(() => {
+ setTeams(
+ Array.from({ length: teamCount }, (_, i) => ({
+ id: `team-${i + 1}`,
+ name: `Team ${i + 1}`,
+ }))
+ );
+ }, [teamCount]);
+
+ const [seededWinnersBracket, setSeededWinnersBracket] = useState(
+ []
+ );
+ const [seededLosersBracket, setSeededLosersBracket] = useState([]);
+ const [bracketMaps, setBracketMaps] = useState(null);
+
+ useEffect(() => {
+ if (!data || teams.length === 0) return;
+
+ const maps = createBracketMaps(data);
+ setBracketMaps(maps);
+
+ const mapBracket = (bracket: Match[][]) => {
+ return bracket.map((round) =>
+ round.map((match) => {
+ const mappedMatch = { ...match };
+
+ if (match.home?.seed && match.home.seed > 0) {
+ const teamIndex = match.home.seed - 1;
+ if (teams[teamIndex]) {
+ mappedMatch.home = {
+ ...match.home,
+ team: teams[teamIndex],
+ };
+ }
+ }
+
+ if (match.away?.seed && match.away.seed > 0) {
+ const teamIndex = match.away.seed - 1;
+ if (teams[teamIndex]) {
+ mappedMatch.away = {
+ ...match.away,
+ team: teams[teamIndex],
+ };
+ }
+ }
+
+ return mappedMatch;
+ })
+ );
+ };
+
+ setSeededWinnersBracket(mapBracket(data.winners));
+ setSeededLosersBracket(mapBracket(data.losers));
+ }, [teams, data]);
+
+ if (error) return Error loading bracket
;
+
+ return (
+
+
+
+ Preview Bracket (Double Elimination)
+
+
+
+ Teams:
+
+ setTeamCount(Number(value) || 12)}
+ min={12}
+ max={20}
+ size="sm"
+ w={80}
+ allowDecimal={false}
+ clampBehavior="strict"
+ />
+
+
+
+ {isLoading ? (
+
+
+
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/src/features/bracket/types.ts b/src/features/bracket/types.ts
new file mode 100644
index 0000000..d821ee0
--- /dev/null
+++ b/src/features/bracket/types.ts
@@ -0,0 +1,19 @@
+export interface Team {
+ id: string;
+ name: string;
+}
+
+export interface Match {
+ lid: number;
+ round: number;
+ order: number | null;
+ type: string;
+ home: any;
+ away?: any;
+ reset?: boolean;
+}
+
+export interface BracketData {
+ winners: Match[][];
+ losers: Match[][];
+}