fix broadcast layout

sync_v2
Raz 6 months ago
parent 8acf2cf427
commit 9ac210a47b
  1. 34
      tournaments/static/tournaments/css/broadcast.css
  2. 9
      tournaments/static/tournaments/css/style.css
  3. 16
      tournaments/static/tournaments/css/tournament_bracket.css
  4. 24
      tournaments/static/tournaments/js/tournament_bracket.js
  5. 72
      tournaments/templates/tournaments/broadcast/broadcasted_bracket.html
  6. 24
      tournaments/templates/tournaments/broadcast/broadcasted_planning.html
  7. 2
      tournaments/views.py

@ -23,12 +23,15 @@ body {
} }
.bubble-header { .bubble-header {
padding: 30px; padding: 20px;
background-color: white; background-color: white;
border-radius: 24px; border-radius: 24px;
box-shadow: 0 0 0px 0px #fbead6; box-shadow: 0 0 0px 0px #fbead6;
} }
.bracket-bubble-header {
}
.bubble-footer { .bubble-footer {
background-color: white; background-color: white;
display: flex; display: flex;
@ -36,7 +39,7 @@ body {
box-shadow: 0 0 0px 0px #fbead6; box-shadow: 0 0 0px 0px #fbead6;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 0px 20px; padding: 20px;
margin: 0; margin: 0;
} }
@ -56,15 +59,21 @@ body {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 10px; padding: 0px;
z-index: 100; z-index: 100;
margin-bottom: 20px;
} }
.sponsor-logo-broadcast { .sponsor-logo-broadcast {
height: 16vh; height: 100px;
object-fit: contain; object-fit: contain;
} }
.sponsor-logo-broadcast.screen-size-overlay {
object-fit: contain;
height: 80px; /* Example height matching QR code */
}
.bold { .bold {
font-family: "Montserrat-Bold"; font-family: "Montserrat-Bold";
} }
@ -122,3 +131,20 @@ body {
.center { .center {
align-items: center; align-items: center;
} }
.left-content.bubble-header {
display: flex;
align-items: top; /* Vertically align items (logo and text) */
height: 140px; /* Example height matching QR code */
}
.left-content.bubble-header.screen-size-overlay {
display: flex;
align-items: top; /* Vertically align items (logo and text) */
height: 100px; /* Example height matching QR code */
}
.logo {
height: 100%; /* Make the logo's height match the parent's height */
width: auto; /* Maintain the logo's aspect ratio */
}

@ -46,7 +46,7 @@ h1 {
} }
header { header {
padding: 0px 10px; padding: 0px 0px;
font-size: 1.5em; font-size: 1.5em;
} }
@ -112,7 +112,7 @@ hr {
@media print, screen and (min-width: 40em) { @media print, screen and (min-width: 40em) {
.wrapper { .wrapper {
margin: 0px 40px; margin: 0px 20px;
} }
} }
@ -930,7 +930,7 @@ h-margin {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 30px 30px; padding: 20px;
} }
.left-content { .left-content {
@ -939,7 +939,8 @@ h-margin {
} }
.right-content { .right-content {
margin-left: auto; display: flex;
align-items: center;
} }
/* CRM form */ /* CRM form */

@ -34,6 +34,7 @@
gap: 40px; /* Increased to account for horizontal lines (20px on each side) */ gap: 40px; /* Increased to account for horizontal lines (20px on each side) */
position: relative; position: relative;
margin-bottom: 80px; margin-bottom: 80px;
font-size: clamp(0.6em, 1vw, 1.2em) !important;
} }
.round-title { .round-title {
@ -54,7 +55,7 @@
} }
.round-title.broadcast-mode { .round-title.broadcast-mode {
font-size: 0.9em; font-size: 0.8em;
width: auto; /* Change from 100% to auto */ width: auto; /* Change from 100% to auto */
} }
@ -208,12 +209,13 @@
.broadcast-mode .round-name, .broadcast-mode .round-name,
.broadcast-mode .round-format { .broadcast-mode .round-format {
padding: 0px; padding: 0px;
color: #505050; color: white;
} }
.broadcast-mode .round-title { .broadcast-mode .round-title {
padding: 8px 20px; /* Slightly more horizontal padding */ padding: 8px 20px; /* Slightly more horizontal padding */
background-color: white; background-color: #1a223a;
color: white !important;
align-content: center; align-content: center;
border-radius: 24px; border-radius: 24px;
} }
@ -227,8 +229,12 @@
background-color: #505050 !important; /* Bright yellow - change to your preferred color */ background-color: #505050 !important; /* Bright yellow - change to your preferred color */
} }
/* Broadcast mode styling for all lines */ .broadcast-mode
.broadcast-mode .butterfly-match::before, .butterfly-round:first-child
.butterfly-match.butterfly-match:has(.incoming-line.disabled)::before {
visibility: hidden;
}
.broadcast-mode .butterfly-match.reverse-bracket::before, .broadcast-mode .butterfly-match.reverse-bracket::before,
.broadcast-mode .incoming-line, .broadcast-mode .incoming-line,
.broadcast-mode .outgoing-line, .broadcast-mode .outgoing-line,

@ -39,15 +39,20 @@ function renderBracket(options) {
if (doubleButterflyMode == true && roundCount > 1) { if (doubleButterflyMode == true && roundCount > 1) {
roundTotalCount = roundCount - 1; roundTotalCount = roundCount - 1;
} }
const padding = 50 * roundTotalCount; // Account for some padding/margin const padding = (15 - roundTotalCount / 1.5 + 20 + 20) * roundTotalCount; // Account for some padding/margin
const availableWidth = screenWidth - padding; const availableWidth = screenWidth - padding;
responsiveMatchWidth = Math.floor(availableWidth / roundTotalCount); responsiveMatchWidth = Math.floor(availableWidth / roundTotalCount);
let topMargin = 0;
if (isBroadcast) { if (isBroadcast) {
responsiveMatchWidth = Math.min( responsiveMatchWidth = Math.min(
365, 500,
Math.floor(availableWidth / roundTotalCount), Math.floor(availableWidth / roundTotalCount),
); );
if (roundTotalCount < 6) {
topMargin = 60;
}
} }
rounds.forEach((roundMatches, roundIndex) => { rounds.forEach((roundMatches, roundIndex) => {
@ -319,7 +324,7 @@ function renderBracket(options) {
"--next-match-distance", "--next-match-distance",
`${nextMatchDistance}px`, `${nextMatchDistance}px`,
); );
matchDiv.style.top = `${top}px`; matchDiv.style.top = `${top + topMargin}px`;
matchPositions[roundIndex][matchRealIndex] = top; matchPositions[roundIndex][matchRealIndex] = top;
if (matchIndex === 0) { if (matchIndex === 0) {
@ -336,19 +341,19 @@ function renderBracket(options) {
// } // }
// Position title above the first match // Position title above the first match
titleDiv.style.top = `${-80}px`; // Adjust the 60px offset as needed titleDiv.style.top = `${topMargin - 80}px`; // Adjust the 60px offset as needed
if ( if (
(roundIndex == finalRoundIndex && realRoundIndex == 0) || (roundIndex == finalRoundIndex && realRoundIndex == 0) ||
isBroadcast == true isBroadcast == true
) { ) {
titleDiv.style.top = `${top - 80}px`; // Adjust the 60px offset as needed titleDiv.style.top = `${top + topMargin - 80}px`; // Adjust the 60px offset as needed
} }
titleDiv.style.position = "absolute"; titleDiv.style.position = "absolute";
if (roundCount >= 5 && doubleButterflyMode == true) { if (roundCount >= 5 && doubleButterflyMode == true) {
if (roundIndex == finalRoundIndex - 1) { if (roundIndex == finalRoundIndex - 1) {
titleDiv.style.marginLeft = "60px"; titleDiv.style.marginLeft = "50px";
} else if (roundIndex == finalRoundIndex + 1) { } else if (roundIndex == finalRoundIndex + 1) {
titleDiv.style.marginLeft = "-60px"; titleDiv.style.marginLeft = "-50px";
} }
} }
matchesContainer.appendChild(titleDiv); matchesContainer.appendChild(titleDiv);
@ -372,11 +377,14 @@ function renderBracket(options) {
titleDiv.className = "round-title"; titleDiv.className = "round-title";
titleDiv.appendChild(nameSpan); titleDiv.appendChild(nameSpan);
titleDiv.appendChild(formatSpan); titleDiv.appendChild(formatSpan);
titleDiv.style.top = `${top - 80}px`; // Adjust the 60px offset as needed titleDiv.style.top = `${top + topMargin - 80}px`; // Adjust the 60px offset as needed
titleDiv.style.position = "absolute"; titleDiv.style.position = "absolute";
matchesContainer.appendChild(titleDiv); matchesContainer.appendChild(titleDiv);
} }
if (roundIndex == 0) {
isIncomingLineIsDisabled = true;
}
matchDiv.innerHTML = ` matchDiv.innerHTML = `
<div class="incoming-line ${isIncomingLineIsDisabled ? "disabled" : ""}"></div> <div class="incoming-line ${isIncomingLineIsDisabled ? "disabled" : ""}"></div>
<div class="match-content ${isDisabled ? "disabled" : ""}">${matchTemplate.innerHTML}</div> <div class="match-content ${isDisabled ? "disabled" : ""}">${matchTemplate.innerHTML}</div>

@ -4,6 +4,7 @@
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="{% static 'tournaments/css/foundation.min.css' %}" /> <link rel="stylesheet" href="{% static 'tournaments/css/foundation.min.css' %}" />
<link rel="stylesheet" href="{% static 'tournaments/css/basics.css' %}" /> <link rel="stylesheet" href="{% static 'tournaments/css/basics.css' %}" />
<link rel="stylesheet" href="{% static 'tournaments/css/style.css' %}" /> <link rel="stylesheet" href="{% static 'tournaments/css/style.css' %}" />
@ -36,15 +37,58 @@
<style> <style>
#screen-size-overlay { #screen-size-overlay {
position: fixed; position: fixed;
top: 10px; left: 50%;
left: 10px; transform: translateX(-50%); /* Center it exactly */
background-color: rgba(0, 0, 0, 0.7);
color: white; color: white;
padding: 10px; padding: 20px;
border-radius: 5px; font-size: 0.6em !important;
font-size: 1em;
z-index: 1000; /* Ensure it's on top of other elements */ z-index: 1000; /* Ensure it's on top of other elements */
} }
html, body {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center; /* Center content horizontally */
flex-direction: column; /* Ensure header and footer are positioned correctly */
min-height: 100vh; /* Make body at least the height of the viewport */
}
header {
/* Your existing header styles */
}
.wrapper {
/* Take up remaining vertical space */
flex-grow: 1;
display: flex;
justify-content: center; /* Center content horizontally within the wrapper */
}
main {
/* Allow main to take the full width for horizontal centering of its content */
display: flex;
justify-content: center; /* Center the bracket container horizontally */
width: 100%;
}
.bracket-container {
/* Allow it to size based on content, with max width constraint */
max-width: 95vw;
/* Remove max-height to allow vertical scrolling */
}
.butterfly-bracket {
/* Let the bracket flow within its container */
width: auto; /* Adjust as needed based on your bracket's inherent width */
}
footer.footer-broadcast {
/* Your existing footer styles */
}
</style> </style>
<!-- <div id="screen-size-overlay"></div> --> <!-- <div id="screen-size-overlay"></div> -->
@ -65,25 +109,15 @@
</head> </head>
<body> <body>
<div x-data="{
loop() {
this.fetchAndRenderBracket()
setInterval(() => {
this.fetchAndRenderBracket()
}, 15000)
},
}" x-init="loop()">
<header> <header>
<div id="header"> <div id="screen-size-overlay">
<div class="left-content bubble-header"> <div class="left-content bubble-header screen-size-overlay">
<img src="{% static 'tournaments/images/PadelClub_logo_512.png' %}" alt="logo" class="logo"> <img src="{% static 'tournaments/images/PadelClub_logo_512.png' %}" alt="logo" class="logo">
<div class="left-margin"> <div class="left-margin">
<h1 class="club">{{ tournament.broadcast_event_display_name }}</h1> <h1 class="club">{{ tournament.broadcast_event_display_name }}</h1>
<h1 class="event">Tableau {{ tournament.broadcast_display_name }}</h1> <h1 class="event">Tableau {{ tournament.broadcast_display_name }}</h1>
</div> </div>
</div> </div>
<div class="right-content">{% qr_from_text qr_code_url options=qr_code_options %}</div>
</div> </div>
</header> </header>
@ -202,7 +236,7 @@
<div class="bubble-sponsor"> <div class="bubble-sponsor">
{% for image in tournament.event.images.all %} {% for image in tournament.event.images.all %}
<img src="{{ image.image.url }}" alt="{{ image.title|default:'Sponsor' }}" <img src="{{ image.image.url }}" alt="{{ image.title|default:'Sponsor' }}"
class="sponsor-logo-broadcast"> class="sponsor-logo-broadcast screen-size-overlay">
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

@ -16,7 +16,7 @@
.timeslot { .timeslot {
font-family: "Anybody-ExtraBold"; font-family: "Anybody-ExtraBold";
font-size: clamp(0.4rem, 1.5vw - 0.2rem, 3rem); /* Adjust these values as needed */ font-size: clamp(0.4rem, 1.5vw - 0.2rem, 3rem); /* Adjust these values as needed */
color: #1b223a; color: white;
} }
.match-cell { .match-cell {
box-sizing: border-box; box-sizing: border-box;
@ -63,7 +63,19 @@
justify-content: center; justify-content: center;
/* Slightly smaller dynamic font size for court labels */ /* Slightly smaller dynamic font size for court labels */
font-size: clamp(0.7rem, 0.8vw + 0.1rem, 3rem); /* Adjust these values as needed */ font-size: clamp(0.7rem, 0.8vw + 0.1rem, 3rem); /* Adjust these values as needed */
color: black; color: white;
background: #1a223a;
}
.bubble-timeslot {
color: white;
background: #1a223a;
display: flex;
border-radius: 24px;
box-shadow: 0 0 0px 0px #fbead6;
align-items: center;
justify-content: center;
padding: 0px 20px;
margin: 0;
} }
.courts-row, .courts-row,
.matches-row { .matches-row {
@ -208,7 +220,7 @@
calculateFractionWidth() { calculateFractionWidth() {
if (this.courtCount >= 5) { if (this.courtCount >= 5) {
const reductionFactor = 0.95; // Adjust this value const reductionFactor = 0.94; // Adjust this value
return `calc((100% / ${this.courtCount}) * ${reductionFactor})`; return `calc((100% / ${this.courtCount}) * ${reductionFactor})`;
} else { } else {
const reductionFactor = 0.90; // Adjust this value const reductionFactor = 0.90; // Adjust this value
@ -235,7 +247,7 @@
<div class="grid-x"> <div class="grid-x">
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}"> <div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}">
<div style="display: flex; margin-bottom: 10px;"> <div style="display: flex; margin-bottom: 10px;">
<div class="bubble-footer" style="visibility: hidden; align-items: center; justify-content: center; margin-right: 10px; width: 6vw;"> <div class="bubble-timeslot" style="visibility: hidden; align-items: center; justify-content: center; margin-right: 10px; width: 6vw;">
<h1 class="timeslot">00:00</h1> <h1 class="timeslot">00:00</h1>
</div> </div>
<div class="courts-row"> <div class="courts-row">
@ -251,7 +263,7 @@
</div> </div>
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}" x-show="courtCount < 5"> <div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}" x-show="courtCount < 5">
<div style="display: flex; margin-bottom: 10px;"> <div style="display: flex; margin-bottom: 10px;">
<div class="bubble-footer" style="visibility: hidden; align-items: center; justify-content: center; margin-right: 10px; width: 6vw;"> <div class="bubble-timeslot" style="visibility: hidden; align-items: center; justify-content: center; margin-right: 10px; width: 6vw;">
<h1 class="timeslot">00:00</h1> <h1 class="timeslot">00:00</h1>
</div> </div>
<div class="courts-row"> <div class="courts-row">
@ -275,7 +287,7 @@
<template x-for="(group, groupIndex) in groupPage" :key="groupIndex"> <template x-for="(group, groupIndex) in groupPage" :key="groupIndex">
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}"> <div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}">
<div style="display: flex; margin-bottom: 10px;"> <div style="display: flex; margin-bottom: 10px;">
<div class="bubble-footer" style="align-items: center; justify-content: center; margin-right: 10px; width: 6vw;"> <div class="bubble-timeslot" style="align-items: center; justify-content: center; margin-right: 10px; width: 6vw;">
<h1 class="timeslot" x-text="group.name.slice(-5)"></h1> <h1 class="timeslot" x-text="group.name.slice(-5)"></h1>
</div> </div>

@ -348,7 +348,7 @@ def qr_code_url_with_query(request, club_id):
return url_with_query return url_with_query
def qr_code_options(): def qr_code_options():
return QRCodeOptions(size=10, border=4, error_correction='L') return QRCodeOptions(size=9, border=4, error_correction='L')
def tournament_matches(request, tournament_id): def tournament_matches(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id) tournament = get_object_or_404(Tournament, pk=tournament_id)

Loading…
Cancel
Save