mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-02-25 15:06:31 +00:00
Compare commits
14 Commits
21ff044044
...
ece128836a
Author | SHA1 | Date | |
---|---|---|---|
|
ece128836a | ||
|
2e574d0659 | ||
|
850659bf48 | ||
|
672529382d | ||
|
c1ce7cb70f | ||
|
bc67d1cf1f | ||
|
652e913f49 | ||
|
089374b937 | ||
|
226e5620f9 | ||
|
ca9652cc60 | ||
|
acd1d80c75 | ||
|
e7c207d2af | ||
|
196ccb69ad | ||
|
2b941cb30f |
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@ from django.utils import timezone
|
|||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.text import format_lazy
|
from django.utils.text import format_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from registration.models import VolunteerRegistration
|
from registration.models import VolunteerRegistration, Payment
|
||||||
from tfjm.lists import get_sympa_client
|
from tfjm.lists import get_sympa_client
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +66,140 @@ class Team(models.Model):
|
|||||||
def coaches(self):
|
def coaches(self):
|
||||||
return self.participants.filter(coachregistration__isnull=False)
|
return self.participants.filter(coachregistration__isnull=False)
|
||||||
|
|
||||||
|
def can_validate(self):
|
||||||
|
if any(not r.email_confirmed for r in self.participants.all()):
|
||||||
|
return False
|
||||||
|
if self.students.count() < 4:
|
||||||
|
return False
|
||||||
|
if not self.coaches.exists():
|
||||||
|
return False
|
||||||
|
if not self.participation.tournament:
|
||||||
|
return False
|
||||||
|
if any(not r.photo_authorization for r in self.participants.all()):
|
||||||
|
return False
|
||||||
|
if not self.motivation_letter:
|
||||||
|
return False
|
||||||
|
if not self.participation.tournament.remote:
|
||||||
|
if any(r.under_18 and not r.health_sheet for r in self.students.all()):
|
||||||
|
return False
|
||||||
|
if any(r.under_18 and not r.vaccine_sheet for r in self.students.all()):
|
||||||
|
return False
|
||||||
|
if any(r.under_18 and not r.parental_authorization for r in self.students.all()):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def important_informations(self):
|
||||||
|
informations = []
|
||||||
|
|
||||||
|
if self.participation.valid is None:
|
||||||
|
if not self.participation.tournament:
|
||||||
|
text = _("The team {trigram} is not registered to any tournament. "
|
||||||
|
"You can register the team to a tournament using <a href='{url}'>this link</a>.")
|
||||||
|
url = reverse_lazy("participation:update_team", args=(self.pk,))
|
||||||
|
content = format_lazy(text, trigram=self.trigram, url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("No tournament"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 4,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
text = _("Registrations for the tournament of {tournament} are ending on the {date:%Y-%m-%d %H:%M}.")
|
||||||
|
content = format_lazy(text,
|
||||||
|
tournament=self.participation.tournament.name,
|
||||||
|
date=self.participation.tournament.inscription_limit)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Registrations closure"),
|
||||||
|
'type': "info",
|
||||||
|
'priority': 1,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
if not self.motivation_letter:
|
||||||
|
text = _("The team {trigram} has not uploaded a motivation letter. "
|
||||||
|
"You can upload your motivation letter using <a href='{url}'>this link</a>.")
|
||||||
|
url = reverse_lazy("participation:upload_team_motivation_letter", args=(self.pk,))
|
||||||
|
content = format_lazy(text, trigram=self.trigram, url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("No motivation letter"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 10,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
nb_students = self.students.count()
|
||||||
|
nb_coaches = self.coaches.count()
|
||||||
|
if nb_students < 4:
|
||||||
|
text = _("The team {trigram} has less than 4 students ({nb_students}). "
|
||||||
|
"You can invite more students to join the team using "
|
||||||
|
"the invite code <strong>{code}</strong>.")
|
||||||
|
content = format_lazy(text, trigram=self.trigram, nb_students=nb_students, code=self.access_code)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Not enough students"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 7,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
if not nb_coaches:
|
||||||
|
text = _("The team {trigram} has no coach. "
|
||||||
|
"You can invite a coach to join the team using the invite code <strong>{code}</strong>.")
|
||||||
|
content = format_lazy(text, trigram=self.trigram, nb_students=nb_students, code=self.access_code)
|
||||||
|
informations.append({
|
||||||
|
'title': _("No coach"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 8,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
if nb_students > 6 or nb_coaches > 2:
|
||||||
|
text = _("The team {trigram} has more than 6 students ({nb_students}) "
|
||||||
|
"or more than 2 coaches ({nb_coaches})."
|
||||||
|
"You have to restrict the number of students and coaches to 6 and 2, respectively.")
|
||||||
|
content = format_lazy(text, trigram=self.trigram, nb_students=nb_students, nb_coaches=nb_coaches)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Too many members"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 7,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
elif nb_students >= 4 and nb_coaches >= 1:
|
||||||
|
if self.can_validate():
|
||||||
|
text = _("The team {trigram} is ready to be validated. "
|
||||||
|
"You can request validation on <a href='{url}'>the page of your team</a>.")
|
||||||
|
url = reverse_lazy("participation:team_detail", args=(self.pk,))
|
||||||
|
content = format_lazy(text, trigram=self.trigram, url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Validate team"),
|
||||||
|
'type': "success",
|
||||||
|
'priority': 2,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
text = _("The team {trigram} has enough participants, but is not ready to be validated. "
|
||||||
|
"Please make sure that all the participants have uploaded the required documents. "
|
||||||
|
"To invite more participants, use the invite code <strong>{code}</strong>.")
|
||||||
|
content = format_lazy(text, trigram=self.trigram, code=self.access_code)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Validate team"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 10,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
elif self.participation.valid is False:
|
||||||
|
text = _("The team {trigram} has not been validated by the organizers yet. Please be patient.")
|
||||||
|
content = format_lazy(text, trigram=self.trigram)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Pending validation"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 2,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
informations.extend(self.participation.important_informations())
|
||||||
|
|
||||||
|
return informations
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def email(self):
|
def email(self):
|
||||||
"""
|
"""
|
||||||
@ -328,6 +462,42 @@ class Participation(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("Participation of the team {name} ({trigram})").format(name=self.team.name, trigram=self.team.trigram)
|
return _("Participation of the team {name} ({trigram})").format(name=self.team.name, trigram=self.team.trigram)
|
||||||
|
|
||||||
|
def important_informations(self):
|
||||||
|
informations = []
|
||||||
|
|
||||||
|
missing_payments = Payment.objects.filter(registration__in=self.team.participants.all(), valid=False)
|
||||||
|
if missing_payments.exists():
|
||||||
|
text = _("<p>The team {trigram} has {nb_missing_payments} missing payments. Each member of the team "
|
||||||
|
"must have a valid payment (or send a scholarship notification) "
|
||||||
|
"to participate to the tournament.</p>"
|
||||||
|
"<p>Participants that have not paid yet are: {participants}.</p>")
|
||||||
|
content = format_lazy(text, trigram=self.team.trigram, nb_missing_payments=missing_payments.count(),
|
||||||
|
participants=", ".join(str(p.registration) for p in missing_payments.all()))
|
||||||
|
informations.append({
|
||||||
|
'title': _("Missing payments"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 10,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
if timezone.now() <= self.tournament.solution_limit:
|
||||||
|
text = _("<p>The solutions for the tournament of {tournament} are due on the {date:%Y-%m-%d %H:%M}.</p>"
|
||||||
|
"<p>You have currently sent <strong>{nb_solutions}</strong> solutions. "
|
||||||
|
"We suggest to send at least <strong>{min_solutions}</strong> different solutions.</p>"
|
||||||
|
"<p>You can upload your solutions on <a href='{url}'>your participation page</a>.</p>")
|
||||||
|
url = reverse_lazy("participation:participation_detail", args=(self.pk,))
|
||||||
|
content = format_lazy(text, tournament=self.tournament.name, date=self.tournament.solution_limit,
|
||||||
|
nb_solutions=self.solutions.count(), min_solutions=len(settings.PROBLEMS) - 3,
|
||||||
|
url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Solutions due"),
|
||||||
|
'type': "info",
|
||||||
|
'priority': 1,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
return informations
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("participation")
|
verbose_name = _("participation")
|
||||||
verbose_name_plural = _("participations")
|
verbose_name_plural = _("participations")
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% load django_tables2 i18n %}
|
{% load django_tables2 i18n %}
|
||||||
|
|
||||||
{% block contenttitle %}
|
{% block content-title %}
|
||||||
<h1>{% trans "All teams" %}</h1>
|
<h1>{% trans "All teams" %}</h1>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% load django_tables2 i18n %}
|
{% load django_tables2 i18n %}
|
||||||
|
|
||||||
{% block contenttitle %}
|
{% block content-title %}
|
||||||
<h1>{% trans "All tournaments" %}</h1>
|
<h1>{% trans "All tournaments" %}</h1>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -438,6 +438,7 @@ class TestStudentParticipation(TestCase):
|
|||||||
self.user.registration.save()
|
self.user.registration.save()
|
||||||
|
|
||||||
# Team is valid
|
# Team is valid
|
||||||
|
self.team.participation.tournament = self.tournament
|
||||||
self.team.participation.valid = True
|
self.team.participation.valid = True
|
||||||
self.team.participation.save()
|
self.team.participation.save()
|
||||||
response = self.client.post(reverse("participation:team_leave"))
|
response = self.client.post(reverse("participation:team_leave"))
|
||||||
@ -479,6 +480,7 @@ class TestStudentParticipation(TestCase):
|
|||||||
reverse("participation:participation_detail", args=(self.team.participation.pk,)),
|
reverse("participation:participation_detail", args=(self.team.participation.pk,)),
|
||||||
302, 403)
|
302, 403)
|
||||||
|
|
||||||
|
self.team.participation.tournament = self.tournament
|
||||||
self.team.participation.valid = True
|
self.team.participation.valid = True
|
||||||
self.team.participation.save()
|
self.team.participation.save()
|
||||||
response = self.client.get(reverse("participation:my_participation_detail"))
|
response = self.client.get(reverse("participation:my_participation_detail"))
|
||||||
|
@ -90,7 +90,7 @@ class JoinTeamView(LoginRequiredMixin, FormView):
|
|||||||
model = Team
|
model = Team
|
||||||
form_class = JoinTeamForm
|
form_class = JoinTeamForm
|
||||||
extra_context = dict(title=_("Join team"))
|
extra_context = dict(title=_("Join team"))
|
||||||
template_name = "participation/create_team.html"
|
template_name = "participation/join_team.html"
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
user = request.user
|
user = request.user
|
||||||
@ -180,15 +180,7 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
|
|||||||
context["validation_form"] = ValidateParticipationForm(self.request.POST or None)
|
context["validation_form"] = ValidateParticipationForm(self.request.POST or None)
|
||||||
# A team is complete when there are at least 4 members plus a coache that have sent their authorizations,
|
# A team is complete when there are at least 4 members plus a coache that have sent their authorizations,
|
||||||
# their health sheet, they confirmed their email address and under-18 people sent their parental authorization.
|
# their health sheet, they confirmed their email address and under-18 people sent their parental authorization.
|
||||||
# TODO: Add vaccine sheets
|
context["can_validate"] = team.can_validate()
|
||||||
context["can_validate"] = team.students.count() >= 4 and team.coaches.exists() and \
|
|
||||||
team.participation.tournament and \
|
|
||||||
all(r.photo_authorization for r in team.participants.all()) and \
|
|
||||||
(team.participation.tournament.remote
|
|
||||||
or all(r.health_sheet for r in team.students.all() if r.under_18)) and \
|
|
||||||
(team.participation.tournament.remote
|
|
||||||
or all(r.parental_authorization for r in team.students.all() if r.under_18)) and \
|
|
||||||
team.motivation_letter
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -228,6 +228,7 @@ class PaymentForm(forms.ModelForm):
|
|||||||
self.fields["valid"].widget.choices[0] = ('unknown', _("Pending"))
|
self.fields["valid"].widget.choices[0] = ('unknown', _("Pending"))
|
||||||
|
|
||||||
def clean_scholarship_file(self):
|
def clean_scholarship_file(self):
|
||||||
|
print(self.files)
|
||||||
if "scholarship_file" in self.files:
|
if "scholarship_file" in self.files:
|
||||||
file = self.files["scholarship_file"]
|
file = self.files["scholarship_file"]
|
||||||
if file.size > 2e6:
|
if file.size > 2e6:
|
||||||
@ -240,7 +241,7 @@ class PaymentForm(forms.ModelForm):
|
|||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
|
|
||||||
if "type" in cleaned_data and cleaned_data["type"] == "scholarship" \
|
if "type" in cleaned_data and cleaned_data["type"] == "scholarship" \
|
||||||
and "scholarship_file" not in cleaned_data and not self.instance.scholarship_file:
|
and "scholarship_file" not in self.files and not self.instance.scholarship_file:
|
||||||
self.add_error("scholarship_file", _("You must upload your scholarship attestation."))
|
self.add_error("scholarship_file", _("You must upload your scholarship attestation."))
|
||||||
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
@ -12,6 +12,7 @@ from django.utils import timezone
|
|||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.http import urlsafe_base64_encode
|
from django.utils.http import urlsafe_base64_encode
|
||||||
|
from django.utils.text import format_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
from polymorphic.models import PolymorphicModel
|
from polymorphic.models import PolymorphicModel
|
||||||
@ -88,6 +89,28 @@ class Registration(PolymorphicModel):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("registration:user_detail", args=(self.user_id,))
|
return reverse_lazy("registration:user_detail", args=(self.user_id,))
|
||||||
|
|
||||||
|
def registration_informations(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def important_informations(self):
|
||||||
|
informations = []
|
||||||
|
if not self.email_confirmed:
|
||||||
|
text = _("Your email address is not validated. Please click on the link you received by email. "
|
||||||
|
"You can resend a mail by clicking on <a href=\"{send_email_url}\">this link</a>.")
|
||||||
|
send_email_url = reverse_lazy("registration:email_validation_resend", args=(self.user_id,))
|
||||||
|
content = format_lazy(text, send_email_url=send_email_url)
|
||||||
|
informations.append({
|
||||||
|
'title': "Validation e-mail",
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 0,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
informations.extend(self.registration_informations())
|
||||||
|
|
||||||
|
informations.sort(key=lambda info: (info['priority'], info['title']))
|
||||||
|
return informations
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.user.first_name} {self.user.last_name}"
|
return f"{self.user.first_name} {self.user.last_name}"
|
||||||
|
|
||||||
@ -196,6 +219,38 @@ class ParticipantRegistration(Registration):
|
|||||||
def form_class(self): # pragma: no cover
|
def form_class(self): # pragma: no cover
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def registration_informations(self):
|
||||||
|
informations = []
|
||||||
|
if not self.team:
|
||||||
|
text = _("You are not in a team. You can <a href=\"{create_url}\">create one</a> "
|
||||||
|
"or <a href=\"{join_url}\">join an existing one</a> to participate.")
|
||||||
|
create_url = reverse_lazy("participation:create_team")
|
||||||
|
join_url = reverse_lazy("participation:join_team")
|
||||||
|
content = format_lazy(text, create_url=create_url, join_url=join_url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("No team"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 1,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
if self.team.participation.tournament:
|
||||||
|
if not self.photo_authorization:
|
||||||
|
text = _("You have not uploaded your photo authorization. "
|
||||||
|
"You can do it by clicking on <a href=\"{photo_url}\">this link</a>.")
|
||||||
|
photo_url = reverse_lazy("registration:upload_user_photo_authorization", args=(self.id,))
|
||||||
|
content = format_lazy(text, photo_url=photo_url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Photo authorization"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 5,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
informations.extend(self.team.important_informations())
|
||||||
|
|
||||||
|
return informations
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("participant registration")
|
verbose_name = _("participant registration")
|
||||||
verbose_name_plural = _("participant registrations")
|
verbose_name_plural = _("participant registrations")
|
||||||
@ -271,6 +326,68 @@ class StudentRegistration(ParticipantRegistration):
|
|||||||
from registration.forms import StudentRegistrationForm
|
from registration.forms import StudentRegistrationForm
|
||||||
return StudentRegistrationForm
|
return StudentRegistrationForm
|
||||||
|
|
||||||
|
def registration_informations(self):
|
||||||
|
informations = super().registration_informations()
|
||||||
|
if self.team and self.team.participation.tournament and self.under_18:
|
||||||
|
if not self.parental_authorization:
|
||||||
|
text = _("You have not uploaded your parental authorization. "
|
||||||
|
"You can do it by clicking on <a href=\"{parental_url}\">this link</a>.")
|
||||||
|
parental_url = reverse_lazy("registration:upload_user_parental_authorization", args=(self.id,))
|
||||||
|
content = format_lazy(text, parental_url=parental_url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Parental authorization"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 5,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
if not self.health_sheet:
|
||||||
|
text = _("You have not uploaded your health sheet. "
|
||||||
|
"You can do it by clicking on <a href=\"{health_url}\">this link</a>.")
|
||||||
|
health_url = reverse_lazy("registration:upload_user_health_sheet", args=(self.id,))
|
||||||
|
content = format_lazy(text, health_url=health_url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Health sheet"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 5,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
if not self.vaccine_sheet:
|
||||||
|
text = _("You have not uploaded your vaccine sheet. "
|
||||||
|
"You can do it by clicking on <a href=\"{vaccine_url}\">this link</a>.")
|
||||||
|
vaccine_url = reverse_lazy("registration:upload_user_vaccine_sheet", args=(self.id,))
|
||||||
|
content = format_lazy(text, vaccine_url=vaccine_url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Vaccine sheet"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 5,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
if self.team and self.team.participation.valid:
|
||||||
|
if self.payment.valid is False:
|
||||||
|
text = _("You have to pay {amount} € for your registration, or send a scholarship "
|
||||||
|
"notification or a payment proof. "
|
||||||
|
"You can do it on <a href=\"{url}\">the payment page</a>.")
|
||||||
|
url = reverse_lazy("registration:update_payment", args=(self.payment.id,))
|
||||||
|
content = format_lazy(text, amount=self.team.participation.tournament.price, url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Payment"),
|
||||||
|
'type': "danger",
|
||||||
|
'priority': 3,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
elif self.payment.valid is None:
|
||||||
|
text = _("Your payment is under approval.")
|
||||||
|
content = text
|
||||||
|
informations.append({
|
||||||
|
'title': _("Payment"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 3,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
return informations
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("student registration")
|
verbose_name = _("student registration")
|
||||||
verbose_name_plural = _("student registrations")
|
verbose_name_plural = _("student registrations")
|
||||||
@ -334,6 +451,41 @@ class VolunteerRegistration(Registration):
|
|||||||
from registration.forms import VolunteerRegistrationForm
|
from registration.forms import VolunteerRegistrationForm
|
||||||
return VolunteerRegistrationForm
|
return VolunteerRegistrationForm
|
||||||
|
|
||||||
|
def important_informations(self):
|
||||||
|
informations = []
|
||||||
|
|
||||||
|
for tournament in self.organized_tournaments.all():
|
||||||
|
if timezone.now() < tournament.inscription_limit \
|
||||||
|
or tournament.participations.filter(valid=True).count() < tournament.max_teams:
|
||||||
|
text = _("Registrations for tournament {tournament} are closing on {date:%Y-%m-%d %H:%M}. "
|
||||||
|
"There are for now {validated_teams} validated teams (+ {pending_teams} pending) "
|
||||||
|
"on {max_teams} expected.")
|
||||||
|
content = format_lazy(text, tournament=tournament.name, date=tournament.inscription_limit,
|
||||||
|
validated_teams=tournament.participations.filter(valid=True).count(),
|
||||||
|
pending_teams=tournament.participations.filter(valid=False).count(),
|
||||||
|
max_teams=tournament.max_teams)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Registrations"),
|
||||||
|
'type': "info",
|
||||||
|
'priority': 2,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
for pending_participation in tournament.participations.filter(valid=False).all():
|
||||||
|
text = _("The team {trigram} requested to be validated for the tournament of {tournament}. "
|
||||||
|
"You can check the status of the team on the <a href=\"{url}\">team page</a>.")
|
||||||
|
url = reverse_lazy("participation:team_detail", args=(pending_participation.team.id,))
|
||||||
|
content = format_lazy(text, trigram=pending_participation.team.trigram,
|
||||||
|
tournament=tournament.name, url=url)
|
||||||
|
informations.append({
|
||||||
|
'title': _("Pending validation"),
|
||||||
|
'type': "warning",
|
||||||
|
'priority': 4,
|
||||||
|
'content': content,
|
||||||
|
})
|
||||||
|
|
||||||
|
return informations
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("volunteer registration")
|
verbose_name = _("volunteer registration")
|
||||||
verbose_name_plural = _("volunteer registrations")
|
verbose_name_plural = _("volunteer registrations")
|
||||||
|
@ -3,50 +3,8 @@
|
|||||||
{% load crispy_forms_filters i18n %}
|
{% load crispy_forms_filters i18n %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="post" enctype="multipart/form-data">
|
<div class="alert alert-warning">
|
||||||
<div id="form-content">
|
Le formulaire de paiement est temporairement désactivé. Il sera accessible d'ici quelques jours.
|
||||||
<div class="alert alert-info text-justify">
|
|
||||||
<p>
|
|
||||||
{% blocktrans trimmed with price=payment.registration.team.participation.tournament.price %}
|
|
||||||
The price of the tournament is {{ price }} €. The participation fee is offered for coaches
|
|
||||||
and for students who have a scholarship. If so, please send us your scholarship attestation.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
{% blocktrans trimmed %}
|
|
||||||
You can pay with a credit card through
|
|
||||||
<a class="alert-link" href="https://www.helloasso.com/associations/animath/evenements/tfjm-2023-tournois-regionaux">our Hello Asso page</a>.
|
|
||||||
To make the validation of the payment easier, <span class="text-danger">please use the same e-mail
|
|
||||||
address that you use on this platform.</span> The payment verification will be checked automatically
|
|
||||||
under 10 minutes, you don't necessary need to fill this form.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
{% blocktrans trimmed %}
|
|
||||||
You can also send a bank transfer to the bank account of Animath. You must put in the reference of the
|
|
||||||
transfer the mention "TFJMpu" followed by the last name and the first name of the student.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
IBAN : FR76 1027 8065 0000 0206 4290 127<br>
|
|
||||||
BIC : CMCIFR2A
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
{% blocktrans trimmed %}
|
|
||||||
If any payment mean is available to you, please contact us at <a class="alert-link" href="mailto:contact@tfjm.org">contact@tfjm.org</a>
|
|
||||||
to find a solution to your difficulties.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form|crispy }}
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" type="submit">{% trans "Update" %}</button>
|
|
||||||
</form>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
@ -263,6 +263,7 @@ class UserUpdateView(UserMixin, UpdateView):
|
|||||||
Update the detail about a user and its registration.
|
Update the detail about a user and its registration.
|
||||||
"""
|
"""
|
||||||
model = User
|
model = User
|
||||||
|
context_object_name = "user_object"
|
||||||
form_class = UserForm
|
form_class = UserForm
|
||||||
template_name = "registration/update_user.html"
|
template_name = "registration/update_user.html"
|
||||||
|
|
||||||
@ -455,13 +456,17 @@ class PaymentUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
if not self.request.user.registration.is_admin:
|
if not self.request.user.registration.is_admin:
|
||||||
del form.fields["type"].widget.choices[-1]
|
form.fields["type"].widget.choices = list(form.fields["type"].widget.choices)[:-1]
|
||||||
del form.fields["valid"]
|
del form.fields["valid"]
|
||||||
return form
|
return form
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
if not self.request.user.registration.is_admin:
|
if not self.request.user.registration.is_admin:
|
||||||
form.instance.valid = None
|
form.instance.valid = None
|
||||||
|
old_instance = Payment.objects.get(pk=self.object.pk)
|
||||||
|
if old_instance.scholarship_file:
|
||||||
|
old_instance.scholarship_file.delete()
|
||||||
|
old_instance.save()
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block contenttitle %}
|
{% block content-title %}
|
||||||
<h1>À propos</h1>
|
<h1>À propos</h1>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
{% load static i18n static %}
|
{% load i18n static %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
|
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
|
||||||
<html lang="{{ LANGUAGE_CODE|default:"en" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %} class="position-relative h-100">
|
<html lang="{{ LANGUAGE_CODE|default:"fr" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %} class="position-relative h-100">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>
|
<title>
|
||||||
{% block title %}{{ title }}{% endblock title %} - Plateforme du TFJM²
|
{% block title %}{{ title }}{% endblock title %} - Plateforme du TFJM²
|
||||||
</title>
|
</title>
|
||||||
<meta name="description" content="Plateform d'inscription au TFJM².">
|
<meta name="description" content="Plateforme d'inscription au TFJM².">
|
||||||
|
|
||||||
{# Favicon #}
|
{# Favicon #}
|
||||||
<link rel="shortcut icon" href="{% static "favicon.ico" %}">
|
<link rel="shortcut icon" href="{% static "favicon.ico" %}">
|
||||||
@ -25,7 +25,7 @@
|
|||||||
{# Bootstrap JavaScript #}
|
{# Bootstrap JavaScript #}
|
||||||
<script src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
<script src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
||||||
|
|
||||||
{# bootstrap-select for beautyful selects and JQuery dependency #}
|
{# bootstrap-select for beautiful selects and JQuery dependency #}
|
||||||
<script src="{% static 'jquery/jquery.min.js' %}"></script>
|
<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/bootstrap-select.min.js' %}"></script>
|
||||||
<script src="{% static 'bootstrap-select/js/defaults-fr_FR.min.js' %}"></script>
|
<script src="{% static 'bootstrap-select/js/defaults-fr_FR.min.js' %}"></script>
|
||||||
@ -38,206 +38,31 @@
|
|||||||
{% 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 fixed-navbar shadow-sm">
|
{% include "navbar.html" %}
|
||||||
<div class="container-fluid">
|
|
||||||
<a class="navbar-brand" href="https://tfjm.org/">
|
<div id="body-wrapper" class="row w-100 my-3">
|
||||||
<img src="{% static "tfjm.svg" %}" style="height: 2em;" alt="Logo TFJM²" id="navbar-logo">
|
<aside class="col-lg-2 px-2">
|
||||||
</a>
|
{% include "sidebar.html" %}
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
</aside>
|
||||||
data-bs-target="#navbarNavDropdown"
|
|
||||||
aria-controls="navbarNavDropdown" aria-expanded="false"
|
<main class="col d-flex flex-column">
|
||||||
aria-label="Toggle navigation">
|
<div class="container">
|
||||||
<span class="navbar-toggler-icon"></span>
|
{% block content-title %}<h1 id="content-title">{{ title }}</h1>{% endblock %}
|
||||||
</button>
|
|
||||||
<div id="navbarNavDropdown" class="collapse navbar-collapse">
|
{% include "messages.html" %}
|
||||||
<ul class="navbar-nav">
|
|
||||||
<li class="nav-item active">
|
|
||||||
<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-bs-toggle="modal" data-bs-target="#tournamentListModal">
|
|
||||||
<i class="fas fa-calendar-day"></i> {% trans "Tournaments" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% if user.is_authenticated and user.registration.is_volunteer %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<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-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-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-bs-toggle="modal" data-bs-target="#joinTeamModal">
|
|
||||||
<i class="fas fa-users"></i> {% trans "Join team" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a href="{% url "participation:my_team_detail" %}" class="nav-link">
|
|
||||||
<i class="fas fa-users"></i> {% trans "My team" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a href="{% url "participation:my_participation_detail" %}" class="nav-link">
|
|
||||||
<i class="fas fa-file-pdf"></i> {% trans "My participation" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
{% if user.registration.is_volunteer or user.registration.team %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="{% url 'draw:index' %}">
|
|
||||||
<i class="fas fa-archive"></i> {% trans "Draw" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<li class="nav-item active d-none">
|
|
||||||
<a class="nav-link" href="{% url "participation:chat" %}">
|
|
||||||
<i class="fas fa-comments"></i> {% trans "Chat" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% if user.registration.is_admin %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="{% url "admin:index" %}"><i class="fas fa-cog"></i> {% trans "Administration" %}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
<ul class="navbar-nav ms-auto">
|
|
||||||
{% if user.registration.is_admin %}
|
|
||||||
<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 }}">
|
|
||||||
<div class="input-group-btn">
|
|
||||||
<button class="btn btn-default" data-bs-toggle="modal" data-bs-target="#searchModal"><i class="fa fa-search text-body"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% if "_fake_user_id" in request.session %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="{% url "registration:reset_admin" %}?path={{ request.path }}"><i class="fas fa-tools"></i> {% trans "Return to admin view" %}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if not user.is_authenticated %}
|
|
||||||
<li class="nav-item active">
|
|
||||||
<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-bs-toggle="modal" data-bs-target="#loginModal">
|
|
||||||
<i class="fas fa-sign-in-alt"></i> {% trans "Log in" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink"
|
|
||||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<i class="fas fa-user"></i> {{ user.first_name }} {{ user.last_name }}
|
|
||||||
</a>
|
|
||||||
<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 %}<h1>{{ title }}</h1>{% endblock %}
|
|
||||||
{% if user.is_authenticated and not user.registration.email_confirmed %}
|
|
||||||
<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.
|
|
||||||
You can resend a mail by clicking on <a href="{{ send_email_url }}">this link</a>.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div id="messages">
|
|
||||||
{% for message in messages %}
|
|
||||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
||||||
{{ message | safe }}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>Default content...</p>
|
<p>Default content...</p>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
</main>
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer class="text-primary mt-auto py-2">
|
<aside class="col-lg-2"></aside>
|
||||||
<div class="container-fluid">
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-1">
|
|
||||||
<span class="text-muted mr-1">
|
|
||||||
<a target="_blank" href="mailto:contact@tfjm.org"
|
|
||||||
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">
|
|
||||||
{% csrf_token %}
|
|
||||||
<select title="language" name="language"
|
|
||||||
class="form-control form-control-sm language"
|
|
||||||
onchange="this.form.submit()">
|
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
|
||||||
{% get_available_languages as LANGUAGES %}
|
|
||||||
{% for lang_code, lang_name in LANGUAGES %}
|
|
||||||
<option value="{{ lang_code }}"
|
|
||||||
{% if lang_code == LANGUAGE_CODE %}
|
|
||||||
selected{% endif %}>
|
|
||||||
{{ lang_name }} ({{ lang_code }})
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
<noscript>
|
|
||||||
<input type="submit">
|
|
||||||
</noscript>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
|
|
||||||
<a target="_blank" class="text-muted" href="{% url "about" %}">{% trans "About" %}</a> —
|
{% include "footer.html" %}
|
||||||
<a target="_blank" class="text-muted"
|
|
||||||
href="https://gitlab.com/animath/si/plateforme-tfjm">
|
|
||||||
<i class="fab fa-gitlab"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-1 text-end">
|
|
||||||
<a href="#" class="text-muted">
|
|
||||||
<i class="fa fa-arrow-up" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
{% trans "All tournaments" as modal_title %}
|
{% trans "All tournaments" as modal_title %}
|
||||||
{% include "base_modal.html" with modal_id="tournamentList" modal_additional_class="modal-lg" %}
|
{% include "base_modal.html" with modal_id="tournamentList" modal_additional_class="modal-lg" %}
|
||||||
|
51
tfjm/templates/footer.html
Normal file
51
tfjm/templates/footer.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{% load i18n static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
|
||||||
|
|
||||||
|
<footer class="text-primary mt-lg-auto">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2 col-lg-1">
|
||||||
|
<span class="text-muted mr-1">
|
||||||
|
<a target="_blank" href="mailto:contact@tfjm.org"
|
||||||
|
class="text-muted"><i class="fas fa-envelope"></i> {% trans "Contact us" %}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 col-lg-1">
|
||||||
|
<form action="{% url 'set_language' %}" method="post"
|
||||||
|
class="form-inline">
|
||||||
|
{% csrf_token %}
|
||||||
|
<select title="language" name="language"
|
||||||
|
class="form-control form-control-sm language"
|
||||||
|
onchange="this.form.submit()">
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
{% get_available_languages as LANGUAGES %}
|
||||||
|
{% for lang_code, lang_name in LANGUAGES %}
|
||||||
|
<option value="{{ lang_code }}"
|
||||||
|
{% if lang_code == LANGUAGE_CODE %}
|
||||||
|
selected{% endif %}>
|
||||||
|
{{ lang_name }} ({{ lang_code }})
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<noscript>
|
||||||
|
<input type="submit">
|
||||||
|
</noscript>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-7 col-lg-9">
|
||||||
|
|
||||||
|
<a target="_blank" class="text-muted" href="{% url "about" %}">{% trans "About" %}</a> —
|
||||||
|
<a target="_blank" class="text-muted" href="/doc/">Documentation</a> —
|
||||||
|
<a target="_blank" class="text-muted"
|
||||||
|
href="https://gitlab.com/animath/si/plateforme-tfjm">
|
||||||
|
<i class="fab fa-gitlab"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 text-end">
|
||||||
|
<a href="#" class="text-muted">
|
||||||
|
<i class="fa fa-arrow-up" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
@ -1,24 +1,6 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
|
||||||
|
|
||||||
<div class="alert alert-success">
|
|
||||||
<p>
|
|
||||||
Les inscriptions pour la session 2024 sont à présent ouvertes, vous pouvez créer votre compte.
|
|
||||||
Prenez garde toutefois aux dates indiquées qui sont pour l'instant provisoires.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Une documentation plus complète est disponible à l'adresse
|
|
||||||
<a href="https://inscription.tfjm.org/doc/">https://inscription.tfjm.org/doc/</a>
|
|
||||||
et sera progressivement actualisée.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
Diverses améliorations fonctionnelles pourront être apportées au site au cours des prochaines semaines.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jumbotron p-5">
|
<div class="jumbotron p-5">
|
||||||
<div class="row text-center">
|
<div class="row text-center">
|
||||||
<h1 class="display-4">
|
<h1 class="display-4">
|
||||||
@ -69,8 +51,13 @@
|
|||||||
<h2>J'ai une question</h2>
|
<h2>J'ai une question</h2>
|
||||||
|
|
||||||
<p class="text-justify">
|
<p class="text-justify">
|
||||||
Pour toute question, vous pouvez soit la poser dans <code>#faq</code> dans l'onglet chat comme indiqué ci-dessus, soit nous
|
N'hésitez pas à consulter la <a href="/doc/" target="_blank">documentation</a> du site, pour vérifier si
|
||||||
contacter par mail à l'adresse <a href="mailto:contact@tfjm.org">contact@tfjm.org</a>.
|
la réponse ne s'y trouve pas déjà. Référez-vous également bien sûr au
|
||||||
|
<a href="https://tfjm.org/reglement/" target="_blank">règlement du 𝕋𝔽𝕁𝕄²</a>.
|
||||||
|
Pour toute autre question, n'hésitez pas à nous contacter par mail à l'adresse
|
||||||
|
<a href="mailto:contact@tfjm.org">
|
||||||
|
contact@tfjm.org
|
||||||
|
</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
@ -78,6 +65,4 @@
|
|||||||
ne pourrez malheureusement pas participer au 𝕋𝔽𝕁𝕄².
|
ne pourrez malheureusement pas participer au 𝕋𝔽𝕁𝕄².
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
8
tfjm/templates/messages.html
Normal file
8
tfjm/templates/messages.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div id="messages">
|
||||||
|
{% for message in messages %}
|
||||||
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
{{ message | safe }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
124
tfjm/templates/navbar.html
Normal file
124
tfjm/templates/navbar.html
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{% load i18n static %}
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand-lg fixed-navbar shadow-sm">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="https://tfjm.org/">
|
||||||
|
<img src="{% static "tfjm.svg" %}" style="height: 2em;" alt="Logo TFJM²" id="navbar-logo">
|
||||||
|
</a>
|
||||||
|
<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>
|
||||||
|
</button>
|
||||||
|
<div id="navbarNavDropdown" class="collapse navbar-collapse">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item active">
|
||||||
|
<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-bs-toggle="modal" data-bs-target="#tournamentListModal">
|
||||||
|
<i class="fas fa-calendar-day"></i> {% trans "Tournaments" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% if user.is_authenticated and user.registration.is_volunteer %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<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-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-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-bs-toggle="modal" data-bs-target="#joinTeamModal">
|
||||||
|
<i class="fas fa-users"></i> {% trans "Join team" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a href="{% url "participation:my_team_detail" %}" class="nav-link">
|
||||||
|
<i class="fas fa-users"></i> {% trans "My team" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a href="{% url "participation:my_participation_detail" %}" class="nav-link">
|
||||||
|
<i class="fas fa-file-pdf"></i> {% trans "My participation" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
{% if user.registration.is_volunteer or user.registration.team %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="{% url 'draw:index' %}">
|
||||||
|
<i class="fas fa-archive"></i> {% trans "Draw" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<li class="nav-item active d-none">
|
||||||
|
<a class="nav-link" href="{% url "participation:chat" %}">
|
||||||
|
<i class="fas fa-comments"></i> {% trans "Chat" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% if user.registration.is_admin %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="{% url "admin:index" %}"><i class="fas fa-cog"></i> {% trans "Administration" %}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
{% if user.registration.is_admin %}
|
||||||
|
<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 }}">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button class="btn btn-default" data-bs-toggle="modal" data-bs-target="#searchModal"><i class="fa fa-search text-body"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if "_fake_user_id" in request.session %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="{% url "registration:reset_admin" %}?path={{ request.path }}"><i class="fas fa-tools"></i> {% trans "Return to admin view" %}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if not user.is_authenticated %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<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-bs-toggle="modal" data-bs-target="#loginModal">
|
||||||
|
<i class="fas fa-sign-in-alt"></i> {% trans "Log in" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink"
|
||||||
|
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<i class="fas fa-user"></i> {{ user.first_name }} {{ user.last_name }}
|
||||||
|
</a>
|
||||||
|
<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>
|
@ -5,7 +5,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||||||
{% load i18n crispy_forms_filters %}
|
{% load i18n crispy_forms_filters %}
|
||||||
|
|
||||||
{% block title %}{% trans "Log in" %}{% endblock %}
|
{% block title %}{% trans "Log in" %}{% endblock %}
|
||||||
{% block contenttitle %}<h1>{% trans "Log in" %}</h1>{% endblock %}
|
{% block content-title %}<h1>{% trans "Log in" %}</h1>{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
40
tfjm/templates/sidebar.html
Normal file
40
tfjm/templates/sidebar.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header bg-dark-subtle">
|
||||||
|
<div class="d-lg-none btn" data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#sidebar-card" aria-controls="sidebar-card" aria-expanded="false"
|
||||||
|
aria-label="Toggle information sidebar">
|
||||||
|
<h3 class="card-title">
|
||||||
|
{% trans "Informations" %}
|
||||||
|
<span class="d-lg-none">
|
||||||
|
<span class="badge text-small bg-danger">
|
||||||
|
<i class="fa fa-warning"></i>
|
||||||
|
{{ user.registration.important_informations|length }}
|
||||||
|
</span>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="d-none d-lg-block">
|
||||||
|
<h3 class="card-title">{% trans "Informations" %}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="sidebar-card" class="collapse d-lg-block">
|
||||||
|
<div class="card-body">
|
||||||
|
{% for information in user.registration.important_informations %}
|
||||||
|
<div class="card my-2">
|
||||||
|
<div class="card-header bg-dark-subtle">
|
||||||
|
<h5 class="card-title">{{ information.title }}</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body bg-{{ information.type }}-subtle">
|
||||||
|
{{ information.content|safe }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
Loading…
x
Reference in New Issue
Block a user