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)
|
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
|
||||||
|
|
|
@ -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%);
|
||||||
|
}
|
||||||
|
|
|
@ -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">
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p id="hello">Hallo, {{ session.user.email }}!</p>
|
<div class="voteform">
|
||||||
<p id="voters">
|
<p id="hello">Hallo, {{ session.user.email }}!</p>
|
||||||
Bisher haben abgestimmt:
|
<p id="voters">
|
||||||
{% for voter in voters %}
|
Bisher haben abgestimmt:
|
||||||
{{ voter.email }}{% if not loop.last %},{% endif %}
|
{% 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 %}
|
{% endfor %}
|
||||||
</p>
|
</form>
|
||||||
<h1>
|
<div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load">
|
||||||
{{ 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}}">
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
<h2 id="h-time">
|
||||||
</form>
|
Zu welcher Zeit?
|
||||||
<div id="r-day" hx-get="/result/{{meet.id}}/date" hx-trigger="load">
|
<a href="/result/{{meet.id}}/time/ballot">[details]</a>
|
||||||
</div>
|
</h2>
|
||||||
<h2 id="h-time">
|
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
|
||||||
Zu welcher Zeit?
|
{% for d in times %}
|
||||||
</h2>
|
<div class="sort-item">
|
||||||
<form id="v-time" class="sortable" hx-post="/vote/time" hx-trigger="end">
|
{{ d.display or d.time }}
|
||||||
{% for d in times %}
|
<input type="hidden" name="time" value="{{d.id}}">
|
||||||
<div class="sort-item">
|
</div>
|
||||||
{{ d.display or d.time }}
|
{% endfor %}
|
||||||
<input type="hidden" name="time" value="{{d.id}}">
|
</form>
|
||||||
|
<div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load">
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
<h2 id="h-place">
|
||||||
</form>
|
An welchem Ort?
|
||||||
<div id="r-time" hx-get="/result/{{meet.id}}/time" hx-trigger="load">
|
<a href="/result/{{meet.id}}/place/ballot">[details]</a>
|
||||||
</div>
|
</h2>
|
||||||
<h2 id="h-place">
|
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
|
||||||
An welchem Ort?
|
{% for d in places %}
|
||||||
</h2>
|
<div class="sort-item">
|
||||||
<form id="v-place" class="sortable" hx-post="/vote/place" hx-trigger="end">
|
{{ d.name }}
|
||||||
{% for d in places %}
|
<input type="hidden" name="place" value="{{d.id}}">
|
||||||
<div class="sort-item">
|
</div>
|
||||||
{{ d.name }}
|
{% endfor %}
|
||||||
<input type="hidden" name="place" value="{{d.id}}">
|
</form>
|
||||||
|
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
</form>
|
|
||||||
<div id="r-place" hx-get="/result/{{meet.id}}/place" hx-trigger="load">
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
|
|
Loading…
Reference in New Issue