diff --git a/tournaments/models/match.py b/tournaments/models/match.py index 1995428..baca94b 100644 --- a/tournaments/models/match.py +++ b/tournaments/models/match.py @@ -480,7 +480,6 @@ class LiveMatch: "group_stage_name": self.group_stage_name, "format": self.format, "disabled": self.disabled, - "start_date": self.start_date, "court_index": self.court_index } diff --git a/tournaments/templates/tournaments/bracket_match_cell.html b/tournaments/templates/tournaments/bracket_match_cell.html index 578c1fd..533ecc9 100644 --- a/tournaments/templates/tournaments/bracket_match_cell.html +++ b/tournaments/templates/tournaments/bracket_match_cell.html @@ -2,16 +2,7 @@
- -
- - {% if not match.ended %} - - {% endif %} -
-
- {% for team in match.teams %}
@@ -62,19 +53,5 @@ {% endfor %}
-
-
- - -
-
diff --git a/tournaments/templates/tournaments/tournament_bracket.html b/tournaments/templates/tournaments/tournament_bracket.html index d6ed322..ac3763b 100644 --- a/tournaments/templates/tournaments/tournament_bracket.html +++ b/tournaments/templates/tournaments/tournament_bracket.html @@ -18,6 +18,8 @@
{% include 'tournaments/bracket_match_cell.html' %}
@@ -34,6 +36,7 @@ function renderBracket() { const rounds = []; const matchPositions = []; + // Group matches by round Array.from(matchTemplates).forEach(template => { const roundIndex = parseInt(template.dataset.matchRound); @@ -54,53 +57,121 @@ function renderBracket() { bracket.innerHTML = ''; const roundCount = rounds.length; const finalRoundIndex = (roundCount - 1) / 2; + let nextMatchDistance = baseDistance; + let minimumMatchDistance = 1; + if (rounds[0].length <= 2) { + minimumMatchDistance = 2 + nextMatchDistance = baseDistance * 2; + } rounds.forEach((roundMatches, roundIndex) => { const roundDiv = document.createElement('div'); roundDiv.className = 'butterfly-round'; roundDiv.style.setProperty('--match-width', `${365}px`); - matchPositions[roundIndex] = []; + // Create title + const titleDiv = document.createElement('div'); + titleDiv.className = 'round-title'; + + // Get the match group name and format + const firstMatchTemplate = roundMatches[0].closest('.match-template'); + const matchGroupName = firstMatchTemplate.dataset.matchGroupName; + const matchFormat = firstMatchTemplate.dataset.matchFormat; + + const nameSpan = document.createElement('div'); + nameSpan.className = 'round-name'; + nameSpan.textContent = matchGroupName; + + const formatSpan = document.createElement('div'); + formatSpan.className = 'round-format'; + formatSpan.textContent = matchFormat; + if (roundIndex >= finalRoundIndex - 1) { + if (roundCount > 5) { + titleDiv.style.transform = `translateX(-50%)`; + if (roundIndex >= finalRoundIndex + 2) { + titleDiv.style.transform = `translateX(-100%)`; + } + } + } + + titleDiv.appendChild(nameSpan); + titleDiv.appendChild(formatSpan); + roundDiv.appendChild(titleDiv); + + // Create matches container + const matchesContainer = document.createElement('div'); + matchesContainer.className = 'matches-container'; + + roundDiv.appendChild(matchesContainer); + + matchPositions[roundIndex] = []; roundMatches.forEach((matchTemplate, matchIndex) => { const matchDiv = document.createElement('div'); matchDiv.className = 'butterfly-match'; + matchDiv.style.position = 'absolute'; const isDisabled = matchTemplate.dataset.disabled === 'true'; let top; let left; let right; - let nextMatchDistance = baseDistance; - - // Check if this round has only one match - const isSingleMatchRound = roundMatches.length === 1; - if (isSingleMatchRound) { - matchDiv.classList.add('single-match-round'); - nextMatchDistance = 0; - } - + const currentMatchesCount = roundMatches.length; if (roundIndex > finalRoundIndex) { matchDiv.classList.add('reverse-bracket'); top = matchPositions[roundCount - roundIndex - 1][matchIndex]; - nextMatchDistance = baseDistance * Math.pow(2, rounds.length - roundIndex - 1); - } else { - nextMatchDistance = baseDistance * Math.pow(2, roundIndex); } if (roundIndex === 0) { - top = matchIndex * (matchHeight + matchSpacing); + const nextMatchesCount = rounds[roundIndex + 1].length; + + if (currentMatchesCount == nextMatchesCount) { + nextMatchDistance = 0; + } + top = matchIndex * (matchHeight + matchSpacing) * minimumMatchDistance; + } else if (roundIndex === roundCount - 1) { + const nextMatchesCount = rounds[roundIndex - 1].length; + if (currentMatchesCount == nextMatchesCount) { + nextMatchDistance = 0; + } } else if (roundIndex == finalRoundIndex) { let lgth = matchPositions[0].length / 2; let index = lgth + matchIndex - 1; // If index goes negative, use 0 instead - top = matchPositions[0][index < 0 ? 0 : index]; + if (matchIndex == 0) { + top = matchPositions[roundIndex - 1][0] - baseDistance / 2; + } else { + top = matchPositions[roundIndex - 1][0] + baseDistance / 2; + } nextMatchDistance = baseDistance; } else if (roundIndex < finalRoundIndex) { - const parentIndex1 = matchIndex * 2; - const parentIndex2 = parentIndex1 + 1; - const parentPos1 = matchPositions[roundIndex - 1][parentIndex1]; - const parentPos2 = matchPositions[roundIndex - 1][parentIndex2]; - top = (parentPos1 + parentPos2) / 2; - nextMatchDistance = baseDistance * Math.pow(2, roundIndex); + const previousMatchesCount = rounds[roundIndex - 1].length; + const nextMatchesCount = rounds[roundIndex + 1].length; + + if (currentMatchesCount == nextMatchesCount) { + nextMatchDistance = 0; + } else if (matchPositions.length > roundIndex - 1) { + nextMatchDistance = (matchPositions[roundIndex - 1][1] - matchPositions[roundIndex - 1][0]); + nextMatchDistance = nextMatchDistance * (previousMatchesCount / currentMatchesCount); + } + + if (currentMatchesCount == previousMatchesCount) { + top = matchPositions[roundIndex - 1][matchIndex]; + } else { + const parentIndex1 = matchIndex * 2; + const parentIndex2 = parentIndex1 + 1; + const parentPos1 = matchPositions[roundIndex - 1][parentIndex1]; + const parentPos2 = matchPositions[roundIndex - 1][parentIndex2]; + top = (parentPos1 + parentPos2) / 2; + } + } else if (roundIndex < roundCount) { + const nextMatchesCount = rounds[roundIndex - 1].length; + const previousMatchesCount = rounds[roundIndex + 1].length; + + if (currentMatchesCount == nextMatchesCount) { + nextMatchDistance = 0; + } else if (matchPositions.length > roundCount - roundIndex - 1 - 1) { + nextMatchDistance = (matchPositions[roundCount - roundIndex - 1 - 1][1] - matchPositions[roundCount - roundIndex - 1 - 1][0]); + nextMatchDistance = nextMatchDistance * (previousMatchesCount / currentMatchesCount); + } } if (roundIndex >= finalRoundIndex - 1) { @@ -121,7 +192,7 @@ function renderBracket() { } if (roundIndex === finalRoundIndex - 2 || roundIndex === finalRoundIndex + 2) { - nextMatchDistance = (nextMatchDistance - baseDistance); + nextMatchDistance = nextMatchDistance - baseDistance; } else if (roundIndex == finalRoundIndex - 1 || roundIndex == finalRoundIndex + 1) { nextMatchDistance = baseDistance; @@ -139,7 +210,6 @@ function renderBracket() { if (roundIndex == finalRoundIndex - 1) { const matchDiv2 = document.createElement('div'); matchDiv2.className = 'butterfly-match'; - matchDiv2.style.position = 'absolute'; if (roundCount > 5) { matchDiv2.style.transform = `translateX(-50%)`; } @@ -147,11 +217,10 @@ function renderBracket() { matchDiv2.classList.add('semi-final'); matchDiv2.style.setProperty('--next-match-distance', `${baseDistance}px`); matchDiv2.style.top = `${top}px`; - matchDiv2.innerHTML = ` - `; - roundDiv.appendChild(matchDiv2); + matchDiv2.innerHTML = `
${rounds[0][0].innerHTML}
`; + matchesContainer.appendChild(matchDiv2); // Append to matchesContainer instead of roundDiv } - roundDiv.appendChild(matchDiv); + matchesContainer.appendChild(matchDiv); // Append to matchesContainer instead of roundDiv }); bracket.appendChild(roundDiv); @@ -163,7 +232,6 @@ function renderBracket() {