Display all votes
This commit is contained in:
parent
b6db3f0ea9
commit
bad50c51cf
36
app.py
36
app.py
|
@ -280,6 +280,34 @@ def result_place(meet_id):
|
|||
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):
|
||||
msg = email.message.EmailMessage()
|
||||
msg["From"] ="noreply@hjp.at"
|
||||
|
@ -294,8 +322,10 @@ def get_ballots(meet_id, kind):
|
|||
csr = get_cursor()
|
||||
|
||||
q = f"""
|
||||
select {kind}.*, bod, position
|
||||
from {kind} join {kind}_vote on {kind}.id = {kind}_vote.{kind}
|
||||
select {kind}.*, bod, position, email
|
||||
from {kind}
|
||||
join {kind}_vote on {kind}.id = {kind}_vote.{kind}
|
||||
join bod on bod = bod.id
|
||||
where meet = %s
|
||||
order by bod, position
|
||||
"""
|
||||
|
@ -361,7 +391,7 @@ def get_cursor():
|
|||
|
||||
def get_db():
|
||||
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
|
||||
|
||||
@app.teardown_appcontext
|
||||
|
|
|
@ -18,7 +18,7 @@ body {
|
|||
cursor: grabbing;
|
||||
}
|
||||
|
||||
body {
|
||||
.voteform {
|
||||
padding: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
@ -45,3 +45,23 @@ h1, h2 {
|
|||
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%);
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -8,54 +8,59 @@
|
|||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<p id="hello">Hallo, {{ session.user.email }}!</p>
|
||||
<p id="voters">
|
||||
Bisher haben abgestimmt:
|
||||
{% for voter in voters %}
|
||||
{{ voter.email }}{% if not loop.last %},{% endif %}
|
||||
<div class="voteform">
|
||||
<p id="hello">Hallo, {{ session.user.email }}!</p>
|
||||
<p id="voters">
|
||||
Bisher haben abgestimmt:
|
||||
{% for voter in voters %}
|
||||
{{ voter.email }}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<h1>
|
||||
{{ meet.title }}
|
||||
</h1>
|
||||
<h2 id="h-day">
|
||||
An welchem Tag?
|
||||
<a href="/result/{{meet.id}}/date/ballot">[details]</a>
|
||||
</h2>
|
||||
<form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end">
|
||||
{% for d in dates %}
|
||||
<div class="sort-item">
|
||||
{{ d.display or d.date }}
|
||||
<input type="hidden" name="date" value="{{d.id}}">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<h1>
|
||||
{{ meet.title }}
|
||||
</h1>
|
||||
<h2 id="h-day">
|
||||
An welchem Tag?
|
||||
</h2>
|
||||
<form id="v-day" class="sortable" hx-post="/vote/date" hx-trigger="end">
|
||||
{% for d in dates %}
|
||||
<div class="sort-item">
|
||||
{{ d.display or d.date }}
|
||||
<input type="hidden" name="date" value="{{d.id}}">
|
||||
</form>
|
||||
<div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
<div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load">
|
||||
</div>
|
||||
<h2 id="h-time">
|
||||
Zu welcher Zeit?
|
||||
</h2>
|
||||
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
|
||||
{% for d in times %}
|
||||
<div class="sort-item">
|
||||
{{ d.display or d.time }}
|
||||
<input type="hidden" name="time" value="{{d.id}}">
|
||||
<h2 id="h-time">
|
||||
Zu welcher Zeit?
|
||||
<a href="/result/{{meet.id}}/time/ballot">[details]</a>
|
||||
</h2>
|
||||
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
|
||||
{% for d in times %}
|
||||
<div class="sort-item">
|
||||
{{ d.display or d.time }}
|
||||
<input type="hidden" name="time" value="{{d.id}}">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
<div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
<div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load">
|
||||
</div>
|
||||
<h2 id="h-place">
|
||||
An welchem Ort?
|
||||
</h2>
|
||||
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
|
||||
{% for d in places %}
|
||||
<div class="sort-item">
|
||||
{{ d.name }}
|
||||
<input type="hidden" name="place" value="{{d.id}}">
|
||||
<h2 id="h-place">
|
||||
An welchem Ort?
|
||||
<a href="/result/{{meet.id}}/place/ballot">[details]</a>
|
||||
</h2>
|
||||
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
|
||||
{% for d in places %}
|
||||
<div class="sort-item">
|
||||
{{ d.name }}
|
||||
<input type="hidden" name="place" value="{{d.id}}">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</form>
|
||||
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
|
|
Loading…
Reference in New Issue