From d93591bcb22338357fd9d11a8d1f3d5f3feda7c6 Mon Sep 17 00:00:00 2001 From: ChaoticByte <9070224-ChaoticByte@users.noreply.gitlab.com> Date: Fri, 17 Feb 2023 22:01:09 +0100 Subject: [PATCH] Redesigned the user interface #23 --- app/db_queries.py | 140 +++++ app/sql_queries.py | 140 ----- app/static/css/appform.css | 61 -- app/static/css/custom_number_input.css | 39 -- app/static/css/history.css | 23 - app/static/css/index.css | 46 -- app/static/css/login.css | 108 ---- app/static/css/main.css | 636 +++++++++++++-------- app/static/css/simple-keyboard_dark.css | 7 +- app/static/css/statistics.css | 53 -- app/static/js/autoreload.js | 2 +- app/static/js/custom_number_input.js | 15 +- app/static/js/deposit.js | 17 +- app/static/js/login.js | 12 +- app/static/js/main.js | 9 +- app/static/js/order.js | 29 +- app/static/js/simple-keyboard_configure.js | 3 +- app/static/js/supply.js | 19 +- app/templates/baselayout.html | 40 +- app/templates/deposit.html | 53 +- app/templates/footer.html | 5 +- app/templates/globalmessage.html | 2 +- app/templates/history.html | 49 +- app/templates/index.html | 62 +- app/templates/order.html | 144 ++--- app/templates/registration/logged_out.html | 21 +- app/templates/registration/login.html | 100 ++-- app/templates/statistics.html | 194 ++----- app/templates/supply.html | 82 +-- app/templates/userpanel.html | 18 +- app/views.py | 13 +- scripts/_bootstrap.py | 1 - 32 files changed, 846 insertions(+), 1297 deletions(-) create mode 100644 app/db_queries.py delete mode 100644 app/sql_queries.py delete mode 100644 app/static/css/appform.css delete mode 100644 app/static/css/custom_number_input.css delete mode 100644 app/static/css/history.css delete mode 100644 app/static/css/index.css delete mode 100644 app/static/css/login.css delete mode 100644 app/static/css/statistics.css diff --git a/app/db_queries.py b/app/db_queries.py new file mode 100644 index 0000000..cd267c8 --- /dev/null +++ b/app/db_queries.py @@ -0,0 +1,140 @@ +#from datetime import datetime + +from django.conf import settings +from django.db import connection + +from .models import Order + + +def _db_select(sql_select:str): + result = None + with connection.cursor() as cursor: + cursor.execute(sql_select) + result = cursor.fetchall() + return result + + +COMBINE_ALPHABET = "abcdefghijklmnopqrstuvwxyz" +def _combine_results(results:list) -> dict: + ''' + e.g. + input: [ + [("x", 12), ("y", 13)], + [("y", 10), ("z", 42)] + ] + output: { + "x": {"a": 12}, + "y": {"a": 13, "b": 10}, + "z": {"b": 42} + } + ''' + result = {} + for i, d in enumerate(results): + a = COMBINE_ALPHABET[i] + for r in d: + r_0 = r[0] + if r_0 not in result: + result[r_0] = {} + result[r_0][a] = r[1] + return result + + +def select_history(user, language_code="en") -> list: + # select order history and deposits + user_id = user.pk + result = _db_select(f""" + select + concat( + product_name, ' (', + content_litres::real, -- converting to real removes trailing zeros + 'l) x ', amount, ' - ', price_sum, '{settings.CURRENCY_SUFFIX}') as "text", + datetime + from app_order + where user_id = {user_id} + + union + + select + concat('Deposit: +', transaction_sum, '{settings.CURRENCY_SUFFIX}') as "text", + datetime + from app_userdeposits_view + where user_id = {user_id} + + order by datetime desc + fetch first 30 rows only; + """) + result = [list(row) for row in result] + if language_code == "de": # reformat for german translation + for row in result: + row[0] = row[0].replace(".", ",") + return result + + +def orders_per_month(user) -> list: + # number of orders per month (last 12 months) + result_user = _db_select(f""" + select + to_char(date_trunc('month', datetime), 'YYYY-MM') as "month", + sum(amount) as "count" + from app_order + where user_id = {user.pk} + and date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval) + group by "month" + order by "month" desc; + """) + result_all = _db_select(f""" + select + to_char(date_trunc('month', datetime), 'YYYY-MM') as "month", + sum(amount) as "count" + from app_order + where date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval) + group by "month" + order by "month" desc; + """) + return _combine_results([result_user, result_all]) + + +def orders_per_weekday(user) -> list: + # number of orders per weekday (all time) + result_user = _db_select(f""" + select + to_char(datetime, 'Day') as "day", + sum(amount) as "count" + from app_order + where user_id = {user.pk} + group by "day" + order by "count" desc; + """) + result_all = _db_select(f""" + select + to_char(datetime, 'Day') as "day", + sum(amount) as "count" + from app_order + group by "day" + order by "count" desc; + """) + return _combine_results([result_user, result_all]) + + +def orders_per_drink(user) -> list: + # number of orders per drink (all time) + result_user = _db_select(f""" + select + d.product_name as "label", + sum(o.amount) as "data" + from app_drink d + join app_order o on (d.id = o.drink_id) + where o.user_id = {user.pk} + group by d.product_name + order by "data" desc; + """) + result_all = _db_select(f""" + select + d.product_name as "label", + sum(o.amount) as "data" + from app_drink d + join app_order o on (d.id = o.drink_id) + group by d.product_name + order by "data" desc; + """) + return _combine_results([result_user, result_all]) diff --git a/app/sql_queries.py b/app/sql_queries.py deleted file mode 100644 index 2066dae..0000000 --- a/app/sql_queries.py +++ /dev/null @@ -1,140 +0,0 @@ -#from datetime import datetime - -from django.conf import settings -from django.db import connection - - -def _select_from_db(sql_select:str): - result = None - with connection.cursor() as cursor: - cursor.execute(sql_select) - result = cursor.fetchall() - return result - - -def select_history(user, language_code="en") -> list: - # select order history and deposits - user_id = user.pk - result = _select_from_db(f""" - select - concat( - product_name, ' (', - content_litres::real, -- converting to real removes trailing zeros - 'l) x ', amount, ' - ', price_sum, '{settings.CURRENCY_SUFFIX}') as "text", - datetime - from app_order - where user_id = {user_id} - - union - - select - concat('Deposit: +', transaction_sum, '{settings.CURRENCY_SUFFIX}') as "text", - datetime - from app_userdeposits_view - where user_id = {user_id} - - order by datetime desc - fetch first 30 rows only; - """) - result = [list(row) for row in result] - if language_code == "de": # reformat for german translation - for row in result: - row[0] = row[0].replace(".", ",") - return result - - -def select_yopml12m(user) -> list: - # number of orders per month (last 12 months) - # only for the specified user - user_id = user.pk - result = _select_from_db(f""" - -- select the count of the orders per month (last 12 days) - select - to_char(date_trunc('month', datetime), 'YYYY-MM') as "month", - sum(amount) as "count" - from app_order - where user_id = {user_id} - and date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval) - group by "month" - order by "month" desc; - """) - return [list(row) for row in result] - - -def select_aopml12m() -> list: - # number of orders per month (last 12 months) - result = _select_from_db(f""" - -- select the count of the orders per month (last 12 days) - select - to_char(date_trunc('month', datetime), 'YYYY-MM') as "month", - sum(amount) as "count" - from app_order - where date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval) - group by "month" - order by "month" desc; - """) - return [list(row) for row in result] - - -def select_yopwd(user) -> list: - # number of orders per weekday (all time) - # only for the specified user - user_id = user.pk - result = _select_from_db(f""" - -- select the count of the orders per weekday (all time) - select - to_char(datetime, 'Day') as "day", - sum(amount) as "count" - from app_order - where user_id = {user_id} - group by "day" - order by "count" desc; - """) - return [list(row) for row in result] - return [] - - -def select_aopwd() -> list: - # number of orders per weekday (all time) - result = _select_from_db(f""" - -- select the count of the orders per weekday (all time) - select - to_char(datetime, 'Day') as "day", - sum(amount) as "count" - from app_order - group by "day" - order by "count" desc; - """) - return [list(row) for row in result] - return [] - - -def select_noyopd(user) -> list: - # number of orders per drink (all time) - # only for specified user - user_id = user.pk - result = _select_from_db(f""" - select - d.product_name as "label", - sum(o.amount) as "data" - from app_drink d - join app_order o on (d.id = o.drink_id) - where o.user_id = {user_id} - group by d.product_name - order by "data" desc; - """) - return [list(row) for row in result] - - -def select_noaopd() -> list: - # number of orders per drink (all time) - result = _select_from_db(f""" - select - d.product_name as "label", - sum(o.amount) as "data" - from app_drink d - join app_order o on (d.id = o.drink_id) - group by d.product_name - order by "data" desc; - """) - return [list(row) for row in result] diff --git a/app/static/css/appform.css b/app/static/css/appform.css deleted file mode 100644 index 5c727b5..0000000 --- a/app/static/css/appform.css +++ /dev/null @@ -1,61 +0,0 @@ -.appform { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: max-content; - font-size: 1.1rem; -} -.appform > .forminfo { - width: 100%; - text-align: left; - margin: .4rem 0; -} -.forminfo > span:first-child { - margin-right: 1rem; -} -.forminfo > span:last-child { - float: right; -} -.appform > .forminput { - width: 100%; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: .8rem 0; - gap: 1rem; -} -.appform > .statusinfo { - margin-top: .5rem; -} -.appform > .formbuttons { - border-top: 1px solid var(--glass-border-color); - padding-top: 1rem; - margin-top: 1rem; - width: 100%; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - gap: 1rem; -} -.formbuttons button, .formbuttons .button { - box-sizing: content-box; - font-size: 1rem; - width: fit-content; -} -.formheading { - text-align: left; - width: 100%; - margin-top: 0; -} -@media only screen and (max-width: 700px) { - .appform > .forminput { - flex-direction: column; - gap: .5rem; - } - .formheading { - text-align: center; - } -} \ No newline at end of file diff --git a/app/static/css/custom_number_input.css b/app/static/css/custom_number_input.css deleted file mode 100644 index 375f0de..0000000 --- a/app/static/css/custom_number_input.css +++ /dev/null @@ -1,39 +0,0 @@ -/* custom number input */ -.customnumberinput { - display: flex; - flex-direction: row; - height: 2.2rem; -} -.customnumberinput button { - min-width: 2.5rem !important; - width: 2.5rem !important; - padding: 0; - margin: 0; - height: 100%; -} -.customnumberinput-minus { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - z-index: 10; -} -.customnumberinput-plus { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - z-index: 10; -} -.customnumberinput input[type="number"] { - max-height: 100%; - width: 4rem; - padding: 0; - margin: 0; - font-size: .9rem; - color: var(--color); - text-align: center; - background: var(--glass-bg-color2); - outline: none; - border: none; - border-radius: 0 !important; - -webkit-appearance: textfield; - -moz-appearance: textfield; - appearance: textfield; -} \ No newline at end of file diff --git a/app/static/css/history.css b/app/static/css/history.css deleted file mode 100644 index 6c87d89..0000000 --- a/app/static/css/history.css +++ /dev/null @@ -1,23 +0,0 @@ -.history { - margin: 0; - padding: 0; - width: 40%; - min-width: 30rem; -} -.history td { - padding-top: .4rem !important; - padding-bottom: .4rem !important; - font-size: .95rem; -} -.history .historydate { - margin-left: auto; - text-align: right; - font-size: .8rem !important; -} -/* mobile devices */ -@media only screen and (max-width: 700px) { - .history { - width: 90%; - min-width: 90%; - } -} \ No newline at end of file diff --git a/app/static/css/index.css b/app/static/css/index.css deleted file mode 100644 index a89df5d..0000000 --- a/app/static/css/index.css +++ /dev/null @@ -1,46 +0,0 @@ -.availabledrinkslist { - width: 50%; - max-width: 45rem; - list-style: none; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - justify-content: start; - align-items: center; -} -.availabledrinkslist li { - display: flex; - width: 100%; - height: fit-content; - margin-bottom: .6rem; -} -.availabledrinkslist li a { - display: flex; - width: 100%; - align-items: center; - justify-content: start; - color: var(--color); - padding: .8rem 1.1rem; - text-decoration: none; - font-size: 1rem; -} -.availabledrinkslist li a span:first-child { - margin-right: 1rem !important; - text-align: left; -} -.availabledrinkslist li a span:last-child { - margin-left: auto; - text-align: right; - font-size: 1rem; -} -/* mobile devices */ -@media only screen and (max-width: 700px) { - .availabledrinkslist { - width: 95%; - } - .availabledrinkslist li a { - width: calc(100vw - (2 * .8rem)) !important; - padding: .8rem !important; - } -} \ No newline at end of file diff --git a/app/static/css/login.css b/app/static/css/login.css deleted file mode 100644 index 6b9fa0c..0000000 --- a/app/static/css/login.css +++ /dev/null @@ -1,108 +0,0 @@ -/* login page */ -main { - margin-top: 2vh; -} -main > h1 { - display: none; -} -.userlistcontainer { - display: flex; - flex-direction: column; - align-items: center; - justify-content: start; -} -.userlist { - width: 50vw; - list-style: none; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} -.userlist > li { - display: flex; - width: 100%; - align-items: center; - justify-content: center; - margin-bottom: .5rem; - padding: 0 .5rem; -} -.userlist > li > img { - margin-right: auto; - margin-left: 0; - height: 2rem; - width: 2rem; -} -.userlist > li > div { - display: flex; - flex-grow: 1; - align-items: center; - justify-content: center; - text-align: center; - padding: .8rem 1.1rem; -} -.userlistbutton { - font-size: 1.1rem; -} -.passwordoverlaycontainer { - position: absolute; - top: 0; - width: 100vw; - height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: start; - background: var(--page-background); - z-index: 40; -} -.passwordoverlay { - display: flex; - flex-direction: column; - justify-content: start; - align-items: center; -} -.passwordoverlay > form { - min-width: unset; - width: fit-content; -} -.passwordoverlay > form > h1 { - margin-top: 2rem; - margin-bottom: 2rem; -} -/* loginform */ -.loginform { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} -.loginform input[type="password"], form input[type="text"] { - width: 94%; - padding-top: .5rem; - padding-bottom: .5rem; - font-size: 1rem; - margin: .1rem 0; -} -.loginform .horizontalbuttonlist { - margin-top: 1.5rem; -} -.horizontalbuttonlist .button, .horizontalbuttonlist button { - font-size: 1rem; -} -@media only screen and (max-width: 700px) { - .userlistcontainer { - width: 95vw; - } - .userlist { - width: 100%; - } - .pinpad table tr td button { - height: 4.2rem; - width: 4.2rem; - font-size: 1.16rem; - margin: .2rem; - } -} \ No newline at end of file diff --git a/app/static/css/main.css b/app/static/css/main.css index eb0633f..afdd6c6 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -1,242 +1,258 @@ -/* VARIABLES */ +/* Variables */ + :root { - /** FONT **/ --font-family: 'Liberation Sans', sans-serif; - /** colors **/ --color: #fafafa; - --color-error: rgb(255, 70, 70); - /** glass **/ - --glass-bg-dropdown: #3a3b44ef; - --glass-bg-dropdown-hover: #55565efa; - --glass-bg-color1: #ffffff31; - --glass-bg-color2: #ffffff1a; - --glass-bg-hover-color1: #ffffff46; - --glass-bg-hover-color2: #ffffff1a; - --glass-blur: none; - --glass-border-color: #ffffff77; - --glass-bg: linear-gradient(var(--glass-bg-color1), var(--glass-bg-color2)); - --glass-bg-hover: linear-gradient(var(--glass-bg-hover-color1), var(--glass-bg-hover-color2)); - --glass-corner-radius: .5rem; - /** page background **/ - --page-background-color1: #131d25; - --page-background-color2: #311d30; - --page-background: linear-gradient(-190deg, var(--page-background-color1), var(--page-background-color2)); - /** global message banner **/ - --bg-globalmessage: linear-gradient(135deg, #4b351c, #411d52, #1c404b); + --color-error: #ff682c; + --bg-page-color: #222222; + --bg-color: #4e4e4e; + --bg-hover-color: #636363; + --bg-color2: #383838; + --bg-hover-color2: #4a4a4a; + --border-color: #808080; + --bg-globalmessage: #161616; + --border-radius: .5rem; } -@supports(backdrop-filter: blur(10px)) { - :root { - --glass-bg-dropdown: #ffffff1a; - --glass-bg-dropdown-hover: #ffffff46; - --glass-blur: blur(18px); - } -} -/* BASE LAYOUT */ + +/* General */ + body { margin: 0; padding: 0; width: 100vw; min-height: 100vh; font-family: var(--font-family); - background: var(--page-background); + background: var(--bg-page-color); color: var(--color); overflow-x: hidden; } + +a { + color: var(--color); +} + +h1 { + font-size: 1.8rem; +} + +h1, h2, h3, h4 { + text-align: center; +} + +input[type="number"] { + width: 8rem; + -webkit-appearance: textfield; + -moz-appearance: textfield; + appearance: textfield; +} + +input[type="number"]::-webkit-inner-spin-button { + display: none; +} + +input[type="text"], input[type="password"], input[type="number"] { + padding: .6rem .8rem; + text-align: center; + font-size: 1rem; + color: var(--color); + border: none; + outline: none; + border-bottom: 1px solid var(--border-color); + border-radius: var(--border-radius); + background: var(--bg-color); +} + +table { + border-collapse: collapse; + border-spacing: 0; + text-align: left; + border-radius: var(--border-radius); +} + +tr { + background: var(--bg-color); +} + +tr:nth-child(2n+2) { + background: var(--bg-color2); +} + +/* +Rounded corners on table cells apparently don't work with +Firefox, so Firefox users won't have rounded corners +on tables. Can't fix that by myself. +*/ + +table tr:first-child th:first-child { + border-top-left-radius: var(--border-radius); +} + +table tr:first-child th:last-child { + border-top-right-radius: var(--border-radius); +} + +table tr:last-child td:first-child { + border-bottom-left-radius: var(--border-radius); +} + +table tr:last-child td:last-child { + border-bottom-right-radius: var(--border-radius); +} + +td, th { + padding: .5rem .8rem; +} + +th { + text-align: left; + border-bottom: 1px solid var(--border-color); +} + +/* Basic Layout */ + .baselayout { - display: flex; - flex-direction: column; justify-content: start; align-items: center; min-height: 100vh; width: 100vw; max-width: 100vw; } -main { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - flex-grow: 1; - width: 100%; - margin-top: 5vh; -} -.userpanel { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - margin-top: 1rem; - font-size: 1rem; - width: 94%; -} -.userinfo > span { - font-size: 1.1rem; - vertical-align: middle; -} -.userinfo > img { - vertical-align: middle; - width: 1.8rem; - height: 1.8rem; - margin: .5rem; -} -.userpanel > .horizontalbuttonlist { - margin-left: auto; - margin-right: 0; -} -.userbalancewarn { - color: var(--color-error); - font-weight: bold; -} -.content { - display: flex; - flex-direction: column; - justify-content: start; - align-items: center; - width: 100%; - flex-grow: 1; -} + .globalmessage { width: 100vw; z-index: 999; - display: flex; - justify-content: center; - align-items: center; background: var(--bg-globalmessage); padding: .3rem 0; } -.globalmessage div { + +.globalmessage > div { width: 96%; text-align: center; word-break: keep-all; word-wrap: break-word; box-sizing: border-box; } -/* DROP DOWN MENUS */ -.dropdownmenu { - display: flex; - flex-direction: column; + +.userpanel { + flex-direction: row; + margin-top: 1rem; + width: 94%; + gap: 1rem; +} + +.userinfo { + text-align: center; +} + +.userinfo > span { + vertical-align: middle; +} + +.userinfo > img { + vertical-align: middle; + width: 1.8rem; + height: 1.8rem; + margin: .5rem; +} + +.userpanel-buttons { + gap: .5rem; +} + +.userbalancewarn { + color: var(--color-error); + font-weight: bold; +} + +main { justify-content: flex-start; align-items: center; - border-radius: var(--glass-corner-radius); + flex-grow: 1; + width: 100%; } -.dropdownbutton { - width: fit-content; - z-index: 190; - text-align: center; - justify-content: center; + +.content { + justify-content: start; + align-items: center; + flex-grow: 1; + padding: 2rem 0; } -.dropdownbutton, .dropdownchoice { - font-size: 1rem; -} -.dropdownlist { - position: absolute; - display: flex; - flex-direction: column; - pointer-events: none; - border-radius: var(--glass-corner-radius) !important; - backdrop-filter: var(--glass-blur); - z-index: 200; - margin-top: 3.2rem; - opacity: 0%; - transition: opacity 100ms; -} -.dropdownchoice { - border-radius: 0 !important; - margin: 0; - margin-top: -1px; - text-align: center; - justify-content: center; - background: var(--glass-bg-dropdown) !important; - backdrop-filter: none !important; -} -.dropdownchoice:hover { - background: var(--glass-bg-dropdown-hover) !important; -} -.dropdownlist :first-child { - border-top-left-radius: var(--glass-corner-radius) !important; - border-top-right-radius: var(--glass-corner-radius) !important; -} -.dropdownlist :last-child { - border-bottom-left-radius: var(--glass-corner-radius) !important; - border-bottom-right-radius: var(--glass-corner-radius) !important; -} -.dropdownvisible .dropdownlist { - opacity: 100%; - visibility: visible; - pointer-events: visible; -} -/* FOOTER */ + .footer-container { z-index: 900; margin-top: auto; pointer-events: none; } + .footer { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - flex-wrap: wrap; - margin-top: 3rem; + margin-top: 1.5rem; padding-bottom: .3rem; text-align: center; pointer-events: initial; } -.footer div { + +.footer > div { font-size: .95rem; margin-top: .15rem; margin-bottom: .15rem; } -.footer div::after { + +.footer > div::after { margin-left: .5rem; content: "-"; margin-right: .5rem; } -.footer div:last-child::after { + +.footer > div:last-child::after { content: none; margin-left: 0; margin-right: 0; } -/* TABLES */ -table { - border-collapse: collapse; - border-spacing: 0; - text-align: left; - border-radius: var(--glass-corner-radius); - backdrop-filter: var(--glass-blur); + +/* Common */ + +.flex { + display: flex; } -tr { - background: var(--glass-bg-color1); + +.flex-row { + flex-direction: row; } -tr:nth-child(2n+2) { - background: var(--glass-bg-color2); + +.flex-column { + flex-direction: column; } -/* -Rounded corners on table cells apparently don't work with -Firefox, so Firefox users won't have rounded corners -on tables. Can't fix that by myself. -*/ -table tr:first-child th:first-child { - border-top-left-radius: var(--glass-corner-radius); + +.flex-center { + justify-content: center; + align-items: center; } -table tr:first-child th:last-child { - border-top-right-radius: var(--glass-corner-radius); + +.flex-wrap { + flex-wrap: wrap; } -table tr:last-child td:first-child { - border-bottom-left-radius: var(--glass-corner-radius); + +.gap-1rem { + gap: 1rem; } -table tr:last-child td:last-child { - border-bottom-right-radius: var(--glass-corner-radius); + +.fill { + height: 100%; + width: 100%; } -/* - */ -td, th { - padding: .5rem .8rem; + +.fill-vertical { + height: 100%; } -th { - text-align: left; - border-bottom: 1px solid var(--color); + +.buttons { + display: flex; + flex-direction: row; + align-items: center; + justify-content: end; + gap: 1rem; } -/* BUTTONS & OTHER INPUT ELEMENTS */ + .button, button { display: flex; align-items: center; @@ -244,100 +260,248 @@ th { font-family: var(--font-family); text-decoration: none; text-align: center !important; - background: var(--glass-bg); + background: var(--bg-color); color: var(--color); + font-size: 1rem; padding: .6rem .8rem; outline: none; - border: 1px solid var(--glass-border-color); - border-radius: var(--glass-corner-radius); - /*backdrop-filter: var(--glass-blur); disabled for performance reasons*/ + border: none; + border-bottom: 1px solid var(--border-color); + border-radius: var(--border-radius); cursor: pointer; user-select: none; + box-sizing: content-box; + width: fit-content; } + .button:hover, button:hover, .button:active, button:active { - background: var(--glass-bg-hover); + background: var(--bg-hover-color); } + .button:disabled, button:disabled { opacity: 40%; } -a { - color: var(--color); + +.appform > .forminfo { + width: 100%; + text-align: left; + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 2rem; } -input[type="number"] { + +.forminfo > span:last-child { + float: right; +} + +.appform > .forminput { + width: 100%; + flex-direction: row; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; + gap: 1rem; +} + +.appform > .statusinfo { + margin-top: .5rem; +} + +.dropdownmenu { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + border-radius: var(--border-radius); +} + +.dropdownbutton { + width: fit-content; + z-index: 190; + text-align: center; + justify-content: center; +} + +.dropdownlist { + position: absolute; + display: flex; + flex-direction: column; + pointer-events: none; + border-radius: var(--border-radius) !important; + z-index: 200; + margin-top: 3.2rem; + opacity: 0%; + transition: opacity 100ms; +} + +.dropdownchoice { + border-radius: 0 !important; + margin: 0; + text-align: center; + justify-content: center; + background: var(--bg-color2) !important; + backdrop-filter: none !important; + width: initial; +} + +.dropdownchoice:hover { + background: var(--bg-hover-color2) !important; +} + +.dropdownlist :first-child { + border-top-left-radius: var(--border-radius) !important; + border-top-right-radius: var(--border-radius) !important; +} + +.dropdownlist :last-child { + border-bottom-left-radius: var(--border-radius) !important; + border-bottom-right-radius: var(--border-radius) !important; +} + +.dropdownvisible .dropdownlist { + opacity: 100%; + visibility: visible; + pointer-events: visible; +} + +.customnumberinput { + height: 2.2rem; +} + +.customnumberinput button { + min-width: 2.5rem !important; + width: 2.5rem !important; + padding: 0; + margin: 0; + height: 100%; +} + +.customnumberinput-minus { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + z-index: 10; +} + +.customnumberinput-plus { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + z-index: 10; +} + +.customnumberinput input[type="number"] { + height: 100%; + width: 4rem; + padding: 0; + margin: 0; + background: var(--bg-color2); + border-radius: 0 !important; -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; } -input[type="number"]::-webkit-inner-spin-button { - display: none; -} -input[type="text"], input[type="password"], input[type="number"] { - background: var(--glass-bg-color2); - outline: none; - padding: .4rem .6rem; - font-size: .9rem; - color: var(--color); - text-align: center; - border: none; - border-radius: var(--glass-corner-radius); -} -/**** OTHER CLASSES ****/ -.centeringflex { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - padding: 2rem 1rem; -} -.horizontalbuttonlist { - display: flex; - flex-direction: row; - align-items: flex-end; - justify-content: space-between; -} -.horizontalbuttonlist > .button, .horizontalbuttonlist > button, .horizontalbuttonlist > div { - margin: 0 .5rem; -} + .errortext { - margin-top: 1rem; color: var(--color-error); } + .nodisplay { display: none !important; } -.heading { + +/* Login */ + +.userlist { + width: 60%; + list-style: none; + margin: 0; + padding: 1rem; + gap: 1rem; +} + +.userlist > li { + margin-bottom: .5rem; + padding: 0 .5rem; +} + +.userlist > li > img { + margin-right: auto; + margin-left: 0; + height: 2rem; + width: 2rem; +} + +.userlist > li > div { + flex-grow: 1; + text-align: center; + padding: .8rem 1.1rem; +} + +.loginform { + gap: 1rem; + flex-direction: row; +} + +.loginform > .buttons { margin-top: 0; } -/* MISC / GENERAL */ -h1 { - text-align: center; - font-size: 1.8rem; + +/* Drinks List */ + +.drinks-list { + justify-content: center; + align-items: start; + padding: 0; + width: 60%; } -/* MOBILE OPTIMIZATIONS */ -@media only screen and (max-width: 700px) { - main { - margin-top: 2rem; + +.drinks-list > li { + flex-grow: 1; +} + +.drinks-list > li > .button { + width: 100%; + justify-content: space-between; + padding: .8rem 1.1rem; +} + +/* Responsive */ + +@media only screen and (max-width: 1200px) { + .userlist { + width: 75%; } - .globalmessage span { + .drinks-list { + width: 70%; + } +} + +@media only screen and (max-width: 1000px) { + .userlist { width: 90%; } + .drinks-list { + width: 80%; + } +} + +@media only screen and (max-width: 700px) { .userpanel { flex-direction: column; - justify-content: start; - align-items: center; } - .userpanel > .horizontalbuttonlist { - margin-right: 0; - margin-left: 0; - margin-top: .5rem; - justify-content: center; - flex-wrap: wrap; + .userlist { + gap: 0.25rem; } - .userpanel > .horizontalbuttonlist > .button, - .userpanel > .horizontalbuttonlist > .dropdownmenu { - margin: 0.25rem; + .userlist > li { + width: 100%; } -} \ No newline at end of file + .userlist > li > div { + margin-right: 2rem; + } + .loginform { + flex-direction: column; + } + .drinks-list { + width: 90%; + } +} diff --git a/app/static/css/simple-keyboard_dark.css b/app/static/css/simple-keyboard_dark.css index 8dc7240..16bfec5 100644 --- a/app/static/css/simple-keyboard_dark.css +++ b/app/static/css/simple-keyboard_dark.css @@ -4,7 +4,6 @@ .simple-keyboard.darkTheme { width: 50rem; max-width: 100%; - margin-top: 2rem; background: transparent; } .simple-keyboard.darkTheme .hg-button { @@ -12,13 +11,13 @@ display: flex; justify-content: center; align-items: center; - background: var(--glass-bg); + background: var(--bg-color); color: white; border: none; - border-bottom: 1px solid var(--glass-border-color); + border-bottom: 1px solid var(--border-color); } .simple-keyboard.darkTheme .hg-button:active, .simple-keyboard.darkTheme .hg-button:hover { color: white; - background: var(--glass-bg-hover); + background: var(--bg-hover-color); } diff --git a/app/static/css/statistics.css b/app/static/css/statistics.css deleted file mode 100644 index 5abc145..0000000 --- a/app/static/css/statistics.css +++ /dev/null @@ -1,53 +0,0 @@ -.maincontainer { - min-width: 70vw; - display: flex; - flex-direction: column; - align-items: center; - justify-content: start; -} -.tablescontainer { - display: flex; - flex-direction: column; - align-items: center; - justify-content: start; - width: 95%; - margin-top: 2rem; -} -.statisticstable { - margin-bottom: 2rem; - padding-bottom: 1rem; - display: flex; - flex-direction: column; - justify-content: start; - align-items: center; - text-align: center; -} -.statisticstable h1 { - margin-top: 0; - font-size: 1.2rem; - text-align: left; - min-width: 10rem; - text-align: center; -} -.statisticstable table { - min-width: 20vw; - width: fit-content; -} -.statisticstable th:last-child { - text-align: right; -} -.statisticstable td:last-child { - text-align: right; -} -@media only screen and (max-width: 700px) { - .statisticstable h1 { - min-width: 90vw; - } - .statisticstable table { - min-width: 80vw; - } - .statisticstable { - margin-bottom: 2rem; - padding-bottom: 1rem; - } -} \ No newline at end of file diff --git a/app/static/js/autoreload.js b/app/static/js/autoreload.js index 0c30078..a86e6ff 100644 --- a/app/static/js/autoreload.js +++ b/app/static/js/autoreload.js @@ -1,3 +1,3 @@ setInterval(() => { location.reload(); -}, 1000*60*2); // reload after 2 minutes \ No newline at end of file +}, 1000*60*2); // reload after 2 minutes diff --git a/app/static/js/custom_number_input.js b/app/static/js/custom_number_input.js index 299e02b..f39d100 100644 --- a/app/static/js/custom_number_input.js +++ b/app/static/js/custom_number_input.js @@ -1,5 +1,4 @@ -{ - +(() => { document.addEventListener("DOMContentLoaded", () => { // get all customnumberinput Elements let customNumberInputElements = document.getElementsByClassName("customnumberinput"); @@ -8,16 +7,11 @@ // number input let numberFieldElement = element.getElementsByClassName("customnumberinput-field")[0]; // minus button - element.getElementsByClassName("customnumberinput-minus")[0].addEventListener("click", () => { - alterCustomNumberField(numberFieldElement, -1) - }); + element.getElementsByClassName("customnumberinput-minus")[0].addEventListener("click", () => alterCustomNumberField(numberFieldElement, -1)); // plus button - element.getElementsByClassName("customnumberinput-plus")[0].addEventListener("click", () => { - alterCustomNumberField(numberFieldElement, +1) - }); + element.getElementsByClassName("customnumberinput-plus")[0].addEventListener("click", () => alterCustomNumberField(numberFieldElement, +1)); }) }) - function alterCustomNumberField(numberFieldElement, n) { numberFieldElement.value = Math.min( Math.max( @@ -26,5 +20,4 @@ numberFieldElement.max || Number.MAX_VALUE ); } - -} \ No newline at end of file +})(); diff --git a/app/static/js/deposit.js b/app/static/js/deposit.js index 4e8905d..c2b6785 100644 --- a/app/static/js/deposit.js +++ b/app/static/js/deposit.js @@ -1,28 +1,18 @@ document.addEventListener("DOMContentLoaded", () => { - // elements - let depositForm = document.getElementById("depositform"); let statusInfo = document.getElementById("statusinfo"); let depositSubmitButton = document.getElementById("depositsubmitbtn"); - // event listener for deposit form // this implements a custom submit method - depositForm.addEventListener("submit", (event) => { - depositSubmitButton.disabled = true; - event.preventDefault(); // Don't do the default submit action! - let xhr = new XMLHttpRequest(); let formData = new FormData(depositForm); - xhr.addEventListener("load", (event) => { - status_ = event.target.status; response_ = event.target.responseText; - if (status_ == 200 && response_ == "success") { statusInfo.innerText = "Success. Redirecting soon."; window.location.replace("/"); @@ -32,18 +22,13 @@ document.addEventListener("DOMContentLoaded", () => { statusInfo.innerText = "An error occured. Redirecting in 5 seconds..."; window.setTimeout(() => { window.location.replace("/") }, 5000); } - }) - xhr.addEventListener("error", (event) => { statusInfo.classList.add("errortext"); statusInfo.innerText = "An error occured. Redirecting in 5 seconds..."; window.setTimeout(() => { window.location.replace("/") }, 5000); }) - xhr.open("POST", "/api/deposit"); xhr.send(formData); - }); - -}) \ No newline at end of file +}); diff --git a/app/static/js/login.js b/app/static/js/login.js index 2f83dcc..0c43a72 100644 --- a/app/static/js/login.js +++ b/app/static/js/login.js @@ -1,5 +1,4 @@ (() => { - // Define variables let usernameInputElement; let passwordInputElement; @@ -9,14 +8,13 @@ let userlistButtons; let pinpadButtons; let userlistContainerElement; - // Add event listeners after DOM Content loaded document.addEventListener("DOMContentLoaded", () => { // elements usernameInputElement = document.getElementById("id_username"); passwordInputElement = document.getElementById("id_password"); submitButton = document.getElementById("submit_login"); - passwordOverlayElement = document.getElementById("passwordoverlaycontainer"); + passwordOverlayElement = document.getElementById("passwordoverlay-container"); pwOverlayCancelButton = document.getElementById("pwocancel"); userlistContainerElement = document.getElementById("userlistcontainer"); userlistButtons = document.getElementsByClassName("userlistbutton"); @@ -32,21 +30,15 @@ hide_password_overlay(); }); }) - function set_username(username) { usernameInputElement.value = username; } - function show_password_overlay() { window.scrollTo(0, 0); passwordOverlayElement.classList.remove("nodisplay"); - userlistContainerElement.classList.add("nodisplay"); } - function hide_password_overlay() { passwordOverlayElement.classList.add("nodisplay"); - userlistContainerElement.classList.remove("nodisplay"); passwordInputElement.value = ""; } - -})() \ No newline at end of file +})(); diff --git a/app/static/js/main.js b/app/static/js/main.js index 58b2373..711aed8 100644 --- a/app/static/js/main.js +++ b/app/static/js/main.js @@ -1,21 +1,14 @@ document.addEventListener("DOMContentLoaded", () => { - let dropdownmenuElement = document.getElementById("dropdownmenu"); let dropdownmenuButtonElement = document.getElementById("dropdownmenu-button"); - if (dropdownmenuButtonElement != null) { - dropdownmenuButtonElement.addEventListener("click", () => { - if (dropdownmenuElement.classList.contains("dropdownvisible")) { dropdownmenuElement.classList.remove("dropdownvisible"); } else { dropdownmenuElement.classList.add("dropdownvisible"); } - }) - } - -}) \ No newline at end of file +}); diff --git a/app/static/js/order.js b/app/static/js/order.js index 46f88b6..801e167 100644 --- a/app/static/js/order.js +++ b/app/static/js/order.js @@ -1,61 +1,39 @@ document.addEventListener("DOMContentLoaded", () => { - // elements - let orderNumberofdrinksInput = document.getElementById("numberofdrinks"); let orderNumberofdrinksBtnA = document.getElementById("numberofdrinks-btn-minus"); let orderNumberofdrinksBtnB = document.getElementById("numberofdrinks-btn-plus"); let orderSumElement = document.getElementById("ordercalculatedsum"); - let orderFormElement = document.getElementById("orderform"); let statusInfoElement = document.getElementById("statusinfo"); let orderSubmitButton = document.getElementById("ordersubmitbtn"); - - // calculate & display sum - let orderPricePerDrink = parseFloat(document.getElementById("priceperdrink").dataset.drinkPrice); - function calculateAndDisplaySum() { - setTimeout(() => { - let numberOfDrinks = parseFloat(orderNumberofdrinksInput.value); if (isNaN(numberOfDrinks)) { numberOfDrinks = 1; } let calculated_sum = orderPricePerDrink * numberOfDrinks; orderSumElement.innerText = new Intl.NumberFormat(undefined, {minimumFractionDigits: 2}).format(calculated_sum); - }, 25); - } - orderNumberofdrinksInput.addEventListener("input", calculateAndDisplaySum); orderNumberofdrinksBtnA.addEventListener("click", calculateAndDisplaySum); orderNumberofdrinksBtnB.addEventListener("click", calculateAndDisplaySum); - - // custom submit method - orderFormElement.addEventListener("submit", (event) => { - orderSubmitButton.disabled = true; - event.preventDefault(); // Don't do the default submit action! - if (isNaN(parseFloat(orderNumberofdrinksInput.value))) { orderNumberofdrinksInput.value = 1; } - let xhr = new XMLHttpRequest(); let formData = new FormData(orderFormElement); - xhr.addEventListener("load", (event) => { - status_ = event.target.status; response_ = event.target.responseText; - if (status_ == 200 && response_ == "success") { statusInfoElement.innerText = "Success."; window.location.replace("/"); @@ -65,18 +43,13 @@ document.addEventListener("DOMContentLoaded", () => { statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); } - }) - xhr.addEventListener("error", (event) => { statusInfoElement.classList.add("errortext"); statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); }) - xhr.open("POST", "/api/order-drink"); xhr.send(formData); - }); - -}) \ No newline at end of file +}); diff --git a/app/static/js/simple-keyboard_configure.js b/app/static/js/simple-keyboard_configure.js index 7d9bd46..326c68e 100644 --- a/app/static/js/simple-keyboard_configure.js +++ b/app/static/js/simple-keyboard_configure.js @@ -43,7 +43,6 @@ } // Check if on smartphone let onSmartphone = navigator.userAgent.toLowerCase().match(/android|webos|iphone|ipod|blackberry/i) != null; - console.log(onSmartphone) // Configure keyboard when all DOM content has loaded document.addEventListener("DOMContentLoaded", () => { if (!onSmartphone) { @@ -97,4 +96,4 @@ } } }); -})() \ No newline at end of file +})(); diff --git a/app/static/js/supply.js b/app/static/js/supply.js index 90e8340..04021e0 100644 --- a/app/static/js/supply.js +++ b/app/static/js/supply.js @@ -1,35 +1,23 @@ document.addEventListener("DOMContentLoaded", () => { - // elements - let supplyDescriptionElement = document.getElementById("supplydescription"); let supplyPriceElement = document.getElementById("supplyprice"); - let supplyFormElement = document.getElementById("supplyform"); let statusInfoElement = document.getElementById("statusinfo"); let supplySubmitButton = document.getElementById("supplysubmitbtn"); - // custom submit method - supplyFormElement.addEventListener("submit", (event) => { - supplySubmitButton.disabled = true; - event.preventDefault(); // Don't do the default submit action! - if (isNaN(parseFloat(supplyPriceElement.value)) || supplyDescriptionElement.value == "") { statusInfoElement.innerText = "Please enter a description and price." supplySubmitButton.disabled = false; } - let xhr = new XMLHttpRequest(); let formData = new FormData(supplyFormElement); - xhr.addEventListener("load", (event) => { - status_ = event.target.status; response_ = event.target.responseText; - if (status_ == 200 && response_ == "success") { statusInfoElement.innerText = "Success."; window.location.replace("/"); @@ -39,18 +27,13 @@ document.addEventListener("DOMContentLoaded", () => { statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); } - }) - xhr.addEventListener("error", (event) => { statusInfoElement.classList.add("errortext"); statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); }) - xhr.open("POST", "/api/supply"); xhr.send(formData); - }); - -}) \ No newline at end of file +}); diff --git a/app/templates/baselayout.html b/app/templates/baselayout.html index 7d0a5e3..5783cf9 100644 --- a/app/templates/baselayout.html +++ b/app/templates/baselayout.html @@ -1,9 +1,6 @@ - {% load i18n %} - - @@ -13,44 +10,27 @@ {% block title %}{% endblock %} {% block headAdditional %}{% endblock %} - - -
- +
{% include "globalmessage.html" %} - {% if user.is_authenticated %} - {% include "userpanel.html" %} - {% endif %} - -
- +
{% if user.is_authenticated or "accounts/login/" in request.path or "accounts/logout/" in request.path or "admin/logout/" in request.path %} - -
- {% block content %}{% endblock %} -
- +
+ {% block content %}{% endblock %} +
{% else %} - -
- {% translate "An error occured. Please log out and log in again." %} -
- log out -
- +
+ {% translate "An error occured. Please log out and log in again." %} +
+ log out +
{% endif %} -
- {% include "footer.html" %} -
- - \ No newline at end of file diff --git a/app/templates/deposit.html b/app/templates/deposit.html index 5e06dd3..9334b3c 100644 --- a/app/templates/deposit.html +++ b/app/templates/deposit.html @@ -3,45 +3,34 @@ {% load i18n %} {% block title %} - {% translate "Drinks - Deposit" %} +{% translate "Drinks - Deposit" %} {% endblock %} {% block headAdditional %} - - - + + {% endblock %} - {% block content %} - -
- {% csrf_token %} - -

{% translate "Deposit" %}

- -
- {% translate "Amount" %} {{ currency_suffix }}: - - - -
- -
- - - -
- +
+ {% csrf_token %} +

{% translate "Deposit" %}

+
+ {% translate "Amount" %} {{ currency_suffix }}: + + + +
+
- - - - -{% endblock %} + +
+ + +{% endblock %} \ No newline at end of file diff --git a/app/templates/footer.html b/app/templates/footer.html index e89bbc5..89d58c6 100644 --- a/app/templates/footer.html +++ b/app/templates/footer.html @@ -1,8 +1,7 @@ {% load i18n %} - + \ No newline at end of file diff --git a/app/templates/globalmessage.html b/app/templates/globalmessage.html index 83fd733..9b33850 100644 --- a/app/templates/globalmessage.html +++ b/app/templates/globalmessage.html @@ -1,5 +1,5 @@ {% if global_message != "" %} -
+
{{ global_message }}
{% endif %} \ No newline at end of file diff --git a/app/templates/history.html b/app/templates/history.html index 7abd1f3..89d689a 100644 --- a/app/templates/history.html +++ b/app/templates/history.html @@ -3,35 +3,26 @@ {% load i18n %} {% block title %} - {% translate "Drinks - History" %} +{% translate "Drinks - History" %} {% endblock %} -{% block headAdditional %} - -{% endblock %} - - {% block content %} - -

{% translate "History" %}

- - {% if history %} - - - - - - {% for h in history %} - - - - - {% endfor %} -
{% translate "last 30 actions" %}
{{ h.0 }}{{ h.1 }}
- {% else %} - {% translate "No history." %} - {% endif %} - - - -{% endblock %} +

{% translate "History" %}

+{% if history %} + + + + + + {% for h in history %} + + + + + {% endfor %} +
{% translate "last 30 actions" %}
{{ h.0 }}{{ h.1 }}
+{% else %} +{% translate "No history." %} +{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index 3756b0b..076af03 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -3,45 +3,33 @@ {% load i18n %} {% block title %} - {% translate "Drinks - Home" %} -{% endblock %} - -{% block headAdditional %} - +{% translate "Drinks - Home" %} {% endblock %} {% block content %} - -

{% translate "Available Drinks" %}

- - {% if available_drinks %} - - - +

{% translate "Available Drinks" %}

+{% if available_drinks %} + +{% else %} +{% translate "No drinks available." %} +{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/app/templates/order.html b/app/templates/order.html index d720197..2cae204 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -7,94 +7,68 @@ {% translate "Drinks - Order" %} {% endblock %} -{% block headAdditional %} - - -{% endblock %} - - {% block content %} - - {% if drink and drink.available > 0 and not drink.deleted %} - - {% if user.balance > 0 or user.allow_order_with_negative_balance %} - -
- {% csrf_token %} - -

{% translate "Order" %}

- -
- {% translate "Drink" %}: - {{ drink.product_name }} -
-
- {% translate "Price per Item" %} ({{ currency_suffix }}): - - {{ drink.price }} - -
- - {% if not drink.do_not_count %} -
- {% translate "Available" %}: - {{ drink.available }} -
+
+{% if drink and drink.available > 0 and not drink.deleted %} +{% if user.balance > 0 or user.allow_order_with_negative_balance %} + + {% csrf_token %} +

{% translate "Order" %}

+
+ {% translate "Drink" %}: + {{ drink.product_name }} +
+
+ {% translate "Price per Item" %} ({{ currency_suffix }}): + + {{ drink.price }} + +
+ {% if not drink.do_not_count %} +
+ {% translate "Available" %}: + {{ drink.available }} +
+ {% endif %} +
+ {% translate "Sum" %} ({{ currency_suffix }}): + {{ drink.price }} +
+
+ {% translate "Count" %}: + + + {% if drink.do_not_count %} + + {% else %} + {% endif %} - -
- {% translate "Sum" %} ({{ currency_suffix }}): - {{ drink.price }} -
- -
- {% translate "Count" %}: - - - {% if drink.do_not_count %} - - {% else %} - - {% endif %} - - -
- -
- - - - - - - - - - - - {% else %} - -
-

{% translate "Your balance is too low to order a drink." %}

- {% translate "back" %} -
- - {% endif %} - - {% else %} - -
+ + +
+
+ + + + + +{% else %} +
+

{% translate "Your balance is too low to order a drink." %}

+ {% translate "back" %} +
+{% endif %} +{% else %} +

{% translate "This drink is not available." %}

{% translate "back" %}
- - {% endif %} - +{% endif %} - -{% endblock %} +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/registration/logged_out.html b/app/templates/registration/logged_out.html index 38bb024..c4d69fc 100644 --- a/app/templates/registration/logged_out.html +++ b/app/templates/registration/logged_out.html @@ -1,24 +1,19 @@ - {% extends "baselayout.html" %} {% load i18n %} {% block title %} - {% translate "Drinks - Logged Out" %} +{% translate "Drinks - Logged Out" %} {% endblock %} {% block headAdditional %} - + {% endblock %} {% block content %} - -
- {% translate "Logged out! You will be redirected shortly." %} -

- {% translate "Click here if automatic redirection does not work." %} -
- - - -{% endblock %} +
+ {% translate "Logged out! You will be redirected shortly." %} + {% translate "Click here if automatic redirection does not work." %} +
+ +{% endblock %} \ No newline at end of file diff --git a/app/templates/registration/login.html b/app/templates/registration/login.html index f287437..837dc70 100644 --- a/app/templates/registration/login.html +++ b/app/templates/registration/login.html @@ -5,66 +5,56 @@ {% load static %} {% block title %} - {% translate "Drinks - Login" %} +{% translate "Drinks - Login" %} {% endblock %} {% block headAdditional %} - - - + + {% endblock %} {% block content %} - - {% if error_message %} -

{{ error_message }}

- {% endif %} - -
-
-
- {% csrf_token %} -

{% translate "Log in" %}

- - -
- - -
-
-
- - {% get_current_language as LANGUAGE_CODE %} -
- - +{% if error_message %} +

{{ error_message }}

+{% endif %} +
+
+

{% translate "Log in" %}

+
+ {% csrf_token %} + + +
+ + +
+
- + + {% get_current_language as LANGUAGE_CODE %} +
+ + +
+

{% translate "Choose your account" %}

- -
-
    - {% for user_ in user_list %} -
  • - -
    - {% if user_.first_name %} - - {% if user_.last_name %} - {{ user_.last_name }}, - {% endif %} - - {{ user_.first_name }} - - {% else %} - {{ user_.username }} - {% endif %} -
    -
  • - {% endfor %} -
-
- - - -{% endblock %} +
    + {% for user_ in user_list %} +
  • + +
    + {% if user_.first_name %} + {% if user_.last_name %} + {{ user_.last_name }}, + {% endif %} + {{ user_.first_name }} + {% else %} + {{ user_.username }} + {% endif %} +
    +
  • + {% endfor %} +
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/templates/statistics.html b/app/templates/statistics.html index 662e7d4..4f938b9 100644 --- a/app/templates/statistics.html +++ b/app/templates/statistics.html @@ -3,146 +3,62 @@ {% load i18n %} {% block title %} - {% translate "Drinks - Statistics" %} +{% translate "Drinks - Statistics" %} {% endblock %} -{% block headAdditional %} - -{% endblock %} - - {% block content %} - -

{% translate "Statistics" %}

- -
- -
- -
-

{% translate "Your orders per drink" %}

- {% if noyopd %} - - - - - - {% for row in noyopd %} - - - - - {% endfor %} -
{% translate "drink" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
-

{% translate "All orders per drink" %}

- {% if noaopd %} - - - - - - {% for row in noaopd %} - - - - - {% endfor %} -
{% translate "drink" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
-

{% translate "Your orders per month (last 12 months)" %}

- {% if yopml12m %} - - - - - - {% for row in yopml12m %} - - - - - {% endfor %} -
{% translate "month" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
-

{% translate "All orders per month (last 12 months)" %}

- {% if aopml12m %} - - - - - - {% for row in aopml12m %} - - - - - {% endfor %} -
{% translate "month" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
-

{% translate "Your orders per weekday" %}

- {% if yopwd %} - - - - - - {% for row in yopwd %} - - - - - {% endfor %} -
{% translate "day" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
-

{% translate "All orders per weekday" %}

- {% if aopwd %} - - - - - - {% for row in aopwd %} - - - - - {% endfor %} -
{% translate "day" %}{% translate "count" %}
{{ row.0 }}{{ row.1 }}
- {% else %} -
{% translate "No history." %}
- {% endif %} -
- -
- +

{% translate "Statistics" %}

+
+
+

{% translate "Orders per drink" %}

+ + + + + + + {% for key, values in orders_per_drink.items %} + + + + + + {% endfor %} +
{% translate "drink" %}{% translate "you" %}{% translate "all" %}
{{ key }}{{ values.a|default:"0" }}{{ values.b|default:"0" }}
- - - -{% endblock %} +
+

{% translate "Orders per month (last 12 months)" %}

+ + + + + + + {% for key, values in orders_per_month.items %} + + + + + + {% endfor %} +
{% translate "month" %}{% translate "you" %}{% translate "all" %}
{{ key }}{{ values.a|default:"0" }}{{ values.b|default:"0" }}
+
+
+

{% translate "Orders per weekday" %}

+ + + + + + + {% for key, values in orders_per_weekday.items %} + + + + + + {% endfor %} +
{% translate "day" %}{% translate "you" %}{% translate "all" %}
{{ key }}{{ values.a|default:"0" }}{{ values.b|default:"0" }}
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/templates/supply.html b/app/templates/supply.html index fabb224..f907f2d 100644 --- a/app/templates/supply.html +++ b/app/templates/supply.html @@ -7,56 +7,36 @@ {% translate "Drinks - Supply" %} {% endblock %} -{% block headAdditional %} - - -{% endblock %} - - {% block content %} - - {% if user.is_superuser or user.allowed_to_supply %} - -
- {% csrf_token %} - -

{% translate "Supply" %}

- -
- {% translate "Description" %}: - - - -
- -
- {% translate "Price" %} ({{ currency_suffix }}): - - - -
- -
- - - -
- - - - - {% else %} - -
-

{% translate "You are not allowed to view this site." %}

- {% translate "back" %} +{% if user.is_superuser or user.allowed_to_supply %} +
+ {% csrf_token %} +

{% translate "Supply" %}

+
+ {% translate "Description" %}: + + +
- - {% endif %} - - - -{% endblock %} +
+ {% translate "Price" %} ({{ currency_suffix }}): + + + +
+
+ +
+ + +{% else %} +
+

{% translate "You are not allowed to view this site." %}

+ {% translate "back" %} +
+{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/app/templates/userpanel.html b/app/templates/userpanel.html index d0809fd..159dcf5 100644 --- a/app/templates/userpanel.html +++ b/app/templates/userpanel.html @@ -1,24 +1,24 @@ {% load i18n %} {% load static %} -
+
{% 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 %} - {% translate "User" %}: {{ user.username }} + {% translate "User" %}: {{ user.username }} {% endif %}  -  {% if user.balance < 0.01 %} - {% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }} + {% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }} {% else %} - {% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }} + {% translate "Balance" %}: {{ user.balance }}{{ currency_suffix }} {% endif %}
-
+
Home {% translate "Deposit" %} {% translate "Logout" %} @@ -30,13 +30,13 @@ {% translate "History" %} {% translate "Statistics" %} {% if user.is_superuser or user.is_staff %} - Admin Panel + Admin Panel {% endif %} {% if user.is_superuser or user.allowed_to_supply %} - {% translate "Supply" %} + {% translate "Supply" %} {% endif %} {% translate "Change Password" %}
-
+
\ No newline at end of file diff --git a/app/views.py b/app/views.py index a9cae08..7f3ea30 100644 --- a/app/views.py +++ b/app/views.py @@ -17,7 +17,7 @@ from django.shortcuts import render from django.utils.translation import gettext as _ from django.utils.formats import decimal -from . import sql_queries +from . import db_queries from .models import Drink from .models import Order @@ -62,7 +62,7 @@ def index(request): @login_required def history(request): context = { - "history": sql_queries.select_history(request.user, language_code=request.LANGUAGE_CODE), + "history": db_queries.select_history(request.user, language_code=request.LANGUAGE_CODE), } return render(request, "history.html", context) @@ -85,12 +85,9 @@ def deposit(request): @login_required def statistics(request): context = { - "yopml12m": sql_queries.select_yopml12m(request.user), - "aopml12m": sql_queries.select_aopml12m(), - "yopwd": sql_queries.select_yopwd(request.user), - "aopwd": sql_queries.select_aopwd(), - "noyopd": sql_queries.select_noyopd(request.user), - "noaopd": sql_queries.select_noaopd() + "orders_per_month": db_queries.orders_per_month(request.user), + "orders_per_weekday": db_queries.orders_per_weekday(request.user), + "orders_per_drink": db_queries.orders_per_drink(request.user), } return render(request, "statistics.html", context) diff --git a/scripts/_bootstrap.py b/scripts/_bootstrap.py index 1821369..9533953 100755 --- a/scripts/_bootstrap.py +++ b/scripts/_bootstrap.py @@ -119,7 +119,6 @@ if __name__ == "__main__": environment_caddy = os.environ environment_caddy["DATADIR"] = str(data_directory.absolute()) environment_caddy["CADDY_HOSTS"] = ", ".join(config["caddy"]["hosts"]) - print(environment_caddy["CADDY_HOSTS"]) environment_caddy["HTTP_PORT"] = str(config["caddy"]["http_port"]) environment_caddy["HTTPS_PORT"] = str(config["caddy"]["https_port"]) environment_caddy["APPLICATION_PORT"] = str(config["app"]["application_port"])