1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-02-26 18:26:28 +00:00

Compare commits

..

No commits in common. "3efe5a2226a4e4de0c9e1581728a28ff3a9a020c" and "0f2c44331c3e44b93356fbed083e0e11d82f2198" have entirely different histories.

55 changed files with 557 additions and 391 deletions

2
.gitignore vendored
View File

@ -36,8 +36,6 @@ secrets.py
*.log *.log
media/ media/
output/ output/
static/
# Virtualenv # Virtualenv
env/ env/
venv/ venv/

View File

@ -0,0 +1,4 @@
# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'eastereggs.apps.EastereggsConfig'

8
apps/eastereggs/apps.py Normal file
View File

@ -0,0 +1,8 @@
# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
class EastereggsConfig(AppConfig):
name = 'eastereggs'

View File

@ -0,0 +1,2 @@
# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later

View File

@ -0,0 +1,19 @@
{% extends "index.html" %}
{% block content %}
<div id="index-content"></div>
{% include "eastereggs/xp_modal.html" %}
{% endblock %}
{% block extrajavascript %}
<script>
$(document).ready(function() {
$("#index-content").load("{% url "index" %} #content");
function displayModal() {
$("#xpModal").modal('toggle');
setTimeout(displayModal, 400);
}
displayModal();
});
</script>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% load crispy_forms_filters i18n %}
<div id="xpModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans "Error" %}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{% trans "This task failed successfully." %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{% trans "Close" %}</button>
</div>
</div>
</div>
</div>

11
apps/eastereggs/urls.py Normal file
View File

@ -0,0 +1,11 @@
# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
from django.views.generic import TemplateView
app_name = "eastereggs"
urlpatterns = [
path("xp/", TemplateView.as_view(template_name="eastereggs/xp.html")),
]

View File

@ -12,6 +12,7 @@ from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from pypdf import PdfFileReader from pypdf import PdfFileReader
from registration.models import VolunteerRegistration
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
@ -119,28 +120,29 @@ class ValidateParticipationForm(forms.Form):
class TournamentForm(forms.ModelForm): class TournamentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["date_start"].widget = forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d')
self.fields["date_end"].widget = forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d')
self.fields["inscription_limit"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["solution_limit"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["solutions_draw"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["syntheses_first_phase_limit"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["solutions_available_second_phase"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["syntheses_second_phase_limit"].widget = forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M')
self.fields["organizers"].widget = forms.CheckboxSelectMultiple()
self.fields["organizers"].queryset = VolunteerRegistration.objects.all()
class Meta: class Meta:
model = Tournament model = Tournament
fields = '__all__' fields = '__all__'
widgets = {
'date_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'date_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'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'),
'solutions_draw': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'),
'syntheses_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'),
'solutions_available_second_phase': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'),
'syntheses_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
format='%Y-%m-%d %H:%M'),
'organizers': forms.SelectMultiple(attrs={
'class': 'selectpicker',
'data-live-search': 'true',
'data-live-search-normalize': 'true',
'data-width': 'fit',
})
}
class SolutionForm(forms.ModelForm): class SolutionForm(forms.ModelForm):
@ -172,11 +174,7 @@ class PoolForm(forms.ModelForm):
model = Pool model = Pool
fields = ('tournament', 'round', 'bbb_url', 'results_available', 'juries',) fields = ('tournament', 'round', 'bbb_url', 'results_available', 'juries',)
widgets = { widgets = {
"juries": forms.SelectMultiple(attrs={ "juries": forms.CheckboxSelectMultiple,
'class': 'selectpicker',
'data-live-search': 'true',
'data-live-search-normalize': 'true',
}),
} }
@ -189,12 +187,7 @@ class PoolTeamsForm(forms.ModelForm):
model = Pool model = Pool
fields = ('participations',) fields = ('participations',)
widgets = { widgets = {
"participations": forms.SelectMultiple(attrs={ "participations": forms.CheckboxSelectMultiple,
'class': 'selectpicker',
'data-live-search': 'true',
'data-live-search-normalize': 'true',
'data-width': 'fit',
}),
} }

View File

@ -23,6 +23,7 @@ class TeamTable(tables.Table):
} }
model = Team model = Team
fields = ('name', 'trigram',) fields = ('name', 'trigram',)
template_name = 'django_tables2/bootstrap4.html'
# noinspection PyTypeChecker # noinspection PyTypeChecker
@ -54,6 +55,7 @@ class ParticipationTable(tables.Table):
} }
model = Team model = Team
fields = ('name', 'trigram', 'valid',) fields = ('name', 'trigram', 'valid',)
template_name = 'django_tables2/bootstrap4.html'
class TournamentTable(tables.Table): class TournamentTable(tables.Table):
@ -73,6 +75,7 @@ class TournamentTable(tables.Table):
model = Tournament model = Tournament
fields = ('name', 'date',) fields = ('name', 'date',)
order_by = ('name', ) order_by = ('name', )
template_name = 'django_tables2/bootstrap4.html'
class PoolTable(tables.Table): class PoolTable(tables.Table):
@ -93,6 +96,7 @@ class PoolTable(tables.Table):
} }
model = Pool model = Pool
fields = ('teams', 'round', 'tournament',) fields = ('teams', 'round', 'tournament',)
template_name = 'django_tables2/bootstrap4.html'
class PassageTable(tables.Table): class PassageTable(tables.Table):
@ -117,6 +121,7 @@ class PassageTable(tables.Table):
} }
model = Passage model = Passage
fields = ('defender', 'opponent', 'reporter', 'solution_number', ) fields = ('defender', 'opponent', 'reporter', 'solution_number', )
template_name = 'django_tables2/bootstrap4.html'
class NoteTable(tables.Table): class NoteTable(tables.Table):
@ -135,3 +140,4 @@ class NoteTable(tables.Table):
model = Note model = Note
fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral', fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral',
'reporter_writing', 'reporter_oral',) 'reporter_writing', 'reporter_oral',)
template_name = 'django_tables2/bootstrap4.html'

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -26,7 +26,7 @@
<dd class="col-sm-10"> <dd class="col-sm-10">
<ul> <ul>
{% for solution in participation.solutions.all %} {% for solution in participation.solutions.all %}
<li><a href="{{ solution.file.url }}">{{ solution }}</a></li> <li><a href="{{ solution.file.url }}" data-turbolinks="false">{{ solution }}</a></li>
{% empty %} {% empty %}
<li>{% trans "No solution was uploaded yet." %}</li> <li>{% trans "No solution was uploaded yet." %}</li>
{% endfor %} {% endfor %}
@ -38,7 +38,7 @@
<dd class="col-sm-10"> <dd class="col-sm-10">
<ul> <ul>
{% for pool in participation.pools.all %} {% for pool in participation.pools.all %}
<li><a href="{{ pool.get_absolute_url }}">{{ pool }}{% if not forloop.last %}, {% endif %}</a></li> <li><a href="{{ pool.get_absolute_url }}" data-turbolinks="false">{{ pool }}{% if not forloop.last %}, {% endif %}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</dd> </dd>
@ -51,7 +51,7 @@
{% trans "If you upload a solution, this will replace the version for the final tournament." %} {% trans "If you upload a solution, this will replace the version for the final tournament." %}
</div> </div>
{% endif %} {% endif %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadSolutionModal">{% trans "Upload solution" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadSolutionModal">{% trans "Upload solution" %}</button>
</div> </div>
</div> </div>
@ -63,8 +63,12 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function () {
initModal("uploadSolution", "{% url "participation:upload_solution" pk=participation.pk %}") $('button[data-target="#uploadSolutionModal"]').click(function() {
}) let modalBody = $("#uploadSolutionModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:upload_solution" pk=participation.pk %} #form-content")
});
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -23,7 +23,7 @@
<dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd> <dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd>
<dt class="col-sm-3">{% trans "Defended solution:" %}</dt> <dt class="col-sm-3">{% trans "Defended solution:" %}</dt>
<dd class="col-sm-9"><a href="{{ passage.defended_solution.file.url }}">{{ passage.defended_solution }}</a></dd> <dd class="col-sm-9"><a href="{{ passage.defended_solution.file.url }}" data-turbolinks="false">{{ passage.defended_solution }}</a></dd>
<dt class="col-sm-3">{% trans "Defender penalties count:" %}</dt> <dt class="col-sm-3">{% trans "Defender penalties count:" %}</dt>
<dd class="col-sm-9">{{ passage.defender_penalties }}</dd> <dd class="col-sm-9">{{ passage.defender_penalties }}</dd>
@ -31,7 +31,7 @@
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt> <dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
{% for synthesis in passage.syntheses.all %} {% for synthesis in passage.syntheses.all %}
<a href="{{ synthesis.file.url }}">{{ synthesis }}{% if not forloop.last %}, {% endif %}</a> <a href="{{ synthesis.file.url }}" data-turbolinks="false">{{ synthesis }}{% if not forloop.last %}, {% endif %}</a>
{% empty %} {% empty %}
{% trans "No synthesis was uploaded yet." %} {% trans "No synthesis was uploaded yet." %}
{% endfor %} {% endfor %}
@ -41,13 +41,13 @@
{% if notes is not None %} {% if notes is not None %}
<div class="card-footer text-center"> <div class="card-footer text-center">
{% if my_note is not None %} {% if my_note is not None %}
<button class="btn btn-info" data-bs-toggle="modal" data-bs-target="#updateNotesModal">{% trans "Update notes" %}</button> <button class="btn btn-info" data-toggle="modal" data-target="#updateNotesModal">{% trans "Update notes" %}</button>
{% endif %} {% endif %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updatePassageModal">{% trans "Update" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#updatePassageModal">{% trans "Update" %}</button>
</div> </div>
{% elif user.registration.participates %} {% elif user.registration.participates %}
<div class="card-footer text-center"> <div class="card-footer text-center">
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadSynthesisModal">{% trans "Upload synthesis" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadSynthesisModal">{% trans "Upload synthesis" %}</button>
</div> </div>
{% endif %} {% endif %}
</div> </div>
@ -119,15 +119,27 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function () {
{% if notes is not None %} {% if notes is not None %}
initModal("updatePassage", "{% url "participation:passage_update" pk=passage.pk %}") $('button[data-target="#updatePassageModal"]').click(function() {
let modalBody = $("#updatePassageModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:passage_update" pk=passage.pk %} #form-content")
});
{% if my_note is not None %} {% if my_note is not None %}
initModal("updateNotesModal", "{% url "participation:update_notes" pk=my_note.pk %}") $('button[data-target="#updateNotesModal"]').click(function() {
let modalBody = $("#updateNotesModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:update_notes" pk=my_note.pk %} #form-content")
});
{% endif %} {% endif %}
{% elif user.registration.participates %} {% elif user.registration.participates %}
initModal("uploadSynthesis", "{% url "participation:upload_synthesis" pk=passage.pk %}") $('button[data-target="#uploadSynthesisModal"]').click(function() {
let modalBody = $("#uploadSynthesisModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:upload_synthesis" pk=passage.pk %} #form-content")
});
{% endif %} {% endif %}
}); });
</script> </script>

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -18,7 +18,7 @@
<dt class="col-sm-3">{% trans "Teams:" %}</dt> <dt class="col-sm-3">{% trans "Teams:" %}</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
{% for participation in pool.participations.all %} {% for participation in pool.participations.all %}
<a href="{{ participation.get_absolute_url }}">{{ participation.team }}{% if not forloop.last %}, {% endif %}</a> <a href="{{ participation.get_absolute_url }}" data-turbolinks="false">{{ participation.team }}{% if not forloop.last %}, {% endif %}</a>
{% endfor %} {% endfor %}
</dd> </dd>
@ -28,7 +28,7 @@
<dt class="col-sm-3">{% trans "Defended solutions:" %}</dt> <dt class="col-sm-3">{% trans "Defended solutions:" %}</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
{% for passage in pool.passages.all %} {% for passage in pool.passages.all %}
<a href="{{ passage.defended_solution.file.url }}">{{ passage.defended_solution }}{% if not forloop.last %}, {% endif %}</a> <a href="{{ passage.defended_solution.file.url }}" data-turbolinks="false">{{ passage.defended_solution }}{% if not forloop.last %}, {% endif %}</a>
{% endfor %} {% endfor %}
</dd> </dd>
@ -51,10 +51,10 @@
</div> </div>
{% if user.registration.is_volunteer %} {% if user.registration.is_volunteer %}
<div class="card-footer text-center"> <div class="card-footer text-center">
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addPassageModal">{% trans "Add passage" %}</button> <button class="btn btn-success" data-toggle="modal" data-target="#addPassageModal">{% trans "Add passage" %}</button>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updatePoolModal">{% trans "Update" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#updatePoolModal">{% trans "Update" %}</button>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updateTeamsModal">{% trans "Update teams" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#updateTeamsModal">{% trans "Update teams" %}</button>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadNotesModal">{% trans "Upload notes from a CSV file" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadNotesModal">{% trans "Upload notes from a CSV file" %}</button>
</div> </div>
{% endif %} {% endif %}
</div> </div>
@ -88,11 +88,30 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function () {
initModal("updatePool", "{% url "participation:pool_update" pk=pool.pk %}") $('button[data-target="#updatePoolModal"]').click(function() {
initModal("updateTeams", "{% url "participation:pool_update_teams" pk=pool.pk %}") let modalBody = $("#updatePoolModal div.modal-body");
initModal("addPassage", "{% url "participation:passage_create" pk=pool.pk %}") if (!modalBody.html().trim())
initModal("uploadNotes", "{% url "participation:pool_upload_notes" pk=pool.pk %}") modalBody.load("{% url "participation:pool_update" pk=pool.pk %} #form-content")
}) });
$('button[data-target="#updateTeamsModal"]').click(function() {
let modalBody = $("#updateTeamsModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:pool_update_teams" pk=pool.pk %} #form-content")
});
$('button[data-target="#addPassageModal"]').click(function() {
let modalBody = $("#addPassageModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:passage_create" pk=pool.pk %} #form-content")
});
$('button[data-target="#uploadNotesModal"]').click(function() {
let modalBody = $("#uploadNotesModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:pool_upload_notes" pk=pool.pk %} #form-content")
});
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -10,19 +10,19 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<dl class="row"> <dl class="row">
<dt class="col-sm-6 text-end">{% trans "Name:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Name:" %}</dt>
<dd class="col-sm-6">{{ team.name }}</dd> <dd class="col-sm-6">{{ team.name }}</dd>
<dt class="col-sm-6 text-end">{% trans "Trigram:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Trigram:" %}</dt>
<dd class="col-sm-6">{{ team.trigram }}</dd> <dd class="col-sm-6">{{ team.trigram }}</dd>
<dt class="col-sm-6 text-end">{% trans "Email:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Email:" %}</dt>
<dd class="col-sm-6"><a href="mailto:{{ team.email }}">{{ team.email }}</a></dd> <dd class="col-sm-6"><a href="mailto:{{ team.email }}">{{ team.email }}</a></dd>
<dt class="col-sm-6 text-end">{% trans "Access code:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Access code:" %}</dt>
<dd class="col-sm-6">{{ team.access_code }}</dd> <dd class="col-sm-6">{{ team.access_code }}</dd>
<dt class="col-sm-6 text-end">{% trans "Coaches:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Coaches:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for coach in team.coaches.all %} {% for coach in team.coaches.all %}
<a href="{% url "registration:user_detail" pk=coach.user.pk %}">{{ coach }}</a>{% if not forloop.last %},{% endif %} <a href="{% url "registration:user_detail" pk=coach.user.pk %}">{{ coach }}</a>{% if not forloop.last %},{% endif %}
@ -31,7 +31,7 @@
{% endfor %} {% endfor %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Participants:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Participants:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for student in team.students.all %} {% for student in team.students.all %}
<a href="{% url "registration:user_detail" pk=student.user.pk %}">{{ student }}</a>{% if not forloop.last %},{% endif %} <a href="{% url "registration:user_detail" pk=student.user.pk %}">{{ student }}</a>{% if not forloop.last %},{% endif %}
@ -40,7 +40,7 @@
{% endfor %} {% endfor %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Tournament:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Tournament:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if team.participation.tournament %} {% if team.participation.tournament %}
<a href="{% url "participation:tournament_detail" pk=team.participation.tournament.pk %}">{{ team.participation.tournament }}</a> <a href="{% url "participation:tournament_detail" pk=team.participation.tournament.pk %}">{{ team.participation.tournament }}</a>
@ -49,11 +49,11 @@
{% endif %} {% endif %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Photo authorizations:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Photo authorizations:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for participant in team.participants.all %} {% for participant in team.participants.all %}
{% if participant.photo_authorization %} {% if participant.photo_authorization %}
<a href="{{ participant.photo_authorization.url }}">{{ participant }}</a>{% if not forloop.last %},{% endif %} <a href="{{ participant.photo_authorization.url }}" data-turbolinks="false">{{ participant }}</a>{% if not forloop.last %},{% endif %}
{% else %} {% else %}
{{ participant }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %} {{ participant }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %}
{% endif %} {% endif %}
@ -61,12 +61,12 @@
</dd> </dd>
{% if not team.participation.tournament.remote %} {% if not team.participation.tournament.remote %}
<dt class="col-sm-6 text-end">{% trans "Health sheets:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Health sheets:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for student in team.students.all %} {% for student in team.students.all %}
{% if student.under_18 %} {% if student.under_18 %}
{% if student.health_sheet %} {% if student.health_sheet %}
<a href="{{ student.health_sheet.url }}">{{ student }}</a>{% if not forloop.last %},{% endif %} <a href="{{ student.health_sheet.url }}" data-turbolinks="false">{{ student }}</a>{% if not forloop.last %},{% endif %}
{% else %} {% else %}
{{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %} {{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %}
{% endif %} {% endif %}
@ -74,12 +74,12 @@
{% endfor %} {% endfor %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Vaccine sheets:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Vaccine sheets:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for student in team.students.all %} {% for student in team.students.all %}
{% if student.under_18 %} {% if student.under_18 %}
{% if student.vaccine_sheet %} {% if student.vaccine_sheet %}
<a href="{{ student.vaccine_sheet.url }}">{{ student }}</a>{% if not forloop.last %},{% endif %} <a href="{{ student.vaccine_sheet.url }}" data-turbolinks="false">{{ student }}</a>{% if not forloop.last %},{% endif %}
{% else %} {% else %}
{{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %} {{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %}
{% endif %} {% endif %}
@ -87,12 +87,12 @@
{% endfor %} {% endfor %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Parental authorizations:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Parental authorizations:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for student in team.students.all %} {% for student in team.students.all %}
{% if student.under_18 %} {% if student.under_18 %}
{% if student.parental_authorization %} {% if student.parental_authorization %}
<a href="{{ student.parental_authorization.url }}">{{ student }}</a>{% if not forloop.last %},{% endif %} <a href="{{ student.parental_authorization.url }}" data-turbolinks="false">{{ student }}</a>{% if not forloop.last %},{% endif %}
{% else %} {% else %}
{{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %} {{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %}
{% endif %} {% endif %}
@ -101,31 +101,31 @@
</dd> </dd>
{% endif %} {% endif %}
<dt class="col-sm-6 text-end">{% trans "Motivation letter:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Motivation letter:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if team.motivation_letter %} {% if team.motivation_letter %}
<a href="{{ team.motivation_letter.url }}">{% trans "Download" %}</a> <a href="{{ team.motivation_letter.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% else %} {% else %}
<em>{% trans "Not uploaded yet" %}</em> <em>{% trans "Not uploaded yet" %}</em>
{% endif %} {% endif %}
{% if user.registration.team == team and not user.registration.team.participation.valid or user.registration.is_admin %} {% if user.registration.team == team and not user.registration.team.participation.valid or user.registration.is_admin %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadMotivationLetterModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadMotivationLetterModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
</dl> </dl>
{% if user.registration.is_volunteer %} {% if user.registration.is_volunteer %}
<div class="text-center"> <div class="text-center">
<a class="btn btn-info" href="{% url "participation:team_authorizations" pk=team.pk %}"> <a class="btn btn-info" href="{% url "participation:team_authorizations" pk=team.pk %}" data-turbolinks="false">
<i class="fas fa-file-archive"></i> {% trans "Download all submitted authorizations" %} <i class="fas fa-file-archive"></i> {% trans "Download all submitted authorizations" %}
</a> </a>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div class="card-footer text-center"> <div class="card-footer text-center">
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updateTeamModal">{% trans "Update" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#updateTeamModal">{% trans "Update" %}</button>
{% if not team.participation.valid %} {% if not team.participation.valid %}
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#leaveTeamModal">{% trans "Leave" %}</button> <button class="btn btn-danger" data-toggle="modal" data-target="#leaveTeamModal">{% trans "Leave" %}</button>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -199,10 +199,22 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function() {
initModal("uploadMotivationLetter", "{% url "participation:upload_team_motivation_letter" pk=team.pk %}") $('button[data-target="#uploadMotivationLetterModal"]').click(function() {
initModal("updateTeam", "{% url "participation:update_team" pk=team.pk %}") let modalBody = $("#uploadMotivationLetterModal div.modal-body");
initModal("leaveTeam", "{% url "participation:team_leave" %}") if (!modalBody.html().trim())
}) modalBody.load("{% url "participation:upload_team_motivation_letter" pk=team.pk %} #form-content");
});
$('button[data-target="#updateTeamModal"]').click(function() {
let modalBody = $("#updateTeamModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:update_team" pk=team.pk %} #form-content");
});
$('button[data-target="#leaveTeamModal"]').click(function() {
let modalBody = $("#leaveTeamModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:team_leave" %} #form-content");
});
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load django_tables2 i18n %} {% load django_tables2 i18n %}

View File

@ -9,52 +9,52 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<dl class="row"> <dl class="row">
<dt class="col-xl-6 text-end">{% trans 'organizers'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'organizers'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.organizers.all|join:", " }}</dd> <dd class="col-xl-6">{{ tournament.organizers.all|join:", " }}</dd>
<dt class="col-xl-6 text-end">{% trans 'size'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'size'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.max_teams }}</dd> <dd class="col-xl-6">{{ tournament.max_teams }}</dd>
<dt class="col-xl-6 text-end">{% trans 'place'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'place'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.place }}</dd> <dd class="col-xl-6">{{ tournament.place }}</dd>
<dt class="col-xl-6 text-end">{% trans 'price'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'price'|capfirst %}</dt>
<dd class="col-xl-6">{% if tournament.price %}{{ tournament.price }} €{% else %}{% trans "Free" %}{% endif %}</dd> <dd class="col-xl-6">{% if tournament.price %}{{ tournament.price }} €{% else %}{% trans "Free" %}{% endif %}</dd>
<dt class="col-xl-6 text-end">{% trans 'remote'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'remote'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.remote|yesno }}</dd> <dd class="col-xl-6">{{ tournament.remote|yesno }}</dd>
<dt class="col-xl-6 text-end">{% trans 'dates'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'dates'|capfirst %}</dt>
<dd class="col-xl-6">{% trans "From" %} {{ tournament.date_start }} {% trans "to" %} {{ tournament.date_end }}</dd> <dd class="col-xl-6">{% trans "From" %} {{ tournament.date_start }} {% trans "to" %} {{ tournament.date_end }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date of registration closing'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date of registration closing'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.inscription_limit }}</dd> <dd class="col-xl-6">{{ tournament.inscription_limit }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date of maximal solution submission'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date of maximal solution submission'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.solution_limit }}</dd> <dd class="col-xl-6">{{ tournament.solution_limit }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date of the random draw'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date of the random draw'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.solutions_draw }}</dd> <dd class="col-xl-6">{{ tournament.solutions_draw }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date of maximal syntheses submission for the first round'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date of maximal syntheses submission for the first round'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.syntheses_first_phase_limit }}</dd> <dd class="col-xl-6">{{ tournament.syntheses_first_phase_limit }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date when solutions of round 2 are available'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date when solutions of round 2 are available'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.solutions_available_second_phase }}</dd> <dd class="col-xl-6">{{ tournament.solutions_available_second_phase }}</dd>
<dt class="col-xl-6 text-end">{% trans 'date of maximal syntheses submission for the second round'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'date of maximal syntheses submission for the second round'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.syntheses_second_phase_limit }}</dd> <dd class="col-xl-6">{{ tournament.syntheses_second_phase_limit }}</dd>
<dt class="col-xl-6 text-end">{% trans 'description'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'description'|capfirst %}</dt>
<dd class="col-xl-6">{{ tournament.description }}</dd> <dd class="col-xl-6">{{ tournament.description }}</dd>
<dt class="col-xl-6 text-end">{% trans 'To contact organizers' %}</dt> <dt class="col-xl-6 text-right">{% trans 'To contact organizers' %}</dt>
<dd class="col-xl-6"><a href="mailto:{{ tournament.organizers_email }}">{{ tournament.organizers_email }}</a></dd> <dd class="col-xl-6"><a href="mailto:{{ tournament.organizers_email }}">{{ tournament.organizers_email }}</a></dd>
<dt class="col-xl-6 text-end">{% trans 'To contact juries' %}</dt> <dt class="col-xl-6 text-right">{% trans 'To contact juries' %}</dt>
<dd class="col-xl-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd> <dd class="col-xl-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd>
<dt class="col-xl-6 text-end">{% trans 'To contact valid teams' %}</dt> <dt class="col-xl-6 text-right">{% trans 'To contact valid teams' %}</dt>
<dd class="col-xl-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd> <dd class="col-xl-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd>
</dl> </dl>
</div> </div>
@ -84,9 +84,7 @@
{% endif %} {% endif %}
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
<div class="d-grid"> <button class="btn btn-block btn-success" data-toggle="modal" data-target="#addPoolModal">{% trans "Add new pool" %}</button>
<button class="btn gap-0 btn-success" data-bs-toggle="modal" data-bs-target="#addPoolModal">{% trans "Add new pool" %}</button>
</div>
{% endif %} {% endif %}
{% if notes %} {% if notes %}
@ -116,9 +114,13 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function () {
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
initModal("addPool", "{% url "participation:pool_create" %}") $('button[data-target="#addPoolModal"]').click(function() {
let modalBody = $("#addPoolModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:pool_create" %} #form-content")
});
{% endif %} {% endif %}
}); });
</script> </script>

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load django_tables2 i18n %} {% load django_tables2 i18n %}
@ -10,9 +10,7 @@
<div id="form-content"> <div id="form-content">
{% render_table table %} {% render_table table %}
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
<div class="d-grid"> <a class="btn btn-block btn-success" href="{% url "participation:tournament_create" %}">{% trans "Add tournament" %}</a>
<a class="btn gap-0 btn-success" href="{% url "participation:tournament_create" %}">{% trans "Add tournament" %}</a>
</div>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load i18n static crispy_forms_filters %} {% load i18n static crispy_forms_filters %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load i18n %} {% load i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n static %} {% load crispy_forms_filters i18n static %}

View File

@ -19,7 +19,7 @@ class RegistrationTable(tables.Table):
) )
def order_type(self, queryset, desc): def order_type(self, queryset, desc):
types = ["volunteerregistration", "-volunteerregistration__admin", "participantregistration"] types = ["-volunteerregistration__admin", "volunteerregistration", "participantregistration"]
return queryset.order_by(*(("-" if desc else "") + t for t in types)), True return queryset.order_by(*(("-" if desc else "") + t for t in types)), True
class Meta: class Meta:
@ -29,3 +29,4 @@ class RegistrationTable(tables.Table):
model = Registration model = Registration
fields = ('last_name', 'user__first_name', 'user__email', 'type',) fields = ('last_name', 'user__first_name', 'user__email', 'type',)
order_by = ('type', 'last_name', 'first_name',) order_by = ('type', 'last_name', 'first_name',)
template_name = 'django_tables2/bootstrap4.html'

View File

@ -29,3 +29,17 @@
{{ admin_registration_form|crispy }} {{ admin_registration_form|crispy }}
</div> </div>
{% endblock %} {% endblock %}
{% block extrajavascript %}
<script>
$("#id_type").change(function() {
let selected_role = $("#id_type :selected");
if (selected_role.val() === "volunteer") {
$("#registration_form").html($("#volunteer_registration_form").html());
}
else {
$("#registration_form").html($("#admin_registration_form").html());
}
}).change();
</script>
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -30,17 +30,14 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $("#id_role").change(function() {
let role_elem = document.getElementById("id_role") let selected_role = $("#id_role :selected");
function updateView () { if (selected_role.val() === "participant") {
let selected_role = role_elem.options[role_elem.selectedIndex].value $("#registration_form").html($("#student_registration_form").html());
if (selected_role === "participant") }
document.getElementById("registration_form").innerHTML = document.getElementById("student_registration_form").innerHTML else {
else $("#registration_form").html($("#coach_registration_form").html());
document.getElementById("registration_form").innerHTML = document.getElementById("coach_registration_form").innerHTML }
} }).change();
role_elem.addEventListener('change', updateView)
updateView()
})
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load crispy_forms_filters i18n %} {% load crispy_forms_filters i18n %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load i18n static crispy_forms_filters %} {% load i18n static crispy_forms_filters %}
@ -9,7 +9,7 @@
<div id="form-content"> <div id="form-content">
<div class="alert alert-info"> <div class="alert alert-info">
{% trans "Authorization template:" %} {% trans "Authorization template:" %}
<a class="alert-link" href="{% url "registration:parental_authorization_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}">{% trans "Download" %}</a> <a class="alert-link" href="{% url "registration:parental_authorization_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}" data-turbolinks="false">{% trans "Download" %}</a>
</div> </div>
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load i18n static crispy_forms_filters %} {% load i18n static crispy_forms_filters %}
@ -9,8 +9,8 @@
<div id="form-content"> <div id="form-content">
<div class="alert alert-info"> <div class="alert alert-info">
{% trans "Authorization templates:" %} {% trans "Authorization templates:" %}
<a class="alert-link" href="{% url "registration:photo_authorization_adult_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}">{% trans "Adult" %}</a> <a class="alert-link" href="{% url "registration:photo_authorization_adult_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}" data-turbolinks="false">{% trans "Adult" %}</a>
<a class="alert-link" href="{% url "registration:photo_authorization_child_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}">{% trans "Child" %}</a> <a class="alert-link" href="{% url "registration:photo_authorization_child_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}" data-turbolinks="false">{% trans "Child" %}</a>
</div> </div>
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% load i18n static crispy_forms_filters %} {% load i18n static crispy_forms_filters %}

View File

@ -11,27 +11,27 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<dl class="row"> <dl class="row">
<dt class="col-sm-6 text-end">{% trans "Last name:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Last name:" %}</dt>
<dd class="col-sm-6">{{ user_object.last_name }}</dd> <dd class="col-sm-6">{{ user_object.last_name }}</dd>
<dt class="col-sm-6 text-end">{% trans "First name:" %}</dt> <dt class="col-sm-6 text-right">{% trans "First name:" %}</dt>
<dd class="col-sm-6">{{ user_object.first_name }}</dd> <dd class="col-sm-6">{{ user_object.first_name }}</dd>
<dt class="col-sm-6 text-end">{% trans "Email:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Email:" %}</dt>
<dd class="col-sm-6"><a href="mailto:{{ user_object.email }}">{{ user_object.email }}</a> <dd class="col-sm-6"><a href="mailto:{{ user_object.email }}">{{ user_object.email }}</a>
{% if not user_object.registration.email_confirmed %} (<em>{% trans "Not confirmed" %}, <a href="{% url "registration:email_validation_resend" pk=user_object.pk %}">{% trans "resend the validation link" %}</a></em>){% endif %}</dd> {% if not user_object.registration.email_confirmed %} (<em>{% trans "Not confirmed" %}, <a href="{% url "registration:email_validation_resend" pk=user_object.pk %}">{% trans "resend the validation link" %}</a></em>){% endif %}</dd>
{% if user_object == user %} {% if user_object == user %}
<dt class="col-sm-6 text-end">{% trans "Password:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Password:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
<a href="{% url 'password_change' %}" class="btn btn-sm btn-secondary"> <a href="{% url 'password_change' %}" class="btn-sm btn-secondary" data-turbolinks="false">
<i class="fas fa-edit"></i> {% trans "Change password" %} <i class="fas fa-edit"></i> {% trans "Change password" %}
</a> </a>
</dd> </dd>
{% endif %} {% endif %}
{% if user_object.registration.participates %} {% if user_object.registration.participates %}
<dt class="col-sm-6 text-end">{% trans "Team:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Team:" %}</dt>
{% trans "any" as any %} {% trans "any" as any %}
<dd class="col-sm-6"> <dd class="col-sm-6">
<a href="{% if user_object.registration.team %}{% url "participation:team_detail" pk=user_object.registration.team.pk %}{% else %}#{% endif %}"> <a href="{% if user_object.registration.team %}{% url "participation:team_detail" pk=user_object.registration.team.pk %}{% else %}#{% endif %}">
@ -40,93 +40,91 @@
</dd> </dd>
{% if user_object.registration.studentregistration %} {% if user_object.registration.studentregistration %}
<dt class="col-sm-6 text-end">{% trans "Birth date:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Birth date:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.birth_date }}</dd> <dd class="col-sm-6">{{ user_object.registration.birth_date }}</dd>
{% endif %} {% endif %}
<dt class="col-sm-6 text-end">{% trans "Gender:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Gender:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.get_gender_display }}</dd> <dd class="col-sm-6">{{ user_object.registration.get_gender_display }}</dd>
<dt class="col-sm-6 text-end">{% trans "Address:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Address:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.address }}, {{ user_object.registration.zip_code|stringformat:'05d' }} {{ user_object.registration.city }}</dd> <dd class="col-sm-6">{{ user_object.registration.address }}, {{ user_object.registration.zip_code|stringformat:'05d' }} {{ user_object.registration.city }}</dd>
<dt class="col-sm-6 text-end">{% trans "Phone number:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Phone number:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.phone_number }}</dd> <dd class="col-sm-6">{{ user_object.registration.phone_number }}</dd>
<dt class="col-sm-6 text-end">{% trans "Health issues:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Health issues:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.health_issues|default:any }}</dd> <dd class="col-sm-6">{{ user_object.registration.health_issues|default:any }}</dd>
<dt class="col-sm-6 text-end">{% trans "Photo authorization:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Photo authorization:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if user_object.registration.photo_authorization %} {% if user_object.registration.photo_authorization %}
<a href="{{ user_object.registration.photo_authorization.url }}">{% trans "Download" %}</a> <a href="{{ user_object.registration.photo_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
{% endif %} {% endif %}
{% if user_object.registration.studentregistration %} {% if user_object.registration.studentregistration %}
{% if user_object.registration.under_18 and user_object.registration.team.participation.tournament and not user_object.registration.team.participation.tournament.remote %} {% if user_object.registration.under_18 and user_object.registration.team.participation.tournament and not user_object.registration.team.participation.tournament.remote %}
<dt class="col-sm-6 text-end">{% trans "Health sheet:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Health sheet:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if user_object.registration.health_sheet %} {% if user_object.registration.health_sheet %}
<a href="{{ user_object.registration.health_sheet.url }}">{% trans "Download" %}</a> <a href="{{ user_object.registration.health_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadHealthSheetModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadHealthSheetModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Vaccine sheet:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Vaccine sheet:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if user_object.registration.vaccine_sheet %} {% if user_object.registration.vaccine_sheet %}
<a href="{{ user_object.registration.vaccine_sheet.url }}">{% trans "Download" %}</a> <a href="{{ user_object.registration.vaccine_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadVaccineSheetModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadVaccineSheetModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
<dt class="col-sm-6 text-end">{% trans "Parental authorization:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Parental authorization:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if user_object.registration.parental_authorization %} {% if user_object.registration.parental_authorization %}
<a href="{{ user_object.registration.parental_authorization.url }}">{% trans "Download" %}</a> <a href="{{ user_object.registration.parental_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} {% endif %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadParentalAuthorizationModal">{% trans "Replace" %}</button> <button class="btn btn-primary" data-toggle="modal" data-target="#uploadParentalAuthorizationModal">{% trans "Replace" %}</button>
{% endif %} {% endif %}
</dd> </dd>
{% endif %} {% endif %}
<dt class="col-sm-6 text-end">{% trans "Student class:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Student class:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.get_student_class_display }}</dd> <dd class="col-sm-6">{{ user_object.registration.get_student_class_display }}</dd>
<dt class="col-sm-6 text-end">{% trans "School:" %}</dt> <dt class="col-sm-6 text-right">{% trans "School:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.school }}</dd> <dd class="col-sm-6">{{ user_object.registration.school }}</dd>
<dt class="col-sm-6 text-end">{% trans "Responsible name:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Responsible name:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.responsible_name }}</dd> <dd class="col-sm-6">{{ user_object.registration.responsible_name }}</dd>
<dt class="col-sm-6 text-end">{% trans "Responsible phone number:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Responsible phone number:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.responsible_phone }}</dd> <dd class="col-sm-6">{{ user_object.registration.responsible_phone }}</dd>
<dt class="col-sm-6 text-end">{% trans "Responsible email address:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Responsible email address:" %}</dt>
{% with user_object.registration.responsible_email as email %} {% with user_object.registration.responsible_email as email %}
<dd class="col-sm-6"><a href="mailto:{{ email }}">{{ email }}</a></dd> <dd class="col-sm-6"><a href="mailto:{{ email }}">{{ email }}</a></dd>
{% endwith %} {% endwith %}
{% elif user_object.registration.is_admin %}
<dt class="col-sm-6 text-right">{% trans "Admin:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.is_admin|yesno }}</dd>
{% elif user_object.registration.coachregistration or user_object.registration.is_volunteer %} {% elif user_object.registration.coachregistration or user_object.registration.is_volunteer %}
<dt class="col-sm-6 text-end">{% trans "Profesional activity:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd> <dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd>
{% if user_object.registration.is_volunteer %}
<dt class="col-sm-6 text-end">{% trans "Admin:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.is_admin|yesno }}</dd>
{% endif %}
{% endif %} {% endif %}
<dt class="col-sm-6 text-end">{% trans "Grant Animath to contact me in the future about other actions:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Grant Animath to contact me in the future about other actions:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.give_contact_to_animath|yesno }}</dd> <dd class="col-sm-6">{{ user_object.registration.give_contact_to_animath|yesno }}</dd>
</dl> </dl>
@ -134,7 +132,7 @@
<hr> <hr>
<dl class="row"> <dl class="row">
<dt class="col-sm-6 text-end">{% trans "Payment information:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Payment information:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% trans "yes,no,pending" as yesnodefault %} {% trans "yes,no,pending" as yesnodefault %}
{% with info=user_object.registration.payment.additional_information %} {% with info=user_object.registration.payment.additional_information %}
@ -146,13 +144,13 @@
{{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }} {{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }}
{% endif %} {% endif %}
{% if user.registration.is_admin or user_object.registration.payment.valid is False %} {% if user.registration.is_admin or user_object.registration.payment.valid is False %}
<button class="btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#updatePaymentModal"> <button class="btn-sm btn-secondary" data-toggle="modal" data-target="#updatePaymentModal">
<i class="fas fa-money-bill-wave"></i> {% trans "Update payment" %} <i class="fas fa-money-bill-wave"></i> {% trans "Update payment" %}
</button> </button>
{% endif %} {% endif %}
{% if user_object.registration.payment.type == "scholarship" %} {% if user_object.registration.payment.type == "scholarship" %}
{% if user.registration.is_admin or user == user_object %} {% if user.registration.is_admin or user == user_object %}
<a href="{{ user_object.registration.payment.scholarship_file.url }}" class="btn btn-info"> <a href="{{ user_object.registration.payment.scholarship_file.url }}" class="btn btn-info" data-turbolinks="false">
<i class="fas fa-file-pdf"></i> {% trans "Download scholarship attestation" %} <i class="fas fa-file-pdf"></i> {% trans "Download scholarship attestation" %}
</a> </a>
{% endif %} {% endif %}
@ -209,16 +207,30 @@
{% block extrajavascript %} {% block extrajavascript %}
<script> <script>
document.addEventListener('DOMContentLoaded', () => { $(document).ready(function() {
{% if user_object.registration.team and not user_object.registration.team.participation.valid %} {% if user_object.registration.team and not user_object.registration.team.participation.valid %}
initModal("uploadPhotoAuthorization", "{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk %}") $('button[data-target="#uploadPhotoAuthorizationModal"]').click(function() {
initModal("uploadHealthSheet", "{% url "registration:upload_user_health_sheet" pk=user_object.registration.pk %}") let modalBody = $("#uploadPhotoAuthorizationModal div.modal-body");
initModal("uploadVaccineSheet", "{% url "registration:upload_user_vaccine_sheet" pk=user_object.registration.pk %}") if (!modalBody.html().trim())
initModal("uploadParentalAuthorization", "{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %}") modalBody.load("{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk %} #form-content");
});
$('button[data-target="#uploadHealthSheetModal"]').click(function() {
let modalBody = $("#uploadHealthSheetModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "registration:upload_user_health_sheet" pk=user_object.registration.pk %} #form-content");
});
$('button[data-target="#uploadParentalAuthorizationModal"]').click(function() {
let modalBody = $("#uploadParentalAuthorizationModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %} #form-content");
});
{% endif %} {% endif %}
{% if user_object.registration.team.participation.valid %} {% if user_object.registration.team.participation.valid %}
initModal("updatePaymentModal", "{% url "registration:update_payment" pk=user_object.registration.payment.pk %}") $('button[data-target="#updatePaymentModal"]').click(function() {
let modalBody = $("#updatePaymentModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "registration:update_payment" pk=user_object.registration.payment.pk %} #form-content");
});
{% endif %} {% endif %}
}); });
</script> </script>

View File

@ -4,11 +4,9 @@
{% block content %} {% block content %}
{% if user.registration.is_volunteer %} {% if user.registration.is_volunteer %}
<div class="d-grid"> <a href="{% url "registration:add_organizer" %}" class="btn btn-block btn-secondary">
<a href="{% url "registration:add_organizer" %}" class="btn gap-0 btn-secondary"> <i class="fas fa-user-plus"></i> {% trans "Add organizer" %}
<i class="fas fa-user-plus"></i> {% trans "Add organizer" %} </a>
</a>
</div>
<hr> <hr>
{% endif %} {% endif %}

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-20 14:52+0100\n" "POT-Creation-Date: 2023-02-20 00:37+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -25,12 +25,12 @@ msgstr "API"
msgid "Error" msgid "Error"
msgstr "Erreur" msgstr "Erreur"
#: apps/eastereggs/templates/eastereggs/xp_modal.html:11 #: apps/eastereggs/templates/eastereggs/xp_modal.html:13
msgid "This task failed successfully." msgid "This task failed successfully."
msgstr "Cette tâche a échoué avec succès." msgstr "Cette tâche a échoué avec succès."
#: apps/eastereggs/templates/eastereggs/xp_modal.html:14 #: apps/eastereggs/templates/eastereggs/xp_modal.html:16
#: tfjm/templates/base_modal.html:17 #: tfjm/templates/base_modal.html:19
msgid "Close" msgid "Close"
msgstr "Fermer" msgstr "Fermer"
@ -100,7 +100,7 @@ msgid "Changelog of type \"{action}\" for model {model} at {timestamp}"
msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}" msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}"
#: apps/participation/admin.py:19 apps/participation/models.py:318 #: apps/participation/admin.py:19 apps/participation/models.py:318
#: apps/participation/tables.py:43 apps/registration/models.py:364 #: apps/participation/tables.py:44 apps/registration/models.py:364
msgid "valid" msgid "valid"
msgstr "valide" msgstr "valide"
@ -120,7 +120,7 @@ msgstr "Ce trigramme est déjà utilisé."
msgid "No team was found with this access code." msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès." msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: apps/participation/forms.py:82 apps/participation/forms.py:282 #: apps/participation/forms.py:82 apps/participation/forms.py:280
#: apps/registration/forms.py:113 apps/registration/forms.py:135 #: apps/registration/forms.py:113 apps/registration/forms.py:135
#: apps/registration/forms.py:157 apps/registration/forms.py:179 #: apps/registration/forms.py:157 apps/registration/forms.py:179
#: apps/registration/forms.py:224 #: apps/registration/forms.py:224
@ -141,52 +141,52 @@ msgstr "Je m'engage à participer à l'intégralité du TFJM²."
msgid "Message to address to the team:" msgid "Message to address to the team:"
msgstr "Message à adresser à l'équipe :" msgstr "Message à adresser à l'équipe :"
#: apps/participation/forms.py:155 #: apps/participation/forms.py:153
msgid "The uploaded file size must be under 5 Mo." msgid "The uploaded file size must be under 5 Mo."
msgstr "Le fichier envoyé doit peser moins de 5 Mo." msgstr "Le fichier envoyé doit peser moins de 5 Mo."
#: apps/participation/forms.py:157 apps/participation/forms.py:284 #: apps/participation/forms.py:155 apps/participation/forms.py:282
msgid "The uploaded file must be a PDF file." msgid "The uploaded file must be a PDF file."
msgstr "Le fichier envoyé doit être au format PDF." msgstr "Le fichier envoyé doit être au format PDF."
#: apps/participation/forms.py:161 #: apps/participation/forms.py:159
msgid "The PDF file must not have more than 30 pages." msgid "The PDF file must not have more than 30 pages."
msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages." msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages."
#: apps/participation/forms.py:198 #: apps/participation/forms.py:196
msgid "CSV file:" msgid "CSV file:"
msgstr "Tableur au format CSV :" msgstr "Tableur au format CSV :"
#: apps/participation/forms.py:215 #: apps/participation/forms.py:213
msgid "" msgid ""
"This file contains non-UTF-8 content. Please send your sheet as a CSV file." "This file contains non-UTF-8 content. Please send your sheet as a CSV file."
msgstr "" msgstr ""
"Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au " "Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au "
"format CSV." "format CSV."
#: apps/participation/forms.py:240 #: apps/participation/forms.py:238
msgid "The following note is higher of the maximum expected value:" msgid "The following note is higher of the maximum expected value:"
msgstr "La note suivante est supérieure au maximum attendu :" msgstr "La note suivante est supérieure au maximum attendu :"
#: apps/participation/forms.py:248 #: apps/participation/forms.py:246
msgid "The following user was not found:" msgid "The following user was not found:"
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :" msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
#: apps/participation/forms.py:265 #: apps/participation/forms.py:263
msgid "The defender, the opponent and the reporter must be different." msgid "The defender, the opponent and the reporter must be different."
msgstr "" msgstr ""
"Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es." "Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es."
#: apps/participation/forms.py:269 #: apps/participation/forms.py:267
msgid "This defender did not work on this problem." msgid "This defender did not work on this problem."
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème." msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
#: apps/participation/models.py:33 apps/participation/models.py:135 #: apps/participation/models.py:33 apps/participation/models.py:135
#: apps/participation/tables.py:17 apps/participation/tables.py:33 #: apps/participation/tables.py:17 apps/participation/tables.py:34
msgid "name" msgid "name"
msgstr "nom" msgstr "nom"
#: apps/participation/models.py:39 apps/participation/tables.py:38 #: apps/participation/models.py:39 apps/participation/tables.py:39
msgid "trigram" msgid "trigram"
msgstr "trigramme" msgstr "trigramme"
@ -216,7 +216,7 @@ msgstr "Équipe {name} ({trigram})"
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
#: apps/participation/models.py:126 apps/participation/tables.py:82 #: apps/participation/models.py:126 apps/participation/tables.py:85
msgid "teams" msgid "teams"
msgstr "équipes" msgstr "équipes"
@ -376,7 +376,7 @@ msgstr "solution défendue"
msgid "Problem #{problem}" msgid "Problem #{problem}"
msgstr "Problème n°{problem}" msgstr "Problème n°{problem}"
#: apps/participation/models.py:422 apps/participation/tables.py:102 #: apps/participation/models.py:422 apps/participation/tables.py:106
msgid "defender" msgid "defender"
msgstr "défenseur" msgstr "défenseur"
@ -521,28 +521,28 @@ msgstr "note"
msgid "notes" msgid "notes"
msgstr "notes" msgstr "notes"
#: apps/participation/tables.py:49 #: apps/participation/tables.py:50
msgid "Validated" msgid "Validated"
msgstr "Validée" msgstr "Validée"
#: apps/participation/tables.py:49 #: apps/participation/tables.py:50
msgid "Validation pending" msgid "Validation pending"
msgstr "Validation en attente" msgstr "Validation en attente"
#: apps/participation/tables.py:49 #: apps/participation/tables.py:50
msgid "Not validated" msgid "Not validated"
msgstr "Non validée" msgstr "Non validée"
#: apps/participation/tables.py:62 #: apps/participation/tables.py:64
msgid "date" msgid "date"
msgstr "date" msgstr "date"
#: apps/participation/tables.py:65 #: apps/participation/tables.py:67
#, python-brace-format #, python-brace-format
msgid "From {start} to {end}" msgid "From {start} to {end}"
msgstr "Du {start} au {end}" msgstr "Du {start} au {end}"
#: apps/participation/tables.py:88 #: apps/participation/tables.py:91
msgid "No defined team" msgid "No defined team"
msgstr "Pas d'équipe définie" msgstr "Pas d'équipe définie"
@ -582,12 +582,12 @@ msgstr ""
#: apps/participation/templates/participation/create_team.html:11 #: apps/participation/templates/participation/create_team.html:11
#: apps/participation/templates/participation/tournament_form.html:14 #: apps/participation/templates/participation/tournament_form.html:14
#: tfjm/templates/base.html:240 #: tfjm/templates/base.html:231
msgid "Create" msgid "Create"
msgstr "Créer" msgstr "Créer"
#: apps/participation/templates/participation/join_team.html:11 #: apps/participation/templates/participation/join_team.html:11
#: tfjm/templates/base.html:235 #: tfjm/templates/base.html:226
msgid "Join" msgid "Join"
msgstr "Rejoindre" msgstr "Rejoindre"
@ -604,8 +604,8 @@ msgstr "Rejoindre"
#: apps/participation/templates/participation/update_team.html:12 #: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/payment_form.html:49 #: apps/registration/templates/registration/payment_form.html:49
#: apps/registration/templates/registration/update_user.html:16 #: apps/registration/templates/registration/update_user.html:16
#: apps/registration/templates/registration/user_detail.html:167 #: apps/registration/templates/registration/user_detail.html:165
#: apps/registration/templates/registration/user_detail.html:204 #: apps/registration/templates/registration/user_detail.html:202
msgid "Update" msgid "Update"
msgstr "Modifier" msgstr "Modifier"
@ -671,11 +671,11 @@ msgstr "Envoyer une solution"
#: apps/registration/templates/registration/upload_parental_authorization.html:17 #: apps/registration/templates/registration/upload_parental_authorization.html:17
#: apps/registration/templates/registration/upload_photo_authorization.html:18 #: apps/registration/templates/registration/upload_photo_authorization.html:18
#: apps/registration/templates/registration/upload_vaccine_sheet.html:13 #: apps/registration/templates/registration/upload_vaccine_sheet.html:13
#: apps/registration/templates/registration/user_detail.html:177 #: apps/registration/templates/registration/user_detail.html:175
#: apps/registration/templates/registration/user_detail.html:182 #: apps/registration/templates/registration/user_detail.html:180
#: apps/registration/templates/registration/user_detail.html:187 #: apps/registration/templates/registration/user_detail.html:185
#: apps/registration/templates/registration/user_detail.html:192 #: apps/registration/templates/registration/user_detail.html:190
#: apps/registration/templates/registration/user_detail.html:197 #: apps/registration/templates/registration/user_detail.html:195
msgid "Upload" msgid "Upload"
msgstr "Téléverser" msgstr "Téléverser"
@ -787,7 +787,7 @@ msgid "BigBlueButton link:"
msgstr "Lien BigBlueButton :" msgstr "Lien BigBlueButton :"
#: apps/participation/templates/participation/pool_detail.html:41 #: apps/participation/templates/participation/pool_detail.html:41
#: apps/participation/templates/participation/tournament_detail.html:97 #: apps/participation/templates/participation/tournament_detail.html:95
msgid "Ranking" msgid "Ranking"
msgstr "Classement" msgstr "Classement"
@ -810,7 +810,7 @@ msgid "Passages"
msgstr "Passages" msgstr "Passages"
#: apps/participation/templates/participation/pool_detail.html:69 #: apps/participation/templates/participation/pool_detail.html:69
#: apps/participation/templates/participation/tournament_detail.html:111 #: apps/participation/templates/participation/tournament_detail.html:109
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
@ -971,7 +971,7 @@ msgid "Are you sure that you want to leave this team?"
msgstr "Êtes-vous sûr·e de vouloir quitter cette équipe ?" msgstr "Êtes-vous sûr·e de vouloir quitter cette équipe ?"
#: apps/participation/templates/participation/team_list.html:6 #: apps/participation/templates/participation/team_list.html:6
#: tfjm/templates/base.html:228 #: tfjm/templates/base.html:219
msgid "All teams" msgid "All teams"
msgstr "Toutes les équipes" msgstr "Toutes les équipes"
@ -1041,7 +1041,7 @@ msgid "Export as CSV"
msgstr "Exporter en CSV" msgstr "Exporter en CSV"
#: apps/participation/templates/participation/tournament_detail.html:72 #: apps/participation/templates/participation/tournament_detail.html:72
#: tfjm/templates/base.html:66 #: tfjm/templates/base.html:65
msgid "Teams" msgid "Teams"
msgstr "Équipes" msgstr "Équipes"
@ -1049,20 +1049,20 @@ msgstr "Équipes"
msgid "Pools" msgid "Pools"
msgstr "Poules" msgstr "Poules"
#: apps/participation/templates/participation/tournament_detail.html:88 #: apps/participation/templates/participation/tournament_detail.html:87
msgid "Add new pool" msgid "Add new pool"
msgstr "Ajouter une nouvelle poule" msgstr "Ajouter une nouvelle poule"
#: apps/participation/templates/participation/tournament_detail.html:110 #: apps/participation/templates/participation/tournament_detail.html:108
msgid "Add pool" msgid "Add pool"
msgstr "Ajouter une poule" msgstr "Ajouter une poule"
#: apps/participation/templates/participation/tournament_list.html:6 #: apps/participation/templates/participation/tournament_list.html:6
#: tfjm/templates/base.html:224 #: tfjm/templates/base.html:215
msgid "All tournaments" msgid "All tournaments"
msgstr "Tous les tournois" msgstr "Tous les tournois"
#: apps/participation/templates/participation/tournament_list.html:14 #: apps/participation/templates/participation/tournament_list.html:13
msgid "Add tournament" msgid "Add tournament"
msgstr "Ajouter un tournoi" msgstr "Ajouter un tournoi"
@ -1074,8 +1074,8 @@ msgstr "Retour aux détails de l'utilisateur⋅rice"
msgid "Templates:" msgid "Templates:"
msgstr "Modèles :" msgstr "Modèles :"
#: apps/participation/views.py:44 tfjm/templates/base.html:72 #: apps/participation/views.py:44 tfjm/templates/base.html:71
#: tfjm/templates/base.html:239 #: tfjm/templates/base.html:230
msgid "Create team" msgid "Create team"
msgstr "Créer une équipe" msgstr "Créer une équipe"
@ -1087,8 +1087,8 @@ msgstr "Vous ne participez pas, vous ne pouvez pas créer d'équipe."
msgid "You are already in a team." msgid "You are already in a team."
msgstr "Vous êtes déjà dans une équipe." msgstr "Vous êtes déjà dans une équipe."
#: apps/participation/views.py:89 tfjm/templates/base.html:77 #: apps/participation/views.py:89 tfjm/templates/base.html:76
#: tfjm/templates/base.html:234 #: tfjm/templates/base.html:225
msgid "Join team" msgid "Join team"
msgstr "Rejoindre une équipe" msgstr "Rejoindre une équipe"
@ -1446,7 +1446,7 @@ msgstr "nom de famille"
#: apps/registration/templates/registration/add_organizer.html:5 #: apps/registration/templates/registration/add_organizer.html:5
#: apps/registration/templates/registration/add_organizer.html:12 #: apps/registration/templates/registration/add_organizer.html:12
#: apps/registration/templates/registration/add_organizer.html:21 #: apps/registration/templates/registration/add_organizer.html:21
#: apps/registration/templates/registration/user_list.html:9 #: apps/registration/templates/registration/user_list.html:8
#: apps/registration/views.py:88 #: apps/registration/views.py:88
msgid "Add organizer" msgid "Add organizer"
msgstr "Ajouter un⋅e organisateur⋅rice" msgstr "Ajouter un⋅e organisateur⋅rice"
@ -1545,8 +1545,8 @@ msgid "Your password has been set. You may go ahead and log in now."
msgstr "Votre mot de passe a été changé. Vous pouvez désormais vous connecter." msgstr "Votre mot de passe a été changé. Vous pouvez désormais vous connecter."
#: apps/registration/templates/registration/password_reset_complete.html:10 #: apps/registration/templates/registration/password_reset_complete.html:10
#: tfjm/templates/base.html:125 tfjm/templates/base.html:244 #: tfjm/templates/base.html:124 tfjm/templates/base.html:235
#: tfjm/templates/base.html:245 tfjm/templates/registration/login.html:7 #: tfjm/templates/base.html:236 tfjm/templates/registration/login.html:7
#: tfjm/templates/registration/login.html:8 #: tfjm/templates/registration/login.html:8
#: tfjm/templates/registration/login.html:25 #: tfjm/templates/registration/login.html:25
msgid "Log in" msgid "Log in"
@ -1764,60 +1764,60 @@ msgid "Responsible email address:"
msgstr "Adresse e-mail de læ responsable légal⋅e :" msgstr "Adresse e-mail de læ responsable légal⋅e :"
#: apps/registration/templates/registration/user_detail.html:120 #: apps/registration/templates/registration/user_detail.html:120
msgid "Profesional activity:"
msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:124
msgid "Admin:" msgid "Admin:"
msgstr "Administrateur⋅rice :" msgstr "Administrateur⋅rice :"
#: apps/registration/templates/registration/user_detail.html:129 #: apps/registration/templates/registration/user_detail.html:123
msgid "Profesional activity:"
msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:127
msgid "Grant Animath to contact me in the future about other actions:" msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :" msgstr "Autorise Animath à recontacter à propos d'autres actions :"
#: apps/registration/templates/registration/user_detail.html:137 #: apps/registration/templates/registration/user_detail.html:135
msgid "Payment information:" msgid "Payment information:"
msgstr "Informations de paiement :" msgstr "Informations de paiement :"
#: apps/registration/templates/registration/user_detail.html:139 #: apps/registration/templates/registration/user_detail.html:137
msgid "yes,no,pending" msgid "yes,no,pending"
msgstr "oui,non,en attente" msgstr "oui,non,en attente"
#: apps/registration/templates/registration/user_detail.html:143 #: apps/registration/templates/registration/user_detail.html:141
#: apps/registration/templates/registration/user_detail.html:146 #: apps/registration/templates/registration/user_detail.html:144
msgid "valid:" msgid "valid:"
msgstr "valide :" msgstr "valide :"
#: apps/registration/templates/registration/user_detail.html:150 #: apps/registration/templates/registration/user_detail.html:148
#: apps/registration/templates/registration/user_detail.html:203 #: apps/registration/templates/registration/user_detail.html:201
msgid "Update payment" msgid "Update payment"
msgstr "Modifier le paiement" msgstr "Modifier le paiement"
#: apps/registration/templates/registration/user_detail.html:156 #: apps/registration/templates/registration/user_detail.html:154
msgid "Download scholarship attestation" msgid "Download scholarship attestation"
msgstr "Télécharger l'attestation de bourse" msgstr "Télécharger l'attestation de bourse"
#: apps/registration/templates/registration/user_detail.html:169 #: apps/registration/templates/registration/user_detail.html:167
msgid "Impersonate" msgid "Impersonate"
msgstr "Impersonifier" msgstr "Impersonifier"
#: apps/registration/templates/registration/user_detail.html:176 #: apps/registration/templates/registration/user_detail.html:174
#: apps/registration/views.py:312 #: apps/registration/views.py:312
msgid "Upload photo authorization" msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image" msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/templates/registration/user_detail.html:181 #: apps/registration/templates/registration/user_detail.html:179
#: apps/registration/views.py:333 #: apps/registration/views.py:333
msgid "Upload health sheet" msgid "Upload health sheet"
msgstr "Téléverser la fiche sanitaire" msgstr "Téléverser la fiche sanitaire"
#: apps/registration/templates/registration/user_detail.html:186 #: apps/registration/templates/registration/user_detail.html:184
#: apps/registration/views.py:354 #: apps/registration/views.py:354
msgid "Upload vaccine sheet" msgid "Upload vaccine sheet"
msgstr "Téléverser le carnet de vaccination" msgstr "Téléverser le carnet de vaccination"
#: apps/registration/templates/registration/user_detail.html:191 #: apps/registration/templates/registration/user_detail.html:189
#: apps/registration/templates/registration/user_detail.html:196 #: apps/registration/templates/registration/user_detail.html:194
#: apps/registration/views.py:375 #: apps/registration/views.py:375
msgid "Upload parental authorization" msgid "Upload parental authorization"
msgstr "Téléverser l'autorisation parentale" msgstr "Téléverser l'autorisation parentale"
@ -1942,55 +1942,55 @@ msgstr ""
"avec les détails de l'erreur. Vous pouvez désormais retourner chercher " "avec les détails de l'erreur. Vous pouvez désormais retourner chercher "
"d'autres solutions.." "d'autres solutions.."
#: tfjm/templates/base.html:54 #: tfjm/templates/base.html:53
msgid "Home" msgid "Home"
msgstr "Accueil" msgstr "Accueil"
#: tfjm/templates/base.html:58 #: tfjm/templates/base.html:57
msgid "Tournaments" msgid "Tournaments"
msgstr "Tournois" msgstr "Tournois"
#: tfjm/templates/base.html:63 #: tfjm/templates/base.html:62
msgid "Users" msgid "Users"
msgstr "Utilisateur⋅rices" msgstr "Utilisateur⋅rices"
#: tfjm/templates/base.html:83 #: tfjm/templates/base.html:82
msgid "My team" msgid "My team"
msgstr "Mon équipe" msgstr "Mon équipe"
#: tfjm/templates/base.html:88 #: tfjm/templates/base.html:87
msgid "My participation" msgid "My participation"
msgstr "Ma participation" msgstr "Ma participation"
#: tfjm/templates/base.html:95 #: tfjm/templates/base.html:94
msgid "Chat" msgid "Chat"
msgstr "Chat" msgstr "Chat"
#: tfjm/templates/base.html:99 #: tfjm/templates/base.html:98
msgid "Administration" msgid "Administration"
msgstr "Administration" msgstr "Administration"
#: tfjm/templates/base.html:107 #: tfjm/templates/base.html:106
msgid "Search" msgid "Search..."
msgstr "Chercher" msgstr "Chercher ..."
#: tfjm/templates/base.html:116 #: tfjm/templates/base.html:115
msgid "Return to admin view" msgid "Return to admin view"
msgstr "Retourner à l'interface administrateur⋅rice" msgstr "Retourner à l'interface administrateur⋅rice"
#: tfjm/templates/base.html:121 #: tfjm/templates/base.html:120
msgid "Register" msgid "Register"
msgstr "S'inscrire" msgstr "S'inscrire"
#: tfjm/templates/base.html:137 #: tfjm/templates/base.html:136
msgid "My account" msgid "My account"
msgstr "Mon compte" msgstr "Mon compte"
#: tfjm/templates/base.html:142 #: tfjm/templates/base.html:139
msgid "Log out" msgid "Log out"
msgstr "Déconnexion" msgstr "Déconnexion"
#: tfjm/templates/base.html:160 #: tfjm/templates/base.html:156
#, python-format #, python-format
msgid "" msgid ""
"Your email address is not validated. Please click on the link you received " "Your email address is not validated. Please click on the link you received "
@ -2001,15 +2001,15 @@ msgstr ""
"avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a " "avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a "
"href=\"%(send_email_url)s\">ce lien</a>." "href=\"%(send_email_url)s\">ce lien</a>."
#: tfjm/templates/base.html:182 #: tfjm/templates/base.html:180
msgid "Contact us" msgid "Contact us"
msgstr "Nous contacter" msgstr "Nous contacter"
#: tfjm/templates/base.html:209 #: tfjm/templates/base.html:199
msgid "About" msgid "About"
msgstr "À propos" msgstr "À propos"
#: tfjm/templates/base.html:231 #: tfjm/templates/base.html:222
msgid "Search results" msgid "Search results"
msgstr "Résultats de la recherche" msgstr "Résultats de la recherche"
@ -2045,3 +2045,15 @@ msgstr "Résultats"
#: tfjm/templates/search/search.html:25 #: tfjm/templates/search/search.html:25
msgid "No results found." msgid "No results found."
msgstr "Aucun résultat." msgstr "Aucun résultat."
#~ msgid "Role:"
#~ msgstr "Rôle :"
#~ msgid "role of the administrator"
#~ msgstr "rôle de l'administrateur⋅rice"
#~ msgid "admin registration"
#~ msgstr "inscription d'administrateur⋅rice"
#~ msgid "admin registrations"
#~ msgstr "inscriptions d'administrateur⋅rices"

View File

@ -1,4 +1,3 @@
crispy-bootstrap5~=0.7
Django>=3.2,<4.0 Django>=3.2,<4.0
django-cas-server~=2.0 django-cas-server~=2.0
django-crispy-forms~=1.14 django-crispy-forms~=1.14

View File

@ -54,14 +54,32 @@ class SessionMiddleware(object):
return response return response
class FetchMiddleware(object): class TurbolinksMiddleware(object): # pragma: no cover
""" """
This middleware let requests to know when this was called by a fetch command or not. Send the `Turbolinks-Location` header in response to a visit that was redirected,
and Turbolinks will replace the browser's topmost history entry.
""" """
def __init__(self, get_response): def __init__(self, get_response):
self.get_response = get_response self.get_response = get_response
def __call__(self, request): def __call__(self, request):
request.content_only = 'CONTENT_ONLY' in request.headers response = self.get_response(request)
return self.get_response(request)
is_turbolinks = request.META.get('HTTP_TURBOLINKS_REFERRER')
is_response_redirect = response.has_header('Location')
if is_turbolinks:
if is_response_redirect:
location = response['Location']
prev_location = request.session.pop('_turbolinks_redirect_to', None)
if prev_location is not None:
# relative subsequent redirect
if location.startswith('.'):
location = prev_location.split('?')[0] + location
request.session['_turbolinks_redirect_to'] = location
else:
if request.session.get('_turbolinks_redirect_to'):
location = request.session.pop('_turbolinks_redirect_to')
response['Turbolinks-Location'] = location
return response

View File

@ -54,7 +54,6 @@ INSTALLED_APPS = [
'django.forms', 'django.forms',
'crispy_forms', 'crispy_forms',
'crispy_bootstrap5',
'django_filters', 'django_filters',
'django_tables2', 'django_tables2',
'haystack', 'haystack',
@ -65,6 +64,7 @@ INSTALLED_APPS = [
'rest_framework.authtoken', 'rest_framework.authtoken',
'api', 'api',
'eastereggs',
'registration', 'registration',
'participation', 'participation',
] ]
@ -87,7 +87,7 @@ MIDDLEWARE = [
'django.middleware.locale.LocaleMiddleware', 'django.middleware.locale.LocaleMiddleware',
'django.contrib.sites.middleware.CurrentSiteMiddleware', 'django.contrib.sites.middleware.CurrentSiteMiddleware',
'tfjm.middlewares.SessionMiddleware', 'tfjm.middlewares.SessionMiddleware',
'tfjm.middlewares.FetchMiddleware', 'tfjm.middlewares.TurbolinksMiddleware',
] ]
ROOT_URLCONF = 'tfjm.urls' ROOT_URLCONF = 'tfjm.urls'
@ -190,9 +190,9 @@ MEDIA_ROOT = os.path.join(BASE_DIR, "media")
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
CRISPY_TEMPLATE_PACK = 'bootstrap5' CRISPY_TEMPLATE_PACK = 'bootstrap4'
DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap5.html' DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html'
HAYSTACK_CONNECTIONS = { HAYSTACK_CONNECTIONS = {
'default': { 'default': {
@ -230,6 +230,9 @@ PHONENUMBER_DEFAULT_REGION = 'FR'
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
# Use local Jquery
JQUERY_URL = False
# Custom parameters # Custom parameters
PROBLEM_COUNT = 8 PROBLEM_COUNT = 8
FORBIDDEN_TRIGRAMS = [ FORBIDDEN_TRIGRAMS = [

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -14,21 +14,19 @@
{# Favicon #} {# Favicon #}
<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">
{% if no_cache %}
<meta name="turbolinks-cache-control" content="no-cache">
{% endif %}
{# Bootstrap CSS #} {# Bootstrap CSS #}
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'fontawasome/css/all.css' %}"> <link rel="stylesheet" href="{% static 'fontawasome/css/all.css' %}">
<link rel="stylesheet" href="{% static 'fontawasome/css/v4-shims.css' %}"> <link rel="stylesheet" href="{% static 'fontawasome/css/v4-shims.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap-select/css/bootstrap-select.min.css' %}"> {# JQuery, Bootstrap and Turbolinks JavaScript #}
<script src="{% static 'jquery/jquery-3.6.0.min.js' %}"></script>
{# Bootstrap JavaScript #}
<script src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script> <script src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'turbolinks/turbolinks.js' %}"></script>
{# bootstrap-select for beautyful selects and JQuery dependency #}
<script src="{% static 'jquery/jquery.min.js' %}"></script>
<script src="{% static 'bootstrap-select/js/bootstrap-select.min.js' %}"></script>
<script src="{% static 'bootstrap-select/js/defaults-fr_FR.min.js' %}"></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 %}
@ -38,13 +36,13 @@
{% block extracss %}{% endblock %} {% block extracss %}{% endblock %}
</head> </head>
<body class="d-flex w-100 h-100 flex-column"> <body class="d-flex w-100 h-100 flex-column">
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-navbar shadow-sm"> <main class="mb-auto">
<div class="container-fluid"> <nav class="navbar navbar-expand-md navbar-light bg-light fixed-navbar shadow-sm">
<a class="navbar-brand" href="https://tfjm.org/"> <a class="navbar-brand" href="https://tfjm.org/">
<img src="{% static "tfjm.svg" %}" style="width: 42px;" alt="Logo TFJM²" id="navbar-logo"> <img src="{% static "tfjm.svg" %}" style="width: 42px;" alt="Logo TFJM²" id="navbar-logo">
</a> </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" <button class="navbar-toggler" type="button" data-toggle="collapse"
data-bs-target="#navbarNavDropdown" data-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown" aria-expanded="false" aria-controls="navbarNavDropdown" aria-expanded="false"
aria-label="Toggle navigation"> aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@ -55,7 +53,7 @@
<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">
<a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#tournamentListModal"> <a href="#" class="nav-link" data-toggle="modal" data-target="#tournamentListModal">
<i class="fas fa-calendar-day"></i> {% trans "Tournaments" %} <i class="fas fa-calendar-day"></i> {% trans "Tournaments" %}
</a> </a>
</li> </li>
@ -64,17 +62,17 @@
<a href="{% url "registration:user_list" %}" class="nav-link"><i class="fas fa-user"></i> {% trans "Users" %}</a> <a href="{% url "registration:user_list" %}" class="nav-link"><i class="fas fa-user"></i> {% trans "Users" %}</a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#teamsModal"><i class="fas fa-users"></i> {% trans "Teams" %}</a> <a href="#" class="nav-link" data-toggle="modal" data-target="#teamsModal"><i class="fas fa-users"></i> {% trans "Teams" %}</a>
</li> </li>
{% elif user.is_authenticated and user.registration.participates %} {% elif user.is_authenticated and user.registration.participates %}
{% if not user.registration.team %} {% if not user.registration.team %}
<li class="nav-item active"> <li class="nav-item active">
<a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#createTeamModal"> <a href="#" class="nav-link" data-toggle="modal" data-target="#createTeamModal">
<i class="fas fa-users"></i> {% trans "Create team" %} <i class="fas fa-users"></i> {% trans "Create team" %}
</a> </a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#joinTeamModal"> <a href="#" class="nav-link" data-toggle="modal" data-target="#joinTeamModal">
<i class="fas fa-users"></i> {% trans "Join team" %} <i class="fas fa-users"></i> {% trans "Join team" %}
</a> </a>
</li> </li>
@ -97,17 +95,17 @@
</li> </li>
{% if user.admin %} {% if user.admin %}
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="{% url "admin:index" %}"><i class="fas fa-cog"></i> {% trans "Administration" %}</a> <a data-turbolinks="false" class="nav-link" href="{% url "admin:index" %}"><i class="fas fa-cog"></i> {% trans "Administration" %}</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ml-auto">
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
<form class="navbar-form d-flex" role="search" onsubmit="event.preventDefault()"> <form class="navbar-form" role="search" onsubmit="event.preventDefault()">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" placeholder="{% trans "Search" %}" name="q" id="search-term" value="{{ request.GET.q }}"> <input type="text" class="form-control" placeholder="{% trans "Search..." %}" name="q" id="search-term" value="{{ request.GET.q }}">
<div class="input-group-btn"> <div class="input-group-btn">
<button class="btn btn-default" data-bs-toggle="modal" data-bs-target="#searchModal"><i class="fa fa-search"></i></button> <button class="btn btn-default" data-toggle="modal" data-target="#searchModal"><i class="fa fa-search"></i></button>
</div> </div>
</div> </div>
</form> </form>
@ -122,41 +120,38 @@
<a class="nav-link" href="{% url "registration:signup" %}"><i class="fas fa-user-plus"></i> {% trans "Register" %}</a> <a class="nav-link" href="{% url "registration:signup" %}"><i class="fas fa-user-plus"></i> {% trans "Register" %}</a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="#" data-bs-toggle="modal" data-bs-target="#loginModal"> <a class="nav-link" href="#" data-toggle="modal" data-target="#loginModal">
<i class="fas fa-sign-in-alt"></i> {% trans "Log in" %} <i class="fas fa-sign-in-alt"></i> {% trans "Log in" %}
</a> </a>
</li> </li>
{% else %} {% else %}
<li class="nav-item dropdown"> <li class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-user"></i> {{ user.first_name }} {{ user.last_name }} <i class="fas fa-user"></i> {{ user.first_name }} {{ user.last_name }}
</a> </a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink"> <div class="dropdown-menu dropdown-menu-right"
<li> aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="{% url "registration:my_account_detail" %}"> <a class="dropdown-item" href="{% url "registration:my_account_detail" %}">
<i class="fas fa-user"></i> {% trans "My account" %} <i class="fas fa-user"></i> {% trans "My account" %}
</a> </a>
</li> <a class="dropdown-item" href="{% url "logout" %}">
<li> <i class="fas fa-sign-out-alt"></i> {% trans "Log out" %}
<a class="dropdown-item" href="{% url "logout" %}"> </a>
<i class="fas fa-sign-out-alt"></i> {% trans "Log out" %} </div>
</a>
</li>
</ul>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
</div>
</nav> </nav>
<main class="mb-auto flex-shrink-0">
{% block fullcontent %} {% block fullcontent %}
<div class="{% block containertype %}container{% endblock %} my-3"> <div class="{% block containertype %}container{% endblock %} my-3">
{% block contenttitle %}{% endblock %} {% block contenttitle %}{% endblock %}
{% if user.is_authenticated and not user.registration.email_confirmed %} {% if user.is_authenticated and not user.registration.email_confirmed %}
<div class="alert alert-warning alert-dismissible" role="alert"> <div class="alert alert-warning alert-dismissible">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
{% url "registration:email_validation_resend" pk=user.pk as send_email_url %} {% url "registration:email_validation_resend" pk=user.pk as send_email_url %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
Your email address is not validated. Please click on the link you received by email. Your email address is not validated. Please click on the link you received by email.
@ -177,15 +172,13 @@
<footer class="bg-light text-primary mt-auto py-2"> <footer class="bg-light text-primary mt-auto py-2">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-sm-1"> <div class="col-10">
<span class="text-muted mr-1">
<a target="_blank" href="mailto:&#99;&#111;&#110;&#116;&#97;&#99;&#116;&#64;&#116;&#102;&#106;&#109;&#46;&#111;&#114;&#103;"
class="text-muted"><i class="fas fa-envelope"></i> {% trans "Contact us" %}</a>
</span>
</div>
<div class="col-sm-1">
<form action="{% url 'set_language' %}" method="post" <form action="{% url 'set_language' %}" method="post"
class="form-inline"> class="form-inline">
<span class="text-muted mr-1">
<a target="_blank" href="mailto:&#99;&#111;&#110;&#116;&#97;&#99;&#116;&#64;&#116;&#102;&#106;&#109;&#46;&#111;&#114;&#103;"
class="text-muted"><i class="fas fa-envelope"></i> {% trans "Contact us" %}</a>
</span>
{% csrf_token %} {% csrf_token %}
<select title="language" name="language" <select title="language" name="language"
class="form-control form-control-sm language" class="form-control form-control-sm language"
@ -202,19 +195,16 @@
</select> &nbsp; </select> &nbsp;
<noscript> <noscript>
<input type="submit"> <input type="submit">
</noscript> </noscript> &nbsp;
</form>
</div>
<div class="col-sm-9">
<a target="_blank" class="text-muted" href="{% url "about" %}">{% trans "About" %}</a> &nbsp; &mdash; &nbsp; <a target="_blank" class="text-muted" href="{% url "about" %}">{% trans "About" %}</a> &nbsp; &mdash; &nbsp;
<a target="_blank" class="text-muted" <a target="_blank" class="text-muted"
href="https://gitlab.com/animath/si/plateforme-tfjm"> href="https://gitlab.com/animath/si/plateforme-tfjm">
<i class="fab fa-gitlab"></i> <i class="fab fa-gitlab"></i>
</a> </a>
</form>
</div> </div>
<div class="col-sm-1 text-end"> <div class="col text-right">
<a href="#" class="text-muted"> <a href="#" data-turbolinks="false" class="text-muted">
<i class="fa fa-arrow-up" aria-hidden="true"></i> <i class="fa fa-arrow-up" aria-hidden="true"></i>
</a> </a>
</div> </div>
@ -250,43 +240,49 @@
<script> <script>
CSRF_TOKEN = "{{ csrf_token }}"; CSRF_TOKEN = "{{ csrf_token }}";
document.querySelectorAll(".invalid-feedback").forEach(elem => elem.classList.add('d-block')) $(".invalid-feedback").addClass("d-block");
function initModal(target, url, content_id = 'form-content') { $(document).ready(function () {
document.querySelector('[data-bs-target="#' + target + 'Modal"]').addEventListener('click', () => { $('a[data-target="#tournamentListModal"]').click(function() {
let modalBody = document.querySelector("#" + target + "Modal div.modal-body") let modalBody = $("#tournamentListModal div.modal-body");
if (!modalBody.html().trim())
if (!modalBody.innerHTML.trim()) { modalBody.load("{% url "participation:tournament_list" %} #form-content")
if (url instanceof Function) url = url() });
fetch(url, {headers: {'CONTENT-ONLY': '1'}})
.then(resp => resp.text())
.then(resp => new DOMParser().parseFromString(resp, 'text/html'))
.then(res => modalBody.innerHTML = res.getElementById(content_id).outerHTML)
.then(() => $('.selectpicker').selectpicker()) // TODO Update that when the library will be JQuery-free
}
})
}
document.addEventListener('DOMContentLoaded', () => {
initModal("tournamentList", "{% url "participation:tournament_list" %}")
{% if user.is_authenticated and user.registration.is_admin %} {% if user.is_authenticated and user.registration.is_admin %}
initModal("teams", "{% url "participation:team_list" %}") $('a[data-target="#teamsModal"]').click(function() {
initModal("search", let modalBody = $("#teamsModal div.modal-body");
() => "{% url "haystack_search" %}?q=" + encodeURI(document.getElementById("search-term").value), if (!modalBody.html().trim())
"search-results") modalBody.load("{% url "participation:team_list" %} #form-content")
});
$('button[data-target="#searchModal"]').click(function() {
let modalBody = $("#searchModal div.modal-body");
let q = encodeURI($("#search-term").val());
modalBody.load("{% url "haystack_search" %}?q=" + q + " #search-results");
});
{% endif %} {% endif %}
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
initModal("login", "{% url 'login' %}") $('a[data-target="#loginModal"]').click(function() {
let modalBody = $("#loginModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "login" %} #form-content")
});
{% endif %} {% endif %}
{% if user.is_authenticated and user.registration.participates and not user.registration.team %} {% if user.is_authenticated and user.registration.participates and not user.registration.team %}
initModal("createTeam", "{% url 'participation:create_team' %}") $('a[data-target="#createTeamModal"]').click(function() {
initModal("joinTeam", "{% url 'participation:join_team' %}") let modalBody = $("#createTeamModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:create_team" %} #form-content");
});
$('a[data-target="#joinTeamModal"]').click(function() {
let modalBody = $("#joinTeamModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:join_team" %} #form-content");
});
{% endif %} {% endif %}
}) });
</script> </script>
{% block extrajavascript %}{% endblock %} {% block extrajavascript %}{% endblock %}

View File

@ -6,7 +6,9 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">{{ modal_title }}</h5> <h5 class="modal-title">{{ modal_title }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
<div class="modal-body">{{ modal_content }}</div> <div class="modal-body">{{ modal_content }}</div>
<div class="modal-footer"> <div class="modal-footer">
@ -14,7 +16,7 @@
{% if modal_button %} {% if modal_button %}
<button type="submit" class="btn btn-{{ modal_button_type|default:"primary" }}">{{ modal_button }}</button> <button type="submit" class="btn btn-{{ modal_button_type|default:"primary" }}">{{ modal_button }}</button>
{% endif %} {% endif %}
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">{% trans "Close" %}</button>
</div> </div>
</div> </div>
</form> </form>

View File

@ -1 +0,0 @@
{% block content %}{% endblock content %}

View File

@ -14,15 +14,14 @@
</p> </p>
</div> </div>
<div class="jumbotron bg-white p-5"> <div class="jumbotron bg-white">
<div class="row text-center"> <div class="row">
<h1 class="display-4"> <h1 class="display-3">
Bienvenue sur le site d'inscription au <a href="https://tfjm.org/" target="_blank">𝕋𝔽𝕁𝕄²</a> ! Bienvenue sur le site d'inscription au <a href="https://tfjm.org/" target="_blank">𝕋𝔽𝕁𝕄²</a> !
</h1> </h1>
</div> </div>
</div> </div>
<div class="row jumbotron bg-white">
<div class="row bg-white p-5">
<div class="col-sm"> <div class="col-sm">
<h3> <h3>
Tu souhaites participer au 𝕋𝔽𝕁𝕄² ? Tu souhaites participer au 𝕋𝔽𝕁𝕄² ?
@ -30,7 +29,7 @@
Ton équipe est déjà formée ? Ton équipe est déjà formée ?
</h3> </h3>
</div> </div>
<div class="col-sm text-end"> <div class="col-sm text-right">
<div class="btn-group-vertical"> <div class="btn-group-vertical">
<a class="btn btn-primary btn-lg" href="{% url "registration:signup" %}" role="button">Inscris-toi maintenant !</a> <a class="btn btn-primary btn-lg" href="{% url "registration:signup" %}" role="button">Inscris-toi maintenant !</a>
<a class="btn btn-light btn-lg" href="{% url "login" %}" role="button">J'ai déjà un compte</a> <a class="btn btn-light btn-lg" href="{% url "login" %}" role="button">J'ai déjà un compte</a>
@ -38,7 +37,7 @@
</div> </div>
</div> </div>
<div class="jumbotron p-5 border rounded-5 bg-light"> <div class="jumbotron">
<h5 class="display-4">Comment ça marche ?</h5> <h5 class="display-4">Comment ça marche ?</h5>
<p> <p>
Pour participer au 𝕋𝔽𝕁𝕄², il suffit de créer un compte sur la rubrique <strong><a href="{% url "registration:signup" %}">Inscription</a></strong>. Pour participer au 𝕋𝔽𝕁𝕄², il suffit de créer un compte sur la rubrique <strong><a href="{% url "registration:signup" %}">Inscription</a></strong>.

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends "base.html" %}
{% comment %} {% comment %}
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
{% endcomment %} {% endcomment %}

View File

@ -1,4 +1,4 @@
{% extends request.content_only|yesno:"empty.html,base.html" %} {% extends 'base.html' %}
{% load crispy_forms_filters highlight i18n search_results_tables django_tables2 %} {% load crispy_forms_filters highlight i18n search_results_tables django_tables2 %}

View File

@ -57,6 +57,8 @@ urlpatterns = [
name='solution'), name='solution'),
path('media/syntheses/<str:filename>/', SynthesisView.as_view(), path('media/syntheses/<str:filename>/', SynthesisView.as_view(),
name='synthesis'), name='synthesis'),
path('', include('eastereggs.urls')),
] ]
if 'cas_server' in settings.INSTALLED_APPS: # pragma: no cover if 'cas_server' in settings.INSTALLED_APPS: # pragma: no cover

View File

@ -11,7 +11,6 @@ skipsdist = True
sitepackages = False sitepackages = False
deps = deps =
coverage coverage
crispy-bootstrap5~=0.7
Django>=3.2,<4.0 Django>=3.2,<4.0
django-crispy-forms~=1.14 django-crispy-forms~=1.14
django-filter~=22.1 django-filter~=22.1