1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2024-12-02 22:06:56 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Emmy D'Anello
ea03bd314b
Fix tests with new stuff
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-06-07 16:39:43 +02:00
Emmy D'Anello
c12972b718
Make Sympa + payment support optional
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-06-07 16:35:08 +02:00
Emmy D'Anello
2a775cedc1
Don't minify what is already minified
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-06-07 16:21:18 +02:00
Emmy D'Anello
9bf3b7dff0
Fix permission to see solutions when they are available
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-06-07 16:16:11 +02:00
16 changed files with 90 additions and 68 deletions

View File

@ -15,11 +15,16 @@
<link rel="shortcut icon" href="{% static "favicon.ico" %}"> <link rel="shortcut icon" href="{% static "favicon.ico" %}">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
{# Bootstrap + Font Awesome CSS #} {# Bootstrap CSS #}
{% stylesheet 'bootstrap_fontawesome' %} <link href="{% static "bootstrap/css/bootstrap.min.css" %}" rel="stylesheet" type="text/css">
{# Fontawesome CSS #}
<link href="{% static "fontawesome/css/all.min.css" %}" rel="stylesheet" type="text/css">
<link href="{% static "fontawesome/css/v4-shims.css" %}">
{# bootstrap-select CSS #}
<link href="{% static "bootstrap-select/css/bootstrap-select.min.css" %}" rel="stylesheet" type="text/css">
{# Bootstrap JavaScript #} {# Bootstrap JavaScript #}
{% javascript 'bootstrap' %} <script type="application/javascript" src="{% static "bootstrap/js/bootstrap.bundle.min.js" %}" charset="utf-8"></script>
{# Webmanifest PWA permettant l'installation de l'application sur un écran d'accueil, pour navigateurs supportés #} {# Webmanifest PWA permettant l'installation de l'application sur un écran d'accueil, pour navigateurs supportés #}
<link rel="manifest" href="{% static "tfjm/chat.webmanifest" %}"> <link rel="manifest" href="{% static "tfjm/chat.webmanifest" %}">

View File

@ -16,10 +16,13 @@
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
{# Bootstrap CSS #} {# Bootstrap CSS #}
{% stylesheet 'bootstrap_fontawesome' %} <link href="{% static "bootstrap/css/bootstrap.min.css" %}" rel="stylesheet" type="text/css">
{# Fontawesome CSS #}
<link href="{% static "fontawesome/css/all.min.css" %}" rel="stylesheet" type="text/css">
<link href="{% static "fontawesome/css/v4-shims.css" %}">
{# Bootstrap JavaScript #} {# Bootstrap JavaScript #}
{% javascript 'bootstrap' %} <script type="application/javascript" src="{% static "bootstrap/js/bootstrap.bundle.min.js" %}" charset="utf-8"></script>
{# Webmanifest PWA permettant l'installation de l'application sur un écran d'accueil, pour navigateurs supportés #} {# Webmanifest PWA permettant l'installation de l'application sur un écran d'accueil, pour navigateurs supportés #}
<link rel="manifest" href="{% static "tfjm/chat.webmanifest" %}"> <link rel="manifest" href="{% static "tfjm/chat.webmanifest" %}">

View File

@ -532,7 +532,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
'visible': True}) 'visible': True})
# First send the second pool to have the good team order # First send the second pool to have the good team order
for r in self.tournament.draw.round_set.filter(number__gte=2).all(): async for r in self.tournament.draw.round_set.filter(number__gte=2).all():
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'tid': self.tournament_id, 'type': 'draw.send_poules', {'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r.number, 'round': r.number,

View File

@ -128,10 +128,12 @@ class ValidateParticipationForm(forms.Form):
class TournamentForm(forms.ModelForm): class TournamentForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if settings.TFJM_APP != "ETEAM": if settings.NB_ROUNDS < 3:
del self.fields['date_third_phase'] del self.fields['date_third_phase']
del self.fields['solutions_available_third_phase'] del self.fields['solutions_available_third_phase']
del self.fields['syntheses_third_phase_limit'] del self.fields['syntheses_third_phase_limit']
if not settings.PAYMENT_MANAGEMENT:
del self.fields['price']
class Meta: class Meta:
model = Tournament model = Tournament
@ -142,10 +144,13 @@ class TournamentForm(forms.ModelForm):
'inscription_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'), 'inscription_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'),
'solution_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'), 'solution_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'),
'solutions_draw': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'), 'solutions_draw': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'),
'date_first_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'syntheses_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, 'syntheses_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'), format='%Y-%m-%d %H:%M'),
'date_second_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'syntheses_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, 'syntheses_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'), format='%Y-%m-%d %H:%M'),
'date_third_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'syntheses_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, 'syntheses_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'), format='%Y-%m-%d %H:%M'),
'organizers': forms.SelectMultiple(attrs={ 'organizers': forms.SelectMultiple(attrs={

View File

@ -1,6 +1,6 @@
# Copyright (C) 2020 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db.models import Q from django.db.models import Q
from participation.models import Team, Tournament from participation.models import Team, Tournament
@ -13,6 +13,9 @@ class Command(BaseCommand):
""" """
Create Sympa mailing lists and register teams. Create Sympa mailing lists and register teams.
""" """
if not settings.ML_MANAGEMENT:
return
sympa = get_sympa_client() sympa = get_sympa_client()
sympa.create_list("equipes", "Equipes du TFJM2", "hotline", sympa.create_list("equipes", "Equipes du TFJM2", "hotline",

View File

@ -239,7 +239,8 @@ class Team(models.Model):
if not self.access_code: if not self.access_code:
# if the team got created, generate the access code, create the contact mailing list # if the team got created, generate the access code, create the contact mailing list
self.access_code = get_random_string(6) self.access_code = get_random_string(6)
self.create_mailing_list() if settings.ML_MANAGEMENT:
self.create_mailing_list()
return super().save(*args, **kwargs) return super().save(*args, **kwargs)

View File

@ -1,7 +1,9 @@
# Copyright (C) 2020 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from typing import Union from typing import Union
from django.conf import settings
from participation.models import Note, Participation, Passage, Pool, Team, Tournament from participation.models import Note, Participation, Passage, Pool, Team, Tournament
from registration.models import Payment from registration.models import Payment
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
@ -22,7 +24,7 @@ def update_mailing_list(instance: Team, raw, **_):
""" """
When a team name or trigram got updated, update mailing lists When a team name or trigram got updated, update mailing lists
""" """
if instance.pk and not raw: if instance.pk and not raw and settings.ML_MANAGEMENT:
old_team = Team.objects.get(pk=instance.pk) old_team = Team.objects.get(pk=instance.pk)
if old_team.trigram != instance.trigram: if old_team.trigram != instance.trigram:
# Delete old mailing list, create a new one # Delete old mailing list, create a new one
@ -41,7 +43,7 @@ def create_payments(instance: Participation, created, raw, **_):
""" """
When a participation got created, create an associated payment. When a participation got created, create an associated payment.
""" """
if instance.valid and not raw: if instance.valid and not raw and settings.PAYMENT_MANAGEMENT:
for student in instance.team.students.all(): for student in instance.team.students.all():
payment_qs = Payment.objects.filter(registrations=student, final=False) payment_qs = Payment.objects.filter(registrations=student, final=False)
if payment_qs.exists(): if payment_qs.exists():

View File

@ -18,8 +18,10 @@
<dt class="col-sm-6 text-sm-end">{% trans 'place'|capfirst %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'place'|capfirst %}</dt>
<dd class="col-sm-6">{{ tournament.place }}</dd> <dd class="col-sm-6">{{ tournament.place }}</dd>
<dt class="col-sm-6 text-sm-end">{% trans 'price'|capfirst %}</dt> {% if TFJM.PAYMENT_MANAGEMENT %}
<dd class="col-sm-6">{% if tournament.price %}{{ tournament.price }} €{% else %}{% trans "Free" %}{% endif %}</dd> <dt class="col-sm-6 text-sm-end">{% trans 'price'|capfirst %}</dt>
<dd class="col-sm-6">{% if tournament.price %}{{ tournament.price }} €{% else %}{% trans "Free" %}{% endif %}</dd>
{% endif %}
<dt class="col-sm-6 text-sm-end">{% trans 'remote'|capfirst %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'remote'|capfirst %}</dt>
<dd class="col-sm-6">{{ tournament.remote|yesno }}</dd> <dd class="col-sm-6">{{ tournament.remote|yesno }}</dd>
@ -42,7 +44,7 @@
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the second round'|capfirst %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the second round'|capfirst %}</dt>
<dd class="col-sm-6">{{ tournament.syntheses_second_phase_limit }}</dd> <dd class="col-sm-6">{{ tournament.syntheses_second_phase_limit }}</dd>
{% if TFJM_APP == "ETEAM" %} {% if TFJM.APP == "ETEAM" %}
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the third round'|capfirst %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the third round'|capfirst %}</dt>
<dd class="col-sm-6">{{ tournament.syntheses_third_phase_limit }}</dd> <dd class="col-sm-6">{{ tournament.syntheses_third_phase_limit }}</dd>
{% endif %} {% endif %}
@ -50,14 +52,16 @@
<dt class="col-sm-6 text-sm-end">{% trans 'description'|capfirst %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'description'|capfirst %}</dt>
<dd class="col-sm-6">{{ tournament.description }}</dd> <dd class="col-sm-6">{{ tournament.description }}</dd>
<dt class="col-sm-6 text-sm-end">{% trans 'To contact organizers' %}</dt> {% if TFJM.ML_MANAGEMENT %}
<dd class="col-sm-6"><a href="mailto:{{ tournament.organizers_email }}">{{ tournament.organizers_email }}</a></dd> <dt class="col-sm-6 text-sm-end">{% trans 'To contact organizers' %}</dt>
<dd class="col-sm-6"><a href="mailto:{{ tournament.organizers_email }}">{{ tournament.organizers_email }}</a></dd>
<dt class="col-sm-6 text-sm-end">{% trans 'To contact juries' %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'To contact juries' %}</dt>
<dd class="col-sm-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd> <dd class="col-sm-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd>
<dt class="col-sm-6 text-sm-end">{% trans 'To contact valid teams' %}</dt> <dt class="col-sm-6 text-sm-end">{% trans 'To contact valid teams' %}</dt>
<dd class="col-sm-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd> <dd class="col-sm-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd>
{% endif %}
</dl> </dl>
</div> </div>
@ -78,12 +82,14 @@
{% render_table teams %} {% render_table teams %}
</div> </div>
{% if user.registration.is_admin or user.registration in tournament.organizers.all %} {% if TFJM.PAYMENT_MANAGEMENT %}
<div class="text-center"> {% if user.registration.is_admin or user.registration in tournament.organizers.all %}
<a href="{% url "participation:tournament_payments" pk=tournament.pk %}" class="btn btn-secondary"> <div class="text-center">
<i class="fas fa-money-bill-wave"></i> {% trans "Access to payments list" %} <a href="{% url "participation:tournament_payments" pk=tournament.pk %}" class="btn btn-secondary">
</a> <i class="fas fa-money-bill-wave"></i> {% trans "Access to payments list" %}
</div> </a>
</div>
{% endif %}
{% endif %} {% endif %}
{% if pools.data %} {% if pools.data %}

View File

@ -3,6 +3,7 @@
import json import json
from django.conf import settings
from django.core.management import BaseCommand from django.core.management import BaseCommand
from ...models import Payment from ...models import Payment
@ -15,6 +16,9 @@ class Command(BaseCommand):
help = "Vérifie si les paiements Hello Asso initiés sont validés ou non. Si oui, valide les inscriptions." help = "Vérifie si les paiements Hello Asso initiés sont validés ou non. Si oui, valide les inscriptions."
def handle(self, *args, **options): def handle(self, *args, **options):
if not settings.PAYMENT_MANAGEMENT:
return
for payment in Payment.objects.exclude(valid=True).filter(checkout_intent_id__isnull=False).all(): for payment in Payment.objects.exclude(valid=True).filter(checkout_intent_id__isnull=False).all():
checkout_intent = payment.get_checkout_intent() checkout_intent = payment.get_checkout_intent()
if checkout_intent is not None and 'order' in checkout_intent: if checkout_intent is not None and 'order' in checkout_intent:

View File

@ -1,6 +1,7 @@
# Copyright (C) 2024 by Animath # Copyright (C) 2024 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.core.management import BaseCommand from django.core.management import BaseCommand
from ...models import Payment from ...models import Payment
@ -13,5 +14,8 @@ class Command(BaseCommand):
help = "Envoie un mail de rappel à toustes les participant⋅es qui n'ont pas encore payé ou déclaré de paiement." help = "Envoie un mail de rappel à toustes les participant⋅es qui n'ont pas encore payé ou déclaré de paiement."
def handle(self, *args, **options): def handle(self, *args, **options):
if not settings.PAYMENT_MANAGEMENT:
return
for payment in Payment.objects.filter(valid=False).filter(registrations__team__participation__valid=True).all(): for payment in Payment.objects.filter(valid=False).filter(registrations__team__participation__valid=True).all():
payment.send_remind_mail() payment.send_remind_mail()

View File

@ -146,6 +146,7 @@ class TestRegistration(TestCase):
address="1 Rue de Rivoli", address="1 Rue de Rivoli",
zip_code=75001, zip_code=75001,
city="Paris", city="Paris",
country="France",
phone_number="0123456789", phone_number="0123456789",
responsible_name="Toto", responsible_name="Toto",
responsible_phone="0123456789", responsible_phone="0123456789",
@ -194,6 +195,7 @@ class TestRegistration(TestCase):
address="1 Rue de Rivoli", address="1 Rue de Rivoli",
zip_code=75001, zip_code=75001,
city="Paris", city="Paris",
country="France",
phone_number="0123456789", phone_number="0123456789",
professional_activity="God", professional_activity="God",
last_degree="Master", last_degree="Master",
@ -274,11 +276,13 @@ class TestRegistration(TestCase):
for user, data in [(self.user, dict(professional_activity="Bot", admin=True)), for user, data in [(self.user, dict(professional_activity="Bot", admin=True)),
(self.student, dict(student_class=11, school="Sky", birth_date="2001-01-01", (self.student, dict(student_class=11, school="Sky", birth_date="2001-01-01",
gender="female", address="1 Rue de Rivoli", zip_code=75001, gender="female", address="1 Rue de Rivoli", zip_code=75001,
city="Paris", responsible_name="Toto", city="Paris", country="France",
responsible_name="Toto",
responsible_phone="0123456789", responsible_phone="0123456789",
responsible_email="toto@example.com")), responsible_email="toto@example.com")),
(self.coach, dict(professional_activity="God", last_degree="Médaille Fields", gender="male", (self.coach, dict(professional_activity="God", last_degree="Médaille Fields", gender="male",
address="1 Rue de Rivoli", zip_code=75001, city="Paris"))]: address="1 Rue de Rivoli", zip_code=75001,
city="Paris", country="France"))]:
response = self.client.get(reverse("registration:update_user", args=(user.pk,))) response = self.client.get(reverse("registration:update_user", args=(user.pk,)))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)

View File

@ -837,7 +837,8 @@ class SolutionView(LoginRequiredMixin, View):
or user.registration.participates and user.registration.team or user.registration.participates and user.registration.team
and (solution.participation.team == user.registration.team or and (solution.participation.team == user.registration.team or
any(passage.pool.round == 1 any(passage.pool.round == 1
or timezone.now() >= passage.pool.tournament.solutions_available_second_phase or (passage.pool.round == 2 and passage.pool.tournament.solutions_available_second_phase)
or (passage.pool.round == 3 and passage.pool.tournament.solutions_available_third_phase)
for passage in passage_participant_qs.all()))): for passage in passage_participant_qs.all()))):
raise PermissionDenied raise PermissionDenied
# Guess mime type of the file # Guess mime type of the file

View File

@ -5,6 +5,11 @@ from participation.models import Tournament
def tfjm_context(request): def tfjm_context(request):
return { return {
'TFJM_APP': settings.TFJM_APP, 'TFJM': {
'SINGLE_TOURNAMENT': Tournament.objects.first() if Tournament.objects.exists() and settings.TFJM_APP else None, 'APP': settings.TFJM_APP,
'ML_MANAGEMENT': settings.ML_MANAGEMENT,
'PAYMENT_MANAGEMENT': settings.PAYMENT_MANAGEMENT,
'SINGLE_TOURNAMENT':
Tournament.objects.first() if Tournament.objects.exists() and settings.TFJM_APP else None,
}
} }

View File

@ -206,25 +206,6 @@ STATICFILES_FINDERS = (
PIPELINE = { PIPELINE = {
'DISABLE_WRAPPER': True, 'DISABLE_WRAPPER': True,
'JAVASCRIPT': { 'JAVASCRIPT': {
'bootstrap': {
'source_filenames': {
'bootstrap/js/bootstrap.bundle.min.js',
},
'output_filename': 'tfjm/js/bootstrap.bundle.min.js',
},
'jquery': {
'source_filenames': {
'jquery/jquery.min.js',
},
'output_filename': 'tfjm/js/jquery.min.js',
},
'bootstrap_select': {
'source_filenames': {
'bootstrap-select/js/bootstrap-select.min.js',
'bootstrap-select/js/defaults-fr_FR.min.js',
},
'output_filename': 'tfjm/js/bootstrap-select-jquery.min.js',
},
'main': { 'main': {
'source_filenames': ( 'source_filenames': (
'tfjm/js/main.js', 'tfjm/js/main.js',
@ -251,17 +232,6 @@ PIPELINE = {
'output_filename': 'tfjm/js/draw.min.js', 'output_filename': 'tfjm/js/draw.min.js',
}, },
}, },
'STYLESHEETS': {
'bootstrap_fontawesome': {
'source_filenames': (
'bootstrap/css/bootstrap.min.css',
'fontawesome/css/all.css',
'fontawesome/css/v4-shims.css',
'bootstrap-select/css/bootstrap-select.min.css',
),
'output_filename': 'tfjm/css/bootstrap_fontawesome.min.css',
}
},
} }
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
@ -379,6 +349,8 @@ if TFJM_APP == "TFJM":
TEAM_CODE_LENGTH = 3 TEAM_CODE_LENGTH = 3
RECOMMENDED_SOLUTIONS_COUNT = 5 RECOMMENDED_SOLUTIONS_COUNT = 5
NB_ROUNDS = 2 NB_ROUNDS = 2
ML_MANAGEMENT = True
PAYMENT_MANAGEMENT = True
PROBLEMS = [ PROBLEMS = [
"Triominos", "Triominos",
@ -394,6 +366,8 @@ elif TFJM_APP == "ETEAM":
TEAM_CODE_LENGTH = 4 TEAM_CODE_LENGTH = 4
RECOMMENDED_SOLUTIONS_COUNT = 6 RECOMMENDED_SOLUTIONS_COUNT = 6
NB_ROUNDS = 3 NB_ROUNDS = 3
ML_MANAGEMENT = False
PAYMENT_MANAGEMENT = False
PROBLEMS = [ PROBLEMS = [
"Exploring Flatland", "Exploring Flatland",

View File

@ -20,13 +20,18 @@
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
{# Bootstrap CSS #} {# Bootstrap CSS #}
{% stylesheet 'bootstrap_fontawesome' %} <link href="{% static "bootstrap/css/bootstrap.min.css" %}" rel="stylesheet" type="text/css">
{# Fontawesome CSS #}
<link href="{% static "fontawesome/css/all.min.css" %}" rel="stylesheet" type="text/css">
<link href="{% static "fontawesome/css/v4-shims.css" %}">
{# bootstrap-select CSS #}
<link href="{% static "bootstrap-select/css/bootstrap-select.min.css" %}" rel="stylesheet" type="text/css">
{# Bootstrap JavaScript #} {# Bootstrap JavaScript #}
{% javascript 'bootstrap' %} <script type="application/javascript" src="{% static "bootstrap/js/bootstrap.bundle.min.js" %}" charset="utf-8"></script>
{# bootstrap-select for beautiful selects and JQuery dependency #} {# bootstrap-select for beautiful selects and JQuery dependency #}
{% javascript 'jquery' %} <script type="application/javascript" src="{% static "jquery/jquery.min.js" %}" charset="utf-8"></script>
{% javascript 'bootstrap_select' %} <script type="application/javascript" src="{% static "bootstrap-select/js/bootstrap-select.min.js" %}" charset="utf-8"></script>
{# Si un formulaire requiert des données supplémentaires (notamment JS), les données sont chargées #} {# Si un formulaire requiert des données supplémentaires (notamment JS), les données sont chargées #}
{% if form.media %} {% if form.media %}

View File

@ -19,8 +19,8 @@
<a href="{% url "index" %}" class="nav-link"><i class="fas fa-home"></i> {% trans "Home" %}</a> <a href="{% url "index" %}" class="nav-link"><i class="fas fa-home"></i> {% trans "Home" %}</a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
{% if SINGLE_TOURNAMENT %} {% if TFJM.SINGLE_TOURNAMENT %}
<a href="{% url 'participation:tournament_detail' pk=SINGLE_TOURNAMENT.pk %}" class="nav-link"> <a href="{% url 'participation:tournament_detail' pk=TFJM.SINGLE_TOURNAMENT.pk %}" class="nav-link">
<i class="fas fa-calendar-day"></i> {% trans "Tournament" %} <i class="fas fa-calendar-day"></i> {% trans "Tournament" %}
</a> </a>
{% else %} {% else %}