Merge branch 'devel' into 'main'
Release 5.0 (devel -> main) See merge request W13R/drinks-manager!1
This commit is contained in:
commit
4d99ac4811
14 changed files with 74 additions and 84 deletions
11
application/app/middleware.py
Normal file
11
application/app/middleware.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
# Define CSP middleware:
|
||||||
|
|
||||||
|
def csp_middleware(get_response):
|
||||||
|
|
||||||
|
def middleware(request):
|
||||||
|
response = get_response(request)
|
||||||
|
response["content-security-policy"] = "default-src 'self'"
|
||||||
|
return response
|
||||||
|
|
||||||
|
return middleware
|
|
@ -22,9 +22,7 @@
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
|
||||||
<div class="userPanel">
|
|
||||||
{% include "userPanel.html" %}
|
{% include "userPanel.html" %}
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "baseLayout.html" %}
|
{% extends "baseLayout.html" %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% load l10n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% translate "Drinks - Order" %}
|
{% translate "Drinks - Order" %}
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="column">{% translate "Price per Item" %} ({{ currency_suffix }}):</div>
|
<div class="column">{% translate "Price per Item" %} ({{ currency_suffix }}):</div>
|
||||||
<div class="column" id="pricePerDrink" data-drink-price="{{ drink.price }}">{{ drink.price }}</div>
|
<div class="column" id="pricePerDrink" data-drink-price="{% localize off %}{{ drink.price }}{% endlocalize %}">{{ drink.price }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not drink.binary_availability %}
|
{% if not drink.binary_availability %}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<div class="dropDownMenu" id="dropDownMenu">
|
<div class="userPanel">
|
||||||
<button class="dropDownButton" id="dropDownMenuButton">
|
<div class="userInfo">
|
||||||
<div>
|
|
||||||
{% if user.first_name != "" %}
|
{% if user.first_name != "" %}
|
||||||
{% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }})
|
{% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }})
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -15,12 +14,16 @@
|
||||||
<span>{% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }}</span>
|
<span>{% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="horizontalButtonList">
|
||||||
|
<a class="button" id="navBarBtnHome" href="/">Home</a>
|
||||||
|
<a class="button" id="navBarBtnDeposit" href="/deposit">{% translate "Deposit" %}</a>
|
||||||
|
<div class="dropDownMenu" id="dropDownMenu">
|
||||||
|
<button class="dropDownButton" id="dropDownMenuButton">
|
||||||
|
<div>{% translate "Account" %}</div>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropDownList">
|
<div class="dropDownList">
|
||||||
<a class="button dropDownChoice" id="navBarBtnHome" href="/">Home</a>
|
|
||||||
<a class="button dropDownChoice" id="navBarBtnHistory" href="/history">{% translate "History" %}</a>
|
<a class="button dropDownChoice" id="navBarBtnHistory" href="/history">{% translate "History" %}</a>
|
||||||
<a class="button dropDownChoice" id="navBarBtnStatistics" href="/statistics">{% translate "Statistics" %}</a>
|
<a class="button dropDownChoice" id="navBarBtnStatistics" href="/statistics">{% translate "Statistics" %}</a>
|
||||||
<a class="button dropDownChoice" id="navBarBtnDeposit" href="/deposit">{% translate "Deposit" %}</a>
|
|
||||||
{% if user.is_superuser %}
|
{% if user.is_superuser %}
|
||||||
<a class="button dropDownChoice" href="/admin/">Admin Panel</a>
|
<a class="button dropDownChoice" href="/admin/">Admin Panel</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -28,4 +31,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="button dropDownChoice" href="/accounts/logout">{% translate "Logout" %}</a>
|
<a class="button dropDownChoice" href="/accounts/logout">{% translate "Logout" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -65,7 +65,7 @@ def login_page(request):
|
||||||
@login_required
|
@login_required
|
||||||
def index(request):
|
def index(request):
|
||||||
context = {
|
context = {
|
||||||
"available_drinks": Drink.objects.filter(available__gt=0).filter(deleted=False),
|
"available_drinks": Drink.objects.filter(available__gt=0).filter(deleted=False).order_by('product_name'),
|
||||||
}
|
}
|
||||||
return render(request, "index.html", context)
|
return render(request, "index.html", context)
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,6 @@ ALLOWED_HOSTS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
### CSP Configuration ###
|
|
||||||
|
|
||||||
|
|
||||||
CSP_DEFAULT_SRC = ("'self'", )
|
|
||||||
|
|
||||||
|
|
||||||
### ----------------- ###
|
### ----------------- ###
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +61,7 @@ MIDDLEWARE = [
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
"django_currentuser.middleware.ThreadLocalUserMiddleware",
|
"django_currentuser.middleware.ThreadLocalUserMiddleware",
|
||||||
"csp.middleware.CSPMiddleware"
|
"app.middleware.csp_middleware"
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'drinks_manager.urls'
|
ROOT_URLCONF = 'drinks_manager.urls'
|
||||||
|
|
6
lib/activate-devel-env.sh
Executable file
6
lib/activate-devel-env.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
source ./lib/env.sh
|
||||||
|
source ./config/config.sh
|
||||||
|
export DJANGO_DEBUG=true
|
||||||
|
export PYTHONPATH="./packages"
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt"
|
export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt"
|
||||||
export STATIC_FILES="$(pwd)/static/"
|
export STATIC_FILES="$(pwd)/static/"
|
||||||
export APP_VERSION="4.0"
|
export APP_VERSION="5.0"
|
||||||
export PYTHONPATH="$(pwd)/packages/"
|
export PYTHONPATH="$(pwd)/packages/"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
django~=3.2.7
|
django~=3.2.7
|
||||||
django-currentuser==0.5.3
|
django-currentuser==0.5.3
|
||||||
django-csp==3.7
|
|
||||||
psycopg2~=2.9.1
|
psycopg2~=2.9.1
|
||||||
uvicorn~=0.17.6
|
uvicorn~=0.17.6
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
#depositAmount {
|
#depositAmount {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
}
|
}
|
||||||
main {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 700px) {
|
|
||||||
main {
|
|
||||||
margin-top: -15vh;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -54,7 +54,6 @@ main > h1 {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 10vh;
|
|
||||||
}
|
}
|
||||||
.passwordOverlay > form {
|
.passwordOverlay > form {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
|
|
|
@ -58,20 +58,23 @@ main {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: calc(-14rem + 2vh);
|
margin-top: 5vh;
|
||||||
}
|
}
|
||||||
.userPanel {
|
.userPanel {
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
min-width: fit-content;
|
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
pointer-events: none;
|
font-size: 1rem;
|
||||||
|
width: 90%;
|
||||||
}
|
}
|
||||||
.userPanel > div {
|
.userInfo span {
|
||||||
margin: 0 1rem;
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
.userPanel > .horizontalButtonList {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
.userBalanceWarn {
|
.userBalanceWarn {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
|
@ -118,25 +121,19 @@ main > h1 {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
pointer-events: all;
|
|
||||||
}
|
}
|
||||||
.dropDownButton, .dropDownChoice {
|
.dropDownButton, .dropDownChoice {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
.dropDownButton > div::after {
|
|
||||||
content: '\25BC';
|
|
||||||
display: inline-block;
|
|
||||||
transition: transform 100ms;
|
|
||||||
padding: 0 .3rem;
|
|
||||||
}
|
|
||||||
.dropDownList {
|
.dropDownList {
|
||||||
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
border-radius: var(--glass-corner-radius) !important;
|
border-radius: var(--glass-corner-radius) !important;
|
||||||
backdrop-filter: var(--glass-blur);
|
backdrop-filter: var(--glass-blur);
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
margin-top: .5rem;
|
margin-top: 3.2rem;
|
||||||
opacity: 0%;
|
opacity: 0%;
|
||||||
transition: opacity 100ms;
|
transition: opacity 100ms;
|
||||||
}
|
}
|
||||||
|
@ -166,12 +163,6 @@ main > h1 {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
pointer-events: visible;
|
pointer-events: visible;
|
||||||
}
|
}
|
||||||
.dropDownVisible > .dropDownButton > div::after {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
.userPanel .dropDownButton, .userPanel .dropDownChoice {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
/* FOOTER */
|
/* FOOTER */
|
||||||
.footer {
|
.footer {
|
||||||
z-index: 990;
|
z-index: 990;
|
||||||
|
@ -215,8 +206,8 @@ tr:nth-child(2n+2) {
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Rounded corners on table cells apparently don't work with
|
Rounded corners on table cells apparently don't work with
|
||||||
Firefox (91), so Firefox users won't have rounded corners
|
Firefox, so Firefox users won't have rounded corners
|
||||||
on tables. Won't fix that by myself.
|
on tables. Can't fix that by myself.
|
||||||
*/
|
*/
|
||||||
table tr:first-child th:first-child {
|
table tr:first-child th:first-child {
|
||||||
border-top-left-radius: var(--glass-corner-radius);
|
border-top-left-radius: var(--glass-corner-radius);
|
||||||
|
@ -285,7 +276,6 @@ form .button, form button {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
font-size: .9rem;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
background: var(--glass-bg);
|
background: var(--glass-bg);
|
||||||
|
@ -341,7 +331,9 @@ input[type="text"], input[type="password"], input[type="number"] {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
}
|
||||||
|
.horizontalButtonList > .button, .horizontalButtonList > button, .horizontalButtonList > div {
|
||||||
|
margin: 0 .5rem;
|
||||||
}
|
}
|
||||||
.errorText {
|
.errorText {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
@ -365,8 +357,9 @@ h1 {
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.userPanel > div {
|
.userPanel > .horizontalButtonList {
|
||||||
margin: 0;
|
margin-right: 0;
|
||||||
margin-bottom: .5rem;
|
margin-left: 0;
|
||||||
|
margin-top: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,3 @@
|
||||||
main {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
form {
|
form {
|
||||||
width: 22rem;
|
width: 22rem;
|
||||||
}
|
}
|
||||||
@media only screen and (max-width: 700px) {
|
|
||||||
main {
|
|
||||||
margin-top: -15vh;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
// calculate & display sum
|
// calculate & display sum
|
||||||
|
|
||||||
let order_price_per_drink = parseFloat(document.getElementById("pricePerDrink").dataset.drinkPrice.replace(",", "."));
|
let order_price_per_drink = parseFloat(document.getElementById("pricePerDrink").dataset.drinkPrice);
|
||||||
|
|
||||||
function calculate_and_display_sum() {
|
function calculate_and_display_sum() {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue