Display all votes

This commit is contained in:
Peter J. Holzer 2022-11-13 21:37:54 +01:00
parent b6db3f0ea9
commit bad50c51cf
6 changed files with 202 additions and 48 deletions

36
app.py
View File

@ -280,6 +280,34 @@ def result_place(meet_id):
return render_template("place_result_fragment.html", result=result) return render_template("place_result_fragment.html", result=result)
@app.get("/result/<int:meet_id>/date/ballot")
def result_ballots_date(meet_id):
ballots = get_ballots(meet_id, "date")
result = instantrunoff_forward(meet_id, "date")
return render_template(
"date_result_ballots.html",
result=result, ballots=ballots)
@app.get("/result/<int:meet_id>/time/ballot")
def result_ballots_time(meet_id):
ballots = get_ballots(meet_id, "time")
result = instantrunoff_forward(meet_id, "time")
return render_template(
"time_result_ballots.html",
result=result, ballots=ballots)
@app.get("/result/<int:meet_id>/place/ballot")
def result_ballots_place(meet_id):
ballots = get_ballots(meet_id, "place")
result = instantrunoff_forward(meet_id, "place")
return render_template(
"place_result_ballots.html",
result=result, ballots=ballots)
def send_mail(email_address, confirmation_url): def send_mail(email_address, confirmation_url):
msg = email.message.EmailMessage() msg = email.message.EmailMessage()
msg["From"] ="noreply@hjp.at" msg["From"] ="noreply@hjp.at"
@ -294,8 +322,10 @@ def get_ballots(meet_id, kind):
csr = get_cursor() csr = get_cursor()
q = f""" q = f"""
select {kind}.*, bod, position select {kind}.*, bod, position, email
from {kind} join {kind}_vote on {kind}.id = {kind}_vote.{kind} from {kind}
join {kind}_vote on {kind}.id = {kind}_vote.{kind}
join bod on bod = bod.id
where meet = %s where meet = %s
order by bod, position order by bod, position
""" """
@ -361,7 +391,7 @@ def get_cursor():
def get_db(): def get_db():
if "db" not in g: if "db" not in g:
g.db = psycopg.connect(dbname=config.dbname) g.db = psycopg.connect(dbname=config.dbname, user=config.dbuser)
return g.db return g.db
@app.teardown_appcontext @app.teardown_appcontext

View File

@ -18,7 +18,7 @@ body {
cursor: grabbing; cursor: grabbing;
} }
body { .voteform {
padding: 1rem; padding: 1rem;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
@ -45,3 +45,23 @@ h1, h2 {
color: #888; color: #888;
} }
.ballot {
border: 1px solid black;
margin: 1em;
border-radius: 0.4em;
}
.pos_1 {
background-color: hsl(120, 80%, 70%);
color: black;
}
.ballotlist {
display: flex;
flex-wrap: wrap;
}
.voter {
padding: 1em;
background-color: hsl(240, 10%, 80%);
}

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/static/htmx.min.js"></script>
<script src="/static/Sortable.min.js"></script>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="ballotlist">
{% for ballot in ballots %}
<div class="ballot">
<div class="voter">
{{ballot.0.email}}
</div>
{% for vote in ballot %}
<div class="result-item
{% for r in result %}
{% if r.id == vote.id %}
pos_{{ loop.index }}
{% endif %}
{% endfor %}
"
>
{{ vote.display or vote.date }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/static/htmx.min.js"></script>
<script src="/static/Sortable.min.js"></script>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="ballotlist">
{% for ballot in ballots %}
<div class="ballot">
<div class="voter">
{{ballot.0.email}}
</div>
{% for vote in ballot %}
<div class="result-item
{% for r in result %}
{% if r.id == vote.id %}
pos_{{ loop.index }}
{% endif %}
{% endfor %}
"
>
{{ vote.name }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/static/htmx.min.js"></script>
<script src="/static/Sortable.min.js"></script>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="ballotlist">
{% for ballot in ballots %}
<div class="ballot">
<div class="voter">
{{ballot.0.email}}
</div>
{% for vote in ballot %}
<div class="result-item
{% for r in result %}
{% if r.id == vote.id %}
pos_{{ loop.index }}
{% endif %}
{% endfor %}
"
>
{{ vote.display or vote.time }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</body>
</html>

View File

@ -8,6 +8,7 @@
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
</head> </head>
<body> <body>
<div class="voteform">
<p id="hello">Hallo, {{ session.user.email }}!</p> <p id="hello">Hallo, {{ session.user.email }}!</p>
<p id="voters"> <p id="voters">
Bisher haben abgestimmt: Bisher haben abgestimmt:
@ -20,6 +21,7 @@
</h1> </h1>
<h2 id="h-day"> <h2 id="h-day">
An welchem Tag? An welchem Tag?
<a href="/result/{{meet.id}}/date/ballot">[details]</a>
</h2> </h2>
<form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end"> <form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end">
{% for d in dates %} {% for d in dates %}
@ -33,6 +35,7 @@
</div> </div>
<h2 id="h-time"> <h2 id="h-time">
Zu welcher Zeit? Zu welcher Zeit?
<a href="/result/{{meet.id}}/time/ballot">[details]</a>
</h2> </h2>
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end"> <form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
{% for d in times %} {% for d in times %}
@ -46,6 +49,7 @@
</div> </div>
<h2 id="h-place"> <h2 id="h-place">
An welchem Ort? An welchem Ort?
<a href="/result/{{meet.id}}/place/ballot">[details]</a>
</h2> </h2>
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end"> <form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
{% for d in places %} {% for d in places %}
@ -57,6 +61,7 @@
</form> </form>
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load"> <div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
</div> </div>
</div>
</body> </body>
<script> <script>
function activateSortables(element) { function activateSortables(element) {