Commit 2c60a20c authored by Mathis Dedial's avatar Mathis Dedial
Browse files

Integrate vote view into template

Split up 'vote' endpoint into 'vote' and 'list'
for easier LDAP integration later on
parent 1e36663e
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Create your a burger for the 125th anniversary of the AMIV! Create your a burger for the 125th anniversary of the AMIV!
</p> </p>
<form method="post"> <form method="POST">
<div id="creator"> <div id="creator">
<!-- Info Section --> <!-- Info Section -->
<section class="bg-primary text-white text-center" id="info"> <section class="bg-primary text-white text-center" id="info">
......
{% extends 'base.html' %} {% block content %} {% extends 'base.html' %} {% block content %}
<div class="list-group">
{% for burger in burger_list %} <p class="lead">
<li class="list-group-item d-flex align-items-center justify-content-between"> Create your a burger for the 125th anniversary of the AMIV!
<div> </p>
<b>{{ burger.name }}</b>
<br> <section class="bg-primary text-white text-center" id="info">
<span>{{ burger.description }}</span> <div class="container">
<h2 class="text-center text-uppercase text-white">Create a Burger</h2>
<hr class="star-light">
<div class="text-center">
<h5>You can create your own AMIV anniversary burger below. Everyone can vote on the submitted burgers to decide which
one is the best. The most popular burger will be available at the canteen Polyterasse on .....</h5>
</span>
</div> </div>
<div> </div>
<ul> </section>
<li>
<b>Bread:</b> {{ bread.get(burger.bread) }}</li> <section class="masthead text-center">
<li> <div class="container">
<b>Patty:</b> {{ patty.get(burger.patty) }}</li> <h3>Burger Gallery</h3>
<li> <hr class="star-dark">
<b>Toppings:</b> <p class="highlight"></p>
<ul>
{% for topping in burger.toppings.split(', ') %} <div class="list-group">
<li>{{ toppings.get(topping|int) }}</li> {% for burger in burger_list %}
{% endfor %} <li class="list-group-item d-flex align-items-center justify-content-between">
</ul> <!-- Ranking -->
</li> <h3 class="text-secondary">
<li> {{ loop.index }}.
<b>Side:</b> {{ side.get(burger.side) }}</li> </h3>
</ul>
<div class="d-flex align-items-center justify-content-between">
<!-- Name & Ingredients -->
<div class="text-left w-50">
<h4 class="text-primary">{{ burger.name }}</h4>
<p class="mb-0">
{{ patty.get(burger.patty) }}
in a {{ bread.get(burger.bread) }}
with
{% for topping in burger.toppings.split(', ') %}
{{ toppings.get(topping|int) }}{{ ', ' if not loop.last }}
{% endfor %}
and a side of {{ side.get(burger.side) }}.
</p>
</div>
<!-- Description and username -->
<blockquote class="blockquote text-center mb-0 w-50">
<p class="mb-0">
{{ burger.description }}
</p>
<footer class="blockquote-footer">{{ burger.nethz }}</footer>
</blockquote>
</div>
<!-- Voting -->
<div>
<h4 class="text-secondary mb-3">{{ burger.vote_count }} Votes</h4>
<form action="/vote" method="POST">
{% if not burger.vote_id %}
<button class="btn btn-primary" type="submit">
<img src="static/images/like.png" alt="Like"> Like
</button>
<input type="hidden" name="action" value="like"> {% else %}
<button class="btn btn-muted" type="submit">Unlike</button>
<input type="hidden" name="action" value="unlike"> {% endif %}
<input type="hidden" name="burger_id" value="{{ burger.id }}">
</form>
</div>
</li>
{% endfor %}
</div> </div>
<span class="badge badge-success badge-pill">{{ burger.vote_count }}</span>
<form method="POST"> </div>
{% if not burger.vote_id %} </section>
<button class="btn btn-success" type="submit">Like</button> {% endblock content %}
<input type="hidden" name="action" value="like"> \ No newline at end of file
{% else %}
<button class="btn btn-danger" type="submit">Unlike</button>
<input type="hidden" name="action" value="unlike">
{% endif %}
<input type="hidden" name="burger_id" value="{{ burger.id }}">
</form>
</li>
{% endfor %}
</div>
{% endblock content %}
...@@ -8,76 +8,74 @@ from sqlalchemy.sql import text ...@@ -8,76 +8,74 @@ from sqlalchemy.sql import text
from .mappings import BREAD, PATTY, TOPPINGS, SIDE from .mappings import BREAD, PATTY, TOPPINGS, SIDE
from .models import db, Burger, Vote from .models import db, Burger, Vote
@app.route('/', methods=['GET', 'POST']) @app.route('/')
def vote(): def list():
''' '''
Front page. Shows a list of all burgers Front page. Shows a list of all burgers
''' '''
# Fetch list of burgers with corresponding vote info
def render_list(): # Could probably also be done with SQLAlchemy but too lazy to look up how
''' # TODO: Query has a bug. Only burgers created by the user himself are returned.
Helper function which gets the latest state from the database before rendering the template. querystring = text('SELECT burger.id AS id, name, description, burger.nethz AS nethz, timestamp, bread, patty, toppings, side, COUNT(vote_1.id) AS vote_count, vote_2.id AS vote_id '
'FROM burger '
Useful since we don't want to send multiple queries for a single request. 'LEFT JOIN vote AS vote_1 ON vote_1.burger_id=burger.id '
''' 'LEFT JOIN vote AS vote_2 ON vote_2.burger_id=burger.id AND vote_2.nethz = :nethz '
# Fetch list of burgers with corresponding vote info 'ORDER BY vote_count ')
# Could probably also be done with SQLAlchemy but too lazy to look up how burger_list = db.engine.execute(querystring, nethz=g.user).fetchall()
querystring = text('SELECT burger.id AS id, name, description, burger.nethz AS nethz, timestamp, bread, patty, toppings, side, COUNT(vote_1.id) AS vote_count, vote_2.id AS vote_id ' return render_template('vote.html',
'FROM burger ' burger_list=burger_list,
'LEFT JOIN vote AS vote_1 ON vote_1.burger_id=burger.id ' bread=BREAD,
'LEFT JOIN vote AS vote_2 ON vote_2.burger_id=burger.id AND vote_2.nethz = :nethz ' patty=PATTY,
'ORDER BY vote_count ') toppings=TOPPINGS,
burger_list = db.engine.execute(querystring, nethz=g.user).fetchall() side=SIDE)
return render_template('vote.html',
burger_list=burger_list,
bread=BREAD, @app.route('/vote', methods=['POST'])
patty=PATTY, def vote():
toppings=TOPPINGS, '''
side=SIDE) Handles POST requests for voting
'''
def die(message): def die(message):
''' '''
Display an error-level flash message and return Display an error-level flash message and return
''' '''
flash(message, 'error') flash(message, 'error')
return render_list() return redirect(url_for('list'))
# Handle like / unlike actions first
if request.method == 'POST':
# Check if the burger_id is valid # Check if the burger_id is valid
burger_id = request.form.get('burger_id') burger_id = request.form.get('burger_id')
if not burger_id or not Burger.query.get(burger_id): if not burger_id or not Burger.query.get(burger_id):
return die('Invalid burger ID') return die('Invalid burger ID')
# User is casting their vote # User is casting their vote
if request.form.get('action') == 'like': if request.form.get('action') == 'like':
# Check if the user hasn't already voted for the same burger # Check if the user hasn't already voted for the same burger
if Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first(): if Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first():
return die('You have already liked this burger.') return die('You have already liked this burger.')
# Add vote # Add vote
vote = Vote( vote = Vote(
nethz=g.user, nethz=g.user,
burger_id=burger_id, burger_id=burger_id,
) )
db.session.add(vote) db.session.add(vote)
db.session.commit() db.session.commit()
flash('Thanks for voting!', 'success') flash('Thanks for voting!', 'success')
# User is revoking their vote
elif request.form.get('action') == 'unlike':
# Find the vote
vote = Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first()
# User is revoking their vote if vote:
elif request.form.get('action') == 'unlike': # Delete the vote
# Find the vote db.session.delete(vote)
vote = Vote.query.filter_by(nethz=g.user, burger_id=burger_id).first() db.session.commit()
if vote: flash('Your like has been removed.', 'success')
# Delete the vote
db.session.delete(vote)
db.session.commit()
flash('Your like has been removed.', 'success') return redirect(url_for('list'))
return render_list()
@app.route('/new', methods=['GET', 'POST']) @app.route('/new', methods=['GET', 'POST'])
def create(): def create():
...@@ -92,10 +90,10 @@ def create(): ...@@ -92,10 +90,10 @@ def create():
flash(message, 'error') flash(message, 'error')
return render_template('creator.html') return render_template('creator.html')
# A new burger was submitted
if request.method == 'POST': if request.method == 'POST':
# A new burger was submitted
# Perform field validation # Perform field validation
bread = request.form.get('bread') bread = request.form.get('bread')
if not bread: if not bread:
return die('Please select a bread for your burger.') return die('Please select a bread for your burger.')
...@@ -138,8 +136,7 @@ def create(): ...@@ -138,8 +136,7 @@ def create():
db.session.add(burger) db.session.add(burger)
db.session.commit() db.session.commit()
# Redirect the user to the detail page of the new burger
flash('Congrats on your new burger!', 'success') flash('Congrats on your new burger!', 'success')
return redirect(url_for('detail', burger_id=burger.id)) return redirect(url_for('list'))
return render_template('creator.html') return render_template('creator.html')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment