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

Compare commits

..

9 Commits

Author SHA1 Message Date
Emmy D'Anello
3efe5a2226
Linting 2023-02-20 21:14:16 +01:00
Emmy D'Anello
a2201e36fa
Add crispy-bootstrap5 as dependency 2023-02-20 21:14:15 +01:00
Emmy D'Anello
69b94c9493
Render only useful content when displaying modals 2023-02-20 21:14:15 +01:00
Emmy D'Anello
a8f24b6581
Use bootstrap-select selector when it is necessary 2023-02-20 21:14:15 +01:00
Emmy D'Anello
e156ed6111
Remove jquery dependency code (keep it for bootstrap-select) 2023-02-20 21:14:15 +01:00
Emmy D'Anello
ea00657405
Use Bootstrap 5 instead of Bootstrap 4 2023-02-20 21:14:15 +01:00
Emmy D'Anello
5abca36498
Drop turbolinks support, too useless 2023-02-20 21:14:15 +01:00
Emmy D'Anello
731dfc049f
Better select widget when searching organizers 2023-02-20 21:14:15 +01:00
Emmy D'Anello
4075f6cf78
Add vaccine sheet field, closes #18 2023-02-20 21:14:15 +01:00
55 changed files with 391 additions and 557 deletions

2
.gitignore vendored
View File

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

View File

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

View File

@ -1,8 +0,0 @@
# 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

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

View File

@ -1,19 +0,0 @@
{% 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

@ -1,20 +0,0 @@
{% 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>

View File

@ -1,11 +0,0 @@
# 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,7 +12,6 @@ from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator
from django.utils.translation import gettext_lazy as _
from pypdf import PdfFileReader
from registration.models import VolunteerRegistration
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
@ -120,29 +119,28 @@ class ValidateParticipationForm(forms.Form):
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:
model = Tournament
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):
@ -174,7 +172,11 @@ class PoolForm(forms.ModelForm):
model = Pool
fields = ('tournament', 'round', 'bbb_url', 'results_available', 'juries',)
widgets = {
"juries": forms.CheckboxSelectMultiple,
"juries": forms.SelectMultiple(attrs={
'class': 'selectpicker',
'data-live-search': 'true',
'data-live-search-normalize': 'true',
}),
}
@ -187,7 +189,12 @@ class PoolTeamsForm(forms.ModelForm):
model = Pool
fields = ('participations',)
widgets = {
"participations": forms.CheckboxSelectMultiple,
"participations": forms.SelectMultiple(attrs={
'class': 'selectpicker',
'data-live-search': 'true',
'data-live-search-normalize': 'true',
'data-width': 'fit',
}),
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,17 +29,3 @@
{{ admin_registration_form|crispy }}
</div>
{% 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 "base.html" %}
{% extends request.content_only|yesno:"empty.html,base.html" %}
{% load crispy_forms_filters i18n %}

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends request.content_only|yesno:"empty.html,base.html" %}
{% load i18n static crispy_forms_filters %}
@ -9,8 +9,8 @@
<div id="form-content">
<div class="alert alert-info">
{% 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 }}" 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 }}" data-turbolinks="false">{% trans "Child" %}</a>
<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_child_template" %}?registration_id={{ object.pk }}&tournament_id={{ object.team.participation.tournament.pk }}">{% trans "Child" %}</a>
</div>
{% csrf_token %}
{{ form|crispy }}

View File

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

View File

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

View File

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

View File

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

View File

@ -54,32 +54,14 @@ class SessionMiddleware(object):
return response
class TurbolinksMiddleware(object): # pragma: no cover
class FetchMiddleware(object):
"""
Send the `Turbolinks-Location` header in response to a visit that was redirected,
and Turbolinks will replace the browser's topmost history entry.
This middleware let requests to know when this was called by a fetch command or not.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = 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
request.content_only = 'CONTENT_ONLY' in request.headers
return self.get_response(request)

View File

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

2
tfjm/static/jquery/jquery.min.js vendored Normal file

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

View File

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

View File

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

View File

@ -14,14 +14,15 @@
</p>
</div>
<div class="jumbotron bg-white">
<div class="row">
<h1 class="display-3">
<div class="jumbotron bg-white p-5">
<div class="row text-center">
<h1 class="display-4">
Bienvenue sur le site d'inscription au <a href="https://tfjm.org/" target="_blank">𝕋𝔽𝕁𝕄²</a> !
</h1>
</div>
</div>
<div class="row jumbotron bg-white">
<div class="row bg-white p-5">
<div class="col-sm">
<h3>
Tu souhaites participer au 𝕋𝔽𝕁𝕄² ?
@ -29,7 +30,7 @@
Ton équipe est déjà formée ?
</h3>
</div>
<div class="col-sm text-right">
<div class="col-sm text-end">
<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-light btn-lg" href="{% url "login" %}" role="button">J'ai déjà un compte</a>
@ -37,7 +38,7 @@
</div>
</div>
<div class="jumbotron">
<div class="jumbotron p-5 border rounded-5 bg-light">
<h5 class="display-4">Comment ça marche ?</h5>
<p>
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 "base.html" %}
{% extends request.content_only|yesno:"empty.html,base.html" %}
{% comment %}
SPDX-License-Identifier: GPL-2.0-or-later
{% endcomment %}

View File

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

View File

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

View File

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