Merge branch 'thubrecht/faq' into 'master'

Création de l'application de faq

See merge request klub-dev-ens/kadenios!6
This commit is contained in:
Tom Hubrecht 2021-06-18 19:25:50 +00:00
commit 191144c234
17 changed files with 560 additions and 113 deletions

0
faqs/__init__.py Normal file
View file

28
faqs/forms.py Normal file
View file

@ -0,0 +1,28 @@
from translated_fields import language_code_formfield_callback
from django import forms
from .models import Faq
class FaqForm(forms.ModelForm):
formfield_callback = language_code_formfield_callback
class Meta:
model = Faq
fields = [
*Faq.title.fields,
"anchor",
*Faq.description.fields,
*Faq.content.fields,
]
widgets = {
"description_en": forms.Textarea(
attrs={"rows": 4, "class": "is-family-monospace"}
),
"description_fr": forms.Textarea(
attrs={"rows": 4, "class": "is-family-monospace"}
),
"content_en": forms.Textarea(attrs={"class": "is-family-monospace"}),
"content_fr": forms.Textarea(attrs={"class": "is-family-monospace"}),
}

View file

@ -0,0 +1,66 @@
# Generated by Django 3.2.4 on 2021-06-15 08:34
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Faq",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("title_fr", models.CharField(max_length=255, verbose_name="titre")),
(
"title_en",
models.CharField(blank=True, max_length=255, verbose_name="titre"),
),
("description_fr", models.TextField(verbose_name="description")),
(
"description_en",
models.TextField(blank=True, verbose_name="description"),
),
("content_fr", models.TextField(blank=True, verbose_name="contenu")),
("content_en", models.TextField(blank=True, verbose_name="contenu")),
(
"last_modified",
models.DateField(auto_now=True, verbose_name="mise à jour"),
),
("anchor", models.CharField(max_length=20, verbose_name="ancre")),
(
"author",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="faqs",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"permissions": [("is_author", "Can create faqs")],
},
),
migrations.AddConstraint(
model_name="faq",
constraint=models.UniqueConstraint(
fields=("anchor",), name="unique_faq_anchor"
),
),
]

View file

14
faqs/mixins.py Normal file
View file

@ -0,0 +1,14 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
class AdminOnlyMixin(PermissionRequiredMixin):
"""Restreint l'accès aux admins"""
permission_required = "faqs.is_author"
class CreatorOnlyMixin(AdminOnlyMixin):
"""Restreint l'accès à l'auteur"""
def get_queryset(self):
return super().get_queryset().filter(author=self.request.user)

32
faqs/models.py Normal file
View file

@ -0,0 +1,32 @@
from translated_fields import TranslatedFieldWithFallback
from django.contrib.auth import get_user_model
from django.db import models
from django.utils.translation import gettext_lazy as _
User = get_user_model()
class Faq(models.Model):
title = TranslatedFieldWithFallback(
models.CharField(_("titre"), blank=False, max_length=255)
)
description = TranslatedFieldWithFallback(
models.TextField(_("description"), blank=False)
)
content = TranslatedFieldWithFallback(models.TextField(_("contenu"), blank=True))
author = models.ForeignKey(
User, related_name="faqs", null=True, on_delete=models.SET_NULL
)
last_modified = models.DateField(_("mise à jour"), auto_now=True)
anchor = models.CharField(_("ancre"), max_length=20)
class Meta:
permissions = [
("is_author", "Can create faqs"),
]
constraints = [
models.UniqueConstraint(fields=["anchor"], name="unique_faq_anchor")
]

View file

@ -0,0 +1,43 @@
{% extends "base.html" %}
{% load i18n markdown %}
{% block content %}
<div class="level">
{# Titre de la FAQ #}
<div class="level-left is-flex-shrink-1">
<h1 class="title">{{ faq.title }}</h1>
</div>
<div class="level-right">
{# Date de dernière modification #}
<div class="level-item">
<span class="tag is-primary is-light is-outlined">{% blocktrans with maj=faq.last_modified|date:'d/m/Y' %}Mis à jour le {{ maj }}{% endblocktrans %}</span>
</div>
{# Lien vers la page d'édition #}
{% if faq.author == user %}
<div class="level-item">
<a class="button has-tooltip-primary" href="{% url 'faq.edit' faq.anchor %}" data-tooltip="{% trans "Modifier" %}">
<span class="icon">
<i class="fas fa-cog"></i>
</span>
</a>
</div>
{% endif %}
</div>
</div>
<hr>
{# Description #}
<div class="message is-primary">
<div class="message-body content">{{ faq.description|markdown|safe }}</div>
</div>
{# Contenu #}
<div class="content">
{{ faq.content|markdown|safe }}
</div>
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
{% for error in form.non_field_errors %}
<div class="notification is-danger">
{{ error }}
</div>
{% endfor %}
<h1 class="title">{% trans "Nouvelle FAQ" %}</h1>
<hr>
{% url 'faq.list' as r_url %}
{% include "forms/common-form.html" with c_size="is-9" errors=False %}
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
{% for error in form.non_field_errors %}
<div class="notification is-danger">
{{ error }}
</div>
{% endfor %}
<h1 class="title">{% trans "Modification de la FAQ" %}</h1>
<hr>
{% url 'faq.view' faq.anchor as r_url %}
{% include "forms/common-form.html" with c_size="is-9" errors=False %}
{% endblock %}

View file

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% load i18n markdown %}
{% block content %}
<div class="level">
<div class="level-left">
<div class="level-item">
<h1 class="title">{% trans "Liste des FAQ" %}</h1>
</div>
</div>
{% if perms.faqs.is_author %}
<div class="level-right">
<div class="level-item">
<a class="button is-light is-outlined is-primary" href={% url 'faq.create' %}>
<span class="icon">
<i class="fas fa-plus"></i>
</span>
<span>{% trans "Créer une FAQ" %}</span>
</a>
</div>
</div>
{% endif %}
</div>
<hr>
{% for f in faq_list %}
<div class="panel is-primary is-radiusless">
<div class="panel-heading is-size-6 is-radiusless">
<a class="has-text-primary-light" href="{% url 'faq.view' f.anchor %}"><u>{{ f.title }}</u></a>
</div>
{% if f.description %}
<div class="panel-block">
<div class="content is-flex-grow-1">
{{ f.description|markdown|safe }}
</div>
</div>
{% endif %}
</div>
{% if not forloop.last %}
<br>
{% endif %}
{% endfor %}
{% endblock %}

12
faqs/urls.py Normal file
View file

@ -0,0 +1,12 @@
from django.urls import path
from . import views
urlpatterns = [
# Admin views
path("create", views.FaqCreateView.as_view(), name="faq.create"),
path("edit/<slug:slug>", views.FaqEditView.as_view(), name="faq.edit"),
# Public views
path("", views.FaqListView.as_view(), name="faq.list"),
path("view/<slug:slug>", views.FaqView.as_view(), name="faq.view"),
]

54
faqs/views.py Normal file
View file

@ -0,0 +1,54 @@
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, ListView, UpdateView
from .forms import FaqForm
from .mixins import AdminOnlyMixin, CreatorOnlyMixin
from .models import Faq
# #############################################################################
# Administration Views
# #############################################################################
class FaqCreateView(AdminOnlyMixin, SuccessMessageMixin, CreateView):
model = Faq
form_class = FaqForm
success_message = _("Faq créée avec succès !")
template_name = "faqs/faq_create.html"
def get_success_url(self):
return reverse("faq.view", args=[self.object.anchor])
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class FaqEditView(CreatorOnlyMixin, SuccessMessageMixin, UpdateView):
model = Faq
form_class = FaqForm
slug_field = "anchor"
success_message = _("Faq modifiée avec succès !")
template_name = "faqs/faq_edit.html"
def get_success_url(self):
return reverse("faq.view", args=[self.object.anchor])
# #############################################################################
# Public Views
# #############################################################################
class FaqListView(ListView):
model = Faq
template_name = "faqs/faq_list.html"
class FaqView(DetailView):
model = Faq
template_name = "faqs/faq.html"
slug_field = "anchor"

View file

@ -55,6 +55,7 @@ INSTALLED_APPS = [
"kadenios.apps.IgnoreSrcStaticFilesConfig",
"shared",
"elections",
"faqs",
"authens",
]

View file

@ -8,6 +8,7 @@ urlpatterns = [
path("", HomeView.as_view(), name="kadenios"),
path("admin/", admin.site.urls),
path("elections/", include("elections.urls")),
path("faqs/", include("faqs.urls")),
path("auth/", include("shared.auth.urls")),
path("authens/", include("authens.urls")),
path("i18n/", include("django.conf.urls.i18n")),

View file

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-05-28 10:58+0200\n"
"PO-Revision-Date: 2021-05-28 10:59+0200\n"
"POT-Creation-Date: 2021-06-18 19:34+0200\n"
"PO-Revision-Date: 2021-06-18 21:19+0200\n"
"Last-Translator: Test Translator <test@translator>\n"
"Language-Team: \n"
"Language: en\n"
@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.4.3\n"
"X-Generator: Poedit 3.0\n"
#: elections/forms.py:19
msgid "Impossible de faire débuter l'élection dans le passé"
@ -31,20 +31,22 @@ msgid ""
"Le mail d'annonce a déjà été envoyé, il n'est pas possible d'ouvrir "
"l'élection à tout le monde"
msgstr ""
"The announcement email has already been sent, it is not possible to open the "
"election to everyone"
#: elections/forms.py:55
#: elections/forms.py:63
msgid "Sélectionnez un fichier .csv"
msgstr "Select a .csv file"
#: elections/forms.py:65
#: elections/forms.py:73
msgid "Extension de fichier invalide, il faut un fichier au format CSV."
msgstr "Invalid file extension, a CSV file is required."
#: elections/forms.py:72
#: elections/forms.py:80
msgid "Objet"
msgstr "Subject"
#: elections/forms.py:94
#: elections/forms.py:102
msgid ""
"L'abréviation est optionnelle et sert à identifier plus facilement les "
"différentes options. Elle est affiché sans espaces et en majuscules."
@ -52,116 +54,120 @@ msgstr ""
"The abbreviation is optional and serves to identify the different options "
"more easily. It is displayed without spaces and in capital letters."
#: elections/forms.py:105
#: elections/forms.py:113
msgid "Supprimer le vote de {} ({}) ?"
msgstr "Delete the vote of {} ({}) ?"
#: elections/forms.py:110 elections/templates/elections/election_admin.html:191
#: elections/templates/elections/election_admin.html:218
#: elections/forms.py:118 elections/templates/elections/election_admin.html:243
#: elections/templates/elections/election_admin.html:270
#: elections/templates/elections/election_voters.html:82
msgid "Supprimer"
msgstr "Delete"
#: elections/forms.py:110
#: elections/forms.py:118
msgid "Non"
msgstr "No"
#: elections/forms.py:110
#: elections/forms.py:118
msgid "Oui"
msgstr "Yes"
#: elections/models.py:31
#: elections/models.py:33
msgid "nom"
msgstr "name"
#: elections/models.py:32
#: elections/models.py:34
msgid "nom bref"
msgstr "short name"
#: elections/models.py:34
#: elections/models.py:36 faqs/models.py:15
msgid "description"
msgstr "description"
#: elections/models.py:37
#: elections/models.py:39
msgid "date et heure de début"
msgstr "start date and time"
#: elections/models.py:38
#: elections/models.py:40
msgid "date et heure de fin"
msgstr "end date and time"
#: elections/models.py:41
#: elections/models.py:42
msgid "visible au public"
msgstr "visible to everyone"
#: elections/models.py:45
msgid "conditions de vote"
msgstr "voting requirements"
#: elections/models.py:45
#: elections/models.py:49
msgid "restreint le vote à une liste de personnes"
msgstr "restricts the vote to a list of people"
#: elections/models.py:49
#: elections/models.py:53
msgid "mail avec les identifiants envoyé"
msgstr "mail with credentials sent"
#: elections/models.py:66
#: elections/models.py:70
msgid "résultats publics"
msgstr "results published"
#: elections/models.py:67
#: elections/models.py:71
msgid "dépouillée"
msgstr "counted"
#: elections/models.py:69
#: elections/models.py:73
msgid "archivée"
msgstr "archived"
#: elections/models.py:79
#: elections/models.py:77
msgid "Peut administrer des élections"
msgstr "Can manage elections"
#: elections/models.py:87
msgid "question"
msgstr "question"
#: elections/models.py:81
#: elections/models.py:90
msgid "type de question"
msgstr "type of question"
#: elections/models.py:88
#: elections/models.py:97
msgid "nombre maximal de votes reçus"
msgstr "maximal number of votes received"
#: elections/models.py:139
#: elections/models.py:154
msgid "texte"
msgstr "text"
#: elections/models.py:140
#: elections/models.py:155
msgid "abréviation"
msgstr "abbreviation"
#: elections/models.py:142
#: elections/models.py:157
msgid "option gagnante"
msgstr "winning option"
#: elections/models.py:150
#: elections/models.py:165
msgid "nombre de votes reçus"
msgstr "number of votes received"
#: elections/models.py:177
#: elections/models.py:192
msgid "rang de l'option"
msgstr "option's ranking"
#: elections/models.py:193
#: elections/models.py:208
msgid "votes supplémentaires"
msgstr "extra votes"
#: elections/models.py:209
#: elections/models.py:224
msgid "Nom et Prénom"
msgstr "Name and surname"
#: elections/models.py:232 elections/tests/test_models.py:57
#: elections/models.py:247 elections/tests/test_models.py:57
msgid "identifiants spécifiques"
msgstr "dedicated credentials"
#: elections/models.py:236
msgid "Peut administrer des élections"
msgstr "Can manage elections"
#: elections/staticdefs.py:26 elections/tests/test_models.py:56
msgid "mot de passe"
msgstr "password"
@ -235,7 +241,7 @@ msgid "Élection en cours"
msgstr "Election in progress"
#: elections/templates/elections/election.html:52
#: elections/templates/elections/election_list.html:72
#: elections/templates/elections/election_list.html:83
msgid "Administrer"
msgstr "Manage"
@ -280,70 +286,92 @@ msgstr "Login with credentials"
msgid "Connexion via CAS"
msgstr "Login via CAS"
#: elections/templates/elections/election.html:189
#: elections/templates/elections/election.html:194
msgid "A voté"
msgstr "Voted"
#: elections/templates/elections/election_admin.html:21
#: elections/templates/elections/election_admin.html:282
#: elections/templates/elections/election_admin.html:291
msgid "Rajouter une question"
msgstr "Add a question"
#: elections/templates/elections/election_admin.html:51
#: elections/templates/elections/election_list.html:58
msgid "Élection invisible"
msgstr "Invisible election"
#: elections/templates/elections/election_admin.html:21
msgid "Modifier la question"
msgstr "Change the question"
#: elections/templates/elections/election_admin.html:58
msgid "Élection visible"
msgstr "Visible election"
#: elections/templates/elections/election_admin.html:26
#: elections/templates/elections/election_admin.html:267
#: elections/templates/elections/election_admin.html:278
msgid "Rajouter une option"
msgstr "Add an option"
#: elections/templates/elections/election_admin.html:26
msgid "Modifier l'option"
msgstr "Change the option"
#: elections/templates/elections/election_admin.html:53
#: elections/templates/elections/election_admin.html:72
msgid "Actions"
msgstr "Actions"
#: elections/templates/elections/election_admin.html:65
#: elections/templates/elections/election_admin.html:84
msgid "Vue classique"
msgstr "Classic view"
#: elections/templates/elections/election_admin.html:95
msgid "Rendre l'élection visible"
msgstr "Make the election visible"
#: elections/templates/elections/election_admin.html:104
msgid "Exporter les votant·e·s"
msgstr "Export the list of voters"
#: elections/templates/elections/election_admin.html:74
#: elections/templates/elections/election_admin.html:200
#: elections/templates/elections/election_admin.html:224
#: elections/templates/elections/election_admin.html:113
#: elections/templates/elections/election_admin.html:252
#: elections/templates/elections/election_admin.html:276
#: faqs/templates/faqs/faq.html:22
msgid "Modifier"
msgstr "Edit"
#: elections/templates/elections/election_admin.html:83
#: elections/templates/elections/election_admin.html:122
#: elections/templates/elections/upload_voters.html:27
msgid "Gestion de la liste de votant·e·s"
msgstr "Management of the voters' list"
#: elections/templates/elections/election_admin.html:95
#: elections/templates/elections/election_admin.html:134
#: elections/templates/elections/election_voters.html:48
msgid "Liste des votant·e·s"
msgstr "Voters' list"
#: elections/templates/elections/election_admin.html:103
#: elections/templates/elections/election_admin.html:142
msgid "Dépouiller"
msgstr "Count"
#: elections/templates/elections/election_admin.html:115
#: elections/templates/elections/election_admin.html:154
msgid "Publier"
msgstr "Publish"
#: elections/templates/elections/election_admin.html:117
#: elections/templates/elections/election_admin.html:156
msgid "Dépublier"
msgstr "De-publish"
#: elections/templates/elections/election_admin.html:128
#: elections/templates/elections/election_admin.html:166
msgid "Télécharger les résultats"
msgstr "Download the results"
#: elections/templates/elections/election_admin.html:175
msgid "Archiver"
msgstr "Archive"
#: elections/templates/elections/election_admin.html:247
msgid "Modifier la question"
msgstr "Change the question"
#: elections/templates/elections/election_admin.html:276
msgid "Modifier l'option"
msgstr "Change the option"
#: elections/templates/elections/election_admin.html:315
#: elections/templates/elections/election_admin.html:319
#: elections/templates/elections/election_admin.html:330
msgid "Rajouter une option"
msgstr "Add an option"
#: elections/templates/elections/election_admin.html:334
#: elections/templates/elections/election_admin.html:339
#: elections/templates/elections/election_admin.html:343
msgid "Rajouter une question"
msgstr "Add a question"
#: elections/templates/elections/election_ballots.html:18
#: elections/templates/elections/election_voters.html:40
#: elections/templates/elections/upload_voters.html:48
@ -359,7 +387,7 @@ msgstr "Back"
msgid "Liste des bulletins"
msgstr "List of ballots"
#: elections/templates/elections/election_create.html:31
#: elections/templates/elections/election_create.html:32
msgid "Création d'une élection"
msgstr "Creating an election"
@ -371,19 +399,19 @@ msgstr "List of elections"
msgid "Créer une élection"
msgstr "Create an election"
#: elections/templates/elections/election_list.html:54
#: elections/templates/elections/election_list.html:65
msgid "Élection dépouillée"
msgstr "Election counted"
#: elections/templates/elections/election_list.html:60
#: elections/templates/elections/election_list.html:71
msgid "Élection publiée"
msgstr "Published election"
#: elections/templates/elections/election_list.html:66
#: elections/templates/elections/election_list.html:77
msgid "Élection archivée"
msgstr "Archived election"
#: elections/templates/elections/election_update.html:31
#: elections/templates/elections/election_update.html:32
msgid "Modification d'une élection"
msgstr "Editing an election"
@ -519,50 +547,50 @@ msgstr "Confirm"
msgid "Annuler"
msgstr "Cancel"
#: elections/templates/elections/vote/rank.html:150
#: elections/templates/elections/vote/rank.html:154
msgid "Classement"
msgstr "Ranking"
#: elections/templates/elections/vote/rank.html:151
#: elections/templates/elections/vote/rank.html:155
#: elections/templates/elections/vote/select.html:24
msgid "Option(s) selectionnée(s)"
msgstr "Selected option(s)"
#: elections/templates/elections/vote/rank.html:171
#: elections/templates/elections/vote/rank.html:224
#: elections/templates/elections/vote/rank.html:175
#: elections/templates/elections/vote/rank.html:228
msgid "Utiliser le formulaire classique"
msgstr "Use the traditional form"
#: elections/templates/elections/vote/rank.html:176
#: elections/templates/elections/vote/rank.html:180
msgid "Utiliser le cliquer-déposer"
msgstr "Use Drag & Drop"
#: elections/templates/elections/vote/rank.html:234
#: elections/templates/elections/vote/rank.html:238
#, python-format
msgid "Rang %(i)s"
msgstr "Rank %(i)s"
#: elections/templates/elections/vote/rank.html:245
#: elections/templates/elections/vote/rank.html:249
msgid "Ajouter un rang"
msgstr "Add an rank"
#: elections/utils.py:207
#: elections/utils.py:195
msgid "Vous devez sélectionnner une option."
msgstr "You must select an option."
#: elections/utils.py:212
#: elections/utils.py:200
msgid "Vous ne pouvez pas sélectionner plus d'une option."
msgstr "You cannot select more than one option."
#: elections/utils.py:229
#: elections/utils.py:217
msgid "Le classement maximal est {}."
msgstr "The maximum ranking is {}."
#: elections/utils.py:233
#: elections/utils.py:221
msgid "Le classement minimal est 1."
msgstr "The minimum ranking is 1."
#: elections/utils.py:347
#: elections/utils.py:335
msgid ""
"Format invalide. Vérifiez que le fichier est bien formé (i.e. chaque ligne "
"de la forme 'login,nom,email')."
@ -570,83 +598,132 @@ msgstr ""
"Invalid format. Check that the file is properly formed (i.e. each line of "
"the form 'login,name,e-mail')."
#: elections/utils.py:361
#: elections/utils.py:349
msgid "La ligne {} n'a pas le bon nombre d'éléments."
msgstr "The line {} has the wrong number of elements."
#: elections/utils.py:366
#: elections/utils.py:354
msgid "Valeur manquante dans la ligne {} : 'login'."
msgstr "Missing value in line {}: 'login'."
#: elections/utils.py:371
#: elections/utils.py:359
msgid "Doublon dans les logins : lignes {} et {}."
msgstr "Duplicate logins: lines {} and {}."
#: elections/utils.py:379
#: elections/utils.py:367
msgid "Valeur manquante dans la ligne {} : 'nom'."
msgstr "Missing value in line {}: 'name'."
#: elections/utils.py:385
#: elections/utils.py:373
msgid "Adresse mail invalide à la ligne {} : '{}'."
msgstr "Invalid e-mail address in line {}: '{}'."
#: elections/views.py:73
#: elections/views.py:58
msgid "Élection créée avec succès !"
msgstr "Election successfully created!"
#: elections/views.py:130
#: elections/views.py:99
msgid "Élection visible !"
msgstr "Election now visible!"
#: elections/views.py:127
msgid "Liste de votant·e·s importée avec succès !"
msgstr "Voters list successfully imported!"
#: elections/views.py:164
#: elections/views.py:161
msgid "Mail d'annonce envoyé avec succès !"
msgstr "Announcement e-mail sent successfully!"
#: elections/views.py:196
#: elections/views.py:193
msgid "Élection modifiée avec succès !"
msgstr "Election successfully modified!"
#: elections/views.py:279
#: elections/views.py:276
msgid "Élection dépouillée avec succès !"
msgstr "Election successfully counted!"
#: elections/views.py:305
#: elections/views.py:302
msgid "Élection publiée avec succès !"
msgstr "Election successfully published!"
#: elections/views.py:306
#: elections/views.py:303
msgid "Élection dépubliée avec succès !"
msgstr "Election successfully de-published!"
#: elections/views.py:318
#: elections/views.py:330
msgid "Élection archivée avec succès !"
msgstr "Election successfully archived!"
#: elections/views.py:350
#: elections/views.py:362
msgid "Question modifiée avec succès !"
msgstr "Question successfully modified!"
#: elections/views.py:362
#: elections/views.py:374
msgid "Question supprimée !"
msgstr "Question deleted!"
#: elections/views.py:400
#: elections/views.py:412
msgid "Option modifiée avec succès !"
msgstr "Option successfully modified!"
#: elections/views.py:412
#: elections/views.py:424
msgid "Option supprimée !"
msgstr "Option deleted!"
#: elections/views.py:566
#: elections/views.py:578
msgid "Votre choix a bien été enregistré !"
msgstr "Your choice has been recorded!"
#: kadenios/settings/common.py:138
#: faqs/models.py:12
msgid "titre"
msgstr "title"
#: faqs/models.py:17
msgid "contenu"
msgstr "content"
#: faqs/models.py:22
msgid "mise à jour"
msgstr "updated"
#: faqs/models.py:24
msgid "ancre"
msgstr "anchor"
#: faqs/templates/faqs/faq.html:16
#, python-format
msgid "Mis à jour le %(maj)s"
msgstr "Updated on %(maj)s"
#: faqs/templates/faqs/faq_create.html:13
msgid "Nouvelle FAQ"
msgstr "New FAQ"
#: faqs/templates/faqs/faq_edit.html:13
msgid "Modification de la FAQ"
msgstr "Editing an FAQ"
#: faqs/templates/faqs/faq_list.html:10
msgid "Liste des FAQ"
msgstr "List of FAQs"
#: faqs/templates/faqs/faq_list.html:21
msgid "Créer une FAQ"
msgstr "Create a FAQ"
#: faqs/views.py:18
msgid "Faq créée avec succès !"
msgstr "FAQ successfully created!"
#: faqs/views.py:34
msgid "Faq modifiée avec succès !"
msgstr "FAQ successfully modified!"
#: kadenios/settings/common.py:140
msgid "Français"
msgstr "French"
#: kadenios/settings/common.py:139
#: kadenios/settings/common.py:141
msgid "Anglais"
msgstr "English"
@ -698,20 +775,43 @@ msgstr "Password reset"
msgid "Envoyer un mail"
msgstr "Send an e-mail"
#: shared/templates/base.html:124
#: shared/templates/authens/pwd_reset_email.txt:2
#, python-format
msgid ""
"Quelqu'un (probablement vous) a demandé la réinitialisation du mot de passe "
"associé à cette addresse sur %(site_name)s."
msgstr ""
#: shared/templates/authens/pwd_reset_email.txt:4
msgid ""
"S'il s'agit bien de vous, vous pouvez vous rendre à l'adresse suivante pour "
"en choisir un nouveau : "
msgstr ""
#: shared/templates/authens/pwd_reset_email.txt:8
#, python-format
msgid "Pour information, votre nom d'utilisateur est le suivant : %(username)s"
msgstr ""
#: shared/templates/authens/pwd_reset_email.txt:10
#, python-format
msgid "L'équipe %(site_name)s"
msgstr ""
#: shared/templates/base.html:122
msgid "Élections"
msgstr "Elections"
#: shared/templates/base.html:136
#: shared/templates/base.html:143
#, python-format
msgid "Connecté·e en tant que %(name)s par %(connection)s"
msgstr "Logged in as %(name)s via %(connection)s"
#: shared/templates/base.html:152
#: shared/templates/base.html:159
msgid "Se connecter"
msgstr "Log in"
#: shared/templates/base.html:235
#: shared/templates/base.html:242
msgid ""
"Développé par <a class=\"tag is-light is-danger\" href=\"https://www.eleves."
"ens.fr/kde\">KDEns</a>. En cas de pépin, contacter <span class=\"tag is-info "

View file

@ -112,16 +112,24 @@
<nav class="level has-background-primary">
<div class="level-left px-4">
<div class="level-item">
<a href="{% url "kadenios" %}">
<a href="{% url 'kadenios' %}">
<h1 class="has-text-primary-light is-size-1 is-family-secondary">Kadenios</h1>
</a>
</div>
<div class="level-item px-4">
<a href="{% url "election.list" %}">
<div class="level-item pl-4">
<a href="{% url 'election.list' %}">
<h3 class="has-text-primary-light has-text-weight-semibold is-size-3">{% trans "Élections" %}</h3>
</a>
</div>
{% comment %}
<div class="level-item pl-4">
<a href="{% url 'faq.list' %}">
<h3 class="has-text-primary-light has-text-weight-semibold is-size-3">{% trans "FAQ" %}</h3>
</a>
</div>
{% endcomment %}
</div>
<div class="level-right px-5">