// frontend/src/components/Bracket/BracketView.jsx
import { useEffect, useRef, useState } from 'react';
import MatchCard from "./MatchCard";
import Podium from "../Tournament/Podium";
export default function BracketView({ matches, onMatchClick }) {
const containerRef = useRef(null);
const [lines, setLines] = useState([]);
useEffect(() => {
const draw = () => {
if (!containerRef.current) return;
const container = containerRef.current.getBoundingClientRect();
const newLines = [];
matches.forEach(m => {
if (m.winner_next_match_id) {
const sEl = document.getElementById(`match-${m.id}`);
const eEl = document.getElementById(`match-${m.winner_next_match_id}`);
if (sEl && eEl) {
const r1 = sEl.getBoundingClientRect(), r2 = eEl.getBoundingClientRect();
const sx = r1.right - container.left, sy = r1.top + r1.height / 2 - container.top;
const ex = r2.left - container.left, ey = r2.top + r2.height / 2 - container.top;
const c1 = sx + (ex - sx) / 2;
newLines.push(
);
}
}
if (m.loser_next_match_id) {
const targetMatch = matches.find(x => x.id === m.loser_next_match_id);
if (targetMatch && targetMatch.bracket === 'Finals') {
const sEl = document.getElementById(`match-${m.id}`);
const eEl = document.getElementById(`match-${targetMatch.id}`);
if (sEl && eEl) {
const r1 = sEl.getBoundingClientRect(), r2 = eEl.getBoundingClientRect();
const sx = r1.right - container.left, sy = r1.top + r1.height / 2 - container.top;
const ex = r2.left - container.left, ey = r2.top + r2.height / 2 - container.top;
const c1 = sx + (ex - sx) / 2;
newLines.push(
);
}
}
}
});
setLines(newLines);
};
const t = setTimeout(draw, 100);
window.addEventListener('resize', draw);
const handlePrint = () => { draw(); setTimeout(draw, 100); };
const mql = window.matchMedia('print');
mql.addEventListener('change', handlePrint);
window.addEventListener('beforeprint', handlePrint);
window.addEventListener('afterprint', draw);
return () => {
clearTimeout(t);
window.removeEventListener('resize', draw);
mql.removeEventListener('change', handlePrint);
window.removeEventListener('beforeprint', handlePrint);
window.removeEventListener('afterprint', draw);
};
}, [matches]);
const renderRound = (list) => {
const rounds = {};
list.forEach(m => (rounds[m.round] = rounds[m.round] || []).push(m));
const roundKeys = Object.keys(rounds).sort((a, b) => Number(a) - Number(b));
return roundKeys.map((r) => {
let matchesInRound = rounds[r];
matchesInRound.sort((a, b) => a.number - b.number);
return (
{matchesInRound.map(m => )}
);
});
};
const isDoubleElim = matches.some(m => m.bracket === 'Loser');
const wb = matches.filter(m => m.bracket === 'Winner');
const lb = matches.filter(m => m.bracket === 'Loser');
const finals = matches.filter(m => m.bracket === 'Finals');
let displayWb = [...wb];
let displayFinals = [...finals];
if (!isDoubleElim && displayWb.length > 0) {
const maxRound = Math.max(...displayWb.map(m => m.round));
const gfIndex = displayWb.findIndex(m => m.round === maxRound);
if (gfIndex !== -1) {
const gfMatch = displayWb.splice(gfIndex, 1)[0];
displayFinals.unshift(gfMatch);
}
}
return (
Winners Bracket
{renderRound(displayWb)}
{isDoubleElim && (
Losers Bracket
{renderRound(lb)}
)}
{displayFinals.length > 0 && (
Championship
{displayFinals.map(m =>
)}
)}
);
}