Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions nanposweb/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,19 @@ def signup():
flash('Username already taken! Please choose a different one.', category='danger')
else:
# Register the user
user = User(name=username, isop=False, pin=calc_hash(form.pin.data))
card_hash = None
if form.card_number.data:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hier könnte man ggf. noch checken, ob die Eingabe passt (Passende Länge, nur Ziffern, etc.)

card_hash = calc_hash(form.card_number.data)

user = User(name=username, isop=False, pin=calc_hash(form.pin.data), card=card_hash)
db.session.add(user)
db.session.commit()

flash('User successfully registered. Go to the login form to log in.', category='success')
return redirect(url_for('auth.login'))
# Log the user in immediately
login_user(user, remember=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das sollte nicht standardmäßig eine angemeldet gebliebene Session sein

identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))

flash('User successfully registered and logged in.', category='success')
return redirect(url_for('main.index'))

return render_template('signup.html', form=form)
3 changes: 2 additions & 1 deletion nanposweb/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class SignUpForm(FlaskForm):
render_kw={'placeholder': 'Username', 'autofocus': True}, )
pin = PasswordField(label='PIN', validators=[InputRequired()], render_kw={'placeholder': 'PIN'}, )
repeat_pin = PasswordField(label='Repeat PIN', validators=[InputRequired()], render_kw={'placeholder': 'PIN'}, )
submit = SubmitField(label='Sign up', )
card_number = StringField(label='Card ID', render_kw={'placeholder': 'KIT Card ID'})
submit = SubmitField(label='Sign up')


class MainForm(FlaskForm):
Expand Down
Binary file added nanposweb/static/Studierendenkarte_Front.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
164 changes: 86 additions & 78 deletions nanposweb/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,89 +47,97 @@
{% endblock %}

{% block content %}
<form action="{{ url_for('main.index') }}" method="post">
{{ form.csrf_token }}
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-3">
{% for product in products %}
{% if product.visible or view_all %}
<div class="d-grid">
{% if product.price < 0 %}
{% if config.VERIFY_FREE_PURCHASES %}
<a class="btn btn-outline-dark py-5 ps-5" href="{{ url_for('main.verify_purchase', product=product.id) }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
<form action="{{ url_for('main.index') }}" method="post">
{{ form.csrf_token }}

<h2 class="mb-3">Recharge Balance</h2>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-3 mb-5">
{% for product in products %}
{% if (product.visible or view_all) and product.price < 0 %}
<div class="d-grid">
{% if config.VERIFY_FREE_PURCHASES %}
<a class="btn btn-outline-dark py-5 ps-5" href="{{ url_for('main.verify_purchase', product=product.id) }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% set icon = (drink_icons | random) %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
{% else %}
{% set icon = (drink_icons | random) %}
{% endif %}
{% endif %}
{% endif %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</a>
{% else %}
<button type="submit" class="btn btn-outline-dark py-5 ps-5" name="product_id" value="{{ product.id }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{% set icon = (drink_icons | random) %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
{% endif %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</button>
{% endif %}
{% else %}
{% if product in favorites %}
<button type="submit" class="btn btn-primary py-5 ps-5" name="product_id" value="{{ product.id }}">
{% set icon = "star" %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</button>
{% else %}
<button type="submit" class="btn btn-outline-primary py-5 ps-5" name="product_id" value="{{ product.id }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
</a>
{% else %}
<button type="submit" class="btn btn-outline-dark py-5 ps-5" name="product_id" value="{{ product.id }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
{% else %}
{% set icon = (drink_icons | random) %}
{% endif %}
{% endif %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{% set icon = (drink_icons | random) %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
{% endif %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</button>
{% endif %}
</button>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>

</div>
{% endif %}
{% endfor %}
</div>
</form>
{% endblock %}
<h2 class="mb-3">Buy product</h2>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-3">
{% for product in products %}
{% if (product.visible or view_all) and product.price >= 0 %}
<div class="d-grid">
{% if product in favorites %}
<button type="submit" class="btn btn-primary py-5 ps-5" name="product_id" value="{{ product.id }}">
{% set icon = "star" %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</button>
{% else %}
<button type="submit" class="btn btn-outline-primary py-5 ps-5" name="product_id" value="{{ product.id }}">
{% if product.is_food %}
{% set icon = (food_icons | random) %}
{% else %}
{% if product.has_alc %}
{% set icon = (alc_icons | random) %}
{% else %}
{% set icon = (drink_icons | random) %}
{% endif %}
{% endif %}
<i class="fa-solid fa-{{ icon }} fa-3x" style="float: left"></i>
{{ product.name }}<br>
{% if config.SHOW_BALANCE_AND_PRICE %}
{{ macro.render_currency(product.price) }}
{% else %}
{{ macro.render_contingent(balance, product.price) }}
{% endif %}
</button>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
</form>
{% endblock %}
44 changes: 31 additions & 13 deletions nanposweb/templates/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
<link rel="stylesheet" href="{{ url_for('static', filename='login.css') }}">
{% endblock %}
{% block main %}
<div class="text-center align-items-center" style="padding-top: 5vh">
<div class="text-center align-items-center" style="padding-top: 2vh">
<div class="mb-3">
<h1>NANPOS Web</h1>
{% if session.get('terminal', False) %}
<h2>Terminal</h2>
{% endif %}
<h3>Sign up</h3>
</div>

Expand All @@ -23,16 +19,38 @@ <h3>Sign up</h3>
{{ form.pin(class='form-control') }}
{{ form.pin.label }}
</div>
<div class="form-floating">
{{ form.repeat_pin(class='form-control') }}
{{ form.repeat_pin.label }}
<div class="form-floating mb-3">
{{ form.repeat_pin(class="form-control", id="floatingRepeatPin", placeholder="1234") }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das placeholder-Argument wirkt redundant. Da das Label schwebt, wird der Placeholder-Text nicht angezeigt und sobald man drauf klickt, wird das Feld active, wodurch der Text standardmäßig verschwindet.

Dies ist auch keine Verbesserung in Richtung Accessibility, da Screenreader dies standardmäßig nicht vorlesen.

Gleiches gilt für die Stelle dadrunter.

<label for="floatingRepeatPin">Repeat PIN</label>
</div>
{{ form.submit(class="w-100 btn btn-lg btn-primary") }}
</form>

<div class="form-signin">
<a class="w-100 btn btn-lg btn-secondary" href="{{ url_for("auth.login") }}" role="button">Back to login</a>
</div>
{# Removed the hr class="my-4" here as requested #}

<div class="mb-3 text-center">
<p>If you want to login with your KIT Card, you need to register your card number</p>
{# Changed placeholder to actual static image #}
<img src="{{ url_for('static', filename='Studierendenkarte_Front.png') }}" alt="KIT Card" class="img-fluid rounded mb-3">
</div>

<div class="form-floating mb-3">
{{ form.card_number(class="form-control", id="floatingCard", placeholder="12345678") }}
<label for="floatingCard">Card ID (Optional)</label>
</div>

<div class="d-grid gap-2">
{{ form.submit(class="btn btn-primary btn-login text-uppercase fw-bold") }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Der Button, sowie die beiden unteren auch, haben ein anderes Aussehen, wie alle anderen Buttons. Diese sollten angepasst werden, dass sie einheitlich aussehen.


{# Wrapped the Back link in the same d-grid container to match size #}
{% if session.get('terminal', False) %}
<a role="button" class="btn btn-secondary btn-login text-uppercase fw-bold"
href="{{ url_for('auth.login', terminal=True) }}">Back to Login</a>
{% else %}
<a role="button" class="btn btn-secondary btn-login text-uppercase fw-bold"
href="{{ url_for('auth.login') }}">Back to Login</a>
{% endif %}
</div>
</form>
</div>
</div>
</div>
{% endblock %}
77 changes: 31 additions & 46 deletions nanposweb/templates/verify.html
Original file line number Diff line number Diff line change
@@ -1,54 +1,39 @@
{% extends 'base.html' %}

{% block pagetitle %}Verify Purchase{% endblock %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Der Titelblock sollte beibehalten werden, um dem Nutzer eine klare und eindeutige Navigation zu präsentieren.


{% block utilbar %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User-Impersonating ist durchaus ein wichtiges Admin-Feature. Es muss daher klar angezeigt werden, wenn man sich gerade als ein anderer Account ausgibt, um Verwirrung/Fehler zu vermeiden. Dies könnte z.B. sein, dass man es für den falschen Account abbucht.

Der Block utilbar soll erhalten bleiben.

<div class="navbar navbar-light bg-light">
<div class="container row-cols-auto">
{% if impersonate_user is not none %}
<div class="d-flex align-items-center me-auto">
<i class="fa-solid fa-user-secret text-danger me-1"></i>
<span class="text-danger me-3">Impersonating {{ impersonate_user.name }}</span>
<a role="button" class="btn btn-danger"
href="{{ url_for('admin.users.pop_impersonate') }}">Disable</a>
</div>
{% endif %}

<div class="row-cols-auto d-flex ms-auto">
<div class="mx-1">
<span class="nav-link text-dark">User: {{ user_name }}</span>
</div>
{% if config.SHOW_BALANCE_AND_PRICE %}
<div>
<span class="nav-link text-dark">Balance: {{ macro.render_currency(balance) }}</span>
</div>
{% endif %}
{% block content %}
<div class="row justify-content-center mt-5">
<div class="col-md-6 text-center">
<h1>Verify Purchase</h1>
<h3 class="mt-4">Purchase the item "Getränkeliste" at the card-terminal to the left.</h3>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Es sollten auf keinen Fall Dinge hardgecoded werden, wie in diesem Fall hier Getränkeliste, da dies dynamische Inhalte aus der Datenbank sind und es mehr als Produkt (mit unterschiedlichen Namen) geben kann, die für das Aufladen verwendet werden.

Zusätzlich ist die Position des Terminals nicht fix. Es passiert regelmäßig, dass dies nicht links davon steht.

Der Bindestrich aus card-termial sollte entfernt werden.


<div class="my-4">
<img src="https://placehold.co/400x300?text=Card+Terminal" alt="Card Terminal" class="img-fluid rounded">
</div>

</div>
</div>
{% endblock %}

{% block content %}
<form action="{{ url_for('main.index') }}" method="post">
{{ form.csrf_token }}
<h1>Verify purchase</h1>
<p class="fs-3">Have you purchased this item, a {{ product.name }}, already at the other device?</p>
<p class="lead">
{% if config.VERIFY_FREE_PURCHASES_NOTE %}
{{ config.VERIFY_FREE_PURCHASES_NOTE }}
{% endif %}
</p>

<div class="container">
<div class="row">
<div class="col">
<a class="btn btn-outline-secondary w-100 py-2" href="{{ url_for('main.index') }}">No</a>
</div>
<div class="col">
<button type="submit" class="btn btn-primary w-100 py-2" name="product_id" value="{{ product.id }}">Yes</button>
<form action="{{ url_for('main.index') }}" method="post">
{{ form.csrf_token }}
<input type="hidden" name="product_id" value="{{ product.id }}">

{# Use a row with two equal columns to make buttons same size #}
<div class="row mt-5">
<div class="col-6 d-grid">
<button type="submit" class="btn btn-success btn-lg">
<i class="fa-solid fa-check me-2"></i>Confirm Purchase
</button>
</div>
<div class="col-6 d-grid">
<a href="{{ url_for('main.index') }}" class="btn btn-danger btn-lg">
<i class="fa-solid fa-times me-2"></i>Cancel
</a>
</div>
</div>
</div>
</form>
</div>
<br>
{% if config.VERIFY_FREE_PURCHASES_NOTE %}
<p>{{ config.VERIFY_FREE_PURCHASES_NOTE }}</p>
{% endif %}

</form>
</div>
{% endblock %}