From 85e49795bc10de0be9308bb952fb1f057a8ef6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 19 Apr 2023 18:23:24 +0200 Subject: [PATCH 01/19] Added missing zero to numeric keyboard layout --- app/static/js/simple-keyboard_configure.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/static/js/simple-keyboard_configure.js b/app/static/js/simple-keyboard_configure.js index 326c68e..8aa9aec 100644 --- a/app/static/js/simple-keyboard_configure.js +++ b/app/static/js/simple-keyboard_configure.js @@ -38,7 +38,8 @@ "1 2 3", "4 5 6", "7 8 9", - "{bksp} . ," + "0 . ,", + "{bksp}" ] } // Check if on smartphone From 51fda112815919a8c8598336db9f441fa4201ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 19 Apr 2023 18:24:05 +0200 Subject: [PATCH 02/19] Bumped version to 17 --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index 4aa13e3..8f4ba06 100755 --- a/start.sh +++ b/start.sh @@ -11,6 +11,6 @@ chmod -c -R g-w,o-rwx .gitignore export PYTHONPATH="$basedir" export DJANGO_SETTINGS_MODULE="project.settings" -export APP_VERSION="16" +export APP_VERSION="17" exec ./scripts/_bootstrap.py "$@" From dd36c3c1149797ea81c93469476858803e1f9702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 7 Jun 2023 19:04:17 +0200 Subject: [PATCH 03/19] Fixed a security issue on the login page by clearing the buffer of the virtual keyboard when pressing 'cancel'. --- app/static/js/login.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/static/js/login.js b/app/static/js/login.js index 0c43a72..cc9274d 100644 --- a/app/static/js/login.js +++ b/app/static/js/login.js @@ -6,7 +6,6 @@ let passwordOverlayElement; let pwOverlayCancelButton; let userlistButtons; - let pinpadButtons; let userlistContainerElement; // Add event listeners after DOM Content loaded document.addEventListener("DOMContentLoaded", () => { @@ -40,5 +39,9 @@ function hide_password_overlay() { passwordOverlayElement.classList.add("nodisplay"); passwordInputElement.value = ""; + // Dispatch an Input Event to the input element to trigger the on- + // screen keyboard to update its buffer. This fixes a security + // issue on the login page. + passwordInputElement.dispatchEvent(new Event("input", {bubbles: true})); } })(); From 60d2df9fb9d84a9fa189dc3a4fa2624e85eb9231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Mon, 30 Oct 2023 18:36:44 +0100 Subject: [PATCH 04/19] Use a dedicated logfile for session cleanup --- scripts/_bootstrap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/_bootstrap.py b/scripts/_bootstrap.py index 71ce28d..142781e 100755 --- a/scripts/_bootstrap.py +++ b/scripts/_bootstrap.py @@ -32,6 +32,7 @@ configuration_file = data_directory / "config.yml" caddyfile = data_directory / "Caddyfile" logfile_caddy = logfile_directory / "caddy.log" logfile_app = logfile_directory / "app.log" +logfile_sessioncleanup = logfile_directory / "session-cleanup.log" class MonitoredSubprocess: @@ -183,6 +184,6 @@ if __name__ == "__main__": MonitoredSubprocess( "Session Autocleaner", ["./scripts/_session-autocleaner.py", str(config["app"]["session_clear_interval"])], - logfile_app) + logfile_sessioncleanup) ] start_and_monitor(procs) From 31ae25116441549596b3d3f840c7e8a3a4864749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 31 Oct 2023 18:00:20 +0100 Subject: [PATCH 05/19] Fixed orders/weekday statistic, improved statistics page layout --- app/db_queries.py | 44 +++++++++++++++------------ app/locales/de/LC_MESSAGES/django.mo | Bin 3672 -> 3624 bytes app/locales/de/LC_MESSAGES/django.po | 12 ++++---- app/static/css/main.css | 17 +++++++++++ app/templates/statistics.html | 28 ++++++++--------- 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/app/db_queries.py b/app/db_queries.py index 656bbda..0363896 100644 --- a/app/db_queries.py +++ b/app/db_queries.py @@ -3,6 +3,7 @@ from django.conf import settings from django.db import connection from django.utils.translation import gettext +from calendar import day_name COMBINE_ALPHABET = "abcdefghijklmnopqrstuvwxyz" @@ -102,29 +103,34 @@ def orders_per_month(user) -> list: group by "month" order by "month" desc; """) - return _combine_results([result_user, result_all]) + return _combine_results([result_all, result_user]) 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 = _db_select(f""" + with q_all as ( + select + extract(isodow from datetime) as "d", + sum(amount) as "c" + from app_order + group by d + ), q_user as ( + select + extract(isodow from datetime) as "d", + sum(amount) as "c" + from app_order + where user_id = {user.pk} + group by d + ) + select q_all.d as "day", q_all.c, q_user.c from q_all full join q_user on q_all.d = q_user.d + group by day, q_all.c, q_user.c + order by day asc; """) - 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]) + for i in range(len(result)): + day_, all_, user_ = result[i] + result[i] = (day_name[int(day_)-1], all_, user_) + return result def orders_per_drink(user) -> list: @@ -148,4 +154,4 @@ def orders_per_drink(user) -> list: group by d.product_name order by "data" desc; """) - return _combine_results([result_user, result_all]) + return _combine_results([result_all, result_user]) diff --git a/app/locales/de/LC_MESSAGES/django.mo b/app/locales/de/LC_MESSAGES/django.mo index d7435cb07bae255287ca6bfa885580bd2e060d15..73d1c7135393360c788e1d6c270bab1427e0c8a3 100644 GIT binary patch delta 1133 zcmZ9~Pe@cz6vy#1IyPF9Nq?-yDaS@F`=e>4maRgtqQ4Xf?WX3XqP~%FhW;&{E2&m7 zwsBLCE}~it4MY$W6hy1m1FecS(W181rtfdO7I^W@=br0*_uYH$E5{$li}6qpHM7Bp zSq+}YdK|_&yo#%F3ajxJuEGH0IE%HofO_s3w&N@8z%QuhqD<0y4H(84YMtg<3ye9| z&VVL%qBhcl>#*PD$DL=K7f~;~geM^$bCHLr*p@jdb``{c&I;s)~HsCDbtm^ETE>bc&) zbxz@C1}-~qIt!=@J;647j(R~E594Q-H?f=DfqNN$>+&DYKX`!g$Xc_5IDop-Db#{_)P`qJmAZ{uzks@u2dD!)LMjv3 zQ#bGiwZjjn2S1`JQbv{bC+cK1T)eJgJ62&Ea>bRh?n5;_r`ANYR(eZ6U7*b#B~(qb zxyEq)i5->h(vLn5HJ!bO=pb4MeU81vEF;`uy2t6&RiMw{9J0pE_i<0^KCG1e*yT(b=&{| delta 1180 zcmZY8OGs2v9LMo9K5{ZsD^t^nu9>E04=o>Mv?!woSWsB2qQN<7INs5jD`rr4or@q0 zf*@!il+?l)Xwgn0B8XZAZQ2IbB5)x=5q*E-5hM@(=X3w(-gC}9|8sp7`x2XrMZ$7p zOmC4fb=Z%aaRN(l3JdWemf~Yvk1wzoUtvDZ<2rncG5mm0TtJOm#72zJ*^Eu7aTlT{ z%uRTSjsiNap(e7(7?X4l2B;UgiDh`l<@cNqoR3iBpP&|aiuDm=p1b>>c>5#te@1Pf zyf`#wD;Kq7TA&S8kuFsKX*`QpQ4`OiDlmtt&}-Cl@2~>DB5RpN*Z&*0kZ;=ij)OIIIW2KJ(k;vD8-KXSymvK~M+RZ^{%*iG~(p|ulw zsiQ;_Va#-8LFpM4_W!n@jt)Y5-9_lLQ^ECrqA#SA*h^3@!&Y)dZJQn`=nCt}x(GFW zY}z&NXgp#Mp|*XQ+^;sLifPk3h<$`A)=jK59ifhIr8T;X7SwU8@@hMc$<`Ov<()jA zPS|wD8?|XKk-p&%n^henDL)wUnv(HM;I*}Txir(f`iTi^hZFJ1?1`ePNcL{@d;XQ< zHWS!na@-%ZzBigqd8cfUelx?wYwq-={CL3hHn div { + height: 100%; + width: 16rem; +} + /* Responsive */ @media only screen and (max-width: 1200px) { diff --git a/app/templates/statistics.html b/app/templates/statistics.html index 4f938b9..0c1e6e7 100644 --- a/app/templates/statistics.html +++ b/app/templates/statistics.html @@ -8,14 +8,14 @@ {% block content %}

{% translate "Statistics" %}

-
-
-

{% translate "Orders per drink" %}

+
+
+

{% translate "orders / drink" %}

- + {% for key, values in orders_per_drink.items %} @@ -26,13 +26,13 @@ {% endfor %}
{% translate "drink" %}{% translate "you" %} {% translate "all" %}{% translate "you" %}
-
-

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

+
+

{% translate "orders / month" %}

- + {% for key, values in orders_per_month.items %} @@ -43,19 +43,19 @@ {% endfor %}
{% translate "month" %}{% translate "you" %} {% translate "all" %}{% translate "you" %}
-
-

{% translate "Orders per weekday" %}

+
+

{% translate "orders / weekday" %}

- + - {% for key, values in orders_per_weekday.items %} + {% for values in orders_per_weekday %} - - - + + + {% endfor %}
{% translate "day" %}{% translate "you" %} {% translate "all" %}{% translate "you" %}
{{ key }}{{ values.a|default:"0" }}{{ values.b|default:"0" }}{{ values.0 }}{{ values.1|default:"0" }}{{ values.2|default:"0" }}
From 4eb2911150778eb3b8e4d2a184de4c2b76dfeeff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 31 Oct 2023 18:17:12 +0100 Subject: [PATCH 06/19] Fixed round corners on tables for Firefox --- app/static/css/main.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 0387a51..4ba0fc7 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -97,11 +97,12 @@ table { border-radius: var(--border-radius); } -tr { +tr > th, +tr > td { background: var(--bg-color); } -tr:nth-child(2n+2) { +tr:nth-child(2n+2) > td { background: var(--bg-color2); } From e4acc5c101b4f901589b6ac4f2259a0030aea986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 1 Nov 2023 19:07:07 +0100 Subject: [PATCH 07/19] Added two new statistics about all users: 'order sum' visible for users having the 'view_order' permission and 'deposit sum' visible for users having the 'view_registertransaction' permission, improved the layout of the statistics page, updated translations --- app/db_queries.py | 37 +++++++++++++++---- app/locales/de/LC_MESSAGES/django.mo | Bin 3624 -> 3704 bytes app/locales/de/LC_MESSAGES/django.po | 43 ++++++++++++---------- app/templates/statistics.html | 51 +++++++++++++++++++++++---- app/views.py | 12 +++++-- 5 files changed, 109 insertions(+), 34 deletions(-) diff --git a/app/db_queries.py b/app/db_queries.py index 0363896..dd79bbe 100644 --- a/app/db_queries.py +++ b/app/db_queries.py @@ -16,7 +16,6 @@ def _db_select(sql_select:str): result = cursor.fetchall() return result - def _combine_results(results:list) -> dict: ''' e.g. @@ -81,8 +80,7 @@ def select_history(user, language_code="en") -> list: result = [list(row) for row in result] return result - -def orders_per_month(user) -> list: +def select_orders_per_month(user) -> dict: # number of orders per month (last 12 months) result_user = _db_select(f""" select @@ -105,8 +103,7 @@ def orders_per_month(user) -> list: """) return _combine_results([result_all, result_user]) - -def orders_per_weekday(user) -> list: +def select_orders_per_weekday(user) -> list: # number of orders per weekday (all time) result = _db_select(f""" with q_all as ( @@ -132,8 +129,7 @@ def orders_per_weekday(user) -> list: result[i] = (day_name[int(day_)-1], all_, user_) return result - -def orders_per_drink(user) -> list: +def select_orders_per_drink(user) -> dict: # number of orders per drink (all time) result_user = _db_select(f""" select @@ -155,3 +151,30 @@ def orders_per_drink(user) -> list: order by "data" desc; """) return _combine_results([result_all, result_user]) + +def select_order_sum_per_user_all_users() -> list: + # sum of all orders per user, for all users + result = _db_select(f""" + select + app_user.username as user, + sum(app_order.price_sum) as sum + from app_user + left outer join app_order on (app_user.id = app_order.user_id) + group by app_user.id + order by app_user asc; + """) + return result + +def select_deposit_sum_per_user_all_users() -> list: + # sum of all orders per user, for all users + result = _db_select(f""" + select + app_user.username as user, + sum(rt.transaction_sum) as sum + from app_user + left outer join app_registertransaction rt on (app_user.id = rt.user_id) + where rt.is_user_deposit is true or rt.is_user_deposit is null + group by app_user.id + order by app_user asc; + """) + return result diff --git a/app/locales/de/LC_MESSAGES/django.mo b/app/locales/de/LC_MESSAGES/django.mo index 73d1c7135393360c788e1d6c270bab1427e0c8a3..2e84d2fd89d1c282b18a917240047d7a23e92828 100644 GIT binary patch delta 1173 zcmXZbUr1A77{~E1`$J+X{XbTK6th8J+tJO3pBMU+c1-l3WWeK(t9f1&wqM(aF zI0QnVbhC;e0%12rT?8>IkRT|Fq8p`)@~R6j4Ep}YdpPHO-aqF&?{l7adz@NHm43wC z`-Y>FE5#M@8*>g<9c~;a1IE;05AMTWT#L7GJ>J7LID_l3j2p0mdj1`9nt$B%oI|iM zhH;ZIC6k~LW1toFU>7QIw{-xc^z*2|MXblW)@eKb2$jGKRJ`}71;67qTtrUeFt{5- zSjYONgT_V%a;VJCq7u1)5gfApG1S7>P!+g?A)G=L>j7$kSyUy<7{oWI_dehb{DwQx z&!ofpriF$AwxNqzRG=>8S#tulz!|J1h_wV!Up!>{6V^%V4Xh=KN?^)5i>mN5ENP+F zG_=55Z1k~bs0EgJJBxo&U%HnYduFnz`Ce3@0Xv?@Q}nN+;#N@!%%du~fO>xkRq@pj z^=B;;qye8u*g_{HkEG-fb|?Kp-3^-qwk29c9YQq3^#LW1KPbo_jK!FTKl8&nD+t@#8DDO0dm!$FhOb^3ADL(vFJAW2!9A`TbA!R2K%{%5FnRIPXt9tVE_e^4 J$Gp$czW*T}Zw&wd delta 1111 zcmXxjPe>GD7{~E<+L_#JXS1y=+_e>KMN6Z0Z8Md?5{wE%DuOOWLF6G2BCvwS(^j|G z$v}b**&(!pBt#$;1VyLLLVuvNOC73HSsnWR;^}2)KJ&i&&hxzQ^X~r4-OokuGyb@v z^>XF7{&>zE#wAR46<=BQr+=eUgG}hrctida|3M;q;M{Q7bE=7P1>t*l+zIRN`Z(3Y@`O96=T9GAcoYs$>O|IEi}i0k+^Aw&6!i zkl&@4rGRzlV*@Hs9+~4>Pzko87FI;2JafcnC@9&Zelp zR(hVBb~uI^tk{GJB!;_Z-_Kb85wXIG9K4QVBQC>2yp$+;y>W-%>~+UO zel{#K+RCMRm*R{5feuwli&fjnr3LEu)5P_^=^v!l6@T}$-i|m7N?y-wUyw<}Cz9>6 Q {{ key }} - {{ values.a|default:"0" }} - {{ values.b|default:"0" }} + {{ values.a|default:0 }} + {{ values.b|default:0 }} {% endfor %}
+
+

{% translate "orders / month" %}

@@ -37,8 +39,8 @@ {% for key, values in orders_per_month.items %} - - + + {% endfor %}
{{ key }}{{ values.a|default:"0" }}{{ values.b|default:"0" }}{{ values.a|default:0 }}{{ values.b|default:0 }}
@@ -54,11 +56,48 @@ {% for values in orders_per_weekday %} {{ values.0 }} - {{ values.1|default:"0" }} - {{ values.2|default:"0" }} + {{ values.1|default:0 }} + {{ values.2|default:0 }} {% endfor %}
+
+
+ {% if user.is_superuser or perms.app.view_order %} +
+

{% translate "order sum" %}

+ + + + + + {% for values in order_sum_per_user %} + + + + + {% endfor %} +
{% translate "user" %}{% translate "sum" %}
{{ values.0 }}{{ values.1|default:0.0 }} {{ currency_suffix }}
+
+ {% endif %} + {% if user.is_superuser or perms.app.view_registertransaction %} +
+

{% translate "deposit sum" %}

+ + + + + + {% for values in deposit_sum_per_user %} + + + + + {% endfor %} +
{% translate "user" %}{% translate "sum" %}
{{ values.0 }}{{ values.1|default:0.0 }} {{ currency_suffix }}
+
+ {% endif %} +
{% endblock %} \ No newline at end of file diff --git a/app/views.py b/app/views.py index b7f936b..ba864a4 100644 --- a/app/views.py +++ b/app/views.py @@ -80,11 +80,17 @@ def deposit(request): @login_required def statistics(request): + user = request.user context = { - "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), + "orders_per_month": db_queries.select_orders_per_month(user), + "orders_per_weekday": db_queries.select_orders_per_weekday(user), + "orders_per_drink": db_queries.select_orders_per_drink(user), } + # Advanced statistics + if user.has_perm("app.view_order") or user.is_superuser: + context["order_sum_per_user"] = db_queries.select_order_sum_per_user_all_users() + if user.has_perm("app.view_registertransaction") or user.is_superuser: + context["deposit_sum_per_user"] = db_queries.select_deposit_sum_per_user_all_users() return render(request, "statistics.html", context) @login_required From 4958a56f8d7c4734d158d391de66997af29c8347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 1 Nov 2023 19:21:34 +0100 Subject: [PATCH 08/19] Bumped version to 19 --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index 8f4ba06..ab9ea5b 100755 --- a/start.sh +++ b/start.sh @@ -11,6 +11,6 @@ chmod -c -R g-w,o-rwx .gitignore export PYTHONPATH="$basedir" export DJANGO_SETTINGS_MODULE="project.settings" -export APP_VERSION="17" +export APP_VERSION="19" exec ./scripts/_bootstrap.py "$@" From 6b5740c6176628ae3a8d6c9b2a9c9ba01e1fbcb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 1 Nov 2023 19:32:25 +0100 Subject: [PATCH 09/19] Added missing translations --- app/locales/de/LC_MESSAGES/django.mo | Bin 3704 -> 3784 bytes app/locales/de/LC_MESSAGES/django.po | 10 +++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/locales/de/LC_MESSAGES/django.mo b/app/locales/de/LC_MESSAGES/django.mo index 2e84d2fd89d1c282b18a917240047d7a23e92828..5d60623853481f95cf22576803b830891e3caf20 100644 GIT binary patch delta 1459 zcmX}sPe@cz6vy$?{7EORCT%MJOl9UwYBv3wN+(OSHW3K6DQek7EtDD?gd$(FD56DB z(6mTsTaXwE5fnni#4Lj#X`{P>h#*=_5dHc7p4Tp(_qq4ZynD|(_l-ZB%W-eME_B~$ zeMGY&V0KD|xX`YL&6Z;UcjGOL;7g2R39Ik}uEu$+$8V_b2e_H8rBUC@U=0pn%*?Yv zI%}B7qP{qWTKJmt4z6VU2(|DeuEN*OcW!#6hA}R2j3Xae20O9eAA4pa zbk;JFM`d;!l}Hh5al(zCpf;XDRbUoZU>Sq>9<{+7s*>|qjlWR$g%~8T9^0`8gY0i- z>1e_8sH*2s3ymT7+Bj;1o9HKqeuAhco^a!*&S~ch^bo%toy!Z&ao7TxEQ&NsN8`H#-;&Ir4xf-TsF?Wpw!u^Ug;Qh!a{ zW1<5e;s$(+By9`GpMBw?C#+x{{ziQs<;`R-YeIdVbmK1E&bZr+&pC6rhxu{bi_;z* zmHabm!LO){E2vWaMQsq_0CglWWN&LgC7wW4DCNcjs6>vV?jJ&Z{|u@^7f_WhpdQpK z($U#Wp>BMRTKE<6ufR&kE8xFq3EW6*CRBwav6E2SM(ih4RyA#&A(WifSJQ(jnN5V& zrg{FRdh#v)c=6H)`pv4f5PEVoy?knV7t}fl{gc^BqzNUy)OOKnBlN%EFwstQ5DkQy zs@}@}{!c?^rE*Yhzue%rF0Lxup~a!?K%L(KH}1uKuCKDH>9?=5J*WY#k{%-$)4s-73oOACzkN<|8xE}|w7VqIYe1tVPiEFWl>#>A-{yp-sKV0-&z+_2G z;zqO3GBnZ*bfX^ZLrr|j9l|yAM^F+u)XpxUHgXkHIPCpV)WSDW5qN+J97hG~32K2UR3wYI8sDPc`-pA$6+1A- z&4Bf-i-so5Vio346ZIj_+G*4R=P}wKMjJ$(c-Z?l+*|H#j5dnez_>ewitsdsTIdZ8 zE$|LoR*^H*0!zG|!{4Zr_HZF*mP6eiKut8{<0E*E{upZBGHL^Js7TJE-d{vTd?i8r zS(b7rulRHK|L{+YjP!(CuXWOYtgNptO zRP@D;+XZq&Lm}Np?W8I%z0^wCLZhwH!4_}tMujx%{XC{;$KrQ_*_zs!c+g+4zsyHp A&;S4c diff --git a/app/locales/de/LC_MESSAGES/django.po b/app/locales/de/LC_MESSAGES/django.po index 9900f3a..278ff86 100644 --- a/app/locales/de/LC_MESSAGES/django.po +++ b/app/locales/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-01 18:52+0100\n" +"POT-Creation-Date: 2023-11-01 19:29+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Julian Müller (ChaoticByte)\n" "Language: DE\n" @@ -207,6 +207,14 @@ msgstr "Tag" msgid "order sum" msgstr "Bestellungen" +#: app/templates/statistics.html:72 app/templates/statistics.html:89 +msgid "user" +msgstr "Benutzer" + +#: app/templates/statistics.html:73 app/templates/statistics.html:90 +msgid "sum" +msgstr "Summe" + #: app/templates/statistics.html:86 msgid "deposit sum" msgstr "Einzahlungen" From b48a1c1888ae6d81fbeb2b2cadda9454f8081ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Wed, 1 Nov 2023 19:32:59 +0100 Subject: [PATCH 10/19] Bumped version to 20 --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index ab9ea5b..6420294 100755 --- a/start.sh +++ b/start.sh @@ -11,6 +11,6 @@ chmod -c -R g-w,o-rwx .gitignore export PYTHONPATH="$basedir" export DJANGO_SETTINGS_MODULE="project.settings" -export APP_VERSION="19" +export APP_VERSION="20" exec ./scripts/_bootstrap.py "$@" From 1e20fd9549eb55cb7588e8df11bb6167d693f9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 13 Feb 2024 17:28:39 +0100 Subject: [PATCH 11/19] Updated dependencies --- app/templates/footer.html | 2 +- requirements.txt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/templates/footer.html b/app/templates/footer.html index 89d58c6..289f81e 100644 --- a/app/templates/footer.html +++ b/app/templates/footer.html @@ -2,6 +2,6 @@
\ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2be275b..ceb35b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django~=4.1 -psycopg2~=2.9.5 -uvicorn~=0.20.0 +Django~=4.2 +psycopg2~=2.9 +uvicorn[standard]~=0.27 PyYAML~=6.0 From 3a9b2c25e78a592bfe962eb584aacd2e4d35a981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 13 Feb 2024 17:30:29 +0100 Subject: [PATCH 12/19] Changed README title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2a4bf6..74a7248 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Drinks Manager (Season 3) +# Drinks Manager Note: This software is tailored to my own needs. I probably won't accept feature requests, and don't recommend you From 0f4b1d9da2f52ada37bab19d1ccb360890028580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 13 Feb 2024 18:01:40 +0100 Subject: [PATCH 13/19] Split up static files into static and django_static --- .gitignore | 2 +- data/Caddyfile | 6 +++++- project/settings.py | 4 ++-- scripts/_bootstrap.py | 1 + {app/static => static}/css/main.css | 0 {app/static => static}/css/simple-keyboard.css | 0 {app/static => static}/css/simple-keyboard_dark.css | 0 {app/static => static}/favicon.ico | Bin {app/static => static}/favicon.png | Bin {app/static => static}/fonts/Inter-Bold.ttf | Bin {app/static => static}/fonts/Inter-Regular.ttf | Bin {app/static => static}/js/autoreload.js | 0 {app/static => static}/js/custom_form.js | 0 {app/static => static}/js/custom_number_input.js | 0 {app/static => static}/js/logged_out.js | 0 {app/static => static}/js/login.js | 0 {app/static => static}/js/main.js | 0 {app/static => static}/js/order.js | 0 {app/static => static}/js/simple-keyboard.js | 0 .../js/simple-keyboard_configure.js | 0 .../material-icons/arrow-drop-down.svg | 0 {app/static => static}/material-icons/menu.svg | 0 22 files changed, 9 insertions(+), 4 deletions(-) rename {app/static => static}/css/main.css (100%) rename {app/static => static}/css/simple-keyboard.css (100%) rename {app/static => static}/css/simple-keyboard_dark.css (100%) rename {app/static => static}/favicon.ico (100%) rename {app/static => static}/favicon.png (100%) rename {app/static => static}/fonts/Inter-Bold.ttf (100%) rename {app/static => static}/fonts/Inter-Regular.ttf (100%) rename {app/static => static}/js/autoreload.js (100%) rename {app/static => static}/js/custom_form.js (100%) rename {app/static => static}/js/custom_number_input.js (100%) rename {app/static => static}/js/logged_out.js (100%) rename {app/static => static}/js/login.js (100%) rename {app/static => static}/js/main.js (100%) rename {app/static => static}/js/order.js (100%) rename {app/static => static}/js/simple-keyboard.js (100%) rename {app/static => static}/js/simple-keyboard_configure.js (100%) rename {app/static => static}/material-icons/arrow-drop-down.svg (100%) rename {app/static => static}/material-icons/menu.svg (100%) diff --git a/.gitignore b/.gitignore index 005984e..280fb6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /data/* /data/logs/* /data/tls/* -/data/static/* +/data/django_static/* /data/profilepictures/* /data/archive/* !/data/logs/ diff --git a/data/Caddyfile b/data/Caddyfile index c5bbc58..84f30f3 100644 --- a/data/Caddyfile +++ b/data/Caddyfile @@ -17,7 +17,11 @@ } # static files file_server /static/* { - root {$DATADIR}/static/.. + root {$ROOTDIR} + } + # django static files + file_server /django_static/* { + root {$DATADIR}/django_static/.. } # favicon redir /favicon.ico /static/favicon.ico diff --git a/project/settings.py b/project/settings.py index a5362ca..56ff5fb 100644 --- a/project/settings.py +++ b/project/settings.py @@ -149,8 +149,8 @@ LOCALE_PATHS = [ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.1/howto/static-files/ -STATIC_URL = "static/" -STATIC_ROOT = BASE_DIR / "data" / "static" +STATIC_URL = "django_static/" +STATIC_ROOT = BASE_DIR / "data" / "django_static" # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field diff --git a/scripts/_bootstrap.py b/scripts/_bootstrap.py index 142781e..7cdee55 100755 --- a/scripts/_bootstrap.py +++ b/scripts/_bootstrap.py @@ -131,6 +131,7 @@ if __name__ == "__main__": ["./venv/bin/python3", "./manage.py", "migrate", "--noinput"], env=os.environ).wait() # Caddy configuration via env environment_caddy = os.environ + environment_caddy["ROOTDIR"] = str(base_directory.absolute()) environment_caddy["DATADIR"] = str(data_directory.absolute()) environment_caddy["CADDY_HOSTS"] = ", ".join(config["caddy"]["hosts"]) environment_caddy["HTTP_PORT"] = str(config["caddy"]["http_port"]) diff --git a/app/static/css/main.css b/static/css/main.css similarity index 100% rename from app/static/css/main.css rename to static/css/main.css diff --git a/app/static/css/simple-keyboard.css b/static/css/simple-keyboard.css similarity index 100% rename from app/static/css/simple-keyboard.css rename to static/css/simple-keyboard.css diff --git a/app/static/css/simple-keyboard_dark.css b/static/css/simple-keyboard_dark.css similarity index 100% rename from app/static/css/simple-keyboard_dark.css rename to static/css/simple-keyboard_dark.css diff --git a/app/static/favicon.ico b/static/favicon.ico similarity index 100% rename from app/static/favicon.ico rename to static/favicon.ico diff --git a/app/static/favicon.png b/static/favicon.png similarity index 100% rename from app/static/favicon.png rename to static/favicon.png diff --git a/app/static/fonts/Inter-Bold.ttf b/static/fonts/Inter-Bold.ttf similarity index 100% rename from app/static/fonts/Inter-Bold.ttf rename to static/fonts/Inter-Bold.ttf diff --git a/app/static/fonts/Inter-Regular.ttf b/static/fonts/Inter-Regular.ttf similarity index 100% rename from app/static/fonts/Inter-Regular.ttf rename to static/fonts/Inter-Regular.ttf diff --git a/app/static/js/autoreload.js b/static/js/autoreload.js similarity index 100% rename from app/static/js/autoreload.js rename to static/js/autoreload.js diff --git a/app/static/js/custom_form.js b/static/js/custom_form.js similarity index 100% rename from app/static/js/custom_form.js rename to static/js/custom_form.js diff --git a/app/static/js/custom_number_input.js b/static/js/custom_number_input.js similarity index 100% rename from app/static/js/custom_number_input.js rename to static/js/custom_number_input.js diff --git a/app/static/js/logged_out.js b/static/js/logged_out.js similarity index 100% rename from app/static/js/logged_out.js rename to static/js/logged_out.js diff --git a/app/static/js/login.js b/static/js/login.js similarity index 100% rename from app/static/js/login.js rename to static/js/login.js diff --git a/app/static/js/main.js b/static/js/main.js similarity index 100% rename from app/static/js/main.js rename to static/js/main.js diff --git a/app/static/js/order.js b/static/js/order.js similarity index 100% rename from app/static/js/order.js rename to static/js/order.js diff --git a/app/static/js/simple-keyboard.js b/static/js/simple-keyboard.js similarity index 100% rename from app/static/js/simple-keyboard.js rename to static/js/simple-keyboard.js diff --git a/app/static/js/simple-keyboard_configure.js b/static/js/simple-keyboard_configure.js similarity index 100% rename from app/static/js/simple-keyboard_configure.js rename to static/js/simple-keyboard_configure.js diff --git a/app/static/material-icons/arrow-drop-down.svg b/static/material-icons/arrow-drop-down.svg similarity index 100% rename from app/static/material-icons/arrow-drop-down.svg rename to static/material-icons/arrow-drop-down.svg diff --git a/app/static/material-icons/menu.svg b/static/material-icons/menu.svg similarity index 100% rename from app/static/material-icons/menu.svg rename to static/material-icons/menu.svg From 69c6b79267ececf97fe7dcc14618406cb0625994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 13 Feb 2024 19:16:59 +0100 Subject: [PATCH 14/19] Small improvements to the UI --- static/css/main.css | 76 ++++++++++++++++------------- static/css/simple-keyboard_dark.css | 1 + 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/static/css/main.css b/static/css/main.css index 4ba0fc7..a6bcf52 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -19,14 +19,15 @@ --font-family: "Inter"; --color: #fafafa; --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-page: linear-gradient(#18151a, #060a0e); + --bg-color: #ffffff2c; + --bg-hover-color: #ffffff50; + --bg-color2: #ffffff44; + --bg-dropdown-color: #3a3a3f; + --bg-dropdown-hover-color: #59595c; + --border-color: #ffffff67; --bg-globalmessage: #161616; - --border-radius: .5rem; + --border-radius: .25rem; } /* General */ @@ -37,7 +38,8 @@ body { width: 100vw; min-height: 100vh; font-family: var(--font-family); - background: var(--bg-page-color); + font-size: 17px; + background: var(--bg-page); color: var(--color); overflow-x: hidden; } @@ -47,7 +49,7 @@ a { } h1 { - font-size: 1.8rem; + font-size: 28px; } h1, h2, h3, h4 { @@ -66,9 +68,9 @@ input[type="number"]::-webkit-inner-spin-button { } input[type="text"], input[type="password"], input[type="number"], select { - padding: .6rem .8rem; + padding: .5rem .8rem; text-align: center; - font-size: 1rem; + font-size: 16px; color: var(--color); border: none; outline: none; @@ -82,7 +84,7 @@ select { appearance: none; -webkit-appearance: none; -moz-appearance: none; - height: 2.5rem; + height: 2.2rem; background-image: url("/static/material-icons/arrow-drop-down.svg"); background-repeat: no-repeat; background-position: right; @@ -165,11 +167,7 @@ th { flex-direction: row; margin-top: 1rem; width: 94%; - gap: 1rem; -} - -.userinfo { - font-size: 1.05rem; + gap: 2rem; } .userinfo > span { @@ -224,7 +222,7 @@ main { } .footer > div { - font-size: .95rem; + font-size: 16px; margin-top: .15rem; margin-bottom: .15rem; } @@ -302,8 +300,8 @@ main { text-align: center !important; background: var(--bg-color); color: var(--color); - font-size: 1rem; - padding: .6rem .8rem; + font-size: 16px; + padding: .5rem .8rem; outline: none; border: none; border-bottom: 1px solid var(--border-color); @@ -338,8 +336,8 @@ main { .appform > .forminput { width: 100%; flex-direction: row; - justify-content: space-evenly; - align-items: center; + justify-content: space-between; + align-items: flex-end; flex-wrap: wrap; gap: 1rem; } @@ -366,30 +364,28 @@ main { } .dropdownlist { + margin-top: 3rem; position: absolute; display: flex; flex-direction: column; pointer-events: none; - border-radius: var(--border-radius) !important; - z-index: 200; - margin-top: 3.2rem; + gap: .5rem; opacity: 0%; - transition: opacity 100ms; - box-shadow: 0 .25rem 1rem #00000090; } .dropdownchoice { - border-radius: 0 !important; + z-index: 200; + border-radius: var(--border-radius) !important; margin: 0; text-align: center; justify-content: center; - background: var(--bg-color2) !important; - backdrop-filter: none !important; + background: var(--bg-dropdown-color) !important; width: initial; + box-shadow: 0 0 1.5rem #00000090; } .dropdownchoice:hover { - background: var(--bg-hover-color2) !important; + background: var(--bg-dropdown-hover-color) !important; } .dropdownlist :first-child { @@ -409,7 +405,7 @@ main { } .customnumberinput { - height: 2.5rem; + height: 2.2rem; } .customnumberinput button { @@ -477,7 +473,7 @@ main { .userlist > li > div { flex-grow: 1; text-align: center; - padding: .8rem 1.1rem; + padding: .7rem 1.1rem; } .loginform { @@ -505,7 +501,7 @@ main { .drinks-list > li > .button { width: 100%; justify-content: space-between; - padding: .8rem 1.1rem; + padding: .7rem 1.1rem; } /* Statistics */ @@ -525,6 +521,18 @@ main { width: 16rem; } +/* Blur */ + +@supports (backdrop-filter: blur()) { + :root { + --bg-dropdown-color: var(--bg-color); + --bg-dropdown-hover-color: var(--bg-hover-color); + } + .dropdownchoice { + backdrop-filter: blur(32px); + } +} + /* Responsive */ @media only screen and (max-width: 1200px) { diff --git a/static/css/simple-keyboard_dark.css b/static/css/simple-keyboard_dark.css index e380b77..ffee807 100644 --- a/static/css/simple-keyboard_dark.css +++ b/static/css/simple-keyboard_dark.css @@ -6,6 +6,7 @@ max-width: 100%; background: transparent; font-family: "Inter"; + font-size: 16px; } .simple-keyboard.darkTheme .hg-button { height: 50px; From 71bc46c72ddd9226084230a26fb331d76bfdc1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Tue, 13 Feb 2024 19:20:50 +0100 Subject: [PATCH 15/19] Bumped version to 21 --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index 6420294..99a6ccd 100755 --- a/start.sh +++ b/start.sh @@ -11,6 +11,6 @@ chmod -c -R g-w,o-rwx .gitignore export PYTHONPATH="$basedir" export DJANGO_SETTINGS_MODULE="project.settings" -export APP_VERSION="20" +export APP_VERSION="21" exec ./scripts/_bootstrap.py "$@" From 054c5db2f265bc2dc67d663b124bc99a8015f727 Mon Sep 17 00:00:00 2001 From: ChaoticByte Date: Sun, 7 Sep 2025 22:27:08 +0200 Subject: [PATCH 16/19] Caddyfile: use internal directive by default for self-signed certs --- data/Caddyfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/Caddyfile b/data/Caddyfile index 84f30f3..d790c4e 100644 --- a/data/Caddyfile +++ b/data/Caddyfile @@ -9,7 +9,8 @@ {$CADDY_HOSTS} { # the tls certificates - tls {$DATADIR}/tls/server.pem {$DATADIR}/tls/server-key.pem + # tls {$DATADIR}/tls/server.pem {$DATADIR}/tls/server-key.pem + tls internal route { # profile pictures file_server /profilepictures/* { From 5fefee228272472d6bb7ab87d7a3a727923ee051 Mon Sep 17 00:00:00 2001 From: ChaoticByte Date: Sun, 7 Sep 2025 22:29:07 +0200 Subject: [PATCH 17/19] Added a small code warning and added more comments to models.py --- app/models.py | 7 ++++--- scripts/_bootstrap.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models.py b/app/models.py index 681a433..717a1cf 100644 --- a/app/models.py +++ b/app/models.py @@ -40,6 +40,7 @@ class Drink(models.Model): do_not_count = models.BooleanField(default=False) def delete(self, *args, **kwargs): + # we flag the field as deleted. self.deleted = True super().save() @@ -107,10 +108,9 @@ class Order(models.Model): price_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0, editable=False) content_litres = models.DecimalField(max_digits=6, decimal_places=3, default=0, editable=False) - # TODO: Add more comments on how and why the save & delete functions are implemented - # address this in a refactoring issue. - def save(self, *args, **kwargs): + # saving this may affect other fields + # so we reimplement the save function drink = Drink.objects.get(pk=self.drink.pk) if self._state.adding and drink.available > 0: if not drink.do_not_count: @@ -126,6 +126,7 @@ class Order(models.Model): raise ValidationError("This entry can't be changed.") def delete(self, *args, **kwargs): + # when deleting, we affect other fields as well. self.user.balance += self.price_sum self.user.save() drink = Drink.objects.get(pk=self.drink.pk) diff --git a/scripts/_bootstrap.py b/scripts/_bootstrap.py index 7cdee55..c162c03 100755 --- a/scripts/_bootstrap.py +++ b/scripts/_bootstrap.py @@ -14,7 +14,7 @@ from time import sleep from yaml import safe_load -banner = """ ___ _ _ +banner = r""" ___ _ _ | \ _ _ (_) _ _ | |__ ___ ___ | |) || '_|| || ' \ | / /(_-< |___| |___/ |_| |_||_||_||_\_\/__/ From 7fa405a95747730333ad6f7a01d3fab562b55cbf Mon Sep 17 00:00:00 2001 From: ChaoticByte Date: Sun, 7 Sep 2025 22:32:38 +0200 Subject: [PATCH 18/19] Overhauled the complete user interface --- app/templates/baselayout.html | 2 +- app/templates/deposit.html | 11 +- app/templates/order.html | 18 +- app/templates/registration/login.html | 6 +- app/templates/supply.html | 14 +- app/templates/transfer.html | 50 ++-- app/templates/userpanel.html | 15 +- static/css/main.css | 260 +++++++++++------- ...rd_dark.css => simple-keyboard_custom.css} | 4 +- static/js/login.js | 1 + static/js/main.js | 21 +- 11 files changed, 229 insertions(+), 173 deletions(-) rename static/css/{simple-keyboard_dark.css => simple-keyboard_custom.css} (86%) diff --git a/app/templates/baselayout.html b/app/templates/baselayout.html index 5783cf9..97ac907 100644 --- a/app/templates/baselayout.html +++ b/app/templates/baselayout.html @@ -25,7 +25,7 @@
{% translate "An error occured. Please log out and log in again." %}
- log out + log out
{% endif %} diff --git a/app/templates/deposit.html b/app/templates/deposit.html index bbce3e1..cf3dbc1 100644 --- a/app/templates/deposit.html +++ b/app/templates/deposit.html @@ -8,20 +8,16 @@ {% block headAdditional %} - + {% endblock %} {% block content %} +

{% translate "Deposit" %}

{% csrf_token %} -

{% translate "Deposit" %}

- {% translate "Amount" %} {{ currency_suffix }}: - - - +
-
@@ -31,6 +27,7 @@
+
{% endblock %} \ No newline at end of file diff --git a/app/templates/order.html b/app/templates/order.html index 2cae204..2e5286f 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -11,31 +11,31 @@
{% if drink and drink.available > 0 and not drink.deleted %} {% if user.balance > 0 or user.allow_order_with_negative_balance %} +

{% translate "Order" %}

{% csrf_token %} -

{% translate "Order" %}

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

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

- {% translate "back" %} + {% translate "back" %}
{% endif %} {% else %} diff --git a/app/templates/registration/login.html b/app/templates/registration/login.html index c9ba292..657c713 100644 --- a/app/templates/registration/login.html +++ b/app/templates/registration/login.html @@ -10,7 +10,7 @@ {% block headAdditional %} - + {% endblock %} {% block content %} @@ -19,7 +19,7 @@ {% endif %}
-

{% translate "Log in" %}

+

{% translate "Log in" %}

{% csrf_token %} @@ -36,7 +36,7 @@
-
+

{% translate "Choose your account" %}

    {% for user_ in user_list %} diff --git a/app/templates/supply.html b/app/templates/supply.html index 4f656c2..bcbc3d0 100644 --- a/app/templates/supply.html +++ b/app/templates/supply.html @@ -9,27 +9,21 @@ {% block content %} {% if user.is_superuser or user.allowed_to_supply %} +

    {% translate "Supply" %}

    {% csrf_token %} -

    {% translate "Supply" %}

    - {% translate "Description" %}: - - - +
    - {% translate "Price" %} ({{ currency_suffix }}): - - - +
    -
    +
    {% else %} diff --git a/app/templates/transfer.html b/app/templates/transfer.html index 74c13f4..bf0524b 100644 --- a/app/templates/transfer.html +++ b/app/templates/transfer.html @@ -8,44 +8,37 @@ {% block headAdditional %} - + {% endblock %} {% block content %} +

    {% translate "Transfer Money" %}

    {% csrf_token %} -

    {% translate "Transfer Money" %}

    - {% translate "Recipient" %}: - - + + {% for user_ in user_list %} + {% if user_.id != user.id %} + - {% endfor %} - - + {{ user_.first_name }} + {% elif user_.last_name %} + {{ user_.last_name }} + {% else %} + {{ user_.username }} + {% endif %} + {% endif %} + + {% endfor %} +
    - {% translate "Amount" %} {{ currency_suffix }}: - - - +
    -
    @@ -55,6 +48,7 @@
+
{% endblock %} \ No newline at end of file diff --git a/app/templates/userpanel.html b/app/templates/userpanel.html index 7d2d015..966f86e 100644 --- a/app/templates/userpanel.html +++ b/app/templates/userpanel.html @@ -18,19 +18,20 @@ {% translate "Deposit" %} {% translate "Logout" %}
-
\ No newline at end of file +
diff --git a/static/css/main.css b/static/css/main.css index a6bcf52..ea44432 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -1,4 +1,4 @@ -/* Font */ +/* Fonts */ @font-face { font-family: "Inter"; @@ -18,26 +18,37 @@ :root { --font-family: "Inter"; --color: #fafafa; - --color-error: #ff682c; - --bg-page: linear-gradient(#18151a, #060a0e); - --bg-color: #ffffff2c; + --color-disabled: #ffffff50; + --color-error: #ff817c; + --bg-page: linear-gradient( + -10deg, + #071c29 10%, + #4a8897 + ); + --bg-color: #ffffff35; + --bg-color2: #ffffff25; --bg-hover-color: #ffffff50; - --bg-color2: #ffffff44; - --bg-dropdown-color: #3a3a3f; - --bg-dropdown-hover-color: #59595c; - --border-color: #ffffff67; + --border-color: #ffffff50; --bg-globalmessage: #161616; - --border-radius: .25rem; + --border-radius: .6rem; + --element-padding: .6rem .8rem; } /* General */ +body, +input, +select, +button, .button +{ + font-family: var(--font-family); +} + body { margin: 0; padding: 0; width: 100vw; min-height: 100vh; - font-family: var(--font-family); font-size: 17px; background: var(--bg-page); color: var(--color); @@ -67,29 +78,36 @@ input[type="number"]::-webkit-inner-spin-button { display: none; } -input[type="text"], input[type="password"], input[type="number"], select { - padding: .5rem .8rem; - text-align: center; +input[type="text"], +input[type="password"], +input[type="number"], +select { + padding: var(--element-padding); + text-align: center !important; font-size: 16px; color: var(--color); border: none; outline: none; - border-bottom: 1px solid var(--border-color); + border: 1px solid var(--border-color); border-radius: var(--border-radius); background: var(--bg-color); - font-family: "Inter"; +} + +input[type="text"]::placeholder, +input[type="password"]::placeholder, +input[type="number"]::placeholder, +select > option:disabled { + color: var(--color-disabled); } select { appearance: none; -webkit-appearance: none; -moz-appearance: none; - height: 2.2rem; background-image: url("/static/material-icons/arrow-drop-down.svg"); background-repeat: no-repeat; background-position: right; background-size: 1.5rem; - padding-right: 1.8rem; } table { @@ -108,12 +126,6 @@ tr:nth-child(2n+2) > td { 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); } @@ -274,15 +286,6 @@ main { gap: 1rem; } -.fill { - height: 100%; - width: 100%; -} - -.fill-vertical { - height: 100%; -} - .buttons { display: flex; flex-direction: row; @@ -295,24 +298,26 @@ main { display: flex; align-items: center; justify-content: center; - font-family: var(--font-family); - text-decoration: none; - text-align: center !important; - background: var(--bg-color); - color: var(--color); - font-size: 16px; - padding: .5rem .8rem; outline: none; - border: none; - border-bottom: 1px solid var(--border-color); + border: 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 { +.button, button, .dropdownchoice { + padding: var(--element-padding); + font-size: 16px; + text-align: center !important; + text-decoration: none; + color: var(--color); + box-sizing: content-box; + cursor: pointer; + user-select: none; + background: var(--bg-color); +} + +.button:hover, button:hover, +.button:active, button:active { background: var(--bg-hover-color); } @@ -320,30 +325,55 @@ main { opacity: 40%; } -.appform > .forminfo { - width: 100%; +.formheading { + margin-bottom: 2rem; +} + +.forminfo { + width: fit-content; + min-width: 16rem; text-align: left; display: flex; flex-direction: row; justify-content: space-between; gap: 2rem; + padding-bottom: .15rem; + border-bottom: 1px solid #ffffff20; } .forminfo > span:last-child { float: right; } +.appform, .appform > * { + max-width: 90vw; +} + .appform > .forminput { width: 100%; flex-direction: row; justify-content: space-between; - align-items: flex-end; + align-items: center; flex-wrap: wrap; gap: 1rem; } -.appform > .statusinfo { - margin-top: .5rem; +.forminput > input, .forminput > select { + width: 100% !important; +} + +.forminput > .keyboard-input, #transfer-recipient { + /* the keyboard has a 5px padding */ + margin-left: 5px !important; + margin-right: 5px !important; +} + +.appform > .buttons { + margin-top: 1rem; +} + +#statusinfo { + margin-top: 1rem; } .dropdownmenu { @@ -354,6 +384,16 @@ main { border-radius: var(--border-radius); } +#dropdownnope { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + margin: 0; + padding: 0; +} + .dropdownbutton { z-index: 190; } @@ -368,64 +408,65 @@ main { position: absolute; display: flex; flex-direction: column; - pointer-events: none; - gap: .5rem; + border-radius: var(--border-radius); + box-shadow: 0 0 .5rem #00000025; +} + +.dropdownlist, #dropdownnope { + visibility: hidden; opacity: 0%; + pointer-events: none; +} + +.dropdownvisible .dropdownlist, +.dropdownvisible #dropdownnope { + opacity: 100%; + background: #00000020; + visibility: visible; + pointer-events: visible; + z-index: 100; } .dropdownchoice { z-index: 200; - border-radius: var(--border-radius) !important; margin: 0; - text-align: center; - justify-content: center; - background: var(--bg-dropdown-color) !important; + text-decoration: none; width: initial; - box-shadow: 0 0 1.5rem #00000090; + min-width: max-content; + border-bottom: 1px solid var(--border-color); + border-left: 1px solid var(--border-color); + border-right: 1px solid var(--border-color); +} + +.dropdownchoice:first-child { + border-top: 1px solid var(--border-color); + border-top-left-radius: var(--border-radius); + border-top-right-radius: var(--border-radius); +} + +.dropdownchoice:last-child { + border-bottom: 1px solid var(--border-color); + border-bottom-left-radius: var(--border-radius); + border-bottom-right-radius: var(--border-radius); } .dropdownchoice:hover { - background: var(--bg-dropdown-hover-color) !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; + background: var(--bg-hover-color); } .customnumberinput { height: 2.2rem; + display: flex; + flex-direction: row; + align-items: center; + gap: .25rem; } .customnumberinput button { - min-width: 2.5rem !important; - width: 2.5rem !important; + width: 2.2rem !important; + height: 2.2rem !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"] { @@ -434,13 +475,13 @@ main { padding: 0; margin: 0; background: var(--bg-color2); - border-radius: 0 !important; -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; } .errortext { + font-weight: bold; color: var(--color-error); } @@ -450,6 +491,11 @@ main { /* Login */ +.userlist-container { + flex-grow: 1; + padding-bottom: 10vh; +} + .userlist { width: 60%; list-style: none; @@ -459,8 +505,7 @@ main { } .userlist > li { - margin-bottom: .5rem; - padding: 0 .5rem; + padding: .1rem .6rem; } .userlist > li > img { @@ -485,6 +530,18 @@ main { margin-top: 0; } +#passwordoverlay-container { + position: fixed; + width: 100vw; + height: 100vh; + top: 0; + right: 0; + background: var(--bg-page); + align-items: center; + padding-top: 10vh; + z-index: 200; +} + /* Drinks List */ .drinks-list { @@ -524,12 +581,13 @@ main { /* Blur */ @supports (backdrop-filter: blur()) { - :root { - --bg-dropdown-color: var(--bg-color); - --bg-dropdown-hover-color: var(--bg-hover-color); + .dropdownvisible #dropdownnope { + backdrop-filter: blur(16px); } - .dropdownchoice { - backdrop-filter: blur(32px); + #passwordoverlay-container { + background: #00000020; + backdrop-filter: blur(64px); /* fallback */ + backdrop-filter: blur(128px); } } @@ -553,9 +611,10 @@ main { } } -@media only screen and (max-width: 700px) { +@media only screen and (max-width: 860px) { .userpanel { flex-direction: column; + gap: 1rem; } .userlist { gap: 0.25rem; @@ -574,7 +633,10 @@ main { } .dropdownlist { width: 14rem; - right: calc(50vw - 7rem); + right: calc(50vw - 7rem); /* regard width */ left: auto; } + #keyboard { + display: none !important; + } } diff --git a/static/css/simple-keyboard_dark.css b/static/css/simple-keyboard_custom.css similarity index 86% rename from static/css/simple-keyboard_dark.css rename to static/css/simple-keyboard_custom.css index ffee807..39da287 100644 --- a/static/css/simple-keyboard_dark.css +++ b/static/css/simple-keyboard_custom.css @@ -15,8 +15,8 @@ align-items: center; background: var(--bg-color); color: white; - border: none; - border-bottom: 1px solid var(--border-color); + border: 1px solid var(--border-color); + border-radius: var(--border-radius); } .simple-keyboard.darkTheme .hg-button:active, .simple-keyboard.darkTheme .hg-button:hover { diff --git a/static/js/login.js b/static/js/login.js index cc9274d..6f62216 100644 --- a/static/js/login.js +++ b/static/js/login.js @@ -35,6 +35,7 @@ function show_password_overlay() { window.scrollTo(0, 0); passwordOverlayElement.classList.remove("nodisplay"); + passwordInputElement.focus() } function hide_password_overlay() { passwordOverlayElement.classList.add("nodisplay"); diff --git a/static/js/main.js b/static/js/main.js index 711aed8..5fab451 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -1,14 +1,21 @@ document.addEventListener("DOMContentLoaded", () => { let dropdownmenuElement = document.getElementById("dropdownmenu"); let dropdownmenuButtonElement = document.getElementById("dropdownmenu-button"); + let dropdownmenuNopeElement = document.getElementById("dropdownnope"); + function toggleDropDown() { + if (dropdownmenuElement.classList.contains("dropdownvisible")) { + dropdownmenuElement.classList.remove("dropdownvisible"); + dropdownmenuNopeElement.classList.remove("dropdownvisible"); + } else { + dropdownmenuElement.classList.add("dropdownvisible"); + dropdownmenuNopeElement.classList.add("dropdownvisible"); + } + } if (dropdownmenuButtonElement != null) { - dropdownmenuButtonElement.addEventListener("click", () => { - if (dropdownmenuElement.classList.contains("dropdownvisible")) { - dropdownmenuElement.classList.remove("dropdownvisible"); - } - else { - dropdownmenuElement.classList.add("dropdownvisible"); - } + dropdownmenuButtonElement.addEventListener("click", toggleDropDown); + dropdownmenuNopeElement.addEventListener("click", () => { + dropdownmenuElement.classList.remove("dropdownvisible"); + dropdownmenuNopeElement.classList.remove("dropdownvisible"); }) } }); From ecae648899eaa985f8362b9e4cfbd4376226e3df Mon Sep 17 00:00:00 2001 From: ChaoticByte Date: Sun, 7 Sep 2025 22:37:53 +0200 Subject: [PATCH 19/19] Bump version to 22 --- app/templates/footer.html | 2 +- start.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/footer.html b/app/templates/footer.html index 289f81e..63b51ec 100644 --- a/app/templates/footer.html +++ b/app/templates/footer.html @@ -2,6 +2,6 @@ \ No newline at end of file diff --git a/start.sh b/start.sh index 99a6ccd..cd50964 100755 --- a/start.sh +++ b/start.sh @@ -11,6 +11,6 @@ chmod -c -R g-w,o-rwx .gitignore export PYTHONPATH="$basedir" export DJANGO_SETTINGS_MODULE="project.settings" -export APP_VERSION="21" +export APP_VERSION="22" exec ./scripts/_bootstrap.py "$@"