add prog view in broadcast

bracket-feature
Raz 10 months ago
parent f13b5ce39a
commit c5baa3a797
  1. 55
      tournaments/models/tournament.py
  2. 8
      tournaments/static/tournaments/css/style.css
  3. 1
      tournaments/templates/tournaments/broadcast/broadcast.html
  4. 1
      tournaments/templates/tournaments/broadcast/broadcast_club.html
  5. 105
      tournaments/templates/tournaments/broadcast/broadcasted_prog.html
  6. 2
      tournaments/urls.py
  7. 23
      tournaments/views.py

@ -1192,6 +1192,61 @@ class Tournament(models.Model):
self._being_deleted = True
super().delete(*args, **kwargs)
def broadcasted_prog(self):
# Get matches from broadcasted_matches_and_group_stages
matches, _ = self.broadcasted_matches_and_group_stages()
if not matches:
return []
# Get all unfinished matches with court assignments
active_matches = [
m for m in matches
if m.end_date is None # Not finished
and m.court_index is not None
]
# Group matches by court
matches_by_court = {}
courts = set()
for match in active_matches:
if match.court_index not in matches_by_court:
matches_by_court[match.court_index] = []
courts.add(match.court_index)
matches_by_court[match.court_index].append(match)
# Sort courts and organize them into groups of 4
sorted_courts = sorted(list(courts))
court_groups = [sorted_courts[i:i+4] for i in range(0, len(sorted_courts), 4)]
ordered_matches = []
# For each group of up to 4 courts
for court_group in court_groups:
# First row: current/next match for each court
for court in court_group:
if court in matches_by_court and matches_by_court[court]:
ordered_matches.append(matches_by_court[court][0])
else:
ordered_matches.append(None) # Empty space
# Second row: next match for each court
for court in court_group:
if court in matches_by_court and len(matches_by_court[court]) > 1:
ordered_matches.append(matches_by_court[court][1])
else:
ordered_matches.append(None) # Empty space
# Add unassigned matches at the end if needed
unassigned_matches = [
m for m in matches
if m.end_date is None and m.court_index is None
]
if unassigned_matches:
ordered_matches.extend(unassigned_matches)
return ordered_matches
class MatchGroup:
def __init__(self, name, matches, formatted_schedule):
self.name = name

@ -816,3 +816,11 @@ h-margin {
.group-stage-link:hover {
color: #f39200; /* Or whatever hover color you prefer */
}
.empty-match-slot {
height: 100%;
min-height: 200px; /* adjust as needed */
background-color: #f5f5f5; /* light grey background */
border-radius: 8px;
margin: 10px;
}

@ -12,6 +12,7 @@
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<div><a href="{% url 'automatic-broadcast' tournament.id %}">Automatique</a></div>
<div><a href="{% url 'broadcasted-prog' tournament.id %}">Programmation</a></div>
<div><a href="{% url 'broadcasted-matches' tournament.id %}">Matchs</a></div>
<div><a href="{% url 'broadcasted-group-stages' tournament.id %}">Poules</a></div>
<div><a href="{% url 'broadcasted-summons' tournament.id %}">Convocations</a></div>

@ -31,6 +31,7 @@
</div>
<div class="table-cell">
<span><a href="{% url 'automatic-broadcast' tournament.id %}">Automatic</a></span> |
<span><a href="{% url 'broadcasted-prog' tournament.id %}">Programmation</a></span> |
<span><a href="{% url 'broadcasted-matches' tournament.id %}">Matchs</a></span> |
<span><a href="{% url 'broadcasted-group-stages' tournament.id %}">Poules</a></span> |
<span><a href="{% url 'broadcasted-summons' tournament.id %}">Convocations</a></span> |

@ -0,0 +1,105 @@
<!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' %}" />
<link rel="icon" type="image/png" href="{% static 'tournaments/images/favicon.png' %}" />
<title>Matchs</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="{
paginatedMatches: null,
active: 1,
retrieveMatches() {
fetch('/tournament/{{ tournament.id }}/prog/json/')
.then(res => res.json())
.then((data) => {
this.paginatedMatches = this.paginate(data, 8)
})
},
paginate(array, pageSize) {
let paginatedArray = [];
for (let i = 0; i < array.length; i += pageSize) {
paginatedArray.push(array.slice(i, i + pageSize));
}
return paginatedArray;
},
loop() {
this.retrieveMatches()
setInterval(() => {
this.retrieveMatches()
this.active = this.active === this.paginatedMatches.length ? 1 : this.active+1
}, 15000)
}
}" x-init="loop()">
<header>
<div id="header">
<div class="left-content bubble">
<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">Programmation {{ tournament.broadcast_display_name }}</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 padding-bottom">
<template x-for="i in paginatedMatches.length" >
<template x-for="match in paginatedMatches[i-1]" >
<div class="cell medium-6 large-3 my-block" x-show="active === i">
<template x-if="!match.empty">
{% include 'tournaments/broadcast/broadcasted_match.html' %}
</template>
<template x-if="match.empty">
<div class="empty-match-slot"></div>
</template>
</div>
</template>
</template>
</div>
</main>
</div>
</body>
</html>

@ -24,8 +24,10 @@ urlpatterns = [
path('broadcast/', views.tournament_broadcast_home, name='broadcast'),
path('broadcast/auto/', views.automatic_broadcast, name='automatic-broadcast'),
path('matches/json/', views.tournament_matches_json, name='tournament-matches-json'),
path('prog/json/', views.tournament_prog_json, name='tournament-prog-json'),
path('broadcast/json/', views.broadcast_json, name='broadcast-json'),
path('broadcast/group-stages/', views.tournament_broadcasted_group_stages, name='broadcasted-group-stages'),
path('broadcast/prog/', views.tournament_broadcasted_prog, name='broadcasted-prog'),
path('group-stages/', views.tournament_group_stages, name='group-stages'),
path('group-stages/json/', views.tournament_live_group_stage_json, name='group-stages-json'),
path('rankings/', views.tournament_rankings, name='tournament-rankings'),

@ -356,6 +356,21 @@ def tournament_matches_json(request, tournament_id):
data = json.dumps(live_matches, default=vars)
return HttpResponse(data, content_type='application/json')
def tournament_prog_json(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
matches = tournament.broadcasted_prog()
# Convert matches to JSON-serializable format, handling None/empty slots
live_matches = []
for match in matches:
if match is None or isinstance(match, dict) and match.get('empty'):
live_matches.append({"empty": True})
else:
live_matches.append(match.live_match())
data = json.dumps(live_matches, default=vars)
return HttpResponse(data, content_type='application/json')
def tournament_group_stages(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
live_group_stages = list(tournament.live_group_stages())
@ -375,6 +390,14 @@ def tournament_broadcasted_group_stages(request, tournament_id):
'qr_code_options': qr_code_options(),
})
def tournament_broadcasted_prog(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
return render(request, 'tournaments/broadcast/broadcasted_prog.html', {
'tournament': tournament,
'qr_code_url': qr_code_url(request, tournament_id),
'qr_code_options': qr_code_options(),
})
def tournament_live_group_stage_json(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)

Loading…
Cancel
Save