sandwitches 2.4.1__py3-none-any.whl → 2.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sandwitches/forms.py CHANGED
@@ -1,5 +1,4 @@
1
1
  from django import forms
2
- from django.conf import settings
3
2
  from django.contrib.auth import get_user_model
4
3
  from django.contrib.auth.forms import UserCreationForm
5
4
  from django.utils.translation import gettext_lazy as _
@@ -47,11 +46,6 @@ class AdminSetupForm(forms.ModelForm, BaseUserFormMixin):
47
46
 
48
47
 
49
48
  class UserSignupForm(UserCreationForm, BaseUserFormMixin):
50
- language = forms.ChoiceField(
51
- choices=settings.LANGUAGES,
52
- label=_("Preferred language"),
53
- initial=settings.LANGUAGE_CODE,
54
- )
55
49
  avatar = forms.ImageField(label=_("Profile Image"), required=False)
56
50
  bio = forms.CharField(
57
51
  widget=forms.Textarea(attrs={"rows": 3}), label=_("Bio"), required=False
@@ -64,7 +58,6 @@ class UserSignupForm(UserCreationForm, BaseUserFormMixin):
64
58
  "first_name",
65
59
  "last_name",
66
60
  "email",
67
- "language",
68
61
  "avatar",
69
62
  "bio",
70
63
  )
@@ -77,7 +70,6 @@ class UserSignupForm(UserCreationForm, BaseUserFormMixin):
77
70
  user.is_superuser = False
78
71
  user.is_staff = False
79
72
  # Explicitly save the extra fields if they aren't automatically handled by ModelForm save (they should be if in Meta.fields)
80
- user.language = self.cleaned_data["language"]
81
73
  user.avatar = self.cleaned_data["avatar"]
82
74
  user.bio = self.cleaned_data["bio"]
83
75
  if commit:
@@ -114,6 +106,16 @@ class UserProfileForm(forms.ModelForm):
114
106
  return user
115
107
 
116
108
 
109
+ class UserSettingsForm(forms.ModelForm):
110
+ class Meta:
111
+ model = User
112
+ fields = ("language", "theme")
113
+ labels = {
114
+ "language": _("Preferred Language"),
115
+ "theme": _("Preferred Theme"),
116
+ }
117
+
118
+
117
119
  class UserEditForm(forms.ModelForm):
118
120
  image_data = forms.CharField(widget=forms.HiddenInput(), required=False)
119
121
 
@@ -299,7 +301,10 @@ class SettingForm(forms.ModelForm):
299
301
  "ai_connection_point",
300
302
  "ai_model",
301
303
  "ai_api_key",
304
+ "gotify_url",
305
+ "gotify_token",
302
306
  ]
303
307
  widgets = {
304
308
  "ai_api_key": forms.PasswordInput(render_value=True),
309
+ "gotify_token": forms.PasswordInput(render_value=True),
305
310
  }
@@ -0,0 +1,21 @@
1
+ # Generated by Django 6.0.1 on 2026-01-28 09:08
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("sandwitches", "0015_order_completed_alter_order_status_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="user",
14
+ name="theme",
15
+ field=models.CharField(
16
+ choices=[("light", "Light"), ("dark", "Dark")],
17
+ default="light",
18
+ max_length=10,
19
+ ),
20
+ ),
21
+ ]
@@ -0,0 +1,31 @@
1
+ # Generated by Django 6.0.1 on 2026-01-28 12:45
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("sandwitches", "0016_user_theme"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="setting",
14
+ name="gotify_token",
15
+ field=models.CharField(
16
+ blank=True,
17
+ help_text="The application token for Gotify",
18
+ max_length=255,
19
+ null=True,
20
+ ),
21
+ ),
22
+ migrations.AddField(
23
+ model_name="setting",
24
+ name="gotify_url",
25
+ field=models.URLField(
26
+ blank=True,
27
+ help_text="The URL of your Gotify server (e.g., https://gotify.example.com)",
28
+ null=True,
29
+ ),
30
+ ),
31
+ ]
sandwitches/models.py CHANGED
@@ -4,7 +4,7 @@ from .storage import HashedFilenameStorage
4
4
  from simple_history.models import HistoricalRecords
5
5
  from django.contrib.auth.models import AbstractUser
6
6
  from django.db.models import Avg
7
- from .tasks import email_users, notify_order_submitted
7
+ from .tasks import email_users, notify_order_submitted, send_gotify_notification
8
8
  from django.conf import settings
9
9
  from django.core.validators import MinValueValidator, MaxValueValidator
10
10
  import logging
@@ -27,6 +27,18 @@ class Setting(SingletonModel):
27
27
  ai_model = models.CharField(max_length=255, blank=True, null=True)
28
28
  ai_api_key = models.CharField(max_length=255, blank=True, null=True)
29
29
 
30
+ gotify_url = models.URLField(
31
+ blank=True,
32
+ null=True,
33
+ help_text="The URL of your Gotify server (e.g., https://gotify.example.com)",
34
+ )
35
+ gotify_token = models.CharField(
36
+ max_length=255,
37
+ blank=True,
38
+ null=True,
39
+ help_text="The application token for Gotify",
40
+ )
41
+
30
42
  def __str__(self):
31
43
  return "Site Settings"
32
44
 
@@ -50,6 +62,11 @@ class User(AbstractUser):
50
62
  choices=settings.LANGUAGES,
51
63
  default=settings.LANGUAGE_CODE,
52
64
  )
65
+ theme = models.CharField(
66
+ max_length=10,
67
+ choices=[("light", "Light"), ("dark", "Dark")],
68
+ default="light",
69
+ )
53
70
  favorites = models.ManyToManyField(
54
71
  "Recipe", related_name="favorited_by", blank=True
55
72
  )
@@ -61,6 +78,16 @@ class User(AbstractUser):
61
78
  def __str__(self):
62
79
  return self.username
63
80
 
81
+ def save(self, *args, **kwargs):
82
+ is_new = self.pk is None
83
+ super().save(*args, **kwargs)
84
+ if is_new:
85
+ send_gotify_notification.enqueue(
86
+ title="New User Created",
87
+ message=f"User {self.username} has joined Sandwitches!",
88
+ priority=4,
89
+ )
90
+
64
91
 
65
92
  class Tag(models.Model):
66
93
  name = models.CharField(max_length=50, unique=True)
@@ -173,6 +200,12 @@ class Recipe(models.Model):
173
200
  logging.warning(
174
201
  "Email sending is disabled; not sending email notification, make sure SEND_EMAIL is set to True in settings."
175
202
  )
203
+
204
+ send_gotify_notification.enqueue(
205
+ title="New Recipe Uploaded",
206
+ message=f"A new recipe '{self.title}' has been uploaded by {self.uploaded_by or 'Unknown'}.",
207
+ priority=5,
208
+ )
176
209
  else:
177
210
  logging.debug(
178
211
  "Existing recipe saved (update); skipping email notification."
@@ -282,6 +315,11 @@ class Order(models.Model):
282
315
 
283
316
  if is_new:
284
317
  notify_order_submitted.enqueue(order_id=self.pk)
318
+ send_gotify_notification.enqueue(
319
+ title="New Order Received",
320
+ message=f"Order #{self.pk} for '{self.recipe.title}' by {self.user.username}. Total: {self.total_price}€",
321
+ priority=6,
322
+ )
285
323
 
286
324
  def __str__(self):
287
325
  return f"Order #{self.pk} - {self.user} - {self.recipe}"
sandwitches/tasks.py CHANGED
@@ -1,5 +1,5 @@
1
- # from gunicorn.http.wsgi import log
2
1
  import logging
2
+ import requests
3
3
 
4
4
  # from django.core.mail import send_mail
5
5
  from django_tasks import task
@@ -109,6 +109,36 @@ def notify_order_submitted(order_id):
109
109
  logging.info(f"Order confirmation email sent to {user.email} for order {order.id}")
110
110
 
111
111
 
112
+ @task(priority=1, queue_name="emails")
113
+ def send_gotify_notification(title, message, priority=5):
114
+ from .models import Setting
115
+
116
+ config = Setting.get_solo()
117
+ url = config.gotify_url
118
+ token = config.gotify_token
119
+
120
+ if not url or not token:
121
+ logging.debug("Gotify URL or Token not configured. Skipping notification.")
122
+ return False
123
+
124
+ try:
125
+ response = requests.post(
126
+ f"{url.rstrip('/')}/message?token={token}",
127
+ json={
128
+ "title": title,
129
+ "message": message,
130
+ "priority": priority,
131
+ },
132
+ timeout=10,
133
+ )
134
+ response.raise_for_status()
135
+ logging.info(f"Gotify notification sent: {title}")
136
+ return True
137
+ except Exception as e:
138
+ logging.error(f"Failed to send Gotify notification: {e}")
139
+ return False
140
+
141
+
112
142
  def send_emails(recipe_id, emails):
113
143
  from .models import Recipe
114
144
 
@@ -30,9 +30,6 @@
30
30
  <h6 class="max">{% block admin_title %}{% trans "Sandwitches Admin" %}{% endblock %}</h6>
31
31
  </a>
32
32
  <div class="max"></div>
33
- <button class="circle transparent" onclick="toggleMode()">
34
- <i>dark_mode</i>
35
- </button>
36
33
 
37
34
  {% if user.avatar %}
38
35
  <img src="{{ user.avatar.url }}" class="circle" data-ui="#user-menu">
@@ -47,7 +47,7 @@
47
47
  </style>
48
48
  {% block extra_head %}{% endblock %}
49
49
  </head>
50
- <body class="{% block body_class %}{% endblock %}">
50
+ <body class="{% block body_class %}{% endblock %} {% if user.is_authenticated %}{{ user.theme }}{% endif %}">
51
51
  <div id="loading-sandwich" class="loading-sandwich-container">
52
52
  <svg class="loading-sandwich-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
53
53
  <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
@@ -12,7 +12,6 @@
12
12
 
13
13
  {% block navbar %}
14
14
  {% include "components/navbar.html" %}
15
- {% include "components/language_dialog.html" %}
16
15
  {% include "components/user_menu.html" %}
17
16
  {% include "components/side_menu.html" %}
18
17
  {% endblock %}
@@ -7,12 +7,6 @@
7
7
  <img src="{% static 'icons/icon.svg' %}" class="circle small">
8
8
  </a>
9
9
  <div class="max"></div>
10
- <button class="circle transparent" onclick="ui('mode', ui('mode') == 'dark' ? 'light' : 'dark')">
11
- <i>dark_mode</i>
12
- </button>
13
- <button class="circle transparent" data-ui="#language-menu">
14
- <i>language</i>
15
- </button>
16
10
 
17
11
  {% if user.is_authenticated %}
18
12
  <a href="{% url 'view_cart' %}" class="button circle transparent">
@@ -19,6 +19,10 @@
19
19
  <i class="extra padding">group</i>
20
20
  <span class="large-text">{% trans "Community" %}</span>
21
21
  </a>
22
+ <a href="{% url 'user_settings' %}" class="padding {% if request.resolver_match.url_name == 'user_settings' %}active{% endif %}">
23
+ <i class="extra padding">settings</i>
24
+ <span class="large-text">{% trans "Settings" %}</span>
25
+ </a>
22
26
  {% endif %}
23
27
  <a href="/api/docs" class="padding">
24
28
  <i class="extra padding">api</i>
@@ -1,6 +1,7 @@
1
1
  {% load i18n %}
2
2
  {% if user.is_authenticated %}
3
3
  <menu id="user-menu" class="no-wrap left">
4
+ <a href="{% url 'user_settings' %}" class="row"><i>settings</i>{% trans "Settings" %}</a>
4
5
  {% if user.is_staff %}
5
6
  <a href="{% url 'admin_dashboard' %}" class="row"><i>admin_panel_settings</i>{% trans "Admin" %}</a>
6
7
  <div class="divider"></div>
@@ -84,6 +84,7 @@
84
84
  <div class="large-space"></div>
85
85
 
86
86
  <nav class="right-align">
87
+ <a class="button transparent border round" href="{% url 'user_settings' %}"><i>settings</i> {% trans "Settings" %}</a>
87
88
  <a class="button transparent border round" href="{% url 'index' %}">{% trans "Cancel" %}</a>
88
89
  <button type="submit" class="button primary round">{% trans "Save changes" %}</button>
89
90
  </nav>
@@ -0,0 +1,53 @@
1
+ {% extends "base_beer.html" %}
2
+ {% load static i18n %}
3
+ {% block title %}{% trans "Settings" %}{% endblock %}
4
+
5
+ {% block content %}
6
+ <div class="large-space"></div>
7
+
8
+ <div class="grid">
9
+ <div class="s12 m8 l6 xl4 middle-align center-align" style="margin: 0 auto;">
10
+ <article class="round elevate">
11
+ <div class="padding">
12
+ <h4 class="center-align primary-text">{% trans "User Settings" %}</h4>
13
+ </div>
14
+
15
+ <form method="post" novalidate>
16
+ {% csrf_token %}
17
+
18
+ <div class="field label border round {% if form.language.errors %}error{% endif %}">
19
+ <select name="{{ form.language.name }}" id="{{ form.language.id_for_label }}">
20
+ {% for value, label in form.language.field.choices %}
21
+ <option value="{{ value }}" {% if form.language.value == value %}selected{% endif %}>{{ label }}</option>
22
+ {% endfor %}
23
+ </select>
24
+ <label>{% trans "Preferred Language" %}</label>
25
+ {% if form.language.errors %}
26
+ <span class="helper error-text">{{ form.language.errors.0 }}</span>
27
+ {% endif %}
28
+ </div>
29
+
30
+ <div class="field label border round {% if form.theme.errors %}error{% endif %}">
31
+ <select name="{{ form.theme.name }}" id="{{ form.theme.id_for_label }}">
32
+ {% for value, label in form.theme.field.choices %}
33
+ <option value="{{ value }}" {% if form.theme.value == value %}selected{% endif %}>{{ label }}</option>
34
+ {% endfor %}
35
+ </select>
36
+ <label>{% trans "Preferred Theme" %}</label>
37
+ {% if form.theme.errors %}
38
+ <span class="helper error-text">{{ form.theme.errors.0 }}</span>
39
+ {% endif %}
40
+ </div>
41
+
42
+ <div class="large-space"></div>
43
+
44
+ <nav class="right-align">
45
+ <a class="button transparent border round" href="{% url 'index' %}">{% trans "Cancel" %}</a>
46
+ <button type="submit" class="button primary round">{% trans "Save changes" %}</button>
47
+ </nav>
48
+
49
+ </form>
50
+ </article>
51
+ </div>
52
+ </div>
53
+ {% endblock %}
@@ -64,18 +64,6 @@
64
64
  {% endif %}
65
65
  </div>
66
66
 
67
- <div class="field label border round {% if form.language.errors %}error{% endif %}">
68
- <select name="{{ form.language.name }}" id="{{ form.language.id_for_label }}">
69
- {% for value, label in form.language.field.choices %}
70
- <option value="{{ value }}" {% if form.language.value == value %}selected{% endif %}>{{ label }}</option>
71
- {% endfor %}
72
- </select>
73
- <label>{% trans "Preferred Language" %}</label>
74
- {% if form.language.errors %}
75
- <span class="helper error-text">{{ form.language.errors.0 }}</span>
76
- {% endif %}
77
- </div>
78
-
79
67
  <div class="field label border round textarea {% if form.bio.errors %}error{% endif %}">
80
68
  <textarea name="{{ form.bio.name }}" id="{{ form.bio.id_for_label }}" rows="3">{{ form.bio.value|default:'' }}</textarea>
81
69
  <label>{% trans "Bio" %}</label>
sandwitches/urls.py CHANGED
@@ -34,6 +34,7 @@ urlpatterns = [
34
34
  path("login/", views.CustomLoginView.as_view(), name="login"),
35
35
  path("logout/", LogoutView.as_view(next_page="index"), name="logout"),
36
36
  path("profile/", views.user_profile, name="user_profile"),
37
+ path("settings/", views.user_settings, name="user_settings"),
37
38
  path("orders/<int:pk>/", views.user_order_detail, name="user_order_detail"),
38
39
  path("community/", views.community, name="community"),
39
40
  path("admin/", admin.site.urls),
sandwitches/views.py CHANGED
@@ -8,6 +8,7 @@ from django.contrib.auth import get_user_model
8
8
  from django.contrib.auth.decorators import login_required
9
9
  from django.contrib.admin.views.decorators import staff_member_required
10
10
  from django.utils.translation import gettext as _
11
+ from django.utils import translation
11
12
  from .models import Recipe, Rating, Tag, Order, CartItem
12
13
  from .forms import (
13
14
  RecipeForm,
@@ -18,6 +19,7 @@ from .forms import (
18
19
  TagForm,
19
20
  UserProfileForm,
20
21
  UserRecipeSubmissionForm,
22
+ UserSettingsForm,
21
23
  )
22
24
  from django.http import HttpResponseBadRequest, Http404
23
25
  from django.conf import settings
@@ -898,6 +900,32 @@ def user_profile(request):
898
900
  )
899
901
 
900
902
 
903
+ @login_required
904
+ def user_settings(request):
905
+ if request.method == "POST":
906
+ form = UserSettingsForm(request.POST, instance=request.user)
907
+ if form.is_valid():
908
+ user = form.save()
909
+ # Update language in session and cookie
910
+ translation.activate(user.language)
911
+ request.session[translation.LANGUAGE_SESSION_KEY] = user.language # ty:ignore[unresolved-attribute]
912
+ messages.success(request, _("Settings updated successfully."))
913
+ response = redirect("user_settings")
914
+ response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user.language)
915
+ return response
916
+ else:
917
+ form = UserSettingsForm(instance=request.user)
918
+
919
+ return render(
920
+ request,
921
+ "settings.html",
922
+ {
923
+ "form": form,
924
+ "version": sandwitches_version,
925
+ },
926
+ )
927
+
928
+
901
929
  @login_required
902
930
  def user_order_detail(request, pk):
903
931
  order = get_object_or_404(Order, pk=pk, user=request.user)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sandwitches
3
- Version: 2.4.1
3
+ Version: 2.5.0
4
4
  Summary: Add your description here
5
5
  Author: Martyn van Dijke
6
6
  Author-email: Martyn van Dijke <martijnvdijke600@gmail.com>
@@ -3,7 +3,7 @@ sandwitches/admin.py,sha256=-4QA5InEvLHyb6VFAGKapWbJO9mXdiV4GeQcGsM4xlI,2510
3
3
  sandwitches/api.py,sha256=ruD5QeOPY-l9PvkJQiaOYoI0sRARDpqpFrFDgBxo9cQ,6389
4
4
  sandwitches/asgi.py,sha256=cygnXdXSSVspM7ZXuj47Ef6oz7HSTw4D7BPzgE2PU5w,399
5
5
  sandwitches/feeds.py,sha256=iz1d11dV0utA0ZNsB7VIAp0h8Zr5mFNSKJWHbw_j6YM,683
6
- sandwitches/forms.py,sha256=VoQ81COBCgwuS161dhF8IVeeAp8dLiQakzs56SV6-T8,9541
6
+ sandwitches/forms.py,sha256=yTiPRw5tknik8D5_8p5FM8cxuTtU5P18v3-tsgHi5kM,9637
7
7
  sandwitches/locale/nl/LC_MESSAGES/django.mo,sha256=EzQWzIhz_Na3w9AS7F-YjB-Xv63t4sMRSAkEQ1-g32M,5965
8
8
  sandwitches/locale/nl/LC_MESSAGES/django.po,sha256=znxspEoMwkmktusZtbVrt1KG1LDUwIEi4ZEIE3XGeoI,25904
9
9
  sandwitches/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -24,12 +24,14 @@ sandwitches/migrations/0012_rename_is_community_made_historicalrecipe_is_approve
24
24
  sandwitches/migrations/0013_cartitem.py,sha256=KYMinpnZiLHwjo7p7EdJHQExuEGC9jtpcZcbm1r7JFo,1787
25
25
  sandwitches/migrations/0014_ensure_groups_exist.py,sha256=5FSA742bEQtwHZl5CWZQYIdmS8FBxMgWS079dOaOltY,564
26
26
  sandwitches/migrations/0015_order_completed_alter_order_status_and_more.py,sha256=PTXQZUE8RqTAK8l0vkZhiGKv2T0PDiWEue7f6qz3AQ0,1670
27
+ sandwitches/migrations/0016_user_theme.py,sha256=2tJnT6Bjd6fuwLAr2J47IXTfmmde1BpPGM_1HB37sSg,537
28
+ sandwitches/migrations/0017_setting_gotify_token_setting_gotify_url.py,sha256=ABebUfj92uZcRg9XnAz-W_am74l9qjrg_vwDKaMjjBc,839
27
29
  sandwitches/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- sandwitches/models.py,sha256=kU71fC9Lf6Ij_8vpN0nB0OUKWpzWxi9WxqIYEzP4Ogg,11144
30
+ sandwitches/models.py,sha256=L8qMFoJ7WpIito2nTgsAB8s-UPUQMwDux63aKbP71aE,12468
29
31
  sandwitches/settings.py,sha256=5_eQAJCAV093hnhr3XOxHekT4IF-PEJcRiTecq71_SQ,5841
30
32
  sandwitches/storage.py,sha256=ibBG6tVtArqzgEKsRimZPwsqW7i9j4WiPLLHrOJchow,3578
31
- sandwitches/tasks.py,sha256=YiliAT2rj0fh7hrwKq5_qWtv9AGhd5iulj_iBwZBBKg,6024
32
- sandwitches/templates/admin/admin_base.html,sha256=aXba3MKFOKhaauFf0z0fFRjPpFHEbT_fREQx31TyxAM,4497
33
+ sandwitches/tasks.py,sha256=cGPgEqxGOCwliIq0oxNZBGjnCtvrTdJN-XyIp1ciJ3k,6865
34
+ sandwitches/templates/admin/admin_base.html,sha256=kpVZkoeDQMqhpxqdKbQ4-t0qqJ3cbFM9LojWY5s8qKk,4403
33
35
  sandwitches/templates/admin/confirm_delete.html,sha256=HfsZI_gV8JQTKz215TYgPWBrgrFhGv1UB3N-0Hln-14,804
34
36
  sandwitches/templates/admin/dashboard.html,sha256=Ial8zH2odIPpstSkQmzGrasl0QxvgGhFPAGy7V5xRzY,5916
35
37
  sandwitches/templates/admin/order_list.html,sha256=eHFUn2speXaaj5_SFUG0Z0HfWVUR9-VCDRBeb8ufFb0,819
@@ -45,8 +47,8 @@ sandwitches/templates/admin/task_detail.html,sha256=dO5zHOG-yTY1ly3VPA3o3jjie0wm
45
47
  sandwitches/templates/admin/task_list.html,sha256=3YF7YQ3nbXnWjApKeA07Z7HkhdMuH4s6sLoN7gwg0eE,1535
46
48
  sandwitches/templates/admin/user_form.html,sha256=7_6GShLROFeJJexL1XLFUXdW9_lYF87eT6cigB5bQo4,1314
47
49
  sandwitches/templates/admin/user_list.html,sha256=6O1YctULY-tqJnagybJof9ERA_NL1LX_a8cAu6_aWVQ,2193
48
- sandwitches/templates/base.html,sha256=mwCESNirfvvdyMg2e1Siy_LA8fLH29m0aS_Jv0Qom4U,3597
49
- sandwitches/templates/base_beer.html,sha256=4QgU4_gu_RRMtimmRAhATDJ3mj_WANxtilQJYNgAL60,2077
50
+ sandwitches/templates/base.html,sha256=4IkEdeEksQ9o4Ad72osMgMVnzz14aJa8WKg9HE3F0MU,3655
51
+ sandwitches/templates/base_beer.html,sha256=7dWwGOUEdBz19X3Rilbam1xSNkQqXqvC6cYrDdQvYIE,2025
50
52
  sandwitches/templates/cart.html,sha256=YqmrzOLLPAXSqeXeUTrt9AwTTWOitOLTaD_k3mYYVpM,4537
51
53
  sandwitches/templates/community.html,sha256=-YhpPtLbrVK9mc2Go1XBInLK-7OXrtb7kKukjl7rGbg,9607
52
54
  sandwitches/templates/components/carousel_scripts.html,sha256=9vEL5JJv8zUUjEtsnHW-BwwXUNWqQ6w_vf6UdxgEv_I,1934
@@ -55,30 +57,30 @@ sandwitches/templates/components/footer.html,sha256=Qk-myRtXS6-1b3fMowVGnSuFb_Uk
55
57
  sandwitches/templates/components/ingredients_scripts.html,sha256=2zKTC65GYF589uW1sCpDq0jOkS3BnsuOwUpJbbigrn4,1794
56
58
  sandwitches/templates/components/ingredients_section.html,sha256=XsaVXTs9MIwjfJeLjlzah3GWWj8oFU-_HJd9i9l1HAo,665
57
59
  sandwitches/templates/components/instructions_section.html,sha256=RFlA4uPiI6vf1e2QgiD5KzGoy7Vg7y7nFY7TFabCYLA,277
58
- sandwitches/templates/components/language_dialog.html,sha256=iz-6QhFe4f_dsVhGDhVx6KKKLgQz4grX8tbIqSQjDsg,1184
59
- sandwitches/templates/components/navbar.html,sha256=t-ZWvd9Z3UQRR2RswcsRXRNbygiesOD0Bh1jhmm2vEY,1396
60
+ sandwitches/templates/components/navbar.html,sha256=UO0F4J_yDTOGo-C7thNNZu_9IJ0t1pDyu5mwm9L-Ql8,1166
60
61
  sandwitches/templates/components/rating_section.html,sha256=8O5IsFfQwnElMQZLnDpJiuCvvQMLa3jCS67u_RhMi7o,2717
61
62
  sandwitches/templates/components/recipe_header.html,sha256=U6CxuR275QD9TIqo3VQftqvV6tqmH1rJdDcQotnXxYM,2001
62
63
  sandwitches/templates/components/search_form.html,sha256=B8579Jo44gLrlmvkkc2-Vuv_QD93Ljt6F2J1WgTDV60,6617
63
64
  sandwitches/templates/components/search_scripts.html,sha256=HvsO5e50DoTZeoFiYeNP5S8S5h7Zfr9VULOWKKR1i_M,3423
64
- sandwitches/templates/components/side_menu.html,sha256=qXYyk8W-GnG-u_mJ65ADa4HWfUa2ubxnQAKwxwacF9M,1787
65
- sandwitches/templates/components/user_menu.html,sha256=c20cBpyLheGvHdQ5nn-c4fjNlhfnAt3FAsw1V46rTwQ,369
65
+ sandwitches/templates/components/side_menu.html,sha256=FMy-gwjBh4JjMD8XcQ1nHBzf6_YoxY97flrafIN30RY,2055
66
+ sandwitches/templates/components/user_menu.html,sha256=KV_0gtvWbo3nvKZQ0peSZDtB3GgVuOyeBdar-wmwsDg,461
66
67
  sandwitches/templates/detail.html,sha256=g-O_RsW9Ix9ivWC0nZ4FwHY2NhgYZ3bEGLpqGY0JSxg,5642
67
68
  sandwitches/templates/favorites.html,sha256=0cPpW07N6Isrb8XpvA5Eh97L2-12QFZ43EzeJvbOlXo,917
68
69
  sandwitches/templates/index.html,sha256=7anU7k8s80JYk59Rwsm8EdlNYd7B5clCvV7pKq2IUy0,2518
69
70
  sandwitches/templates/login.html,sha256=LiQskhkOkfx0EE4ssA1ToqQ3oEll08OPYLDIkLjHfU8,2177
70
71
  sandwitches/templates/order_detail.html,sha256=D6MjUVibQuED2VRNHSjKVnLHcLgFtLvcVmuwlzfoJzo,2498
71
72
  sandwitches/templates/partials/recipe_list.html,sha256=LUHKFKG90D72K9X2X3d1osvj2jX1QU_MbPe0lNwRSII,4555
72
- sandwitches/templates/profile.html,sha256=m3-31b_z5QhHLgol-QwHrb3MM9B9kk5kybL3B1nWC5Y,8539
73
+ sandwitches/templates/profile.html,sha256=9Sj0UjbUNmWHEG9Nnc95LK5P3Gl86FqsnikDsubJERY,8670
74
+ sandwitches/templates/settings.html,sha256=Q3dwXdwiNgPxevfArjiHhIu-wCsQaii2Uymf_CqbWWg,2121
73
75
  sandwitches/templates/setup.html,sha256=iNveFgePATsCSO4XMbGPa8TnWHyvj8S_5WwcW6i7pbo,4661
74
- sandwitches/templates/signup.html,sha256=pNBSlRGZI_B5ccF3dWpUgWBcjODkdLlq7HhyJLYIHCI,6176
76
+ sandwitches/templates/signup.html,sha256=wVRyj6Sy1z5TRvJDT9ufEOp8-tKbW44Fzer4SYq9AGw,5518
75
77
  sandwitches/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
78
  sandwitches/templatetags/custom_filters.py,sha256=0KDFlFz4b5LwlcURBAmzyYWKKea-LwydZytJGVkkuKA,243
77
79
  sandwitches/templatetags/markdown_extras.py,sha256=0ibmRzxE3r85x4k7kK71R-9UT0CgeegYF7MHzj3juTI,344
78
- sandwitches/urls.py,sha256=TysY6JhOV2kGC-9KloZjLDfk4TUZS6xX95A_RfG971g,4940
80
+ sandwitches/urls.py,sha256=0p7MpYranWc4qNPyInxNzg8J3vNhap_gdt2n892exJM,5006
79
81
  sandwitches/utils.py,sha256=SJP-TkeRZ0OIfaMigYrOSbxRqYXswoqoWhwll3nFuAM,7245
80
- sandwitches/views.py,sha256=pDDDXaojPstj5E_k5gBQmW901Lol0R3gUl3qWGwUmI0,32145
82
+ sandwitches/views.py,sha256=Bv05_8qEbuD_f3EkiR-2PAIx0XbJCNvoR3ZeOz6Yfqg,33078
81
83
  sandwitches/wsgi.py,sha256=Eyncpnahq_4s3Lr9ruB-R3Lu9j9zBXqgPbUj7qhIbwU,399
82
- sandwitches-2.4.1.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
83
- sandwitches-2.4.1.dist-info/METADATA,sha256=97JvkhJ7rzJpQIfULxJ-0yz3rN1EfGZkhB-zpihx4wg,3111
84
- sandwitches-2.4.1.dist-info/RECORD,,
84
+ sandwitches-2.5.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
85
+ sandwitches-2.5.0.dist-info/METADATA,sha256=WfoggpXEkhWfIgBchLTnE1Rrj6Tlw7jOkTjus4wRzU4,3111
86
+ sandwitches-2.5.0.dist-info/RECORD,,
@@ -1,26 +0,0 @@
1
- {% load i18n %}
2
- <dialog id="language-menu">
3
- <form method="post" action="{% url 'set_language' %}">
4
- {% csrf_token %}
5
- <h5 class="center-align">{% trans "Select Language" %}</h5>
6
- <div class="grid center-align">
7
- {% get_current_language as LANGUAGE_CODE %}
8
- {% get_available_languages as LANGUAGES %}
9
- {% for code, name in LANGUAGES %}
10
- <div class="s6">
11
- <button type="submit" name="language" value="{{ code }}" class="circle large {% if code == LANGUAGE_CODE %}primary{% else %}surface{% endif %}">
12
- <span style="font-size: 2rem;">
13
- {% if code == 'en' %}🇬🇧{% elif code == 'nl' %}🇳🇱{% else %}🌐{% endif %}
14
- </span>
15
- </button>
16
- <div class="small-text">{{ name }}</div>
17
- </div>
18
- {% endfor %}
19
- </div>
20
- <input type="hidden" name="next" value="{{ request.get_full_path }}" />
21
- </form>
22
- <div class="space"></div>
23
- <nav class="center-align">
24
- <button class="transparent link" data-ui="#language-menu">{% trans "Close" %}</button>
25
- </nav>
26
- </dialog>