diff --git a/management/templates/management/add_election.html b/management/templates/management/add_election.html index 9c4fd6c5d777b26d80fbbfe11b99090a82ddbf5e..82a98cd7ae7d0d7ed2056222b456f5038d3eeb11 100644 --- a/management/templates/management/add_election.html +++ b/management/templates/management/add_election.html @@ -86,9 +86,11 @@ </div> <br> - <button type="submit" id="id_btn_send_test" class="btn btn-success" name="submit_type" value="commit"> + <button type="submit" id="id_btn_send_test" class="btn btn-primary btn-block" name="submit_type" value="commit"> Submit </button> + <a class="btn btn-secondary btn-block" + href="{% url 'management:session' session.pk %}">Cancel</a> <div id="dtBox"></div> </form> </div> diff --git a/management/templates/management/add_session.html b/management/templates/management/add_session.html index b87df27e5e833c731329c947628be890491dfa74..39aaf6fefa663895d523b8eda86ba66961e07394 100644 --- a/management/templates/management/add_session.html +++ b/management/templates/management/add_session.html @@ -78,7 +78,11 @@ </div> <br> - <button type="submit" id="id_btn_start" class="btn btn-success">Create Session</button> + <button type="submit" id="id_btn_start" class="btn btn-primary btn-block">Create Session</button> + + <a class="btn btn-secondary btn-block" + href="{% url 'management:index' %}">Cancel</a> + <div id="dtBox"></div> </form> </div> diff --git a/management/templates/management/add_tokens.html b/management/templates/management/add_tokens.html index 21e0ba4f66044a3f65a207df87de18a93e764755..f7b6bacc2f4c3ec1311ff75778bed780c97e7dc8 100644 --- a/management/templates/management/add_tokens.html +++ b/management/templates/management/add_tokens.html @@ -17,7 +17,9 @@ <form class="user" action="{% url 'management:add_tokens' session.pk %}" method="post"> {% csrf_token %} {{ form|crispy }} - <button type="submit" id="id_btn_start" class="btn btn-success">Submit</button> + <button type="submit" id="id_btn_start" class="btn btn-primary btn-block">Submit</button> + <a class="btn btn-secondary btn-block" + href="{% url 'management:session' session.pk %}">Cancel</a> </form> </div> </div> diff --git a/management/templates/management/add_voters.html b/management/templates/management/add_voters.html index 2edf5473d41faf598e665c86c930c1ad10387830..5201d110c4cef2d0525a357bfcc5a76b4d6f78a1 100644 --- a/management/templates/management/add_voters.html +++ b/management/templates/management/add_voters.html @@ -15,7 +15,9 @@ <form class="user" action="{% url 'management:add_voters' session.pk %}" method="post"> {% csrf_token %} {{ form|crispy }} - <button type="submit" id="id_btn_start" class="btn btn-success">Submit</button> + <button type="submit" id="id_btn_start" class="btn btn-primary btn-block">Submit</button> + <a class="btn btn-secondary btn-block" + href="{% url 'management:session' session.pk %}">Cancel</a> </form> </div> </div> diff --git a/management/templates/management/import_csv.html b/management/templates/management/import_csv.html index 811080645efeef2f3f296bbb15897f43368b6050..feeeb36121b9c59f7b14a684fbf6c16eda8356ec 100644 --- a/management/templates/management/import_csv.html +++ b/management/templates/management/import_csv.html @@ -18,7 +18,9 @@ enctype="multipart/form-data"> {% csrf_token %} {{ form|crispy }} - <button type="submit" id="id_btn_start" class="btn btn-success">Submit</button> + <button type="submit" id="id_btn_start" class="btn btn-primary btn-block">Submit</button> + <a class="btn btn-secondary btn-block" + href="{% url 'management:session' session.pk %}">Cancel</a> </form> </div> </div> diff --git a/management/templates/management/index.html b/management/templates/management/index.html index 4b888882945abd2982674655aab7a473ebde1684..9d304f8c7458849fa179bd10bbdfbec97de5f39e 100644 --- a/management/templates/management/index.html +++ b/management/templates/management/index.html @@ -5,8 +5,12 @@ <div class="row justify-content-center"> <div class="col-12"> <div class="card shadow"> + <div class="card-header bg-dark text-light"> + <h4 class="d-inline">My Sessions</h4> + <a class="btn btn-success float-right" + href="{% url 'management:index' %}?action=add_session">Create New Session</a> + </div> <div class="card-body"> - <h4>My Sessions</h4> <div class="list-group"> {% for session in sessions %} <div class="list-group-item list-group-item-action"> @@ -25,9 +29,6 @@ </div> {% endfor %} </div> - <hr> - <a class="btn btn-success" - href="{% url 'management:index' %}?action=add_session">Create Session</a> </div> </div> </div> diff --git a/management/templates/management/session.html b/management/templates/management/session.html index 0a23bafbb91b6ef83c9b0d720bda3dd2d32a372a..d9b2c88ab5d9b8f8ffc9882cda67ad3337bd3235 100644 --- a/management/templates/management/session.html +++ b/management/templates/management/session.html @@ -151,7 +151,7 @@ <a class="btn btn-warning d-inline float-left ml-2" id="downloadlink" href="{% url 'management:print_token' session.pk %}">Download Tokens</a> - <button type="button" class="btn btn-light" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> diff --git a/management/templates/management/session_settings.html b/management/templates/management/session_settings.html index a445afdcfcf1c9da1956e6ba40041bb5dcefe63b..30001f6baa01cc19fe61b58641841ec105d1df2a 100644 --- a/management/templates/management/session_settings.html +++ b/management/templates/management/session_settings.html @@ -91,7 +91,12 @@ </div> <br> - <button type="submit" id="id_btn_start" class="btn btn-success">Update</button> + <button type="submit" id="id_btn_start" class="btn btn-primary btn-block">Update</button> + + + <a class="btn btn-secondary btn-block" + href="{% url 'management:session' session.pk %}">Cancel</a> + <div id="dtBox"></div> </form> </div> diff --git a/management/views.py b/management/views.py index 489e81edd9940fcf88b64ef41caf437912feadeb..795a8e0efd79c78f6f86537fa091cd63ca73bb05 100644 --- a/management/views.py +++ b/management/views.py @@ -61,7 +61,8 @@ def index(request): manager = request.user if request.GET.get("action") == "add_session": - form = AddSessionForm(request=request, user=request.user, data=request.POST or None) + form = AddSessionForm( + request=request, user=request.user, data=request.POST or None) if request.POST and form.is_valid(): if request.POST.get("submit_type") != "test": @@ -71,7 +72,8 @@ def index(request): messages.add_message(request, messages.INFO, 'Test email sent.') Voter.send_test_invitation( title=form.cleaned_data['title'], - start_date=form.cleaned_data['start_date'] if form.cleaned_data['start_date'] else timezone.now(), + start_date=form.cleaned_data['start_date'] if form.cleaned_data['start_date'] else timezone.now( + ), meeting_link=form.cleaned_data['meeting_link'], invite_text=form.cleaned_data['invite_text'], to_email=form.cleaned_data['email'], @@ -93,7 +95,7 @@ def session_detail(request, pk=None): session = manager.sessions.get(id=pk) context = { 'session': session, - 'existing_elections': bool(session.elections), + 'existing_elections': (session.elections.count() > 0), 'open_elections': open_elections(session), 'upcoming_elections': upcoming_elections(session), 'published_elections': published_elections(session), @@ -108,14 +110,17 @@ def session_settings(request, pk=None): manager = request.user session = manager.sessions.get(pk=pk) - form = SessionSettingsForm(instance=session, request=request, user=request.user, data=request.POST or None) + form = SessionSettingsForm( + instance=session, request=request, user=request.user, data=request.POST or None) if request.POST: if form.is_valid(): if request.POST.get("submit_type") == "test": - messages.add_message(request, messages.INFO, 'Test email sent.') + messages.add_message( + request, messages.INFO, 'Test email sent.') Voter.send_test_invitation( title=form.cleaned_data['title'], - start_date=form.cleaned_data['start_date'] if form.cleaned_data['start_date'] else timezone.now(), + start_date=form.cleaned_data['start_date'] if form.cleaned_data['start_date'] else timezone.now( + ), meeting_link=form.cleaned_data['meeting_link'], invite_text=form.cleaned_data['invite_text'], to_email=form.cleaned_data['email'], @@ -123,7 +128,8 @@ def session_settings(request, pk=None): ) else: form.save() - messages.add_message(request, messages.INFO, 'Session updated successfully!') + messages.add_message(request, messages.INFO, + 'Session updated successfully!') return redirect('management:session', session.id) context = { @@ -144,7 +150,8 @@ def add_election(request, pk=None): 'session': session, } - form = AddElectionForm(session=session, request=request, user=manager, data=request.POST if request.POST else None) + form = AddElectionForm(session=session, request=request, + user=manager, data=request.POST if request.POST else None) context['form'] = form context['variables'] = form.variables if request.POST and form.is_valid(): @@ -163,7 +170,8 @@ def add_election(request, pk=None): "end_date": form.cleaned_data['end_date'], }) - Voter.send_reminder(test_voter, manager.sender_email, test_election) + Voter.send_reminder( + test_voter, manager.sender_email, test_election) else: form.save() return redirect('management:session', pk=session.pk) @@ -179,7 +187,8 @@ def add_voters(request, pk): 'session': session, 'form': AddVotersForm(session=session) } - form = AddVotersForm(session=session, data=request.POST if request.POST else None) + form = AddVotersForm( + session=session, data=request.POST if request.POST else None) context['form'] = form if request.POST and form.is_valid(): form.save() @@ -196,7 +205,8 @@ def add_tokens(request, pk): 'session': session, 'form': AddTokensForm(session=session) } - form = AddTokensForm(session=session, data=request.POST if request.POST else None) + form = AddTokensForm( + session=session, data=request.POST if request.POST else None) context['form'] = form if request.POST and form.is_valid(): form.save() @@ -238,7 +248,8 @@ def election_detail(request, pk): form.save() if election.send_emails_on_start: for voter in session.participants.all(): - voter.send_reminder(session.managers.all().first().sender_email, election) + voter.send_reminder( + session.managers.all().first().sender_email, election) else: context['start_election_form'] = form @@ -254,7 +265,8 @@ def election_upload_application(request, pk, application_id=None): _, election, _ = _unpack(request, pk) if not election.can_apply: - messages.add_message(request, messages.ERROR, 'Applications are currently not accepted') + messages.add_message(request, messages.ERROR, + 'Applications are currently not accepted') return redirect('management:election', pk=pk) if application_id: @@ -268,7 +280,8 @@ def election_upload_application(request, pk, application_id=None): if request.method == 'GET': form = ApplicationUploadForm(election, request, instance=instance) else: - form = ApplicationUploadForm(election, request, data=request.POST, files=request.FILES, instance=instance) + form = ApplicationUploadForm( + election, request, data=request.POST, files=request.FILES, instance=instance) if form.is_valid(): form.save() return redirect('management:election', election.pk) @@ -339,9 +352,11 @@ def print_token(request, pk): return HttpResponseNotFound('Session does not exist') session = session.first() participants = session.participants - tokens = [participant.new_access_token() for participant in participants.all() if participant.is_anonymous] + tokens = [participant.new_access_token() + for participant in participants.all() if participant.is_anonymous] if len(tokens) == 0: - messages.add_message(request, messages.ERROR, 'No tokens have yet been generated.') + messages.add_message(request, messages.ERROR, + 'No tokens have yet been generated.') return redirect('management:session', pk=session.pk) img = [qrcode.make(f'https://{settings.URL}' + reverse('vote:link_login', kwargs={'access_code': access_code})) @@ -359,7 +374,8 @@ def print_token(request, pk): path_i = os.path.join(tmp_qr_path, 'qr_{}.png'.format(idx)) i.save(path_i) paths.append(path_i) - zipped = [{'path': path, 'token': token} for path, token in zip(paths, tokens)] + zipped = [{'path': path, 'token': token} + for path, token in zip(paths, tokens)] context = { 'session': session, 'tokens': zipped, @@ -378,7 +394,8 @@ def generate_pdf(template_name: str, context: Dict, tex_path: str): template = get_template(template_name).render(context).encode('utf8') with open("/tmp/template.tex", "wb") as f: f.write(template) - pdf = PdfLatexBuilder(pdflatex='pdflatex').build_pdf(template, texinputs=[tex_path, '']) + pdf = PdfLatexBuilder(pdflatex='pdflatex').build_pdf( + template, texinputs=[tex_path, '']) return pdf diff --git a/vote/templates/vote/application.html b/vote/templates/vote/application.html index 72e42dcfd264f65304cf6f15ad42e2d1329f7b80..1538f42272a819c320234a8fdd1184a1bed7267c 100644 --- a/vote/templates/vote/application.html +++ b/vote/templates/vote/application.html @@ -69,6 +69,8 @@ </div> {% endif %} <button type="submit" class="btn btn-primary btn-block">Submit</button> + <a class="btn btn-secondary btn-block" + href="{% url 'vote:index' %}">Cancel</a> </form> </div> </div> diff --git a/vote/templates/vote/index.html b/vote/templates/vote/index.html index 08ec37e7a9f08046faeec35f13f9272a18a2559d..30bd8a6ecebea75dceef6c3a72bb0b14119c6e6c 100644 --- a/vote/templates/vote/index.html +++ b/vote/templates/vote/index.html @@ -2,76 +2,80 @@ {% load static %} {% block content %} - <div class="row justify-content-center"> +<div class="row justify-content-center"> - <div class="col-12"> - <div class="card bg-dark text-light shadow mb-2 py-2"> + <div class="col-12"> + <div class="card bg-dark text-light shadow mb-2 py-2"> + <div class="card-body"> + <h4 class="text-center d-inline">{{ title }}</h4> + {% if meeting_link %} + <div><small>Meeting at <a href="{{ meeting_link }}">{{ meeting_link }}</a></small></div> + {% endif %} + </div> + </div> + <div id="electionCard"> + {% if not existing_elections %} + <div class="list-group-item mt-3"> + <span>There are no elections for this session</span> + </div> + {% elif open_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Open Elections</h4> + </div> <div class="card-body"> - <h4 class="text-center d-inline">{{ title }}</h4> - {% if meeting_link %} - <div><small>Meeting at <a href="{{ meeting_link }}">{{ meeting_link }}</a></small></div> - {% endif %} + {% for election, can_vote, edit in open_elections %} + {% include 'vote/index_election_item.html' %} + {% endfor %} </div> </div> - <div id="electionCard"> - {% if open_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Open Elections</h4> - </div> - <div class="card-body"> - {% for election, can_vote, edit in open_elections %} - {% include 'vote/index_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if upcoming_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Upcoming Elections</h4> - </div> - <div class="card-body"> - {% for election, can_vote, edit in upcoming_elections %} - {% include 'vote/index_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if published_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Published Results</h4> - </div> - <div class="card-body"> - {% for election, can_vote, edit in published_elections %} - {% include 'vote/index_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if closed_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Closed Elections</h4> - </div> - <div class="card-body"> - {% for election, can_vote, edit in closed_elections %} - {% include 'vote/index_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} + {% endif %} + {% if upcoming_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Upcoming Elections</h4> + </div> + <div class="card-body"> + {% for election, can_vote, edit in upcoming_elections %} + {% include 'vote/index_election_item.html' %} + {% endfor %} + </div> + </div> + {% endif %} + {% if published_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Published Results</h4> + </div> + <div class="card-body"> + {% for election, can_vote, edit in published_elections %} + {% include 'vote/index_election_item.html' %} + {% endfor %} + </div> </div> + {% endif %} + {% if closed_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Closed Elections</h4> + </div> + <div class="card-body"> + {% for election, can_vote, edit in closed_elections %} + {% include 'vote/index_election_item.html' %} + {% endfor %} + </div> + </div> + {% endif %} </div> </div> +</div> {% endblock %} {% block footer_scripts %} - {# Automatic reload of the page: #} - {# - either if the start date / end date of a election is due#} - {# - or if the admin started / stopped one election and the page is notified with a websocket#} - <script src="{% static "js/jquery-3.5.1.min.js" %}" - integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script> - <script src="{% static "js/reload.js" %}"></script> -{% endblock %} +{# Automatic reload of the page: #} +{# - either if the start date / end date of a election is due#} +{# - or if the admin started / stopped one election and the page is notified with a websocket#} +<script src="{% static " js/jquery-3.5.1.min.js" %}" + integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script> +<script src="{% static " js/reload.js" %}"></script> +{% endblock %} \ No newline at end of file diff --git a/vote/templates/vote/spectator.html b/vote/templates/vote/spectator.html index a77fc3da78d963de9cf2062454e64a5e2458714d..2c8accf3749f3e0e1dd12e332f5753b1583d3896 100644 --- a/vote/templates/vote/spectator.html +++ b/vote/templates/vote/spectator.html @@ -3,76 +3,80 @@ {% load vote_extras %} {% block content %} - <div class="row justify-content-center"> +<div class="row justify-content-center"> - <div class="col-12"> - <div class="card bg-dark text-light shadow mb-2 py-2"> + <div class="col-12"> + <div class="card bg-dark text-light shadow mb-2 py-2"> + <div class="card-body"> + <h4 class="text-center d-inline">{{ title }} - Spectator View</h4> + {% if meeting_link %} + <div><small>Meeting at <a href="{{ meeting_link }}">{{ meeting_link }}</a></small></div> + {% endif %} + </div> + </div> + <div id="electionCard"> + {% if not existing_elections %} + <div class="list-group-item mt-3"> + <span>There are no elections for this session</span> + </div> + {% elif open_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Open Elections</h4> + </div> <div class="card-body"> - <h4 class="text-center d-inline">{{ title }} - Spectator View</h4> - {% if meeting_link %} - <div><small>Meeting at <a href="{{ meeting_link }}">{{ meeting_link }}</a></small></div> - {% endif %} + {% for election in open_elections %} + {% include 'vote/spectator_election_item.html' %} + {% endfor %} </div> </div> - <div id="electionCard"> - {% if open_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Open Elections</h4> - </div> - <div class="card-body"> - {% for election in open_elections %} - {% include 'vote/spectator_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if upcoming_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Upcoming Elections</h4> - </div> - <div class="card-body"> - {% for election in upcoming_elections %} - {% include 'vote/spectator_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if published_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Published Results</h4> - </div> - <div class="card-body"> - {% for election in published_elections %} - {% include 'vote/spectator_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} - {% if closed_elections %} - <div class="card shadow mb-2"> - <div class="card-header"> - <h4>Closed Elections</h4> - </div> - <div class="card-body"> - {% for election in closed_elections %} - {% include 'vote/spectator_election_item.html' %} - {% endfor %} - </div> - </div> - {% endif %} + {% endif %} + {% if upcoming_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Upcoming Elections</h4> + </div> + <div class="card-body"> + {% for election in upcoming_elections %} + {% include 'vote/spectator_election_item.html' %} + {% endfor %} + </div> + </div> + {% endif %} + {% if published_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Published Results</h4> + </div> + <div class="card-body"> + {% for election in published_elections %} + {% include 'vote/spectator_election_item.html' %} + {% endfor %} + </div> </div> + {% endif %} + {% if closed_elections %} + <div class="card shadow mb-2"> + <div class="card-header"> + <h4>Closed Elections</h4> + </div> + <div class="card-body"> + {% for election in closed_elections %} + {% include 'vote/spectator_election_item.html' %} + {% endfor %} + </div> + </div> + {% endif %} </div> </div> +</div> {% endblock %} {% block footer_scripts %} - {# Automatic reload of the page: #} - {# - either if the start date / end date of a election is due#} - {# - or if the admin started / stopped one election and the page is notified with a websocket#} - <script src="{% static "js/jquery-3.5.1.min.js" %}" - integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script> - <script src="{% static "js/reload.js" %}"></script> -{% endblock %} +{# Automatic reload of the page: #} +{# - either if the start date / end date of a election is due#} +{# - or if the admin started / stopped one election and the page is notified with a websocket#} +<script src="{% static " js/jquery-3.5.1.min.js" %}" + integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script> +<script src="{% static " js/reload.js" %}"></script> +{% endblock %} \ No newline at end of file diff --git a/vote/views.py b/vote/views.py index 315d9b96dc5fc52e6cfaf86173f90f989192f68a..a4f78698e3bf73cc02af948f0a6cf780562a41db 100644 --- a/vote/views.py +++ b/vote/views.py @@ -71,6 +71,7 @@ def index(request): 'title': session.title, 'meeting_link': session.meeting_link, 'voter': voter, + 'existing_elections': (session.elections.count() > 0), 'open_elections': list_elections(open_elections(session)), 'upcoming_elections': list_elections(upcoming_elections(session)), 'published_elections': list_elections(published_elections(session)), @@ -91,7 +92,8 @@ def vote(request, election_id): can_vote = voter.can_vote(election) if election.max_votes_yes is not None: - max_votes_yes = min(election.max_votes_yes, election.applications.all().count()) + max_votes_yes = min(election.max_votes_yes, + election.applications.all().count()) else: max_votes_yes = election.applications.all().count() @@ -132,7 +134,8 @@ def apply(request, election_id): if request.method == 'GET': form = ApplicationUploadFormUser(election, request, instance=instance) else: - form = ApplicationUploadFormUser(election, request, data=request.POST, files=request.FILES, instance=instance) + form = ApplicationUploadFormUser( + election, request, data=request.POST, files=request.FILES, instance=instance) if form.is_valid(): form.save() return redirect('vote:index') @@ -152,7 +155,8 @@ def delete_own_application(request, election_id): election = get_object_or_404(voter.session.elections, pk=election_id) application = voter.applications.filter(election__id=election_id) if not election.can_apply: - messages.add_message(request, messages.ERROR, 'Applications can currently not be deleted') + messages.add_message(request, messages.ERROR, + 'Applications can currently not be deleted') return redirect('vote:index') if application.exists(): instance = application.first() @@ -172,6 +176,7 @@ def spectator(request, uuid): context = { 'title': session.title, 'meeting_link': session.meeting_link, + 'existing_elections': (session.elections.count() > 0), 'open_elections': open_elections(session), 'upcoming_elections': upcoming_elections(session), 'published_elections': published_elections(session),