diff --git a/elections/forms.py b/elections/forms.py index bb04956..363dfbd 100644 --- a/elections/forms.py +++ b/elections/forms.py @@ -24,6 +24,10 @@ class ElectionForm(forms.ModelForm): fields = ["name", "description", "restricted", "start_date", "end_date"] +class UploadVotersForm(forms.Form): + csv_file = forms.FileField(label=_("Sélectionnez un fichier .csv")) + + class QuestionForm(forms.ModelForm): class Meta: model = Question diff --git a/elections/templates/elections/election_admin.html b/elections/templates/elections/election_admin.html index d5d668a..27554fd 100644 --- a/elections/templates/elections/election_admin.html +++ b/elections/templates/elections/election_admin.html @@ -22,9 +22,9 @@
- {% if election.start_date > current_time %} - {# Lien pour la modification #} + {# Lien pour la modification et l'upload des votant·e·s #} + {% if election.start_date > current_time %}
@@ -33,10 +33,22 @@ {% trans "Modifier" %}
+ + {% if election.restricted %} +
+ + + + + {% trans "Importer une liste de votant·e·s" %} + +
+ {% endif %} + {% elif election.end_date < current_time %} - {% if not election.tallied %} {# Lien pour le dépouillement #} + {% if not election.tallied %}
@@ -45,9 +57,9 @@ {% trans "Dépouiller" %}
- {% else %} {# Lien pour la publication des résultats #} + {% else %}
diff --git a/elections/templates/elections/upload_voters.html b/elections/templates/elections/upload_voters.html new file mode 100644 index 0000000..8f3f8db --- /dev/null +++ b/elections/templates/elections/upload_voters.html @@ -0,0 +1,60 @@ +{% extends "base.html" %} +{% load i18n %} + + +{% block extra_head %} + +{% endblock %} + +{% block content %} + +

{% trans "Importer une liste de votant·e·s" %}

+
+ +
+
+ {% trans "Importez un fichier au format CSV, avec sur la première colonne les prénoms, sur la deuxième le nom et la troisième l'adresse email. Soit :

Prénom_1,Nom_1,mail_1@machin.test
Prénom_2,Nom_2,mail_2@bidule.test
...
" %} +
+
+ +
+ +{% endblock %} diff --git a/elections/urls.py b/elections/urls.py index 24ca25e..370b70c 100644 --- a/elections/urls.py +++ b/elections/urls.py @@ -7,6 +7,11 @@ urlpatterns = [ path("create/", views.ElectionCreateView.as_view(), name="election.create"), path("created/", views.ElectionListView.as_view(), name="election.created"), path("admin/", views.ElectionAdminView.as_view(), name="election.admin"), + path( + "upload-voters/", + views.ElectionUploadVotersView.as_view(), + name="election.upload-voters", + ), path("update/", views.ElectionUpdateView.as_view(), name="election.update"), path("tally/", views.ElectionTallyView.as_view(), name="election.tally"), path( diff --git a/elections/views.py b/elections/views.py index daecd29..3c6976c 100644 --- a/elections/views.py +++ b/elections/views.py @@ -10,12 +10,19 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import ( CreateView, DetailView, + FormView, ListView, RedirectView, UpdateView, ) -from .forms import ElectionForm, OptionForm, OptionFormSet, QuestionForm +from .forms import ( + ElectionForm, + OptionForm, + OptionFormSet, + QuestionForm, + UploadVotersForm, +) from .mixins import CreatorOnlyEditMixin, CreatorOnlyMixin, OpenElectionOnlyMixin from .models import Election, Option, Question @@ -63,11 +70,13 @@ class ElectionCreateView(SuccessMessageMixin, CreateView): return super().form_valid(form) -# TODO : only the creator can edit the election and view the admin panel class ElectionAdminView(CreatorOnlyMixin, DetailView): model = Election template_name = "elections/election_admin.html" + def get_next_url(self): + return reverse("election.view", args=[self.object.pk]) + def get_context_data(self, **kwargs): kwargs.update({"current_time": timezone.now()}) return super().get_context_data(**kwargs) @@ -76,6 +85,19 @@ class ElectionAdminView(CreatorOnlyMixin, DetailView): return super().get_queryset().prefetch_related("questions__options") +class ElectionUploadVotersView(CreatorOnlyEditMixin, FormView): + model = Election + form_class = UploadVotersForm + template_name = "elections/upload_voters.html" + + def get(self, request, *args, **kwargs): + self.object = self.get_object() + return super().get(request, *args, **kwargs) + + def form_valid(self, form): + pass + + class ElectionListView(CreatorOnlyMixin, ListView): model = Election template_name = "elections/election_list.html" @@ -290,7 +312,7 @@ class VoteView(OpenElectionOnlyMixin, DetailView): model = Question template_name = "elections/vote.html" - def get_newt_url(self): + def get_next_url(self): return reverse("election.view", args=[self.object.election.pk]) def get_success_url(self): diff --git a/shared/auth/views.py b/shared/auth/views.py index 831e42a..1dea011 100644 --- a/shared/auth/views.py +++ b/shared/auth/views.py @@ -94,6 +94,8 @@ class LogoutView(auth_views.LogoutView): logged in via CAS. """ + template_name = "auth/logout.html" + def setup(self, request): super().setup(request) if "CASCONNECTED" in request.session: diff --git a/shared/templates/auth/logout.html b/shared/templates/auth/logout.html new file mode 100644 index 0000000..bfaee74 --- /dev/null +++ b/shared/templates/auth/logout.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% load i18n %} + + +{% block auth %}{% endblock %} + +{% block content %} + +

{% trans "Vous avez bien été déconnecté." %}

+
+ +{% endblock %} diff --git a/shared/templates/base.html b/shared/templates/base.html index 9b1b857..3de407a 100644 --- a/shared/templates/base.html +++ b/shared/templates/base.html @@ -55,7 +55,7 @@
- +
diff --git a/shared/templates/forms/file.html b/shared/templates/forms/file.html index fbabfd5..627fe19 100644 --- a/shared/templates/forms/file.html +++ b/shared/templates/forms/file.html @@ -1,22 +1,27 @@ {% load bulma_utils i18n %}
-