import { Flex, Box } from "@mantine/core"; import { Match } from "@/features/matches/types"; import { MatchCard } from "./match-card"; import { useEffect, useRef } from "react"; interface BracketProps { rounds: Match[][]; orders: Record; showControls?: boolean; groupConfig?: { num_groups: number; advance_per_group: number; }; } export const Bracket: React.FC = ({ rounds, orders, showControls, groupConfig, }) => { const containerRef = useRef(null); const svgRef = useRef(null); useEffect(() => { const updateConnectorLines = () => { if (!containerRef.current || !svgRef.current) return; const svg = svgRef.current; const container = containerRef.current; const flexContainer = container.querySelector('.bracket-flex-container') as HTMLElement; if (!flexContainer) return; svg.innerHTML = ''; const flexRect = flexContainer.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); svg.style.width = `${flexContainer.scrollWidth}px`; svg.style.height = `${flexContainer.scrollHeight}px`; rounds.forEach((round, roundIndex) => { if (roundIndex === rounds.length - 1) return; const nextRound = rounds[roundIndex + 1]; round.forEach((match, matchIndex) => { if (match.bye) return; const matchElement = container.querySelector(`[data-match-lid="${match.lid}"]`) as HTMLElement; if (!matchElement) return; const nextMatches = nextRound.filter(nextMatch => !nextMatch.bye && ( orders[nextMatch.home_from_lid] === match.order || orders[nextMatch.away_from_lid] === match.order ) ); nextMatches.forEach(nextMatch => { const nextMatchElement = container.querySelector(`[data-match-lid="${nextMatch.lid}"]`) as HTMLElement; if (!nextMatchElement) return; const matchRect = matchElement.getBoundingClientRect(); const nextMatchRect = nextMatchElement.getBoundingClientRect(); const startX = matchRect.right - flexRect.left; const startY = matchRect.top + matchRect.height / 2 - flexRect.top; const endX = nextMatchRect.left - flexRect.left; const endY = nextMatchRect.top + nextMatchRect.height / 2 - flexRect.top; const midX = startX + (endX - startX) * 0.5; const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); const pathData = `M ${startX} ${startY} L ${midX} ${startY} L ${midX} ${endY} L ${endX} ${endY}`; path.setAttribute('d', pathData); path.setAttribute('stroke', 'var(--mantine-color-default-border)'); path.setAttribute('stroke-width', '2'); path.setAttribute('fill', 'none'); path.setAttribute('stroke-linecap', 'round'); path.setAttribute('stroke-linejoin', 'round'); svg.appendChild(path); }); }); }); }; updateConnectorLines(); const handleUpdate = () => { requestAnimationFrame(updateConnectorLines); }; const scrollContainer = containerRef.current?.closest('.mantine-ScrollArea-viewport'); scrollContainer?.addEventListener('scroll', handleUpdate); window.addEventListener('resize', handleUpdate); return () => { scrollContainer?.removeEventListener('scroll', handleUpdate); window.removeEventListener('resize', handleUpdate); }; }, [rounds, orders]); return ( {rounds.map((round, roundIndex) => ( {round.map((match) => match.bye ? (
) : (
) )}
))}
); };