From 3cf00cc426eea7fbaf7f2e7fa56acf7a63abeb8d Mon Sep 17 00:00:00 2001 From: yohlo Date: Sat, 23 Aug 2025 15:25:28 -0500 Subject: [PATCH] more bracket refactor --- .../bracket/components/bracket-round.tsx | 54 +++++ .../bracket/components/bracket-view.tsx | 190 ++---------------- .../bracket/components/match-card.tsx | 66 ++++++ .../bracket/components/match-slot.tsx | 43 ++++ .../bracket/components/seed-badge.tsx | 29 +++ 5 files changed, 204 insertions(+), 178 deletions(-) create mode 100644 src/features/bracket/components/bracket-round.tsx create mode 100644 src/features/bracket/components/match-card.tsx create mode 100644 src/features/bracket/components/match-slot.tsx create mode 100644 src/features/bracket/components/seed-badge.tsx diff --git a/src/features/bracket/components/bracket-round.tsx b/src/features/bracket/components/bracket-round.tsx new file mode 100644 index 0000000..3267e4f --- /dev/null +++ b/src/features/bracket/components/bracket-round.tsx @@ -0,0 +1,54 @@ +import { Flex, Text } from '@mantine/core'; +import React from 'react'; +import { MatchCard } from './match-card'; +import { Match } from '../types'; + +interface BracketRoundProps { + matches: Match[]; + roundIndex: number; + getParentMatchOrder: (parentLid: number) => number | string; + onAnnounce?: (teamOne: any, teamTwo: any) => void; +} + +export const BracketRound: React.FC = ({ + matches, + roundIndex, + getParentMatchOrder, + onAnnounce, +}) => { + const isMatchType = (type: string, expected: string) => { + return type?.toLowerCase() === expected.toLowerCase(); + }; + + return ( + + {matches.map((match, matchIndex) => { + if (!match) return null; + + // Handle bye matches + if (isMatchType(match.type, 'bye') || isMatchType(match.type, 'tbye')) { + return ; + } + + return ( + + + {match.order} + + + + ); + })} + + ); +}; \ No newline at end of file diff --git a/src/features/bracket/components/bracket-view.tsx b/src/features/bracket/components/bracket-view.tsx index 4108f51..bf14f71 100644 --- a/src/features/bracket/components/bracket-view.tsx +++ b/src/features/bracket/components/bracket-view.tsx @@ -1,17 +1,8 @@ -import { ActionIcon, Card, Flex, Text } from "@mantine/core"; -import { PlayIcon } from "@phosphor-icons/react"; -import React from "react"; -import { BracketMaps } from "../utils/bracket-maps"; - -interface Match { - lid: number; - round: number; - order: number | null; - type: string; - home: any; - away?: any; - reset?: boolean; -} +import { Flex } from '@mantine/core'; +import React from 'react'; +import { BracketMaps } from '../utils/bracket-maps'; +import { BracketRound } from './bracket-round'; +import { Match } from '../types'; interface BracketViewProps { bracket: Match[][]; @@ -24,9 +15,6 @@ const BracketView: React.FC = ({ bracketMaps, onAnnounce, }) => { - const isMatchType = (type: string, expected: string) => { - return type?.toLowerCase() === expected.toLowerCase(); - }; const getParentMatchOrder = (parentLid: number): number | string => { const parentMatch = bracketMaps.matchByLid.get(parentLid); @@ -43,170 +31,16 @@ const BracketView: React.FC = ({ return ( {bracket.map((round, roundIndex) => ( - - {round.map((match, matchIndex) => { - if (!match) return null; - - if ( - isMatchType(match.type, "bye") || - isMatchType(match.type, "tbye") - ) { - return ; - } - - return ( - - - {match.order} - - - - - {match.home?.seed && ( - - {match.home.seed} - - )} -
- {match.home?.seed ? ( - match.home.team ? ( - {match.home.team.name} - ) : ( - - Team {match.home.seed} - - ) - ) : match.home?.parent_lid !== null && - match.home?.parent_lid !== undefined ? ( - - {match.home.loser ? "Loser" : "Winner"} of Match{" "} - {getParentMatchOrder(match.home.parent_lid)} - - ) : ( - - TBD - - )} -
-
-
- - - {match.away?.seed && ( - - {match.away.seed} - - )} -
- {match.away?.seed ? ( - match.away.team ? ( - {match.away.team.name} - ) : ( - - 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 ? ( - - 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" - > - - - )} -
-
- ); - })} -
+ matches={round} + roundIndex={roundIndex} + getParentMatchOrder={getParentMatchOrder} + onAnnounce={onAnnounce} + /> ))}
); }; -export default BracketView; +export default BracketView; \ No newline at end of file diff --git a/src/features/bracket/components/match-card.tsx b/src/features/bracket/components/match-card.tsx new file mode 100644 index 0000000..0efe0b6 --- /dev/null +++ b/src/features/bracket/components/match-card.tsx @@ -0,0 +1,66 @@ +import { ActionIcon, Card, Text } from '@mantine/core'; +import { PlayIcon } from '@phosphor-icons/react'; +import React from 'react'; +import { MatchSlot } from './match-slot'; +import { Match } from '../types'; + +interface MatchCardProps { + match: Match; + getParentMatchOrder: (parentLid: number) => number | string; + onAnnounce?: (teamOne: any, teamTwo: any) => void; +} + +export const MatchCard: React.FC = ({ + match, + getParentMatchOrder, + onAnnounce +}) => { + return ( + + + + + + + + + + {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" + > + + + )} + + ); +}; \ No newline at end of file diff --git a/src/features/bracket/components/match-slot.tsx b/src/features/bracket/components/match-slot.tsx new file mode 100644 index 0000000..bf64522 --- /dev/null +++ b/src/features/bracket/components/match-slot.tsx @@ -0,0 +1,43 @@ +import { Flex, Text } from '@mantine/core'; +import React from 'react'; +import { SeedBadge } from './seed-badge'; + +interface MatchSlotProps { + slot: any; + getParentMatchOrder: (parentLid: number) => number | string; +} + +export const MatchSlot: React.FC = ({ slot, getParentMatchOrder }) => { + const renderSlotContent = () => { + if (slot?.seed) { + return slot.team ? ( + {slot.team.name} + ) : ( + Team {slot.seed} + ); + } + + if (slot?.parent_lid !== null && slot?.parent_lid !== undefined) { + return ( + + {slot.loser ? 'Loser' : 'Winner'} of Match {getParentMatchOrder(slot.parent_lid)} + + ); + } + + if (slot) { + return TBD; + } + + return null; + }; + + return ( + + {slot?.seed && } +
+ {renderSlotContent()} +
+
+ ); +}; \ No newline at end of file diff --git a/src/features/bracket/components/seed-badge.tsx b/src/features/bracket/components/seed-badge.tsx new file mode 100644 index 0000000..e30d72b --- /dev/null +++ b/src/features/bracket/components/seed-badge.tsx @@ -0,0 +1,29 @@ +import { Text } from '@mantine/core'; +import React from 'react'; + +interface SeedBadgeProps { + seed: number; +} + +export const SeedBadge: React.FC = ({ seed }) => { + return ( + + {seed} + + ); +}; \ No newline at end of file