mirror of
https://github.com/ae-utbm/sith.git
synced 2024-12-22 15:51:19 +00:00
Finished main view. Some tuning are to be done.
This commit is contained in:
parent
9ac1cab983
commit
a3a5a0446d
@ -36,6 +36,9 @@ class Election(models.Model):
|
||||
now = timezone.now()
|
||||
return bool(now <= self.end_candidature and now >= self.start_candidature)
|
||||
|
||||
def has_voted(self, user):
|
||||
return hasattr(user, 'has_voted') and user.has_voted.all() == list(self.role.all())
|
||||
|
||||
# Permissions
|
||||
|
||||
|
||||
|
@ -35,6 +35,10 @@ th {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.election__vote-form {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.role {
|
||||
|
||||
}
|
||||
@ -47,6 +51,10 @@ th {
|
||||
color: darkgreen;
|
||||
}
|
||||
|
||||
.role__error {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.role .role_candidates {
|
||||
background: white;
|
||||
}
|
||||
@ -78,6 +86,8 @@ th {
|
||||
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
min-width: 150px;
|
||||
min-height: 150px;
|
||||
|
||||
background-color: lightgrey;
|
||||
}
|
||||
@ -117,13 +127,15 @@ th {
|
||||
}
|
||||
|
||||
.candidate__vote-choice {
|
||||
margin-top: 5px;
|
||||
padding: 15px;
|
||||
margin-top: 5px;
|
||||
padding: 15px;
|
||||
|
||||
border: solid 1px darkgrey;
|
||||
border: solid 1px darkgrey;
|
||||
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: dimgray;
|
||||
text-align: center;
|
||||
font-weight: bolder;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.candidate__vote-choice:hover, .candidate__vote-choice:focus {
|
||||
@ -131,10 +143,10 @@ th {
|
||||
}
|
||||
|
||||
.candidate__vote-input:checked + .candidate__vote-choice {
|
||||
padding: 14px;
|
||||
border-width: 2px;
|
||||
border-color: darkgreen;
|
||||
color: darkgreen;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.candidate__vote-input:checked + .candidate__vote-choice:hover,
|
||||
@ -142,6 +154,16 @@ th {
|
||||
background: palegreen;
|
||||
}
|
||||
|
||||
.role_error .candidate__vote-input:checked + .candidate__vote-choice {
|
||||
border-color: darkred;
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.role_error .candidate__vote-input:checked + .candidate__vote-choice:hover,
|
||||
.role_error .candidate__vote-input:checked + .candidate__vote-choice:focus {
|
||||
background: indianred;
|
||||
}
|
||||
|
||||
.election__sumbit-section {
|
||||
margin-top: 5px;
|
||||
}
|
||||
@ -151,103 +173,117 @@ th {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border: solid 15px orange;
|
||||
border: solid 15px #4081cb;
|
||||
text-align: center;
|
||||
font-size: 200%;
|
||||
font-weight: bolder;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.election__sumbit-button:hover,
|
||||
.election__sumbit-button:focus {
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
</style>
|
||||
{%- endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h3 class="election__title">{{ object.title }}</h3>
|
||||
<p class="election__description">{{ object.description }}</p>
|
||||
<h3 class="election__title">{{ election.title }}</h3>
|
||||
<p class="election__description">{{ election.description }}</p>
|
||||
<hr>
|
||||
<section>
|
||||
<p class="election__details">
|
||||
{% trans %}Polls close {% endtrans %}
|
||||
<time datetime="{{ election.end_date }}">{{ election.end_date|date("l d F Y") }}</time> at <time>{{ election.end_date|time("G:i") }}</time>
|
||||
</p>
|
||||
{# {%- if object.has_voted(request.user) %}
|
||||
{%- if election.has_voted(request.user) %}
|
||||
<p class="election__elector-infos">
|
||||
<span>{% trans %}You already have submitted your vote.{% endtrans %}</span>
|
||||
</p>
|
||||
{%- endif %}
|
||||
#} </section>
|
||||
</section>
|
||||
<section>
|
||||
<table>
|
||||
{%- set election_lists = object.election_list.all() -%}
|
||||
<caption></caption>
|
||||
<thead>
|
||||
{%- for election_list in election_lists %}
|
||||
<th>{{election_list.title}}</th>
|
||||
{%- endfor %}
|
||||
<th>{% trans %}Blank vote{% endtrans %}</th>
|
||||
</thead>
|
||||
{%- for role in object.role.all() %}
|
||||
<tbody class="role">
|
||||
<tr class="role__title">
|
||||
<td colspan="{{election_lists.count() + 1}}">
|
||||
<span>{{role.title}}</span>
|
||||
{%- if role.max_choice > 1 %}
|
||||
<strong class="role__multiple-choices">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
|
||||
{%- endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="role_candidates">
|
||||
<form action="/election/1/vote" method="post" class="election__vote-form" name="vote-form" id="vote-form">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{%- set election_lists = election.election_list.all() -%}
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<th>{% trans %}Blank vote{% endtrans %}</th>
|
||||
{%- for election_list in election_lists %}
|
||||
<td class="list-per-role">
|
||||
<ul class="list-per-role__candidates">
|
||||
{%- for candidature in election_list.candidature.filter(role=role) %}
|
||||
<li class="list-per-role__candidate">
|
||||
<figure class="candidate">
|
||||
<div class="candidate__picture-wrapper">
|
||||
{%- if candidature.user.profile_pict %}
|
||||
<img class="candidate__picture" src="{{candidature.user.profile_pict.get_download_url()}}" alt="{% trans %}Profile{% endtrans %}">
|
||||
{%- endif %}
|
||||
</div>
|
||||
<figcaption class="candidate__infos">
|
||||
<cite class="candidate__full-name">{{ candidature.user.first_name }} <em class="candidate__nick-name">{{candidature.user.nick_name or ''}} </em>{{ candidature.user.last_name }}</cite>
|
||||
<q class="candidate__program">{{ candidature.program or '' }}</q>
|
||||
</figcaption>
|
||||
</figure>
|
||||
{%- if object.is_active %}
|
||||
<input id="id" class="candidate__vote-input" type="radio" name="vote">
|
||||
<label for="id" class="candidate__vote-choice">
|
||||
<span>{% trans %}Choose{% endtrans %} {{ candidature.user.nick_name or candidature.user.first_name }}</span>
|
||||
</label>
|
||||
{% endif %}
|
||||
</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<th>{{election_list.title}}</th>
|
||||
{%- endfor %}
|
||||
<td class="list-per-role">
|
||||
{%- if object.is_active %}
|
||||
<input id="id" class="candidate__vote-input" type="radio" name="vote">
|
||||
<label for="id" class="candidate__vote-choice">
|
||||
<span>{% trans %}Choose blank vote{% endtrans %}</span>
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{%- endfor %}
|
||||
</table>
|
||||
</thead>
|
||||
{%- for role in election.role.all() %}
|
||||
{%- set count = [0] %}
|
||||
{%- set role_data = election_form.data.getlist(role.title) if role.title in election_form.data else [] %}
|
||||
<tbody class="role {% if election_form.errors[role.title] is defined %}role_error{% endif %}">
|
||||
<tr class="role__title">
|
||||
<td colspan="{{election_lists.count() + 1}}">
|
||||
<span>{{role.title}}</span>
|
||||
{%- if role.max_choice > 1 %}
|
||||
<strong class="role__multiple-choices">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
|
||||
{%- endif %}
|
||||
{%- if election_form.errors[role.title] is defined %}
|
||||
{%- for error in election_form.errors.as_data()[role.title] %}
|
||||
<strong class="role__error">{{ error.message }}</strong>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="role_candidates">
|
||||
<td class="list-per-role">
|
||||
{%- if election.is_active and role.max_choice == 1 %}
|
||||
<input id="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-input" type="radio" name="{{ role.title }}" value {{ '' if role_data in election_form else 'checked' }}>
|
||||
<label for="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-choice">
|
||||
<span>{% trans %}Choose blank vote{% endtrans %}</span>
|
||||
</label>
|
||||
{%- set _ = count.append(count.pop() + 1) %}
|
||||
{%- endif %}
|
||||
</td>
|
||||
{%- for election_list in election_lists %}
|
||||
<td class="list-per-role">
|
||||
<ul class="list-per-role__candidates">
|
||||
{%- for candidature in election_list.candidature.filter(role=role) %}
|
||||
<li class="list-per-role__candidate">
|
||||
<figure class="candidate">
|
||||
<div class="candidate__picture-wrapper">
|
||||
{%- if candidature.user.profile_pict %}
|
||||
<img class="candidate__picture" src="{{candidature.user.profile_pict.get_download_url()}}" alt="{% trans %}Profile{% endtrans %}">
|
||||
{%- endif %}
|
||||
</div>
|
||||
<figcaption class="candidate__infos">
|
||||
<cite class="candidate__full-name">{{ candidature.user.first_name }} <em class="candidate__nick-name">{{candidature.user.nick_name or ''}} </em>{{ candidature.user.last_name }}</cite>
|
||||
<q class="candidate__program">{{ candidature.program or '' }}</q>
|
||||
</figcaption>
|
||||
</figure>
|
||||
{%- if election.is_active %}
|
||||
<input id="id_{{ role.title }}_{{ count[0] }}" type="{{ 'checkbox' if role.max_choice > 1 else 'radio' }}" {{ 'checked' if candidature.id|string in role_data else '' }} name="{{ role.title }}" value="{{ candidature.id }}" class="candidate__vote-input">
|
||||
<label for="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-choice">
|
||||
<span>{% trans %}Choose{% endtrans %} {{ candidature.user.nick_name or candidature.user.first_name }}</span>
|
||||
</label>
|
||||
{%- set _ = count.append(count.pop() + 1) %}
|
||||
{%- endif %}
|
||||
</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
{%- endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
{%- endfor %}
|
||||
</table>
|
||||
</form>
|
||||
</section>
|
||||
<section class="election__sumbit-section">
|
||||
<button class="election__sumbit-button">{% trans %}Submit the vote !{% endtrans %}</button>
|
||||
<button class="election__sumbit-button" form="vote-form">{% trans %}Submit the vote !{% endtrans %}</button>
|
||||
</section>
|
||||
<a href="{{url('election:create_list')}}">{% trans %}Add a new list{% endtrans %}</a>
|
||||
<a href="{{url('election:create_role')}}">{% trans %}Add a new role{% endtrans %}</a>
|
||||
<form action="{{url('election:candidate', election_id=object.id)}}" method="post">{{candidate_form}}
|
||||
<section class="election__add-elements">
|
||||
<a href="{{url('election:create_list')}}">{% trans %}Add a new list{% endtrans %}</a>
|
||||
<a href="{{url('election:create_role')}}">{% trans %}Add a new role{% endtrans %}</a>
|
||||
</section>
|
||||
<form action="{{url('election:candidate', election_id=election.id)}}" method="post">{{candidate_form}}
|
||||
{% csrf_token %}
|
||||
<p><input type="submit" value="{% trans %}Candidate{% endtrans %}" /></p>
|
||||
</form>
|
||||
<form action="{{url('election:vote', election_id=object.id)}}" method="post">
|
||||
{{election_form.as_p()}}
|
||||
<p><input type="submit" value="{% trans %}Vote{% endtrans %}" /></p>
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
{% endblock %}
|
@ -40,7 +40,7 @@ class VoteCheckbox(forms.ModelMultipleChoiceField):
|
||||
|
||||
def validate(self, qs):
|
||||
if qs.count() > self.max_choice:
|
||||
raise forms.ValidationError(_("You have selected too much candidate"))
|
||||
raise forms.ValidationError(_("You have selected too much candidates."), code='invalid')
|
||||
|
||||
|
||||
# Forms
|
||||
|
Loading…
Reference in New Issue
Block a user