From 86ea7c0000cd7daf34ad21431119a21ae8300474 Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Sat, 15 Oct 2022 19:37:01 +0200 Subject: [PATCH 1/7] Added 'supply' page to create negative register transactions, updated translation --- application/app/admin.py | 4 + application/app/models.py | 1 + application/app/templates/supply.html | 61 +++++++ application/app/templates/userPanel.html | 3 + application/app/urls.py | 2 + application/app/views.py | 36 +++- application/locale/de/LC_MESSAGES/django.mo | Bin 3469 -> 3806 bytes application/locale/de/LC_MESSAGES/django.po | 177 ++++++++++++-------- static/css/supply.css | 6 + static/js/supply.js | 56 +++++++ 10 files changed, 278 insertions(+), 68 deletions(-) create mode 100644 application/app/templates/supply.html create mode 100644 static/css/supply.css create mode 100644 static/js/supply.js diff --git a/application/app/admin.py b/application/app/admin.py index 7e81374..e72e506 100644 --- a/application/app/admin.py +++ b/application/app/admin.py @@ -49,6 +49,10 @@ class CustomUserAdmin(UserAdmin): {"fields": ("balance", "allow_order_with_negative_balance")}, )) fieldsets_.insert(2, ( + "Supply", + {"fields": ("allowed_to_supply",)}, + )) + fieldsets_.insert(3, ( "Profile Picture", {"fields": ("profile_picture_filename",)}, )) diff --git a/application/app/models.py b/application/app/models.py index 370a0dd..b92672c 100644 --- a/application/app/models.py +++ b/application/app/models.py @@ -21,6 +21,7 @@ class User(AbstractUser): balance = models.DecimalField(max_digits=8, decimal_places=2, default=0.00) allow_order_with_negative_balance = models.BooleanField(default=False) profile_picture_filename = models.CharField(default="default.svg", max_length=25) + allowed_to_supply = models.BooleanField(default=False) def delete(self, *args, **kwargs): self.balance = 0 diff --git a/application/app/templates/supply.html b/application/app/templates/supply.html new file mode 100644 index 0000000..0f62ad5 --- /dev/null +++ b/application/app/templates/supply.html @@ -0,0 +1,61 @@ +{% extends "baseLayout.html" %} + +{% load i18n %} +{% load l10n %} + +{% block title %} +{% translate "Drinks - Supply" %} +{% endblock %} + +{% block headAdditional %} + + +{% endblock %} + +{% block heading %} + {% translate "Supply" %} +{% endblock %} + +{% block content %} + + {% if user.is_superuser or user.allowed_to_supply %} + +
+ {% csrf_token %} + +
+
{% translate "Description" %}:
+ +
+ +
+
{% translate "Price" %} ({{ currency_suffix }}):
+
+ +
+
+ +
+ +
+ {% translate "cancel" %} + +
+ +
+ + + + + {% else %} + +
+

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

+ {% translate "back" %} +
+ + {% endif %} + + + +{% endblock %} diff --git a/application/app/templates/userPanel.html b/application/app/templates/userPanel.html index b634cd3..447c2d8 100644 --- a/application/app/templates/userPanel.html +++ b/application/app/templates/userPanel.html @@ -32,6 +32,9 @@ {% if user.is_superuser or user.is_staff %} Admin Panel {% endif %} + {% if user.is_superuser or user.allowed_to_supply %} + {% translate "Supply" %} + {% endif %} {% translate "Change Password" %} diff --git a/application/app/urls.py b/application/app/urls.py index c7a221a..e720876 100644 --- a/application/app/urls.py +++ b/application/app/urls.py @@ -10,6 +10,7 @@ urlpatterns = [ path('history/', views.history), path('deposit/', views.deposit), path('statistics/', views.statistics), + path('supply/', views.supply), path('accounts/login/', views.login_page, name="login"), path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'), path('accounts/password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'), @@ -18,5 +19,6 @@ urlpatterns = [ # API # path('api/order-drink', views.api_order_drink), path('api/deposit', views.api_deposit), + path('api/supply', views.api_supply) #path('api/get-statistics', views.api_get_statistics) ] \ No newline at end of file diff --git a/application/app/views.py b/application/app/views.py index 152d8bd..8511249 100644 --- a/application/app/views.py +++ b/application/app/views.py @@ -103,6 +103,10 @@ def statistics(request): } return render(request, "statistics.html", context) +@login_required +def supply(request): + return render(request, "supply.html") + @login_required def redirect_home(request): return HttpResponseRedirect("/") @@ -132,7 +136,7 @@ def api_order_drink(request): else: return HttpResponse("notAvailable", status=400) - else: raise Exception("Balance below zero.") + else: raise Exception("Unexpected input or missing privileges.") except Exception as e: print(f"An exception occured while processing an order: User: {user.username} - Exception: {e}", file=sys.stderr) @@ -163,5 +167,33 @@ def api_deposit(request): else: raise Exception("Deposit amount too big or small.") except Exception as e: - print(f"An exception occured while processing an transaction: User: {user.username} - Exception: {e}", file=sys.stderr) + print(f"An exception occured while processing a transaction: User: {user.username} - Exception: {e}", file=sys.stderr) + return HttpResponse(b"", status=500) + +@login_required +def api_supply(request): + + # check request -> supply + + user = request.user + + try: + + price = decimal.Decimal(request.POST["supplyPrice"]) + description = str(request.POST["supplyDescription"]) + + if 0.00 < price < 9999.99 and (user.allowed_to_supply or user.is_superuser): + # create transaction + RegisterTransaction.objects.create( + transaction_sum=-price, + comment=f"Supply: {description}", + is_user_deposit=False, + user=user + ) + # + return HttpResponse("success", status=200) + else: raise Exception("Unexpected input or missing privileges.") + + except Exception as e: + print(f"An exception occured while processing a supply transaction: User: {user.username} - Exception: {e}", file=sys.stderr) return HttpResponse(b"", status=500) diff --git a/application/locale/de/LC_MESSAGES/django.mo b/application/locale/de/LC_MESSAGES/django.mo index 07c684c8c574ed25adf7f9061611ea3ad5285e44..1f4683e4dba324f38b3068033447107f11c95ead 100644 GIT binary patch delta 1595 zcmYk+TWC~A9LMpA=GJ86B{p7@I;mzgO^h{F6RV{lYEfH=ET}IQH_0S9WOEYEp7j!> zt0)S=LSd<3iDtmC4P_fqPrNNLCWTXTxlq=Y8B>AH_#tk4c2kM7kU^VWs}Cy+n$2NxaDKd9%=P)9TE+h5@x z>Sd%)6Lz6CbO4pXbT#?c03i)Z^%-O><|3;7GU`nKL=F4^_0m1}&);~f7)=?o-cHnp zy08fkqQ?CWx8ONn|2skcKcV3s4NGwbS+tqQ8^x_zhT2&YYq1rX(|qaM_xk!iY^D7W zYN9dx3=6msCsCPvi|etT7sle(d2Te}5NgH8P$@cznrIA_x(lc?zJ!`!9F>_XzJ43E z&`DJPhp2u}krOt{2_2ov3ZjkBQRh3jyes;CHMq)}S&G*=T$d3_NWxvhe5e4C3)~>Uu+{j4gc;RsQPfeyP3VNI!agp5}yCIW`({YfEgPyEO z<*3g7vbG|*%BCY{!{OMbGnwI|uGhxH_DJB4+IS$y+H4TJw!+4WN9EaE_fQZ|%&pAN zNo;2Y1Ca~5b76nsRMq_@U%5EC^J_ThSVi$+y01^q_Et|78WYLt_uF8;raR6w&TS^m%0_KQ8*9@1D95NpAFC`3q=MQ+wX01K7)59UxoB0J zOH@!$)TTuQO|=LVqKJ@L8H7+sXhG1*ASjCJ|6GsI;lAg0&-LE(@t!lzG+)VNV-~%k+1g^wSScAWCGe%=(ORr2-A23>+vM= ze%VI2;j%|mdhsbX;5aVFx5#Cmsnp?D=Wq0B`;4v*v$zbqojcs~{iuFVU^AXVF1t+C z!T5I7J$Q~<;R~$Acc_79F@;}H1ANCMdi1I!rBRuyN0MMYSi}-)A;+*C&*Cb)h04$q z^cdeJxS>ybiCi{GrGckV15CU22UH4YUHhB!hw~3Mv3*`*p`SdXwD5iryKn&4;yG0R z*Ri~vo7>!IMboGm&$$1~LbG=$=1AZBZ4~ z-$&HhnNN~`eV8EMvIUi*K4dXAhy^@^>hJ4>~ zPgX*$d^dLDo)r04$HP46!%*bkt4Jv zI{7-hi$#O$=UVQh($7pqd!lq|=K6o2)RBPj@IZK&l;&PFC|a4aq0`+)EEd)juCf(- z+(TtAODJ3VwWyFWeY%k960RY%|BZyoIzs8RN+Fhy1P5yF1+ng>_ diff --git a/application/locale/de/LC_MESSAGES/django.po b/application/locale/de/LC_MESSAGES/django.po index 22c05b2..997e989 100644 --- a/application/locale/de/LC_MESSAGES/django.po +++ b/application/locale/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: 2022-06-13 19:01+0200\n" +"POT-Creation-Date: 2022-10-15 19:20+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Julian Müller (W13R)\n" "Language: DE\n" @@ -17,221 +17,266 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: app/templates/admin/base_site.html:7 +#: application/app/templates/admin/base_site.html:7 msgid "Django site admin" msgstr "Django Administrator" -#: app/templates/admin/base_site.html:15 +#: application/app/templates/admin/base_site.html:15 msgid "Django administration" msgstr "Django Administration" -#: app/templates/baseLayout.html:41 +#: application/app/templates/baseLayout.html:41 msgid "An error occured. Please log out and log in again." msgstr "Ein Fehler ist aufgetreten. Bitte ab- und wieder anmelden." -#: app/templates/deposit.html:6 +#: application/app/templates/deposit.html:6 msgid "Drinks - Deposit" msgstr "Getränke - Einzahlen" -#: app/templates/deposit.html:14 app/templates/userPanel.html:19 +#: application/app/templates/deposit.html:14 +#: application/app/templates/userPanel.html:23 msgid "Deposit" msgstr "Einzahlen" -#: app/templates/deposit.html:23 +#: application/app/templates/deposit.html:23 msgid "Amount" msgstr "Summe" -#: app/templates/deposit.html:31 app/templates/order.html:72 -#: app/templates/registration/login.html:56 +#: application/app/templates/deposit.html:31 +#: application/app/templates/order.html:72 +#: application/app/templates/registration/login.html:57 +#: application/app/templates/supply.html:41 msgid "cancel" msgstr "Abbrechen" -#: app/templates/deposit.html:32 +#: application/app/templates/deposit.html:32 msgid "confirm" msgstr "Bestätigen" -#: app/templates/history.html:6 +#: application/app/templates/history.html:6 msgid "Drinks - History" msgstr "Getränke - Verlauf" -#: app/templates/history.html:14 app/templates/userPanel.html:25 +#: application/app/templates/history.html:14 +#: application/app/templates/userPanel.html:30 msgid "History" msgstr "Verlauf" -#: app/templates/history.html:22 +#: application/app/templates/history.html:22 msgid "last 30 actions" msgstr "letzte 30 Vorgänge" -#: app/templates/history.html:33 app/templates/statistics.html:41 -#: app/templates/statistics.html:61 app/templates/statistics.html:81 -#: app/templates/statistics.html:101 app/templates/statistics.html:121 -#: app/templates/statistics.html:141 +#: application/app/templates/history.html:33 +#: application/app/templates/statistics.html:41 +#: application/app/templates/statistics.html:61 +#: application/app/templates/statistics.html:81 +#: application/app/templates/statistics.html:101 +#: application/app/templates/statistics.html:121 +#: application/app/templates/statistics.html:141 msgid "No history." msgstr "Kein Verlauf verfügbar." -#: app/templates/index.html:6 +#: application/app/templates/index.html:6 msgid "Drinks - Home" msgstr "Getränke - Home" -#: app/templates/index.html:14 +#: application/app/templates/index.html:14 msgid "Available Drinks" msgstr "Verfügbare Getränke" -#: app/templates/index.html:27 app/templates/index.html:34 +#: application/app/templates/index.html:27 +#: application/app/templates/index.html:34 msgid "available" msgstr "verfügbar" -#: app/templates/index.html:43 +#: application/app/templates/index.html:43 msgid "No drinks available." msgstr "Es sind gerade keine Getränke verfügbar." -#: app/templates/order.html:7 +#: application/app/templates/order.html:7 msgid "Drinks - Order" msgstr "Getränke - Bestellen" -#: app/templates/order.html:16 +#: application/app/templates/order.html:16 +#: packages/django/forms/formsets.py:405 packages/django/forms/formsets.py:412 msgid "Order" msgstr "Bestellung" -#: app/templates/order.html:29 +#: application/app/templates/order.html:29 msgid "Drink" msgstr "Getränk" -#: app/templates/order.html:34 +#: application/app/templates/order.html:34 msgid "Price per Item" msgstr "Preis pro Getränk" -#: app/templates/order.html:40 +#: application/app/templates/order.html:40 msgid "Available" msgstr "Verfügbar" -#: app/templates/order.html:46 +#: application/app/templates/order.html:46 msgid "Count" msgstr "Anzahl" -#: app/templates/order.html:63 +#: application/app/templates/order.html:63 msgid "Sum" msgstr "Summe" -#: app/templates/order.html:73 +#: application/app/templates/order.html:73 msgid "order" msgstr "Bestellen" -#: app/templates/order.html:85 +#: application/app/templates/order.html:85 msgid "Your balance is too low to order a drink." msgstr "Dein Saldo ist zu niedrig um Getränke zu bestellen." -#: app/templates/order.html:86 app/templates/order.html:95 +#: application/app/templates/order.html:86 +#: application/app/templates/order.html:95 +#: application/app/templates/supply.html:54 msgid "back" msgstr "zurück" -#: app/templates/order.html:94 +#: application/app/templates/order.html:94 msgid "This drink is not available." msgstr "Dieses Getränk ist gerade nicht verfügbar." -#: app/templates/registration/logged_out.html:7 +#: application/app/templates/registration/logged_out.html:7 msgid "Drinks - Logged Out" msgstr "Getränke - Abgemeldet" -#: app/templates/registration/logged_out.html:17 +#: application/app/templates/registration/logged_out.html:17 msgid "Logged out! You will be redirected shortly." msgstr "Du wurdest abgemeldet und wirst in Kürze weitergeleitet." -#: app/templates/registration/logged_out.html:19 +#: application/app/templates/registration/logged_out.html:19 msgid "Click here if automatic redirection does not work." msgstr "" "Bitte klicke hier, wenn die automatische Weiterleitung nicht funktioniert." -#: app/templates/registration/login.html:7 +#: application/app/templates/registration/login.html:8 msgid "Drinks - Login" msgstr "Getränke - Anmeldung" -#: app/templates/registration/login.html:26 +#: application/app/templates/registration/login.html:27 msgid "Log in" msgstr "Anmelden" -#: app/templates/registration/login.html:28 +#: application/app/templates/registration/login.html:29 msgid "Password/PIN" msgstr "Passwort/PIN" -#: app/templates/registration/login.html:57 +#: application/app/templates/registration/login.html:58 msgid "login" msgstr "Anmelden" -#: app/templates/registration/login.html:65 +#: application/app/templates/registration/login.html:66 msgid "Choose your account" msgstr "Wähle deinen Account" -#: app/templates/statistics.html:6 +#: application/app/templates/statistics.html:6 msgid "Drinks - Statistics" msgstr "Getränke - Statistiken" -#: app/templates/statistics.html:15 app/templates/userPanel.html:26 +#: application/app/templates/statistics.html:15 +#: application/app/templates/userPanel.html:31 msgid "Statistics" msgstr "Statistiken" -#: app/templates/statistics.html:26 +#: application/app/templates/statistics.html:26 msgid "Your orders per drink" msgstr "Deine Bestellungen pro Getränk" -#: app/templates/statistics.html:30 app/templates/statistics.html:50 +#: application/app/templates/statistics.html:30 +#: application/app/templates/statistics.html:50 msgid "drink" msgstr "Getränk" -#: app/templates/statistics.html:31 app/templates/statistics.html:51 -#: app/templates/statistics.html:71 app/templates/statistics.html:91 -#: app/templates/statistics.html:111 app/templates/statistics.html:131 +#: application/app/templates/statistics.html:31 +#: application/app/templates/statistics.html:51 +#: application/app/templates/statistics.html:71 +#: application/app/templates/statistics.html:91 +#: application/app/templates/statistics.html:111 +#: application/app/templates/statistics.html:131 msgid "count" msgstr "Anzahl" -#: app/templates/statistics.html:46 +#: application/app/templates/statistics.html:46 msgid "All orders per drink" msgstr "Alle Bestellungen pro Getränk" -#: app/templates/statistics.html:66 +#: application/app/templates/statistics.html:66 msgid "Your orders per month (last 12 months)" msgstr "Deine Bestellungen pro Monat (letzte 12 Monate)" -#: app/templates/statistics.html:70 app/templates/statistics.html:90 +#: application/app/templates/statistics.html:70 +#: application/app/templates/statistics.html:90 msgid "month" msgstr "Monat" -#: app/templates/statistics.html:86 +#: application/app/templates/statistics.html:86 msgid "All orders per month (last 12 months)" msgstr "Alle Bestellungen pro Monat (letzte 12 Monate)" -#: app/templates/statistics.html:106 +#: application/app/templates/statistics.html:106 msgid "Your orders per weekday" msgstr "Deine Bestellungen pro Wochentag" -#: app/templates/statistics.html:110 app/templates/statistics.html:130 +#: application/app/templates/statistics.html:110 +#: application/app/templates/statistics.html:130 msgid "day" msgstr "Tag" -#: app/templates/statistics.html:126 +#: application/app/templates/statistics.html:126 msgid "All orders per weekday" msgstr "Alle Bestellungen pro Wochentag" -#: app/templates/userPanel.html:6 app/templates/userPanel.html:8 +#: application/app/templates/supply.html:7 +msgid "Drinks - Supply" +msgstr "Getränke - Beschaffung" + +#: application/app/templates/supply.html:16 +#: application/app/templates/userPanel.html:36 +msgid "Supply" +msgstr "Beschaffung" + +#: application/app/templates/supply.html:27 +msgid "Description" +msgstr "Beschreibung" + +#: application/app/templates/supply.html:32 +msgid "Price" +msgstr "Preis" + +#: application/app/templates/supply.html:42 +msgid "submit" +msgstr "Senden" + +#: application/app/templates/supply.html:53 +msgid "You are not allowed to view this site." +msgstr "Dir fehlt die Berechtigung, diese Seite anzuzeigen." + +#: application/app/templates/userPanel.html:9 +#: application/app/templates/userPanel.html:11 msgid "User" msgstr "Benutzer" -#: app/templates/userPanel.html:12 app/templates/userPanel.html:14 +#: application/app/templates/userPanel.html:15 +#: application/app/templates/userPanel.html:17 msgid "Balance" msgstr "Saldo" -#: app/templates/userPanel.html:22 -msgid "Account" -msgstr "Account" - -#: app/templates/userPanel.html:30 -msgid "Change Password" -msgstr "Passwort ändern" - -#: app/templates/userPanel.html:31 +#: application/app/templates/userPanel.html:24 msgid "Logout" msgstr "Abmelden" -#: app/views.py:47 +#: application/app/templates/userPanel.html:27 +msgid "Account" +msgstr "Account" + +#: application/app/templates/userPanel.html:38 +msgid "Change Password" +msgstr "Passwort ändern" + +#: application/app/views.py:47 msgid "Invalid username or password." msgstr "Benutzername oder Passwort ungültig." diff --git a/static/css/supply.css b/static/css/supply.css new file mode 100644 index 0000000..a149993 --- /dev/null +++ b/static/css/supply.css @@ -0,0 +1,6 @@ +form { + width: 24rem; +} +#supplyPrice { + width: 10rem; +} \ No newline at end of file diff --git a/static/js/supply.js b/static/js/supply.js new file mode 100644 index 0000000..054b08d --- /dev/null +++ b/static/js/supply.js @@ -0,0 +1,56 @@ +document.addEventListener("DOMContentLoaded", () => { + + // elements + + let supply_description = document.getElementById("supplyDescription"); + let supply_price = document.getElementById("supplyPrice"); + + let supply_form = document.getElementById("supplyForm"); + let status_info = document.getElementById("statusInfo"); + let supply_submit_button = document.getElementById("supplySubmitBtn"); + + // custom submit method + + supply_form.addEventListener("submit", (event) => { + + supply_submit_button.disabled = true; + + event.preventDefault(); // Don't do the default submit action! + + if (isNaN(parseFloat(supply_price.value)) || supply_description.value == "") { + status_info.innerText = "Please enter a description and price." + supply_submit_button.disabled = false; + } + + let xhr = new XMLHttpRequest(); + let formData = new FormData(supply_form); + + xhr.addEventListener("load", (event) => { + + status_ = event.target.status; + response_ = event.target.responseText; + + if (status_ == 200 && response_ == "success") { + status_info.innerText = "Success."; + window.location.replace("/"); + } + else { + status_info.classList.add("errorText"); + status_info.innerText = "An error occured."; + window.setTimeout(() => { window.location.reload() }, 5000); + } + + }) + + xhr.addEventListener("error", (event) => { + status_info.classList.add("errorText"); + status_info.innerText = "An error occured."; + window.setTimeout(() => { window.location.reload() }, 5000); + }) + + xhr.open("POST", "/api/supply"); + xhr.send(formData); + + }); + +}) \ No newline at end of file From 9f270c12b485e7ea4a4478fde379406910fbc661 Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Wed, 2 Nov 2022 21:55:36 +0100 Subject: [PATCH 2/7] Profile pictures are now handled by the application to mitigate possible directory traversals to other sub-directories of the static directory (Admins/Staff with the right to edit user accounts were able to set a path like ../static/favicon.png for the profile picture - this isn't a "i'm in, now i have root access and can hack your mom"-vulnerability, but better fix it before it evolves to one. or a dragon. it's too late for this crap.) --- .gitignore | 4 +++- .../app/templates/registration/login.html | 2 +- application/app/templates/userPanel.html | 2 +- application/app/urls.py | 3 ++- application/app/views.py | 24 +++++++++++++++++++ application/drinks_manager/settings.py | 2 ++ lib/env.sh | 1 + .../default.svg | 0 8 files changed, 34 insertions(+), 4 deletions(-) rename {static/profilepictures => profilepictures}/default.svg (100%) diff --git a/.gitignore b/.gitignore index 8db7fca..4f97b84 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /archive/* /logs/* /packages/* +/profilepictures/* /temp /tmp __pycache__ @@ -12,4 +13,5 @@ __pycache__ !/config/config.sample.sh !/config/Caddyfile !/config/tls/ -!.gitkeep \ No newline at end of file +!/profilepictures/default.svg +!.gitkeep diff --git a/application/app/templates/registration/login.html b/application/app/templates/registration/login.html index af1f25c..765172e 100644 --- a/application/app/templates/registration/login.html +++ b/application/app/templates/registration/login.html @@ -69,7 +69,7 @@
    {% for user_ in user_list %}
  • - +
    {% if user_.first_name %} diff --git a/application/app/templates/userPanel.html b/application/app/templates/userPanel.html index 447c2d8..32afe40 100644 --- a/application/app/templates/userPanel.html +++ b/application/app/templates/userPanel.html @@ -3,7 +3,7 @@
    - + {% if user.first_name != "" %} {% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }}) diff --git a/application/app/urls.py b/application/app/urls.py index e720876..788ecd9 100644 --- a/application/app/urls.py +++ b/application/app/urls.py @@ -16,9 +16,10 @@ urlpatterns = [ path('accounts/password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'), path('accounts/password_change_done/', views.redirect_home, name='password_change_done'), path('admin/', adminSite.urls), + # custom-handled resources + path('profilepictures', views.profile_pictures), # API # path('api/order-drink', views.api_order_drink), path('api/deposit', views.api_deposit), path('api/supply', views.api_supply) - #path('api/get-statistics', views.api_get_statistics) ] \ No newline at end of file diff --git a/application/app/views.py b/application/app/views.py index 8511249..d3fafb5 100644 --- a/application/app/views.py +++ b/application/app/views.py @@ -1,12 +1,16 @@ import json import sys +from pathlib import Path + +from django.conf import settings from django.contrib.auth import authenticate from django.contrib.auth import get_user_model from django.contrib.auth import login from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import AuthenticationForm from django.http.response import HttpResponseRedirect +from django.http.response import FileResponse from django.http.response import HttpResponse from django.shortcuts import render @@ -20,6 +24,9 @@ from .models import Drink from .models import Order from .models import RegisterTransaction +# + +profile_pictures_path = Path(settings.PROFILE_PICTURES).resolve() # login view @@ -112,6 +119,23 @@ def redirect_home(request): return HttpResponseRedirect("/") +# Custom-Handled Resources + +def profile_pictures(request): + if not "name" in request.GET: + return HttpResponse(b"", status=400) + print(request.GET["name"]) + ppic_filepath = Path(profile_pictures_path / request.GET["name"]).resolve() + try: + ppic_filepath.relative_to(profile_pictures_path) + except: + return HttpResponse("No.", status=403) + if ppic_filepath.is_file(): + return FileResponse(ppic_filepath.open('rb')) + else: + return FileResponse(b"", status=404) + + # API for XHR requests # @login_required diff --git a/application/drinks_manager/settings.py b/application/drinks_manager/settings.py index 9523d14..d01503f 100644 --- a/application/drinks_manager/settings.py +++ b/application/drinks_manager/settings.py @@ -175,3 +175,5 @@ try: CURRENCY_SUFFIX = os.environ["CURRENCY_SUFFIX"] except KeyError: CURRENCY_SUFFIX = "$" + +PROFILE_PICTURES = os.environ["PROFILE_PICTURES"] diff --git a/lib/env.sh b/lib/env.sh index 8781ef1..67c9e68 100644 --- a/lib/env.sh +++ b/lib/env.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt" +export PROFILE_PICTURES="$(pwd)/profilepictures/" export STATIC_FILES="$(pwd)/static/" export APP_VERSION="12" export PYTHONPATH="$(pwd)/packages/" diff --git a/static/profilepictures/default.svg b/profilepictures/default.svg similarity index 100% rename from static/profilepictures/default.svg rename to profilepictures/default.svg From 1e32e2b5dd415a13e71b8dafd40567bcc3da68a0 Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Thu, 3 Nov 2022 20:45:52 +0100 Subject: [PATCH 3/7] The application now correctly encodes the url query string for the profile-picture name (for security reasons), removed a left-over print-statement --- application/app/templates/registration/login.html | 2 +- application/app/templates/userPanel.html | 2 +- application/app/views.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/application/app/templates/registration/login.html b/application/app/templates/registration/login.html index 765172e..184022f 100644 --- a/application/app/templates/registration/login.html +++ b/application/app/templates/registration/login.html @@ -69,7 +69,7 @@
      {% for user_ in user_list %}
    • - +
      {% if user_.first_name %} diff --git a/application/app/templates/userPanel.html b/application/app/templates/userPanel.html index 32afe40..7e95ff6 100644 --- a/application/app/templates/userPanel.html +++ b/application/app/templates/userPanel.html @@ -3,7 +3,7 @@
      - + {% if user.first_name != "" %} {% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }}) diff --git a/application/app/views.py b/application/app/views.py index d3fafb5..f380851 100644 --- a/application/app/views.py +++ b/application/app/views.py @@ -124,7 +124,6 @@ def redirect_home(request): def profile_pictures(request): if not "name" in request.GET: return HttpResponse(b"", status=400) - print(request.GET["name"]) ppic_filepath = Path(profile_pictures_path / request.GET["name"]).resolve() try: ppic_filepath.relative_to(profile_pictures_path) From 8599f49857b0eab793d1ee1065f2e819e732a01f Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Fri, 4 Nov 2022 20:35:28 +0100 Subject: [PATCH 4/7] Refactored CSS and HTML templates and polished UI (#10), changed JavaScript variable names to camelCase, adjusted filenames and some url parameter names in urlpatterns, and more. --- .../{baseLayout.html => baselayout.html} | 9 +- application/app/templates/deposit.html | 26 ++-- ...{globalMessage.html => globalmessage.html} | 2 +- application/app/templates/history.html | 9 +- application/app/templates/index.html | 10 +- application/app/templates/order.html | 84 ++++++------ .../templates/registration/logged_out.html | 4 +- .../app/templates/registration/login.html | 42 +++--- application/app/templates/statistics.html | 25 ++-- application/app/templates/supply.html | 41 +++--- .../{userPanel.html => userpanel.html} | 28 ++-- application/app/urls.py | 2 +- application/app/views.py | 16 +-- application/locale/de/LC_MESSAGES/django.po | 24 ++-- static/css/appform.css | 61 +++++++++ ...umberInput.css => custom_number_input.css} | 13 +- static/css/deposit.css | 3 - static/css/history.css | 2 +- static/css/index.css | 15 ++- static/css/login.css | 33 +++-- static/css/main.css | 124 ++++++------------ static/css/order.css | 3 - static/css/statistics.css | 30 ++--- static/css/supply.css | 6 - ...mNumberInput.js => custom_number_input.js} | 14 +- static/js/deposit.js | 22 ++-- static/js/login.js | 56 ++++---- static/js/main.js | 14 +- static/js/order.js | 54 ++++---- static/js/supply.js | 32 ++--- 30 files changed, 401 insertions(+), 403 deletions(-) rename application/app/templates/{baseLayout.html => baselayout.html} (84%) rename application/app/templates/{globalMessage.html => globalmessage.html} (65%) rename application/app/templates/{userPanel.html => userpanel.html} (56%) create mode 100644 static/css/appform.css rename static/css/{customNumberInput.css => custom_number_input.css} (78%) delete mode 100644 static/css/deposit.css delete mode 100644 static/css/order.css delete mode 100644 static/css/supply.css rename static/js/{customNumberInput.js => custom_number_input.js} (64%) diff --git a/application/app/templates/baseLayout.html b/application/app/templates/baselayout.html similarity index 84% rename from application/app/templates/baseLayout.html rename to application/app/templates/baselayout.html index ced9bb8..7d0a5e3 100644 --- a/application/app/templates/baseLayout.html +++ b/application/app/templates/baselayout.html @@ -16,13 +16,13 @@ -
      +
      - {% include "globalMessage.html" %} + {% include "globalmessage.html" %} {% if user.is_authenticated %} - {% include "userPanel.html" %} + {% include "userpanel.html" %} {% endif %} @@ -30,14 +30,13 @@ {% if user.is_authenticated or "accounts/login/" in request.path or "accounts/logout/" in request.path or "admin/logout/" in request.path %} -

      {% block heading %}{% endblock %}

      {% block content %}{% endblock %}
      {% else %} -
      +
      {% translate "An error occured. Please log out and log in again." %}
      log out diff --git a/application/app/templates/deposit.html b/application/app/templates/deposit.html index dac6950..cec4ef2 100644 --- a/application/app/templates/deposit.html +++ b/application/app/templates/deposit.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} @@ -7,29 +7,29 @@ {% endblock %} {% block headAdditional %} - + {% endblock %} -{% block heading %} - {% translate "Deposit" %} -{% endblock %} {% block content %} -
      + {% csrf_token %} -
      -
      {% translate "Amount" %} {{ currency_suffix }}:
      -
      +

      {% translate "Deposit" %}

      + +
      + {% translate "Amount" %} {{ currency_suffix }}: + + +
      -
      +
      -
      + diff --git a/application/app/templates/globalMessage.html b/application/app/templates/globalmessage.html similarity index 65% rename from application/app/templates/globalMessage.html rename to application/app/templates/globalmessage.html index f6995fa..83fd733 100644 --- a/application/app/templates/globalMessage.html +++ b/application/app/templates/globalmessage.html @@ -1,5 +1,5 @@ {% if global_message != "" %} -
      +
      {{ global_message }}
      {% endif %} \ No newline at end of file diff --git a/application/app/templates/history.html b/application/app/templates/history.html index ff43b23..7abd1f3 100644 --- a/application/app/templates/history.html +++ b/application/app/templates/history.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} @@ -10,12 +10,11 @@ {% endblock %} -{% block heading %} - {% translate "History" %} -{% endblock %} {% block content %} +

      {% translate "History" %}

      + {% if history %} @@ -25,7 +24,7 @@ {% for h in history %} - + {% endfor %}
      {{ h.0 }}{{ h.1 }}{{ h.1 }}
      diff --git a/application/app/templates/index.html b/application/app/templates/index.html index 9836e32..3756b0b 100644 --- a/application/app/templates/index.html +++ b/application/app/templates/index.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} @@ -10,15 +10,13 @@ {% endblock %} -{% block heading %} - {% translate "Available Drinks" %} -{% endblock %} - {% block content %} +

      {% translate "Available Drinks" %}

      + {% if available_drinks %} -
        +
          {% for drink in available_drinks %} {% if drink.do_not_count %}
        • diff --git a/application/app/templates/order.html b/application/app/templates/order.html index 5c72755..d720197 100644 --- a/application/app/templates/order.html +++ b/application/app/templates/order.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} {% load l10n %} @@ -8,13 +8,10 @@ {% endblock %} {% block headAdditional %} - - + + {% endblock %} -{% block heading %} - {% translate "Order" %} -{% endblock %} {% block content %} @@ -22,66 +19,67 @@ {% if user.balance > 0 or user.allow_order_with_negative_balance %} -
          + {% csrf_token %} -
          -
          {% translate "Drink" %}:
          -
          {{ drink.product_name }}
          -
          +

          {% translate "Order" %}

          -
          -
          {% translate "Price per Item" %} ({{ currency_suffix }}):
          -
          {{ drink.price }}
          +
          + {% translate "Drink" %}: + {{ drink.product_name }} +
          +
          + {% translate "Price per Item" %} ({{ currency_suffix }}): + + {{ drink.price }} +
          {% if not drink.do_not_count %} -
          -
          {% translate "Available" %}:
          -
          {{ drink.available }}
          +
          + {% translate "Available" %}: + {{ drink.available }}
          {% endif %} -
          -
          {% translate "Count" %}:
          -
          - - - {% if drink.do_not_count %} - - {% else %} - - {% endif %} - - -
          +
          + {% translate "Sum" %} ({{ currency_suffix }}): + {{ drink.price }}
          -
          -
          {% 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" %}
          @@ -90,7 +88,7 @@ {% else %} -
          +

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

          {% translate "back" %}
          diff --git a/application/app/templates/registration/logged_out.html b/application/app/templates/registration/logged_out.html index 4f36790..38bb024 100644 --- a/application/app/templates/registration/logged_out.html +++ b/application/app/templates/registration/logged_out.html @@ -1,5 +1,5 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} @@ -13,7 +13,7 @@ {% block content %} -
          +
          {% translate "Logged out! You will be redirected shortly." %}

          {% translate "Click here if automatic redirection does not work." %} diff --git a/application/app/templates/registration/login.html b/application/app/templates/registration/login.html index 184022f..4323c9e 100644 --- a/application/app/templates/registration/login.html +++ b/application/app/templates/registration/login.html @@ -1,5 +1,5 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} {% load static %} @@ -15,14 +15,14 @@ {% block content %} {% if error_message %} -

          {{ error_message }}

          +

          {{ error_message }}

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

          {% translate "Log in" %}

          @@ -31,30 +31,30 @@
          - - - + + + - - - + + + - - - + + + - - - + + +
          -
          - +
          +
          @@ -65,10 +65,10 @@

          {% translate "Choose your account" %}

          -
          +
            {% for user_ in user_list %} -
          • +
          • {% if user_.first_name %} diff --git a/application/app/templates/statistics.html b/application/app/templates/statistics.html index cc340fd..662e7d4 100644 --- a/application/app/templates/statistics.html +++ b/application/app/templates/statistics.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} @@ -11,18 +11,15 @@ {% endblock %} -{% block heading %} - {% translate "Statistics" %} -{% endblock %} - - {% block content %} -
            +

            {% translate "Statistics" %}

            -
            +
            -
            +
            + +

            {% translate "Your orders per drink" %}

            {% if noyopd %} @@ -42,7 +39,7 @@ {% endif %} -
            +

            {% translate "All orders per drink" %}

            {% if noaopd %}
            @@ -62,7 +59,7 @@ {% endif %} -
            +

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

            {% if yopml12m %}
            @@ -82,7 +79,7 @@ {% endif %} -
            +

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

            {% if aopml12m %}
            @@ -102,7 +99,7 @@ {% endif %} -
            +

            {% translate "Your orders per weekday" %}

            {% if yopwd %}
            @@ -122,7 +119,7 @@ {% endif %} -
            +

            {% translate "All orders per weekday" %}

            {% if aopwd %}
            diff --git a/application/app/templates/supply.html b/application/app/templates/supply.html index 0f62ad5..fabb224 100644 --- a/application/app/templates/supply.html +++ b/application/app/templates/supply.html @@ -1,4 +1,4 @@ -{% extends "baseLayout.html" %} +{% extends "baselayout.html" %} {% load i18n %} {% load l10n %} @@ -8,48 +8,49 @@ {% endblock %} {% block headAdditional %} - - + + {% endblock %} -{% block heading %} - {% translate "Supply" %} -{% endblock %} {% block content %} {% if user.is_superuser or user.allowed_to_supply %} - + {% csrf_token %} -
            -
            {% translate "Description" %}:
            - +

            {% translate "Supply" %}

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

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

            {% translate "back" %}
            diff --git a/application/app/templates/userPanel.html b/application/app/templates/userpanel.html similarity index 56% rename from application/app/templates/userPanel.html rename to application/app/templates/userpanel.html index 7e95ff6..7a15a36 100644 --- a/application/app/templates/userPanel.html +++ b/application/app/templates/userpanel.html @@ -1,8 +1,8 @@ {% load i18n %} {% load static %} -
            -
            +
            +
            {% if user.first_name != "" %} @@ -12,30 +12,30 @@ {% 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 }} {% endif %}
            -
            - Home - {% translate "Deposit" %} +
            + Home + {% translate "Deposit" %} {% translate "Logout" %} - diff --git a/application/app/urls.py b/application/app/urls.py index 788ecd9..70feadd 100644 --- a/application/app/urls.py +++ b/application/app/urls.py @@ -6,7 +6,7 @@ from .admin import adminSite urlpatterns = [ path('', views.index), - path('order//', views.order), + path('order//', views.order), path('history/', views.history), path('deposit/', views.deposit), path('statistics/', views.statistics), diff --git a/application/app/views.py b/application/app/views.py index f380851..33e4b49 100644 --- a/application/app/views.py +++ b/application/app/views.py @@ -84,9 +84,9 @@ def history(request): return render(request, "history.html", context) @login_required -def order(request, drinkID): +def order(request, drinkid): try: - drink_ = Drink.objects.get(pk=drinkID) + drink_ = Drink.objects.get(pk=drinkid) context = { "drink": drink_ } @@ -148,10 +148,10 @@ def api_order_drink(request): if user.allow_order_with_negative_balance or user.balance > 0: - drinkID = int(request.POST["drinkID"]) - amount = int(request.POST["numberOfDrinks"]) + drinkid = int(request.POST["drinkid"]) + amount = int(request.POST["numberofdrinks"]) - drink = Drink.objects.get(pk=drinkID) + drink = Drink.objects.get(pk=drinkid) if ((drink.do_not_count and drink.available > 0) or (drink.available >= amount)) and not drink.deleted: Order.objects.create(drink=drink, user=user, amount=amount) @@ -175,7 +175,7 @@ def api_deposit(request): try: - amount = decimal.Decimal(request.POST["depositAmount"]) + amount = decimal.Decimal(request.POST["depositamount"]) if 0.00 < amount < 9999.99: # create transaction @@ -202,8 +202,8 @@ def api_supply(request): try: - price = decimal.Decimal(request.POST["supplyPrice"]) - description = str(request.POST["supplyDescription"]) + price = decimal.Decimal(request.POST["supplyprice"]) + description = str(request.POST["supplydescription"]) if 0.00 < price < 9999.99 and (user.allowed_to_supply or user.is_superuser): # create transaction diff --git a/application/locale/de/LC_MESSAGES/django.po b/application/locale/de/LC_MESSAGES/django.po index 997e989..efc8657 100644 --- a/application/locale/de/LC_MESSAGES/django.po +++ b/application/locale/de/LC_MESSAGES/django.po @@ -25,7 +25,7 @@ msgstr "Django Administrator" msgid "Django administration" msgstr "Django Administration" -#: application/app/templates/baseLayout.html:41 +#: application/app/templates/baselayout.html:41 msgid "An error occured. Please log out and log in again." msgstr "Ein Fehler ist aufgetreten. Bitte ab- und wieder anmelden." @@ -34,7 +34,7 @@ msgid "Drinks - Deposit" msgstr "Getränke - Einzahlen" #: application/app/templates/deposit.html:14 -#: application/app/templates/userPanel.html:23 +#: application/app/templates/userpanel.html:23 msgid "Deposit" msgstr "Einzahlen" @@ -58,7 +58,7 @@ msgid "Drinks - History" msgstr "Getränke - Verlauf" #: application/app/templates/history.html:14 -#: application/app/templates/userPanel.html:30 +#: application/app/templates/userpanel.html:30 msgid "History" msgstr "Verlauf" @@ -178,7 +178,7 @@ msgid "Drinks - Statistics" msgstr "Getränke - Statistiken" #: application/app/templates/statistics.html:15 -#: application/app/templates/userPanel.html:31 +#: application/app/templates/userpanel.html:31 msgid "Statistics" msgstr "Statistiken" @@ -235,7 +235,7 @@ msgid "Drinks - Supply" msgstr "Getränke - Beschaffung" #: application/app/templates/supply.html:16 -#: application/app/templates/userPanel.html:36 +#: application/app/templates/userpanel.html:36 msgid "Supply" msgstr "Beschaffung" @@ -255,25 +255,25 @@ msgstr "Senden" msgid "You are not allowed to view this site." msgstr "Dir fehlt die Berechtigung, diese Seite anzuzeigen." -#: application/app/templates/userPanel.html:9 -#: application/app/templates/userPanel.html:11 +#: application/app/templates/userpanel.html:9 +#: application/app/templates/userpanel.html:11 msgid "User" msgstr "Benutzer" -#: application/app/templates/userPanel.html:15 -#: application/app/templates/userPanel.html:17 +#: application/app/templates/userpanel.html:15 +#: application/app/templates/userpanel.html:17 msgid "Balance" msgstr "Saldo" -#: application/app/templates/userPanel.html:24 +#: application/app/templates/userpanel.html:24 msgid "Logout" msgstr "Abmelden" -#: application/app/templates/userPanel.html:27 +#: application/app/templates/userpanel.html:27 msgid "Account" msgstr "Account" -#: application/app/templates/userPanel.html:38 +#: application/app/templates/userpanel.html:38 msgid "Change Password" msgstr "Passwort ändern" diff --git a/static/css/appform.css b/static/css/appform.css new file mode 100644 index 0000000..5c727b5 --- /dev/null +++ b/static/css/appform.css @@ -0,0 +1,61 @@ +.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/static/css/customNumberInput.css b/static/css/custom_number_input.css similarity index 78% rename from static/css/customNumberInput.css rename to static/css/custom_number_input.css index 4df663f..375f0de 100644 --- a/static/css/customNumberInput.css +++ b/static/css/custom_number_input.css @@ -1,30 +1,29 @@ /* custom number input */ -.customNumberInput { +.customnumberinput { display: flex; flex-direction: row; height: 2.2rem; - width: 100% !important; } -.customNumberInput button { +.customnumberinput button { min-width: 2.5rem !important; width: 2.5rem !important; padding: 0; margin: 0; height: 100%; } -.customNumberInput-minus { +.customnumberinput-minus { border-bottom-right-radius: 0; border-top-right-radius: 0; z-index: 10; } -.customNumberInput-plus { +.customnumberinput-plus { border-bottom-left-radius: 0; border-top-left-radius: 0; z-index: 10; } -.customNumberInput input[type="number"] { +.customnumberinput input[type="number"] { max-height: 100%; - width: 5rem; + width: 4rem; padding: 0; margin: 0; font-size: .9rem; diff --git a/static/css/deposit.css b/static/css/deposit.css deleted file mode 100644 index 3b4ff50..0000000 --- a/static/css/deposit.css +++ /dev/null @@ -1,3 +0,0 @@ -#depositAmount { - width: 10rem; -} \ No newline at end of file diff --git a/static/css/history.css b/static/css/history.css index cb0ce7a..6c87d89 100644 --- a/static/css/history.css +++ b/static/css/history.css @@ -9,7 +9,7 @@ padding-bottom: .4rem !important; font-size: .95rem; } -.history .historyDate { +.history .historydate { margin-left: auto; text-align: right; font-size: .8rem !important; diff --git a/static/css/index.css b/static/css/index.css index b5caa67..a89df5d 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -1,4 +1,4 @@ -.availableDrinksList { +.availabledrinkslist { width: 50%; max-width: 45rem; list-style: none; @@ -9,13 +9,13 @@ justify-content: start; align-items: center; } -.availableDrinksList li { +.availabledrinkslist li { display: flex; width: 100%; height: fit-content; margin-bottom: .6rem; } -.availableDrinksList li a { +.availabledrinkslist li a { display: flex; width: 100%; align-items: center; @@ -25,20 +25,21 @@ text-decoration: none; font-size: 1rem; } -.availableDrinksList li a span:first-child { +.availabledrinkslist li a span:first-child { margin-right: 1rem !important; + text-align: left; } -.availableDrinksList li a span:last-child { +.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 { + .availabledrinkslist { width: 95%; } - .availableDrinksList li a { + .availabledrinkslist li a { width: calc(100vw - (2 * .8rem)) !important; padding: .8rem !important; } diff --git a/static/css/login.css b/static/css/login.css index 6414c2d..13776e9 100644 --- a/static/css/login.css +++ b/static/css/login.css @@ -1,15 +1,11 @@ /* login page */ -body.overflowHidden { - overflow-y: hidden !important; - overflow-x: hidden !important; -} main { margin-top: 2vh; } main > h1 { display: none; } -.userlistContainer { +.userlistcontainer { display: flex; flex-direction: column; align-items: center; @@ -47,10 +43,10 @@ main > h1 { text-align: center; padding: .8rem 1.1rem; } -.userlistButton { +.userlistbutton { font-size: 1.1rem; } -.passwordOverlayContainer { +.passwordoverlaycontainer { position: absolute; top: 0; width: 100vw; @@ -62,30 +58,41 @@ main > h1 { background: var(--page-background); z-index: 40; } -.passwordOverlay { +.passwordoverlay { display: flex; flex-direction: column; justify-content: start; align-items: center; } -.passwordOverlay > form { +.passwordoverlay > form { min-width: unset; width: fit-content; } -.passwordOverlay > form > h1 { +.passwordoverlay > form > h1 { margin-top: 2rem; margin-bottom: 2rem; } -form input[type="password"], form input[type="text"] { +/* 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; } -form .horizontalButtonList { +.loginform .horizontalbuttonlist { margin-top: 1.5rem; } +.horizontalbuttonlist .button, .horizontalbuttonlist button { + font-size: 1rem; +} +/***/ .pinpad { margin-top: 1.5rem; margin-bottom: 0; @@ -109,7 +116,7 @@ form .horizontalButtonList { margin: .2rem !important; } @media only screen and (max-width: 700px) { - .userlistContainer { + .userlistcontainer { width: 95vw; } .userlist { diff --git a/static/css/main.css b/static/css/main.css index c9cb878..8b999b7 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -6,8 +6,8 @@ --color: #fafafa; --color-error: rgb(255, 70, 70); /** glass **/ - --glass-bg-dropDown: #3a3b44ef; - --glass-bg-dropDown-hover: #55565efa; + --glass-bg-dropdown: #3a3b44ef; + --glass-bg-dropdown-hover: #55565efa; --glass-bg-color1: #ffffff31; --glass-bg-color2: #ffffff1a; --glass-bg-hover-color1: #ffffff46; @@ -16,18 +16,18 @@ --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: .3rem; + --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); + --bg-globalmessage: linear-gradient(135deg, #4b351c, #411d52, #1c404b); } @supports(backdrop-filter: blur(10px)) { :root { - --glass-bg-dropDown: #ffffff1a; - --glass-bg-dropDown-hover: #ffffff46; + --glass-bg-dropdown: #ffffff1a; + --glass-bg-dropdown-hover: #ffffff46; --glass-blur: blur(18px); } } @@ -42,7 +42,7 @@ body { color: var(--color); overflow-x: hidden; } -.baseLayout { +.baselayout { display: flex; flex-direction: column; justify-content: start; @@ -60,7 +60,7 @@ main { width: 100%; margin-top: 5vh; } -.userPanel { +.userpanel { display: flex; flex-direction: row; justify-content: center; @@ -69,21 +69,21 @@ main { font-size: 1rem; width: 94%; } -.userInfo > span { +.userinfo > span { font-size: 1.1rem; vertical-align: middle; } -.userInfo > img { +.userinfo > img { vertical-align: middle; width: 1.8rem; height: 1.8rem; margin: .5rem; } -.userPanel > .horizontalButtonList { +.userpanel > .horizontalbuttonlist { margin-left: auto; margin-right: 0; } -.userBalanceWarn { +.userbalancewarn { color: var(--color-error); font-weight: bold; } @@ -95,19 +95,16 @@ main { width: 100%; flex-grow: 1; } -main > h1 { - margin-top: 0; -} -.globalMessage { +.globalmessage { width: 100vw; z-index: 999; display: flex; justify-content: center; align-items: center; - background: var(--bg-globalMessage); + background: var(--bg-globalmessage); padding: .3rem 0; } -.globalMessage div { +.globalmessage div { width: 96%; text-align: center; word-break: keep-all; @@ -115,24 +112,24 @@ main > h1 { box-sizing: border-box; } /* DROP DOWN MENUS */ -.dropDownMenu { +.dropdownmenu { display: flex; flex-direction: column; justify-content: flex-start; align-items: center; border-radius: var(--glass-corner-radius); } -.dropDownButton { +.dropdownbutton { width: fit-content; z-index: 190; box-shadow: none; text-align: center; justify-content: center; } -.dropDownButton, .dropDownChoice { +.dropdownbutton, .dropdownchoice { font-size: 1rem; } -.dropDownList { +.dropdownlist { position: absolute; display: flex; flex-direction: column; @@ -144,35 +141,35 @@ main > h1 { opacity: 0%; transition: opacity 100ms; } -.dropDownChoice { +.dropdownchoice { box-shadow: none; border-radius: 0 !important; margin: 0; margin-top: -1px; text-align: center; justify-content: center; - background: var(--glass-bg-dropDown) !important; + background: var(--glass-bg-dropdown) !important; backdrop-filter: none !important; } -.dropDownChoice:hover { - background: var(--glass-bg-dropDown-hover) !important; +.dropdownchoice:hover { + background: var(--glass-bg-dropdown-hover) !important; } -.dropDownList :first-child { +.dropdownlist :first-child { border-top-left-radius: var(--glass-corner-radius) !important; border-top-right-radius: var(--glass-corner-radius) !important; } -.dropDownList :last-child { +.dropdownlist :last-child { border-bottom-left-radius: var(--glass-corner-radius) !important; border-bottom-right-radius: var(--glass-corner-radius) !important; } -.dropDownVisible .dropDownList { +.dropdownvisible .dropdownlist { opacity: 100%; visibility: visible; pointer-events: visible; } /* FOOTER */ .footer { - z-index: 990; + z-index: 900; display: flex; flex-direction: row; justify-content: center; @@ -181,6 +178,7 @@ main > h1 { margin-top: auto; padding-top: 3rem; padding-bottom: .3rem; + text-align: center; } .footer div { font-size: .95rem; @@ -236,47 +234,6 @@ th { text-align: left; border-bottom: 1px solid var(--color); } -/* FORMS */ -form { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-width: 18rem; - height: max-content; -} -form .row { - width: 100%; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - margin: .2rem 0; -} -form .row .column { - display: flex; - flex-direction: row; -} -form h1 { - font-size: 1.6rem; - margin-bottom: 2rem; -} -form { - font-size: 1.1rem; -} -form .customNumberInput { - width: 100%; -} -form .statusInfo { - margin-top: .5rem; -} -form .horizontalButtonList { - margin-top: 2rem; - width: 100%; -} -form .button, form button { - font-size: 1rem; -} /* BUTTONS & OTHER INPUT ELEMENTS */ .button, button { display: flex; @@ -322,8 +279,8 @@ input[type="text"], input[type="password"], input[type="number"] { border: none; border-radius: var(--glass-corner-radius); } -/**** CUSTOM CLASSES ****/ -.centeringFlex { +/**** OTHER CLASSES ****/ +.centeringflex { width: 100%; height: 100%; display: flex; @@ -333,22 +290,25 @@ input[type="text"], input[type="password"], input[type="number"] { text-align: center; padding: 2rem 1rem; } -.horizontalButtonList { +.horizontalbuttonlist { display: flex; flex-direction: row; align-items: flex-end; justify-content: space-between; } -.horizontalButtonList > .button, .horizontalButtonList > button, .horizontalButtonList > div { +.horizontalbuttonlist > .button, .horizontalbuttonlist > button, .horizontalbuttonlist > div { margin: 0 .5rem; } -.errorText { +.errortext { margin-top: 1rem; color: var(--color-error); } .nodisplay { display: none !important; } +.heading { + margin-top: 0; +} /* MISC / GENERAL */ h1 { text-align: center; @@ -357,25 +317,25 @@ h1 { /* MOBILE OPTIMIZATIONS */ @media only screen and (max-width: 700px) { main { - margin-top: 1.5rem; + margin-top: 2rem; } - .globalMessage span { + .globalmessage span { width: 90%; } - .userPanel { + .userpanel { flex-direction: column; justify-content: start; align-items: center; } - .userPanel > .horizontalButtonList { + .userpanel > .horizontalbuttonlist { margin-right: 0; margin-left: 0; margin-top: .5rem; justify-content: center; flex-wrap: wrap; } - .userPanel > .horizontalButtonList > .button, - .userPanel > .horizontalButtonList > .dropDownMenu { + .userpanel > .horizontalbuttonlist > .button, + .userpanel > .horizontalbuttonlist > .dropdownmenu { margin: 0.25rem; } } \ No newline at end of file diff --git a/static/css/order.css b/static/css/order.css deleted file mode 100644 index 3d2685b..0000000 --- a/static/css/order.css +++ /dev/null @@ -1,3 +0,0 @@ -form { - width: 22rem; -} \ No newline at end of file diff --git a/static/css/statistics.css b/static/css/statistics.css index 9416b17..5abc145 100644 --- a/static/css/statistics.css +++ b/static/css/statistics.css @@ -1,15 +1,11 @@ -.mainContainer { +.maincontainer { min-width: 70vw; display: flex; flex-direction: column; align-items: center; justify-content: start; } -.statsHeading { - min-width: max-content; - margin-top: 0; -} -.tablesContainer { +.tablescontainer { display: flex; flex-direction: column; align-items: center; @@ -17,7 +13,7 @@ width: 95%; margin-top: 2rem; } -.statisticsTable { +.statisticstable { margin-bottom: 2rem; padding-bottom: 1rem; display: flex; @@ -26,38 +22,32 @@ align-items: center; text-align: center; } -.statisticsTable h1 { +.statisticstable h1 { margin-top: 0; font-size: 1.2rem; text-align: left; min-width: 10rem; text-align: center; } -.statisticsTable table { +.statisticstable table { min-width: 20vw; width: fit-content; } -.statisticsTable th:last-child { +.statisticstable th:last-child { text-align: right; } -.statisticsTable td:last-child { +.statisticstable td:last-child { text-align: right; } @media only screen and (max-width: 700px) { - .statisticsTable h1 { + .statisticstable h1 { min-width: 90vw; } - .statisticsTable table { + .statisticstable table { min-width: 80vw; } - .statisticsTable { + .statisticstable { margin-bottom: 2rem; padding-bottom: 1rem; } - .statsHeading { - margin-left: 0; - margin-right: 0; - padding-top: 1rem; - padding-bottom: 2rem; - } } \ No newline at end of file diff --git a/static/css/supply.css b/static/css/supply.css deleted file mode 100644 index a149993..0000000 --- a/static/css/supply.css +++ /dev/null @@ -1,6 +0,0 @@ -form { - width: 24rem; -} -#supplyPrice { - width: 10rem; -} \ No newline at end of file diff --git a/static/js/customNumberInput.js b/static/js/custom_number_input.js similarity index 64% rename from static/js/customNumberInput.js rename to static/js/custom_number_input.js index fd50680..299e02b 100644 --- a/static/js/customNumberInput.js +++ b/static/js/custom_number_input.js @@ -1,18 +1,18 @@ { document.addEventListener("DOMContentLoaded", () => { - // get all customNumberInput Elements - let custom_number_inputs = document.getElementsByClassName("customNumberInput"); - // Add Event Handler to the elements of the customNumberInputs - [...custom_number_inputs].forEach(element => { + // get all customnumberinput Elements + let customNumberInputElements = document.getElementsByClassName("customnumberinput"); + // Add Event Handler to the elements of the customnumberinputs + [...customNumberInputElements].forEach(element => { // number input - let numberFieldElement = element.getElementsByClassName("customNumberInputField")[0]; + let numberFieldElement = element.getElementsByClassName("customnumberinput-field")[0]; // minus button - element.getElementsByClassName("customNumberInput-minus")[0].addEventListener("click", () => { + element.getElementsByClassName("customnumberinput-minus")[0].addEventListener("click", () => { alterCustomNumberField(numberFieldElement, -1) }); // plus button - element.getElementsByClassName("customNumberInput-plus")[0].addEventListener("click", () => { + element.getElementsByClassName("customnumberinput-plus")[0].addEventListener("click", () => { alterCustomNumberField(numberFieldElement, +1) }); }) diff --git a/static/js/deposit.js b/static/js/deposit.js index fb3242c..4e8905d 100644 --- a/static/js/deposit.js +++ b/static/js/deposit.js @@ -2,21 +2,21 @@ document.addEventListener("DOMContentLoaded", () => { // elements - let deposit_form = document.getElementById("depositForm"); - let status_info = document.getElementById("statusInfo"); - let deposit_submit_button = document.getElementById("depositSubmitBtn"); + 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 - deposit_form.addEventListener("submit", (event) => { + depositForm.addEventListener("submit", (event) => { - deposit_submit_button.disabled = true; + depositSubmitButton.disabled = true; event.preventDefault(); // Don't do the default submit action! let xhr = new XMLHttpRequest(); - let formData = new FormData(deposit_form); + let formData = new FormData(depositForm); xhr.addEventListener("load", (event) => { @@ -24,20 +24,20 @@ document.addEventListener("DOMContentLoaded", () => { response_ = event.target.responseText; if (status_ == 200 && response_ == "success") { - status_info.innerText = "Success. Redirecting soon."; + statusInfo.innerText = "Success. Redirecting soon."; window.location.replace("/"); } else { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured. Redirecting in 5 seconds..."; + statusInfo.classList.add("errortext"); + statusInfo.innerText = "An error occured. Redirecting in 5 seconds..."; window.setTimeout(() => { window.location.replace("/") }, 5000); } }) xhr.addEventListener("error", (event) => { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured. Redirecting in 5 seconds..."; + statusInfo.classList.add("errortext"); + statusInfo.innerText = "An error occured. Redirecting in 5 seconds..."; window.setTimeout(() => { window.location.replace("/") }, 5000); }) diff --git a/static/js/login.js b/static/js/login.js index aea0630..47c2b9f 100644 --- a/static/js/login.js +++ b/static/js/login.js @@ -2,14 +2,14 @@ // Define variables - let username_input; - let password_input; - let submit_button; - let password_overlay; - let pw_overlay_cancel; - let userlist_buttons; - let pinpad_buttons; - let userlist_container; + let usernameInputElement; + let passwordInputElement; + let submitButton; + let passwordOverlayElement; + let pwOverlayCancelButton; + let userlistButtons; + let pinpadButtons; + let userlistContainerElement; // Add event listeners after DOM Content loaded @@ -18,34 +18,34 @@ // elements - username_input = document.getElementById("id_username"); - password_input = document.getElementById("id_password"); - submit_button = document.getElementById("submit_login"); - password_overlay = document.getElementById("passwordOverlayContainer"); - pw_overlay_cancel = document.getElementById("pwoCancel"); - userlist_container = document.getElementById("userlistContainer"); + usernameInputElement = document.getElementById("id_username"); + passwordInputElement = document.getElementById("id_password"); + submitButton = document.getElementById("submit_login"); + passwordOverlayElement = document.getElementById("passwordoverlaycontainer"); + pwOverlayCancelButton = document.getElementById("pwocancel"); + userlistContainerElement = document.getElementById("userlistcontainer"); - userlist_buttons = document.getElementsByClassName("userlistButton"); - pinpad_buttons = document.getElementsByClassName("pinpadBtn"); + userlistButtons = document.getElementsByClassName("userlistbutton"); + pinpadButtons = document.getElementsByClassName("pinpadbtn"); // event listeners // [...] converts an html collection to an array - [...userlist_buttons].forEach(element => { + [...userlistButtons].forEach(element => { element.addEventListener("click", () => { set_username(element.dataset.username); show_password_overlay(); }) }); - [...pinpad_buttons].forEach(element => { + [...pinpadButtons].forEach(element => { element.addEventListener("click", () => { pinpad_press(element.dataset.btn); }) }) - pw_overlay_cancel.addEventListener("click", () => { + pwOverlayCancelButton.addEventListener("click", () => { hide_password_overlay(); }); @@ -53,34 +53,34 @@ function set_username(username) { - username_input.value = username; + usernameInputElement.value = username; } function show_password_overlay() { window.scrollTo(0, 0); - password_overlay.classList.remove("nodisplay"); - userlist_container.classList.add("nodisplay"); + passwordOverlayElement.classList.remove("nodisplay"); + userlistContainerElement.classList.add("nodisplay"); } function hide_password_overlay() { - password_overlay.classList.add("nodisplay"); - userlist_container.classList.remove("nodisplay"); - password_input.value = ""; + passwordOverlayElement.classList.add("nodisplay"); + userlistContainerElement.classList.remove("nodisplay"); + passwordInputElement.value = ""; } function pinpad_press(key) { if (key == "enter") { - submit_button.click(); + submitButton.click(); } else if (key == "x") { - password_input.value = ""; + passwordInputElement.value = ""; } else { - password_input.value += key; + passwordInputElement.value += key; } } diff --git a/static/js/main.js b/static/js/main.js index 8fdc085..58b2373 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -1,17 +1,17 @@ document.addEventListener("DOMContentLoaded", () => { - let dropDownMenuElement = document.getElementById("dropDownMenu"); - let dropDownMenuButtonElement = document.getElementById("dropDownMenuButton"); + let dropdownmenuElement = document.getElementById("dropdownmenu"); + let dropdownmenuButtonElement = document.getElementById("dropdownmenu-button"); - if (dropDownMenuButtonElement != null) { + if (dropdownmenuButtonElement != null) { - dropDownMenuButtonElement.addEventListener("click", () => { + dropdownmenuButtonElement.addEventListener("click", () => { - if (dropDownMenuElement.classList.contains("dropDownVisible")) { - dropDownMenuElement.classList.remove("dropDownVisible"); + if (dropdownmenuElement.classList.contains("dropdownvisible")) { + dropdownmenuElement.classList.remove("dropdownvisible"); } else { - dropDownMenuElement.classList.add("dropDownVisible"); + dropdownmenuElement.classList.add("dropdownvisible"); } }) diff --git a/static/js/order.js b/static/js/order.js index 8451e8c..46f88b6 100644 --- a/static/js/order.js +++ b/static/js/order.js @@ -2,54 +2,54 @@ document.addEventListener("DOMContentLoaded", () => { // elements - let order_number_of_drinks_input = document.getElementById("numberOfDrinks"); - let order_number_of_drinks_btn_a = document.getElementById("numberOfDrinksBtnA"); - let order_number_of_drinks_btn_b = document.getElementById("numberOfDrinksBtnB"); - let order_sum_element = document.getElementById("orderCalculatedSum"); + 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 order_form = document.getElementById("orderForm"); - let status_info = document.getElementById("statusInfo"); - let order_submit_button = document.getElementById("orderSubmitBtn"); + let orderFormElement = document.getElementById("orderform"); + let statusInfoElement = document.getElementById("statusinfo"); + let orderSubmitButton = document.getElementById("ordersubmitbtn"); // calculate & display sum - let order_price_per_drink = parseFloat(document.getElementById("pricePerDrink").dataset.drinkPrice); + let orderPricePerDrink = parseFloat(document.getElementById("priceperdrink").dataset.drinkPrice); - function calculate_and_display_sum() { + function calculateAndDisplaySum() { setTimeout(() => { - let number_of_drinks = parseFloat(order_number_of_drinks_input.value); - if (isNaN(number_of_drinks)) { - number_of_drinks = 1; + let numberOfDrinks = parseFloat(orderNumberofdrinksInput.value); + if (isNaN(numberOfDrinks)) { + numberOfDrinks = 1; } - let calculated_sum = order_price_per_drink * number_of_drinks; - order_sum_element.innerText = new Intl.NumberFormat(undefined, {minimumFractionDigits: 2}).format(calculated_sum); + let calculated_sum = orderPricePerDrink * numberOfDrinks; + orderSumElement.innerText = new Intl.NumberFormat(undefined, {minimumFractionDigits: 2}).format(calculated_sum); }, 25); } - order_number_of_drinks_input.addEventListener("input", calculate_and_display_sum); - order_number_of_drinks_btn_a.addEventListener("click", calculate_and_display_sum); - order_number_of_drinks_btn_b.addEventListener("click", calculate_and_display_sum); + orderNumberofdrinksInput.addEventListener("input", calculateAndDisplaySum); + orderNumberofdrinksBtnA.addEventListener("click", calculateAndDisplaySum); + orderNumberofdrinksBtnB.addEventListener("click", calculateAndDisplaySum); // custom submit method - order_form.addEventListener("submit", (event) => { + orderFormElement.addEventListener("submit", (event) => { - order_submit_button.disabled = true; + orderSubmitButton.disabled = true; event.preventDefault(); // Don't do the default submit action! - if (isNaN(parseFloat(order_number_of_drinks_input.value))) { - order_number_of_drinks_input.value = 1; + if (isNaN(parseFloat(orderNumberofdrinksInput.value))) { + orderNumberofdrinksInput.value = 1; } let xhr = new XMLHttpRequest(); - let formData = new FormData(order_form); + let formData = new FormData(orderFormElement); xhr.addEventListener("load", (event) => { @@ -57,20 +57,20 @@ document.addEventListener("DOMContentLoaded", () => { response_ = event.target.responseText; if (status_ == 200 && response_ == "success") { - status_info.innerText = "Success."; + statusInfoElement.innerText = "Success."; window.location.replace("/"); } else { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured."; + statusInfoElement.classList.add("errortext"); + statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); } }) xhr.addEventListener("error", (event) => { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured."; + statusInfoElement.classList.add("errortext"); + statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); }) diff --git a/static/js/supply.js b/static/js/supply.js index 054b08d..90e8340 100644 --- a/static/js/supply.js +++ b/static/js/supply.js @@ -2,28 +2,28 @@ document.addEventListener("DOMContentLoaded", () => { // elements - let supply_description = document.getElementById("supplyDescription"); - let supply_price = document.getElementById("supplyPrice"); + let supplyDescriptionElement = document.getElementById("supplydescription"); + let supplyPriceElement = document.getElementById("supplyprice"); - let supply_form = document.getElementById("supplyForm"); - let status_info = document.getElementById("statusInfo"); - let supply_submit_button = document.getElementById("supplySubmitBtn"); + let supplyFormElement = document.getElementById("supplyform"); + let statusInfoElement = document.getElementById("statusinfo"); + let supplySubmitButton = document.getElementById("supplysubmitbtn"); // custom submit method - supply_form.addEventListener("submit", (event) => { + supplyFormElement.addEventListener("submit", (event) => { - supply_submit_button.disabled = true; + supplySubmitButton.disabled = true; event.preventDefault(); // Don't do the default submit action! - if (isNaN(parseFloat(supply_price.value)) || supply_description.value == "") { - status_info.innerText = "Please enter a description and price." - supply_submit_button.disabled = false; + 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(supply_form); + let formData = new FormData(supplyFormElement); xhr.addEventListener("load", (event) => { @@ -31,20 +31,20 @@ document.addEventListener("DOMContentLoaded", () => { response_ = event.target.responseText; if (status_ == 200 && response_ == "success") { - status_info.innerText = "Success."; + statusInfoElement.innerText = "Success."; window.location.replace("/"); } else { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured."; + statusInfoElement.classList.add("errortext"); + statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); } }) xhr.addEventListener("error", (event) => { - status_info.classList.add("errorText"); - status_info.innerText = "An error occured."; + statusInfoElement.classList.add("errortext"); + statusInfoElement.innerText = "An error occured."; window.setTimeout(() => { window.location.reload() }, 5000); }) From 3d778df3d5bb0c1b2e578a9ced40cebfc1b8589e Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Sat, 5 Nov 2022 09:33:58 +0100 Subject: [PATCH 5/7] Removed feature: register balance (closes #8) --- application/app/admin.py | 3 --- application/app/models.py | 12 +----------- application/app/templates/admin/index.html | 1 - lib/upgrade-db.py | 5 +---- lib/verify-db-app-version.py | 1 - 5 files changed, 2 insertions(+), 20 deletions(-) diff --git a/application/app/admin.py b/application/app/admin.py index e72e506..4234240 100644 --- a/application/app/admin.py +++ b/application/app/admin.py @@ -26,9 +26,6 @@ class CustomAdminSite(admin.AdminSite): def index(self, request, extra_context=None): return super().index(request, extra_context={ - "registerBalance": "{:10.2f}".format( - Global.objects.get(name="register_balance").value_float - ), "admin_info": Global.objects.get(name="admin_info").value_string, **(extra_context or {}) }) diff --git a/application/app/models.py b/application/app/models.py index b92672c..3e71331 100644 --- a/application/app/models.py +++ b/application/app/models.py @@ -7,13 +7,6 @@ from django.forms import ValidationError from django.utils import timezone -# helper - -def make_register_transaction(transaction_sum:float): - regbalance = Global.objects.get(name="register_balance") - regbalance.value_float += float(round(float(transaction_sum), 2)) - regbalance.save() - # Custom user model class User(AbstractUser): @@ -61,7 +54,7 @@ class RegisterTransaction(models.Model): class Meta: verbose_name = "register transaction" verbose_name_plural = "register" - + transaction_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0.00) # the following original_transaction_sum is needed when need to be # updated, but the old value needs to be known (field is hidden) @@ -73,7 +66,6 @@ class RegisterTransaction(models.Model): def save(self, *args, **kwargs): if self._state.adding: - make_register_transaction(self.transaction_sum) if self.is_user_deposit == True: # update user balance self.user.balance += self.transaction_sum self.user.save() @@ -82,7 +74,6 @@ class RegisterTransaction(models.Model): else: # update register transaction sum_diff = self.transaction_sum - self.old_transaction_sum - make_register_transaction(sum_diff) # update user balance if self.is_user_deposit == True: ub_sum_diff = self.transaction_sum - self.old_transaction_sum @@ -92,7 +83,6 @@ class RegisterTransaction(models.Model): super().save(*args, **kwargs) def delete(self, *args, **kwargs): - make_register_transaction(-self.transaction_sum) # update user deposit if self.is_user_deposit: self.user.balance -= self.transaction_sum diff --git a/application/app/templates/admin/index.html b/application/app/templates/admin/index.html index 4e90d29..118829a 100644 --- a/application/app/templates/admin/index.html +++ b/application/app/templates/admin/index.html @@ -6,7 +6,6 @@
            -

            Current Register Balance: {{ registerBalance }}{{ currency_suffix }}

            {% if global_message != "" %}

            Global Message: {{ global_message }}

            {% endif %} diff --git a/lib/upgrade-db.py b/lib/upgrade-db.py index b773ac2..2bc239c 100644 --- a/lib/upgrade-db.py +++ b/lib/upgrade-db.py @@ -59,10 +59,7 @@ if __name__ == "__main__": # # # # # - execute_sql_statement(cur, conn, """ - insert into app_global - values ('register_balance', 'This is the current balance of the register.', 0.0, ''); - """) + log("Not deleting register_balance. You can delete it via the Admin Panel (Globals -> register_balance), as it is no more used.") execute_sql_statement(cur, conn, """ insert into app_global diff --git a/lib/verify-db-app-version.py b/lib/verify-db-app-version.py index 4367f32..92a7627 100644 --- a/lib/verify-db-app-version.py +++ b/lib/verify-db-app-version.py @@ -63,7 +63,6 @@ def check_database(): required_rows = [ "global_message", - "register_balance", "admin_info" ] From af4dbc74b59fa4055e2e438880d25c4770d481c8 Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Sat, 5 Nov 2022 09:40:41 +0100 Subject: [PATCH 6/7] Rename Register Transactions to Transactions in the Admin Panel (#9) --- application/app/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/app/models.py b/application/app/models.py index 3e71331..a3bb11c 100644 --- a/application/app/models.py +++ b/application/app/models.py @@ -52,8 +52,8 @@ class Drink(models.Model): class RegisterTransaction(models.Model): class Meta: - verbose_name = "register transaction" - verbose_name_plural = "register" + verbose_name = "transaction" + verbose_name_plural = "transactions" transaction_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0.00) # the following original_transaction_sum is needed when need to be From 09836176e6b8eec8da282e8791979141db3abbbb Mon Sep 17 00:00:00 2001 From: W13R <9070224-W13R@users.noreply.gitlab.com> Date: Sat, 5 Nov 2022 09:47:18 +0100 Subject: [PATCH 7/7] Bumped version to 13 --- lib/env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/env.sh b/lib/env.sh index 67c9e68..5863525 100644 --- a/lib/env.sh +++ b/lib/env.sh @@ -3,5 +3,5 @@ export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt" export PROFILE_PICTURES="$(pwd)/profilepictures/" export STATIC_FILES="$(pwd)/static/" -export APP_VERSION="12" +export APP_VERSION="13" export PYTHONPATH="$(pwd)/packages/"