From 81744b5c5e173b6e525ac8777c8030f28da03776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 7 Oct 2025 09:10:29 +0200 Subject: [PATCH] kolory kategorii i jedniklikowy wybor kategorii w modalu --- app.py | 43 ++++++++++++++++++++++++------------- static/js/category_modal.js | 18 ++++++++++++++++ templates/list.html | 22 +++++++++++++++++-- 3 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 static/js/category_modal.js diff --git a/app.py b/app.py index 56d83fe..a48cf13 100644 --- a/app.py +++ b/app.py @@ -885,12 +885,13 @@ def get_admin_expense_summary(): } -def category_to_color(name): - hash_val = int(hashlib.md5(name.encode("utf-8")).hexdigest(), 16) - hue = (hash_val % 360) / 360.0 - saturation = 0.60 + ((hash_val >> 8) % 17) / 100.0 - lightness = 0.28 + ((hash_val >> 16) % 11) / 100.0 +import hashlib, colorsys +def category_to_color(name: str) -> str: + hash_val = int(hashlib.md5(name.encode("utf-8")).hexdigest(), 16) + hue = ((hash_val % 360) + ((hash_val >> 24) % 20)) % 360 / 360.0 + saturation = 0.55 + ((hash_val >> 8) % 40) / 100.0 + lightness = 0.35 + ((hash_val >> 16) % 30) / 100.0 r, g, b = colorsys.hls_to_rgb(hue, lightness, saturation) return f"#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}" @@ -2110,10 +2111,6 @@ def create_list(): @app.route("/list/") @login_required -# ───────────────────────────────────────────────────────────────────────────── -# Widok listy właściciela – dopięcie permitted_users do kontekstu -# ───────────────────────────────────────────────────────────────────────────── -@login_required def view_list(list_id): shopping_list = db.session.get(ShoppingList, list_id) if not shopping_list: @@ -2126,30 +2123,45 @@ def view_list(list_id): flash("W celu modyfikacji listy, przejdź do panelu administracyjnego.", "info") return redirect(url_for("shared_list", token=shopping_list.share_token)) - # Twoja obecna logika ładująca szczegóły listy: shopping_list, items, receipts, expenses, total_expense = get_list_details(list_id) total_count = len(items) purchased_count = len([i for i in items if i.purchased]) percent = (purchased_count / total_count * 100) if total_count > 0 else 0 - # Uzupełnienie "added_by_display" — jak u Ciebie: for item in items: if item.added_by != shopping_list.owner_id: item.added_by_display = (item.added_by_user.username if item.added_by_user else "?") else: item.added_by_display = None - # Badges kategorii (jak u Ciebie) shopping_list.category_badges = [ {"name": c.name, "color": category_to_color(c.name)} for c in shopping_list.categories ] - # Dane do modala kategorii + # Wszystkie kategorie (do selecta) categories = Category.query.order_by(Category.name.asc()).all() selected_categories_ids = {c.id for c in shopping_list.categories} - # ⬅️ NOWE: użytkownicy z uprawnieniami do tej listy (dla modala w list.html) + # Najczęściej używane kategorie właściciela (top N) + popular_categories = ( + db.session.query(Category) + .join( + shopping_list_category, + shopping_list_category.c.category_id == Category.id, + ) + .join( + ShoppingList, + ShoppingList.id == shopping_list_category.c.shopping_list_id, + ) + .filter(ShoppingList.owner_id == current_user.id) + .group_by(Category.id) + .order_by(func.count(ShoppingList.id).desc(), func.lower(Category.name).asc()) + .limit(6) + .all() + ) + + # Użytkownicy z uprawnieniami do listy permitted_users = ( db.session.query(User) .join(ListPermission, ListPermission.user_id == User.id) @@ -2172,7 +2184,8 @@ def view_list(list_id): is_owner=is_owner, categories=categories, selected_categories=selected_categories_ids, - permitted_users=permitted_users, # ⬅️ ważne dla tokenów w modalu + permitted_users=permitted_users, + popular_categories=popular_categories, ) diff --git a/static/js/category_modal.js b/static/js/category_modal.js new file mode 100644 index 0000000..423af70 --- /dev/null +++ b/static/js/category_modal.js @@ -0,0 +1,18 @@ +document.addEventListener('DOMContentLoaded', () => { + document.querySelectorAll('#categoriesModal .category-suggestion').forEach(btn => { + btn.addEventListener('click', () => { + const select = document.getElementById('category_id'); + if (!select) return; + + select.value = btn.dataset.catId || ''; + const form = btn.closest('form'); + if (form) { + if (typeof form.requestSubmit === 'function') { + form.requestSubmit(); + } else { + form.submit(); + } + } + }); + }); +}); diff --git a/templates/list.html b/templates/list.html index bbf74a4..f721867 100644 --- a/templates/list.html +++ b/templates/list.html @@ -204,12 +204,29 @@