parent
96fe35a742
commit
c6f5571d43
@ -0,0 +1,301 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
{% load static %} |
||||||
|
{% load qr_code %} |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> |
||||||
|
<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/style.css' %}" /> |
||||||
|
<link rel="stylesheet" href="{% static 'tournaments/css/broadcast.css' %}" /> |
||||||
|
<style> |
||||||
|
.running { |
||||||
|
background-color: #90ee90 !important; |
||||||
|
} |
||||||
|
.bubble-footer.score, .match-cell .bubble { |
||||||
|
height: 8rem; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
box-sizing: border-box; |
||||||
|
font-size: 1.2em; |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
width: 100%; |
||||||
|
color: black; |
||||||
|
} |
||||||
|
.court-label .bubble { |
||||||
|
height: 4rem; |
||||||
|
font-weight: bold; |
||||||
|
margin: 0; |
||||||
|
width: 100%; |
||||||
|
text-align: center; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
font-size: 1em; |
||||||
|
color: black; |
||||||
|
} |
||||||
|
.match-cell .bubble { |
||||||
|
background-color: white; /* Light blue */ |
||||||
|
} |
||||||
|
.match-cell .bubble.even { |
||||||
|
background-color: white; /* Light mint */ |
||||||
|
} |
||||||
|
.match-cell .bubble.empty { |
||||||
|
background-color: rgba(173, 216, 230, 0.3); /* Light blue */ |
||||||
|
color: white; |
||||||
|
} |
||||||
|
.match-cell, .court-label { |
||||||
|
width: 10rem; |
||||||
|
display: flex; |
||||||
|
} |
||||||
|
/* Adjust width when court count is 5 or more */ |
||||||
|
.court-label .bubble, |
||||||
|
.match-cell .bubble { |
||||||
|
width: 100%; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
.court-label .bubble, |
||||||
|
.cell.large-6 { |
||||||
|
width: 50%; |
||||||
|
padding: 0px; |
||||||
|
} |
||||||
|
.court-label .bubble, |
||||||
|
.cell.large-12 { |
||||||
|
width: 100%; |
||||||
|
padding: 0px; |
||||||
|
} |
||||||
|
.grid-x { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
.courts-row, |
||||||
|
.matches-row { |
||||||
|
display: flex; |
||||||
|
width: 100%; |
||||||
|
gap: 20px; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="{% static 'tournaments/images/favicon.png' %}" /> |
||||||
|
|
||||||
|
<title>Programmation</title> |
||||||
|
|
||||||
|
<script src="{% static 'tournaments/js/alpine.min.js' %}"></script> |
||||||
|
<!-- Matomo --> |
||||||
|
<script> |
||||||
|
var _paq = window._paq = window._paq || []; |
||||||
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */ |
||||||
|
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]); |
||||||
|
_paq.push(["setDoNotTrack", true]); |
||||||
|
_paq.push(['trackPageView']); |
||||||
|
_paq.push(['enableLinkTracking']); |
||||||
|
(function() { |
||||||
|
var u="//matomo.padelclub.app/"; |
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']); |
||||||
|
_paq.push(['setSiteId', '1']); |
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); |
||||||
|
})(); |
||||||
|
</script> |
||||||
|
<!-- End Matomo Code --> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body x-data="{ |
||||||
|
days: [], |
||||||
|
currentDayIndex: 0, |
||||||
|
currentPageIndex: 0, |
||||||
|
matchGroups: [], |
||||||
|
courtCount: {{ tournament.court_count|default:1 }}, |
||||||
|
groupsPerPage: 8, |
||||||
|
|
||||||
|
retrieveData() { |
||||||
|
fetch('/tournament/{{ tournament.id }}/planning/json/') |
||||||
|
.then(res => res.json()) |
||||||
|
.then((data) => { |
||||||
|
this.days = data.days || []; |
||||||
|
this.matchGroups = data.match_groups || []; |
||||||
|
this.currentPageIndex = 0; |
||||||
|
|
||||||
|
if (this.days.length > 0 && this.currentDayIndex >= this.days.length) { |
||||||
|
this.currentDayIndex = 0; |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
getMatchGroupsForDay(day) { |
||||||
|
const formattedDay = day; |
||||||
|
const filteredGroups = this.matchGroups.filter(group => { |
||||||
|
if (!group.matches || group.matches.length === 0) return false; |
||||||
|
return group.name && formattedDay && group.name.includes(formattedDay); |
||||||
|
}); |
||||||
|
|
||||||
|
// If court count is 5 or more, show fewer groups per page |
||||||
|
let groupsPerPageThreshold = this.courtCount >= 5 ? Math.ceil(this.groupsPerPage / 2) : this.groupsPerPage; |
||||||
|
|
||||||
|
const paginatedGroups = []; |
||||||
|
for (let i = 0; i < Math.ceil(filteredGroups.length / groupsPerPageThreshold); i++) { |
||||||
|
paginatedGroups.push(filteredGroups.slice(i * groupsPerPageThreshold, (i + 1) * groupsPerPageThreshold)); |
||||||
|
} |
||||||
|
return paginatedGroups; |
||||||
|
}, |
||||||
|
|
||||||
|
getCourtNumber(courtName) { |
||||||
|
if (!courtName) return 999; |
||||||
|
const match = courtName.match(/(\d+)/); |
||||||
|
return match ? parseInt(match[1]) : 999; |
||||||
|
}, |
||||||
|
|
||||||
|
organizeMatchesByCourt(matches) { |
||||||
|
// Create an array of court positions, each containing the match or null |
||||||
|
const courtMatches = Array(this.courtCount).fill(null); |
||||||
|
|
||||||
|
if (matches && matches.length > 0) { |
||||||
|
matches.forEach(match => { |
||||||
|
if (match && match.court) { |
||||||
|
const courtNum = this.getCourtNumber(match.court); |
||||||
|
if (courtNum > 0 && courtNum <= this.courtCount) { |
||||||
|
courtMatches[courtNum - 1] = match; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return courtMatches; |
||||||
|
}, |
||||||
|
|
||||||
|
loop() { |
||||||
|
this.retrieveData(); |
||||||
|
setInterval(() => { |
||||||
|
if (this.days.length > 0) { |
||||||
|
const currentDay = this.days[this.currentDayIndex]; |
||||||
|
const pagesForDay = this.getMatchGroupsForDay(currentDay); |
||||||
|
|
||||||
|
if (pagesForDay && pagesForDay.length > 1) { |
||||||
|
const _currentPageIndex = this.currentPageIndex; |
||||||
|
this.currentPageIndex = (this.currentPageIndex + 1) % pagesForDay.length; |
||||||
|
if (_currentPageIndex >= 1 && this.currentPageIndex === 0) { |
||||||
|
this.currentDayIndex = (this.currentDayIndex + 1) % this.days.length; |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.currentPageIndex = 0; |
||||||
|
this.currentDayIndex = (this.currentDayIndex + 1) % this.days.length; |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.currentDayIndex = 0; |
||||||
|
this.currentPageIndex = 0; |
||||||
|
} |
||||||
|
}, 15000); |
||||||
|
} |
||||||
|
}" x-init="loop()"> |
||||||
|
|
||||||
|
<header> |
||||||
|
<div id="header"> |
||||||
|
<div class="left-content bubble-header"> |
||||||
|
<img src="{% static 'tournaments/images/PadelClub_logo_512.png' %}" alt="logo" class="logo"> |
||||||
|
<div class="left-margin"> |
||||||
|
<h1 class="club">{{ tournament.broadcast_event_display_name }}</h1> |
||||||
|
<h1 class="event" x-text="days[currentDayIndex]"></h1> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="right-content">{% qr_from_text qr_code_url options=qr_code_options %}</div> |
||||||
|
</div> |
||||||
|
</header> |
||||||
|
|
||||||
|
<div class="wrapper"> |
||||||
|
<main> |
||||||
|
<div class="grid-x"> |
||||||
|
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}"> |
||||||
|
<div style="display: flex; margin-bottom: 20px;"> |
||||||
|
<div class="bubble-footer score ws bold" style="visibility: hidden; display: flex; align-items: center; justify-content: center; margin: 0; width: 7em; margin-right: 15px; height: 40px;"> |
||||||
|
<h1 class="score ws bold" style="margin: 0; padding: 0;">00:00</h1> |
||||||
|
</div> |
||||||
|
<div class="courts-row"> |
||||||
|
<template x-for="courtNum in Array.from({length: courtCount || 1}, (_, i) => i + 1)" :key="courtNum"> |
||||||
|
<div class="court-label"> |
||||||
|
<div class="bubble"> |
||||||
|
<div class="score ws bold">Terrain <span x-text="courtNum"></span></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}" x-show="courtCount < 5"> |
||||||
|
<div style="display: flex; margin-bottom: 20px;"> |
||||||
|
<div class="bubble-footer score ws bold" style="visibility: hidden; display: flex; align-items: center; justify-content: center; margin: 0; width: 7em; margin-right: 15px; height: 40px;"> |
||||||
|
<h1 class="score ws bold" style="margin: 0; padding: 0;">00:00</h1> |
||||||
|
</div> |
||||||
|
<div class="courts-row"> |
||||||
|
<template x-for="courtNum in Array.from({length: courtCount || 1}, (_, i) => i + 1)" :key="courtNum"> |
||||||
|
<div class="court-label"> |
||||||
|
<div class="bubble"> |
||||||
|
<div class="score ws bold">Terrain <span x-text="courtNum"></span></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
<template x-for="(day, dayIndex) in days" :key="day"> |
||||||
|
<div x-show="currentDayIndex === dayIndex"> |
||||||
|
<template x-for="(groupPage, pageIndex) in getMatchGroupsForDay(day)" :key="'page-' + pageIndex"> |
||||||
|
<div x-show="currentPageIndex === pageIndex"> |
||||||
|
<div class="grid-x"> |
||||||
|
<template x-for="(group, groupIndex) in groupPage" :key="groupIndex"> |
||||||
|
<div class="cell" :class="{'large-12': courtCount >= 5, 'large-6': courtCount < 5}"> |
||||||
|
<div style="display: flex; margin-bottom: 20px;"> |
||||||
|
<!-- Group name container --> |
||||||
|
<div class="bubble-footer score ws bold" style="display: flex; align-items: center; justify-content: center; margin: 0; width: 7em; margin-right: 15px;"> |
||||||
|
<h1 class="score ws bold" style="margin: 0; padding: 0;" x-text="group.name.slice(-5)"></h1> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- Matches container --> |
||||||
|
<div class="matches-row"> |
||||||
|
<template x-for="(match, courtIndex) in organizeMatchesByCourt(group.matches)" :key="courtIndex"> |
||||||
|
<div class="match-cell"> |
||||||
|
<template x-if="match"> |
||||||
|
<div class="bubble" :class="{'running': !match.ended && match.started, 'even': courtIndex % 2 === 1}" style="text-align: center;"> |
||||||
|
<div class="score ws bold" x-text="match.group_stage_name ? match.group_stage_name : match.title"></div> |
||||||
|
<template x-if="match.tournament_title"> |
||||||
|
<div class="minor-info semibold" x-text="match.tournament_title"></div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<template x-if="!match"> |
||||||
|
<div class="bubble empty" style="text-align: center;"> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</main> |
||||||
|
</div> |
||||||
|
|
||||||
|
<footer class="footer-broadcast"> |
||||||
|
{% if tournament.event.images.exists %} |
||||||
|
<div class="bubble-footer"> |
||||||
|
<div class="bubble-sponsor"> |
||||||
|
{% for image in tournament.event.images.all %} |
||||||
|
<img src="{{ image.image.url }}" alt="{{ image.title|default:'Sponsor' }}" |
||||||
|
class="sponsor-logo-broadcast"> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
</footer> |
||||||
|
</body> |
||||||
|
</html> |
||||||
Loading…
Reference in new issue