Adds group stage page

clubs
Laurent 2 years ago
parent cd4e41a05b
commit ae968fcf46
  1. 10
      static/tournaments/Padeltest.html
  2. 19
      static/tournaments/css/broadcast.css
  3. 99
      static/tournaments/css/style.css
  4. 5
      static/tournaments/js/alpine.min.js
  5. 228
      static/tournaments/test.html
  6. 91
      tournaments/models/group_stage.py
  7. 3
      tournaments/models/team_score.py
  8. 2
      tournaments/models/tournament.py
  9. 23
      tournaments/static/tournaments/css/style.css
  10. 61
      tournaments/templates/tournaments/group_stage_cell.html
  11. 13
      tournaments/templates/tournaments/group_stages.html
  12. 17
      tournaments/urls.py
  13. 4
      tournaments/utils/extensions.py
  14. 10
      tournaments/views.py

@ -1,11 +1,11 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="foundation.css" />
<link rel="stylesheet" href="style.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="css/foundation.css" />
<link rel="stylesheet" href="css/style.css" />
<link rel="icon" type="image/png" href="images/favicon.png" />
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<title>Padel</title>
</head>
@ -31,7 +31,7 @@
</div> -->
<img
src="PadelClub_logo_512.png"
src="images/PadelClub_logo_512.png"
class="logo inline"
/>
<div class="inline">

@ -0,0 +1,19 @@
html,
body {
background: linear-gradient(
20deg,
#1b223a 0 20%,
#e84038 20% 40%,
#f39200 40% 60%,
#ffd300 60% 80%,
#1b223a 80% 100%
);
}
.bubble {
padding: 20px;
background-color: white;
border-radius: 24px;
/* box-shadow: 0 0 0px 1px #fbead6; */
box-shadow: 0 0 0px 0px #fbead6;
}

@ -15,14 +15,7 @@
html,
body {
background: linear-gradient(
20deg,
#1b223a 0 20%,
#e84038 20% 40%,
#f39200 40% 60%,
#ffd300 60% 80%,
#1b223a 80% 100%
);
background: #fff7ed;
font-family: "Montserrat-Regular";
font-size: 16px;
@ -55,10 +48,6 @@ header {
font-size: 20px;
}
/* .page-body {
flex-grow: 1;
} */
a {
color: #707070;
}
@ -76,6 +65,11 @@ a:hover {
font-weight: 600;
} */
.container {
/* width: 100%; */
/* text-align:center; */
}
.wrapper {
margin: 0px 10px;
}
@ -85,6 +79,10 @@ a:hover {
}
}
.beige {
color: #fff7ed;
}
.mybox {
color: #707070;
padding: 8px 12px;
@ -151,6 +149,9 @@ tr {
font-size: 18px;
/* color: #707070; */
}
.semibold {
font-weight: 600;
}
.info {
font-family: "Montserrat-SemiBold";
@ -185,6 +186,9 @@ tr {
.names {
/* width: 70%; */
}
.team-names-box {
height: 60px;
}
.scores {
vertical-align: middle;
@ -217,14 +221,14 @@ tr {
}
.my-block {
padding: 0px 10px;
padding: 10px 10px;
}
@media print, screen and (min-width: 40em) {
/* @media print, screen and (min-width: 40em) {
.my-block {
padding: 10px 10px;
}
}
} */
.red {
background-color: red;
@ -234,7 +238,19 @@ tr {
padding: 20px;
background-color: white;
border-radius: 24px;
/* box-shadow: 10px 10px lightblue; */
box-shadow: 0 0 10px 5px #f9e7cf;
}
.dark_bubble {
padding: 20px;
background-color: #1b223a;
color: white;
border-radius: 24px;
/* box-shadow: 0 0 10px 5px #f9e7cf; */
}
.white {
color: white;
}
.test {
@ -336,11 +352,6 @@ tr {
align-items: center;
}
.container {
width: 100%;
/* text-align:center; */
}
.verticalmargin {
margin: 10px 0px;
}
@ -356,6 +367,8 @@ tr {
.flex-row {
display: flex;
justify-content: space-between;
height: 29px;
align-items: center;
/* vertical-align: middle; */
}
@ -420,19 +433,57 @@ tr {
width: 100px;
}
.table-row {
.table-row-2-colums {
display: grid;
grid-template-columns: 1px auto 40px;
align-items: center; /* Vertically center the content within each column */
padding: 5px 0px;
}
.table-row-3-colums {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center; /* Vertically center the content within each column */
padding: 5px 0px;
}
.table-row-4-colums {
display: grid;
grid-template-columns: 1px auto 50px 70px 130px; /* first column is a hack */
align-items: center; /* Vertically center the content within each column */
padding: 5px 0px;
}
.table-row-5-colums {
display: grid;
grid-template-columns: 60px auto 50px 70px 130px;
align-items: center; /* Vertically center the content within each column */
padding: 5px 0px;
}
.table-cell {
flex-grow: 1;
text-align: center;
padding: 10px;
/* text-align: center; */
/* padding: 5px; */
}
.table-cell-large {
grid-column: 2 / span 1; /* Center column spans from column 2 to column 3 */
text-align: left;
}
.wrap {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100vh; /*the height will need to be customized*/
width: 50px;
}
#xrow {
background: #000;
color: #fff;
height: 50px;
width: 50px;
margin-left: 10px;
}

File diff suppressed because one or more lines are too long

@ -11,154 +11,88 @@
</head>
<body>
<div class="wrapper">
<main class="page-body">
<div class="container">
<div class="grid-x">
<div class="cell medium-6 large-6 topblock my-block">
<div class="bubble">
<img
src="images/PadelClub_logo_512.png"
class="logo inline"
/>
<div class="inline">
<h1 class="club">Bienvenue !</h1>
<h1 class="event">Matchs</h1>
<!-- <span>Propulsé par Padel Club</span> -->
</div>
</div>
</div>
</div>
<main>
<div class="grid-x">
<div class="cell medium-3 large-3 topblock my-block">
<div class="bubble">
<div class="flex-row">
<label class="left-label matchtitle">Match 2</label>
<label class="right-label info"></label>
</div>
<div>
<div class="table-row bottom-border padding-bottom-small">
<div class="table-cell">
<img src="images/pc_icon_round_200.png" class="team_image" />
</div>
<div class="table-cell horizontal-padding table-cell table-cell-large">
<div class="">
Jacky Gun
</div>
<div class="">
Joe Gun
</div>
</div>
<div class="table-cell alignright">
<span class="score ws ">4</span>
<span class="score ws ">6</span>
<span class="score ws ">6</span>
</div>
</div>
<div class="table-row bottom-border padding-bottom-small">
<div class="table-cell">
<img src="images/pc_icon_round_200.png" class="team_image" />
</div>
<div class="table-cell horizontal-padding table-cell table-cell-large">
<div class="">
Jolly Jumper Gun
</div>
<div class="">
Miky mike Miker
</div>
</div>
<div class="table-cell alignright">
<span class="score ws ">6</span>
<span class="score ws ">4</span>
<span class="score ws ">2</span>
</div>
</div>
</div>
<div class="top-margin flex-row">
<label class="left-label minor-info">50h42min</label>
<!-- <a href="" class="right-label">détails</a> -->
</div>
</div>
<div class="bubble">
<div class="flex-row">
<label class="left-label matchtitle">Match 2</label>
<label class="right-label info"></label>
</div>
<div>
</div>
<div class="top-margin flex-row">
<label class="left-label minor-info">29h46min</label>
<!-- <a href="" class="right-label">détails</a> -->
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</main>
<div class="wrap my-block bubble">
<div id="xrow">1</div><br/>
<div id="xrow">2b</div><br/>
<div id="xrow">3c</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3v</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">2x</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3</div><br/>
<div id="xrow">1</div><br/>
<div id="xrow">2</div><br/>
<div id="xrow">3aa</div><br/>
<!-- Add more rows as needed -->
</div>
</body>
</html>

@ -1,6 +1,7 @@
from django.db import models
from . import Tournament, FederalMatchCategory
import uuid
from ..utils.extensions import format_seconds
class GroupStage(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
@ -22,29 +23,93 @@ class GroupStage(models.Model):
team_scores = TeamScore.objects.filter(player_registrations=player_registration)
return map(lambda ts: ts.match, team_scores)
def live_group_stage(self):
def live_group_stages(self):
lgs = LiveGroupStage(self.name())
for team_registration in self.teamregistration_set.all():
team = GroupStageTeam(team_registration.team_names(), self.score(), self.diff())
lgs.add_team(team)
return lgs
gs_teams = {}
for match in self.match_set.all():
lgs.add_match(match)
team_scores = match.team_scores.all()
if len(team_scores) == 2:
for team_score in match.team_scores.all():
team_registration = team_score.team_registration
if team_registration in gs_teams:
team = gs_teams[team_registration]
else:
team = GroupStageTeam(team_registration)
gs_teams[team_registration] = team
if match.winning_team_id == team_registration.id:
team.wins += 1
else:
team.losses += 1
ts1 = team_scores[0]
ts2 = team_scores[1]
scores1 = ts1.scores()
scores2 = ts2.scores()
total1 = 0
total2 = 0
if len(scores1) == len(scores2):
if len(scores1) > 1: # multiple sets
for i in range(len(scores1)):
if scores1[i] > scores2[i]:
total1 += 1
else:
total2 += 1
elif len(scores1) == 1:
total1 = scores1[0]
total2 = scores2[0]
def score(self):
return "2-0"
team1 = gs_teams[ts1.team_registration]
team2 = gs_teams[ts2.team_registration]
team1.diff = total1 - total2
team2.diff = total2 - total1
def diff(self):
return "+6"
for team in gs_teams.values():
lgs.add_team(team)
return lgs
class LiveGroupStage:
def __init__(self, title):
self.title = title
self.teams = []
self.start = None
self.end = None
def add_match(self, match):
if self.start and match.start_date and match.start_date < self.start:
self.start = match.start_date
elif not self.start:
self.start = match.start_date
if self.end and match.end_date and match.end_date > self.end:
self.end = match.end_date
elif not self.end:
self.end = match.end_date
def add_team(self, team):
self.teams.append(team)
def formatted_duration(self):
# return "test d"
if self.start and self.end:
return format_seconds((self.end - self.start).total_seconds())
else:
return "--"
class GroupStageTeam:
def __init__(self, names, score, diff):
self.names = names
self.score = score
self.diff = diff
def __init__(self, team_registration):
self.names = team_registration.team_names()
self.wins = 0
self.losses = 0
self.diff = 0
def wins_losses(self):
return f"{self.wins}/{self.losses}"
def formatted_diff(self):
if self.diff >= 0:
return f"+{self.diff}"
else:
return f"{self.diff}"

@ -26,6 +26,9 @@ class TeamScore(models.Model):
names = list(map(lambda player: player.name(), self.player_registrations.all()))
return names
def scores(self):
return [int(x) for x in self.score.split(',')]
def scores_array(self):
scores = []
if self.score:

@ -82,7 +82,7 @@ class Tournament(models.Model):
return map(lambda match: match.live_match(), matches)
def live_group_stages(self):
return map(lambda gs: gs.live_group_stage(), self.groupstage_set.all())
return map(lambda gs: gs.live_group_stages(), self.groupstage_set.all())
class TeamSummon:
def __init__(self, names, date, weight, stage, image):

@ -79,6 +79,10 @@ a:hover {
}
}
.beige {
color: #fff7ed;
}
.mybox {
color: #707070;
padding: 8px 12px;
@ -237,6 +241,18 @@ tr {
box-shadow: 0 0 10px 5px #f9e7cf;
}
.dark_bubble {
padding: 20px;
background-color: #1b223a;
color: white;
border-radius: 24px;
/* box-shadow: 0 0 10px 5px #f9e7cf; */
}
.white {
color: white;
}
.test {
display: flex;
justify-content: space-between;
@ -417,6 +433,13 @@ tr {
width: 100px;
}
.table-row-2-colums {
display: grid;
grid-template-columns: 1px auto 40px;
align-items: center; /* Vertically center the content within each column */
padding: 5px 0px;
}
.table-row-3-colums {
display: grid;
grid-template-columns: auto 1fr auto;

@ -0,0 +1,61 @@
{% load static %}
<div class="cell medium-6 large-3 my-block">
<div class="dark_bubble">
<div class="flex-row">
<label class="left-label matchtitle white">{{ group_stage.title }}</label>
<!-- <label class="right-label info">{{ match.date }}</label> -->
</div>
<div>
{% for team in group_stage.teams %}
<div class="table-row-2-colums bottom-border">
<div class="table-cell table-cell-large">
{% for name in team.names %}
<div class="{% if team.is_winner %}winner{% endif %}">
{{ name }}
</div>
{% endfor %}
</div>
<div class="table-cell center">
<div class="score ws">{{ team.wins_losses }}</div>
<div class="ws">{{ team.formatted_diff }}</div>
</div>
</div>
<!-- <div class="table-row-3-colums team-names-box {% cycle 'bottom-border' '' %} padding-bottom-small">
<div class="table-cell table-cell-large">
{% for name in team.names %}
<div class="semibold {% if team.is_winner %}winner{% endif %}">
{{ name }}
</div>
{% endfor %}
</div>
<div class="table-cell alignright">
{% if match.started %}
{% for score in team.scores %}
<span class="score ws {% if team.is_winner %}winner{% endif %}">{{ score }}</span>
{% endfor %}
{% else %}
<span class="score ws">{{ team.weight }}</span>
{% endif %}
</div>
</div> -->
{% endfor %}
</div>
<div class="flex-row top-margin">
<label class="left-label minor-info semibold beige">{{ group_stage.formatted_duration }}</label>
<!-- <label class="right-label minor-info">{{ match.court }}</label> -->
<!-- <a href="" class="right-label">{{ match.court }}</a> -->
</div>
</div>
</div>

@ -0,0 +1,13 @@
{% extends 'tournaments/base.html' %}
{% block head_title %}Poules{% endblock %}
{% block first_title %}{{ tournament.event.display_name }}{% endblock %}
{% block second_title %}{{ tournament.name }}{% endblock %}
{% block content %}
<div class="grid-x">
{% for group_stage in group_stages %}
{% include 'tournaments/group_stage_cell.html' %}
{% endfor %}
</div>
{% endblock %}

@ -1,13 +1,18 @@
from django.urls import path
from django.urls import include, path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path('tournament/<str:tournament_id>/', views.tournament, name='tournament'),
path('tournament/<str:tournament_id>/summons/', views.tournament_summons, name='tournament-summons'),
path('tournament/<str:tournament_id>/broadcast/', views.tournament_matches, name='tournament-matches'),
path('tournament/<str:tournament_id>/matches-json/', views.tournament_matches_json, name='tournament-matches-json'),
path('tournament/<str:tournament_id>/live-group-stages-json/', views.tournament_live_group_stage_json, name='live-group-stages-json'),
path("tournament/<str:tournament_id>/",
include([
path('', views.tournament, name='tournament'),
path('summons/', views.tournament_summons, name='tournament-summons'),
path('broadcast/matches', views.tournament_matches, name='broadcasted-matches'),
path('matches-json/', views.tournament_matches_json, name='tournament-matches-json'),
path('broadcast/group-stages/', views.tournament_broadcasted_group_stages, name='broadcasted-group-stages'),
path('group-stages/', views.tournament_group_stages, name='group-stages'),
])
),
path('players/', views.players, name='players'),
]

@ -0,0 +1,4 @@
def format_seconds(seconds):
hours = int(seconds / 3600)
minutes = int((seconds % 3600) / 60)
return f"{hours:02d}h{minutes:02d}min"

@ -63,7 +63,15 @@ def tournament_matches_json(request, tournament_id):
data = json.dumps(live_matches, default=vars)
return HttpResponse(data, content_type='application/json')
def tournament_live_group_stage(request, tournament_id):
def tournament_group_stages(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
live_group_stages = list(tournament.live_group_stages())
return render(request, 'tournaments/group_stages.html', {
'tournament': tournament,
'group_stages': live_group_stages,
})
def tournament_broadcasted_group_stages(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
return render(request, 'tournaments/broadcasted_group_stages.html', {
'tournament': tournament,

Loading…
Cancel
Save