redesign-tournament-list
Raz 8 months ago
parent d8ea9bc812
commit 3205a1400e
  1. 43
      tournaments/models/enums.py
  2. 179
      tournaments/models/tournament.py
  3. 23
      tournaments/static/tournaments/css/style.css
  4. 79
      tournaments/templates/tournaments/tournament_row.html
  5. 6
      tournaments/templates/tournaments/tournaments.html
  6. 28
      tournaments/views.py

@ -138,6 +138,11 @@ class OnlineRegistrationStatus(models.IntegerChoices):
WAITING_LIST_FULL = 6, 'Waiting List Full'
IN_PROGRESS = 7, 'In Progress'
ENDED_WITH_RESULTS = 8, 'Ended with Results'
CONFIRMED = 9, 'Confirmed'
WALKOUT = 10, 'Walkout'
WAITING_LIST = 11, 'Waiting list'
CANCELED = 12, 'Canceled'
USER_IN_PROGRESS = 13, 'User in progress'
def status_localized(self) -> str:
status_map = {
@ -145,13 +150,43 @@ class OnlineRegistrationStatus(models.IntegerChoices):
OnlineRegistrationStatus.NOT_ENABLED: "Inscription désactivée",
OnlineRegistrationStatus.NOT_STARTED: "Ouverture des inscriptions à venir",
OnlineRegistrationStatus.ENDED: "Inscription terminée",
OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: "Liste d'attente ouverte",
OnlineRegistrationStatus.WAITING_LIST_FULL: "Liste d'attente complète",
OnlineRegistrationStatus.IN_PROGRESS: "Tournoi en cours",
OnlineRegistrationStatus.ENDED_WITH_RESULTS: "Tournoi terminé"
OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: "Liste d'attente",
OnlineRegistrationStatus.WAITING_LIST_FULL: "Complet",
OnlineRegistrationStatus.IN_PROGRESS: "En cours",
OnlineRegistrationStatus.ENDED_WITH_RESULTS: "Tournoi terminé",
OnlineRegistrationStatus.CONFIRMED: "Inscription\nconfirmée",
OnlineRegistrationStatus.WALKOUT: "Forfait",
OnlineRegistrationStatus.WAITING_LIST: "Inscription\nen attente",
OnlineRegistrationStatus.CANCELED: "Annulé",
OnlineRegistrationStatus.USER_IN_PROGRESS: "En lice",
}
return status_map.get(self, "")
def color(self) -> str:
status_map = {
OnlineRegistrationStatus.OPEN: "#90ee90", #orange
OnlineRegistrationStatus.NOT_ENABLED: "#90ee90",
OnlineRegistrationStatus.NOT_STARTED: "#90ee90",
OnlineRegistrationStatus.ENDED: "#90ee90", #green
OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: "#90ee90", #yellow
OnlineRegistrationStatus.WAITING_LIST_FULL: "#E84038", #red
OnlineRegistrationStatus.IN_PROGRESS: "#90ee90",
OnlineRegistrationStatus.ENDED_WITH_RESULTS: "#F39200",
OnlineRegistrationStatus.CONFIRMED: "#F39200",
OnlineRegistrationStatus.WALKOUT: "#E84038",
OnlineRegistrationStatus.WAITING_LIST: "#F39200",
OnlineRegistrationStatus.CANCELED: "#E84038",
OnlineRegistrationStatus.USER_IN_PROGRESS: "#F39200",
}
return status_map.get(self, "")
def text_color(self) -> str:
status_map = {
OnlineRegistrationStatus.OPEN: "#707070", #orange
OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: "#707070", #yellow
}
return status_map.get(self, "#FFFFFF")
class UserOrigin(models.IntegerChoices):
ADMIN = 0, 'Admin'
SITE = 1, 'Site'

@ -14,6 +14,7 @@ from zoneinfo import ZoneInfo
from tournaments.utils.player_search import get_player_name_from_csv
from shared.cryptography import encryption_util
from ..utils.extensions import plural_format
from ..utils.licence_validator import LicenseValidator
class TeamSortingType(models.IntegerChoices):
RANK = 1, 'Rank'
@ -170,7 +171,10 @@ class Tournament(models.Model):
return self.get_federal_age_category_display()
def formatted_start_date(self):
return self.start_date.strftime("%d/%m/%y")
return formats.date_format(self.start_date, format='d/m/Y')
def formatted_start_date_short(self):
return formats.date_format(self.start_date, format='l d/m/Y')
def in_progress(self):
return self.end_date is None
@ -210,36 +214,95 @@ class Tournament(models.Model):
else:
return None
def status_header(self):
if self.supposedly_in_progress() or self.end_date is not None or self.should_be_over():
return "Statut"
if self.end_date is not None or self.should_be_over():
return "Classement"
return "Inscriptions"
def tournament_status_display(self):
if self.is_canceled() is True:
return "Annulé"
teams = self.teams(True)
if self.supposedly_in_progress() or self.end_date is not None or self.should_be_over():
teams = [t for t in teams if t.stage != "Attente"]
if teams is not None and len(teams) > 0:
word = "équipe"
if len(teams) > 1:
word = word + "s"
return f"{len(teams)} {word}"
else:
return None
registration_status = None
if self.enable_online_registration == True:
registration_status = self.get_online_registration_status().status_localized()
if teams is not None and len(teams) > 0:
word = "inscription"
if len(teams) > 1:
word = word + "s"
if registration_status is not None:
return f"{registration_status}\n{len(teams)} {word}"
else:
return f"{len(teams)} {word}"
else:
if registration_status is not None:
return f"{registration_status}"
return None
teams = self.teams(True)
if self.supposedly_in_progress() or self.end_date is not None or self.should_be_over():
teams = [t for t in teams if t.stage != "Attente"]
return f"{len(teams)}"
return f"{len(teams)}"
def tournament_user_team(self, user):
team_registration = None
if user.is_authenticated:
# Assuming user's licence_id is stored in the user profile (e.g., request.user.licence_id)
user_licence_id = user.licence_id
player_register_check = self.player_register_check(user_licence_id)
registered_user = None
if user_licence_id is not None and player_register_check is None:
validator = LicenseValidator(user_licence_id)
stripped_license = validator.stripped_license
# Check if there is a PlayerRegistration for this user in this tournament
from tournaments.models import PlayerRegistration
registered_user = PlayerRegistration.objects.filter(
licence_id__startswith=stripped_license,
team_registration__tournament=self,
).first()
# If the user is registered, retrieve their team registration
if registered_user:
team_registration = registered_user.team_registration
return team_registration
def tournament_register_status_display(self, user):
# if user.is_authenticated:
# return f"confirmée"
# else:
# return "ouverte"
#
team_registration = None
if user and user.is_authenticated:
team_registration = self.tournament_user_team(user)
team_status = self.team_status(team_registration)
if team_status and team_registration:
if team_status is OnlineRegistrationStatus.ENDED_WITH_RESULTS and team_registration.get_points_earned():
message = f"+{team_registration.get_points_earned()} pts"
return message, team_status.color(), team_status.text_color()
return team_status.status_localized(), team_status.color(), team_status.text_color()
if team_status:
return team_status.status_localized(), team_status.color(), team_status.text_color()
return None
def team_status(self, team_registration):
if team_registration:
if team_registration.out_of_tournament():
return OnlineRegistrationStatus.WALKOUT
elif team_registration.is_in_waiting_list() >= 0:
return OnlineRegistrationStatus.WAITING_LIST
elif self.end_date is not None or self.should_be_over():
return self.get_online_registration_status()
elif self.supposedly_in_progress():
return OnlineRegistrationStatus.USER_IN_PROGRESS
return OnlineRegistrationStatus.CONFIRMED
if self.end_date is not None or self.should_be_over():
return None
if self.is_canceled() is True:
return OnlineRegistrationStatus.CANCELED
if self.enable_online_registration is False:
return None
return self.get_online_registration_status()
registration_status = None
if self.enable_online_registration == True:
registration_status = self.get_online_registration_status().status_localized()
if registration_status is not None:
return f"{registration_status}"
return None
def name_and_event(self):
event_name = None
@ -1055,35 +1118,35 @@ class Tournament(models.Model):
return True
def get_online_registration_status(self):
if self.supposedly_in_progress():
return OnlineRegistrationStatus.ENDED
if self.closed_registration_date is not None:
if self.closed_registration_date is not None:
return OnlineRegistrationStatus.ENDED
if self.end_date is not None:
return OnlineRegistrationStatus.ENDED_WITH_RESULTS
if self.supposedly_in_progress():
return OnlineRegistrationStatus.IN_PROGRESS
now = timezone.now()
if self.opening_registration_date is not None:
timezoned_datetime = timezone.localtime(self.opening_registration_date)
if now < timezoned_datetime:
return OnlineRegistrationStatus.NOT_STARTED
if self.registration_date_limit is not None:
timezoned_datetime = timezone.localtime(self.registration_date_limit)
if now > timezoned_datetime:
return OnlineRegistrationStatus.ENDED
if self.end_date is not None:
return OnlineRegistrationStatus.ENDED_WITH_RESULTS
now = timezone.now()
if self.opening_registration_date is not None:
timezoned_datetime = timezone.localtime(self.opening_registration_date)
if now < timezoned_datetime:
return OnlineRegistrationStatus.NOT_STARTED
if self.registration_date_limit is not None:
timezoned_datetime = timezone.localtime(self.registration_date_limit)
if now > timezoned_datetime:
return OnlineRegistrationStatus.ENDED
if self.team_count is not None:
# Get all team registrations excluding walk_outs
current_team_count = self.teamregistration_set.exclude(walk_out=True).count()
if current_team_count >= self.team_count:
if self.waiting_list_limit is not None:
waiting_list_count = current_team_count - self.team_count
if waiting_list_count >= self.waiting_list_limit:
return OnlineRegistrationStatus.WAITING_LIST_FULL
return OnlineRegistrationStatus.WAITING_LIST_POSSIBLE
return OnlineRegistrationStatus.OPEN
if self.team_count is not None:
# Get all team registrations excluding walk_outs
current_team_count = self.teamregistration_set.exclude(walk_out=True).count()
if current_team_count >= self.team_count:
if self.waiting_list_limit is not None:
waiting_list_count = current_team_count - self.team_count
if waiting_list_count >= self.waiting_list_limit:
return OnlineRegistrationStatus.WAITING_LIST_FULL
return OnlineRegistrationStatus.WAITING_LIST_POSSIBLE
return OnlineRegistrationStatus.OPEN
def is_unregistration_possible(self):
# Check if tournament has started

@ -200,6 +200,10 @@ tr {
text-decoration: none;
font-size: 12px;
font-weight: 600;
height: inherit; /* or height: 100% */
display: flex;
align-items: center;
justify-content: center;
}
@media (max-width: 80em) {
@ -260,6 +264,11 @@ tr {
font-size: 1.2em;
}
.medium {
font-family: "Montserrat-SemiBold";
font-size: 0.8em;
}
@media screen and (max-width: 40em) {
.large {
font-size: 0.9em;
@ -589,6 +598,14 @@ h-margin {
padding: 5px 0px;
}
.table-row-6-colums-tournament {
display: grid;
grid-template-columns: 12% 1fr 10% 8% 12% 12%;
align-items: center;
padding: 8px 0px;
gap: 8px; /* Adds equal spacing between all grid items */
}
.table-row-6-colums-club-tournament {
display: grid;
grid-template-columns: 100px 80px 100px 80px 1fr auto;
@ -675,9 +692,9 @@ h-margin {
}
.table-cell {
flex-grow: 1;
/* text-align: center; */
/* padding: 5px; */
align-items: center;
text-align: left;
height: 100%;
}
.table-cell-large {

@ -1,43 +1,36 @@
<a href="{% url 'tournament' tournament.id %}">
<div class="table-row-4-colums-tournament vertical-padding">
<div class="tight table-cell">
<div class="large">{{ tournament.level }}</div>
<div class="small">{{ tournament.category }}</div>
{% if tournament.age %}
<div class="small">{{ tournament.age }}</div>
{% endif %}
</div>
<div class="table-cell-responsive-large table-cell-large horizontal-padding semibold">
<div><span>{{ tournament.event.club.name }}</span></div>
{% if tournament.name_and_event %}
<div>
<span>{{ tournament.name_and_event }}</span>
</div>
{% endif %}
</div>
<div class="table-cell-responsive-short table-cell-large horizontal-padding semibold">
<div><span>{{ tournament.event.club.computedShortTitle }}</span></div>
{% if tournament.event.name %}
<div><span>{{ tournament.event.name }}</span></div>
{% endif %}
{% if tournament.name %}
<div><span>{{ tournament.name }}</span></div>
{% endif %}
</div>
{% if tournament.tournament_status_display %}
<div class="table-cell-responsive-large right horizontal-padding">
{{ tournament.tournament_status_display|linebreaksbr }}
</div>
{% endif %}
<div class="table-cell">
<div class="mybox center">{{ tournament.formatted_start_date }}</div>
{% if tournament.tournament_status_display %}
<div class="table-cell-responsive-short small center">{{ tournament.tournament_status_display|linebreaksbr }}</div>
{% endif %}
</div>
</div>
</a>
{% if not forloop.last %}
<hr/>
{% endif %}
<a href="{% url 'tournament' tournament.id %}">
<div class="table-row-6-colums-tournament">
<div class="tight table-cell">
<div class="large">{{ tournament.level }}</div>
<div class="small">{{ tournament.category }}</div>
{% if tournament.age %}
<div class="small">{{ tournament.age }}</div>
{% endif %}
</div>
<div class="table-cell">
<div class="large">{{ tournament.event.club.name }}</div>
{% if tournament.name_and_event %}
<div class="small">{{ tournament.name_and_event }}</div>
{% endif %}
</div>
<div class="table-cell">
<div class="small">Équipes</div>
<div class="large">{{ tournament.tournament_status_display }}</div>
</div>
<div class="table-cell">
<div class="small">Durée</div>
<div class="large">{{ tournament.day_duration }} j.</div>
</div>
<div class="table-cell">
<div class="mybox center">{{ tournament.formatted_start_date_short|linebreaksbr }}</div>
</div>
<div class="table-cell">
{% if register_status %}
<div class="mybox center" style="background-color:{{ register_status.1 }}; color:{{ register_status.2 }}">{{ register_status.0|linebreaksbr }}</div>
{% endif %}
</div>
</div>
</a>
{% if not forloop.last %}
<hr/>
{% endif %}

@ -24,7 +24,7 @@
<label class="title">En cours</label>
{% for tournament in live %}
{% include 'tournaments/tournament_row.html' %}
{% include 'tournaments/tournament_row.html' with tournament=tournament.tournament register_status=tournament.register_status %}
{% endfor %}
{% if live|length >= 10 %}
@ -44,7 +44,7 @@
<label class="title">À venir</label>
{% for tournament in future %}
{% include 'tournaments/tournament_row.html' %}
{% include 'tournaments/tournament_row.html' with tournament=tournament.tournament register_status=tournament.register_status %}
{% endfor %}
{% if future|length >= 10 %}
@ -71,7 +71,7 @@
<label class="title">Terminés</label>
{% for tournament in ended %}
{% include 'tournaments/tournament_row.html' %}
{% include 'tournaments/tournament_row.html' with tournament=tournament.tournament register_status=tournament.register_status %}
{% endfor %}
{% if ended|length >= 10 %}

@ -112,6 +112,34 @@ def index(request):
live = live_tournaments(club_id)
finished = finished_tournaments(club_id)
tournaments_with_status = []
for tournament in live:
status = tournament.tournament_register_status_display(request.user)
tournaments_with_status.append({
'tournament': tournament,
'register_status': status
})
live = tournaments_with_status
tournaments_with_status = []
for tournament in future:
status = tournament.tournament_register_status_display(request.user)
tournaments_with_status.append({
'tournament': tournament,
'register_status': status
})
future = tournaments_with_status
tournaments_with_status = []
for tournament in finished:
status = tournament.tournament_register_status_display(request.user)
tournaments_with_status.append({
'tournament': tournament,
'register_status': status
})
finished = tournaments_with_status
club = None
if club_id:
club = get_object_or_404(Club, pk=club_id)

Loading…
Cancel
Save