From 3abad9e151029dcfb3b3b4cdaba30ceba041d6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Wed, 6 Aug 2025 13:42:20 +0200 Subject: [PATCH] poprawki w jogice js, progressbar warstwowy i fix w notatkach --- app.py | 18 +++++++++---- static/js/functions.js | 61 +++++++++++++++++------------------------- static/js/live.js | 13 +-------- templates/list.html | 12 ++++----- templates/main.html | 48 ++++++++++++++++++++++++++------- 5 files changed, 82 insertions(+), 70 deletions(-) diff --git a/app.py b/app.py index 137e253..53efe8b 100644 --- a/app.py +++ b/app.py @@ -1308,16 +1308,21 @@ def main_page(): db.session.query( Item.list_id, func.count(Item.id).label("total_count"), - func.sum(case((Item.purchased == True, 1), else_=0)).label( - "purchased_count" - ), + func.sum(case((Item.purchased == True, 1), else_=0)).label("purchased_count"), + func.sum(case((Item.not_purchased == True, 1), else_=0)).label("not_purchased_count"), ) .filter(Item.list_id.in_(all_ids)) .group_by(Item.list_id) .all() ) + stats_map = { - s.list_id: (s.total_count or 0, s.purchased_count or 0) for s in stats + s.list_id: ( + s.total_count or 0, + s.purchased_count or 0, + s.not_purchased_count or 0 + ) + for s in stats } latest_expenses_map = dict( @@ -1330,9 +1335,10 @@ def main_page(): ) for l in all_lists: - total_count, purchased_count = stats_map.get(l.id, (0, 0)) + total_count, purchased_count, not_purchased_count = stats_map.get(l.id, (0, 0, 0)) l.total_count = total_count l.purchased_count = purchased_count + l.not_purchased_count = not_purchased_count l.total_expense = latest_expenses_map.get(l.id, 0) l.category_badges = [ @@ -1343,6 +1349,7 @@ def main_page(): for l in all_lists: l.total_count = 0 l.purchased_count = 0 + l.not_purchased_count = 0 l.total_expense = 0 l.category_badges = [] @@ -1356,6 +1363,7 @@ def main_page(): ) + @app.route("/system-auth", methods=["GET", "POST"]) def system_auth(): if ( diff --git a/static/js/functions.js b/static/js/functions.js index e344aaf..51ba022 100644 --- a/static/js/functions.js +++ b/static/js/functions.js @@ -22,45 +22,33 @@ function updateItemState(itemId, isChecked) { function updateProgressBar() { const items = document.querySelectorAll('#items li'); const total = items.length; + const purchased = Array.from(items).filter(li => li.classList.contains('bg-success')).length; - const percent = total > 0 ? Math.round((purchased / total) * 100) : 0; + const notPurchased = Array.from(items).filter(li => li.classList.contains('bg-warning')).length; + const remaining = total - purchased - notPurchased; - // Pasek postępu - const progressBar = document.getElementById('progress-bar'); - if (progressBar) { - progressBar.style.width = `${percent}%`; - progressBar.setAttribute('aria-valuenow', percent); - progressBar.textContent = percent > 0 ? `${percent}%` : ''; // opcjonalnie - } + const percentPurchased = total > 0 ? (purchased / total) * 100 : 0; + const percentNotPurchased = total > 0 ? (notPurchased / total) * 100 : 0; + const percentRemaining = total > 0 ? (remaining / total) * 100 : 0; - // Label na pasku postępu + document.getElementById('progress-bar-purchased').style.width = `${percentPurchased}%`; + document.getElementById('progress-bar-not-purchased').style.width = `${percentNotPurchased}%`; + document.getElementById('progress-bar-remaining').style.width = `${percentRemaining}%`; + + // etykieta const progressLabel = document.getElementById('progress-label'); - if (progressLabel) { - progressLabel.textContent = `${percent}%`; - if (percent === 0) { - progressLabel.style.display = 'inline'; - } else { - progressLabel.style.display = 'none'; - } - // Kolor tekstu labela - if (percent < 50) { - progressLabel.classList.remove('text-dark'); - progressLabel.classList.add('text-white'); - } else { - progressLabel.classList.remove('text-white'); - progressLabel.classList.add('text-dark'); - } - } + const percent = total > 0 ? Math.round((purchased / total) * 100) : 0; + progressLabel.textContent = `${percent}%`; + progressLabel.classList.toggle('text-white', percent < 50); + progressLabel.classList.toggle('text-dark', percent >= 50); - // Nagłówek - const purchasedCount = document.getElementById('purchased-count'); - if (purchasedCount) purchasedCount.textContent = purchased; - const totalCount = document.getElementById('total-count'); - if (totalCount) totalCount.textContent = total; - const percentValue = document.getElementById('percent-value'); - if (percentValue) percentValue.textContent = percent; + // liczniki + document.getElementById('purchased-count').textContent = purchased; + document.getElementById('total-count').textContent = total; + document.getElementById('percent-value').textContent = percent; } + function addItem(listId) { const name = document.getElementById('newItem').value; const quantityInput = document.getElementById('newQuantity'); @@ -179,7 +167,6 @@ function openList(link) { } function applyHidePurchased(isInit = false) { - //console.log("applyHidePurchased: wywołana, isInit =", isInit); const toggle = document.getElementById('hidePurchasedToggle'); if (!toggle) return; const hide = toggle.checked; @@ -187,9 +174,11 @@ function applyHidePurchased(isInit = false) { const items = document.querySelectorAll('#items li'); items.forEach(li => { - const isPurchased = li.classList.contains('bg-success'); + const isCheckedItem = + li.classList.contains('bg-success') || // kupione + li.classList.contains('bg-warning'); // niekupione - if (isPurchased) { + if (isCheckedItem) { if (hide) { if (isInit) { // Jeśli inicjalizacja: od razu ukryj @@ -210,7 +199,7 @@ function applyHidePurchased(isInit = false) { }, 10); } } else { - // Element niekupiony — zawsze pokazany + // Element nieoznaczony — zawsze pokazany li.classList.remove('hide-purchased', 'fade-out'); } }); diff --git a/static/js/live.js b/static/js/live.js index ee4654b..dfbaf7c 100644 --- a/static/js/live.js +++ b/static/js/live.js @@ -205,21 +205,10 @@ function setupList(listId, username) { }); socket.on('note_updated', data => { - const idx = window.currentItems.findIndex(i => i.id === data.item_id); - if (idx !== -1) { - window.currentItems[idx].note = data.note; - - const newItem = renderItem(window.currentItems[idx], true); - const oldItem = document.getElementById(`item-${data.item_id}`); - if (oldItem && newItem) { - oldItem.replaceWith(newItem); - } - } - + socket.emit('request_full_list', { list_id: window.LIST_ID }); showToast('Notatka dodana/zaktualizowana', 'success'); }); - socket.on('item_edited', data => { const idx = window.currentItems.findIndex(i => i.id === data.item_id); if (idx !== -1) { diff --git a/templates/list.html b/templates/list.html index e07a344..63e3f72 100644 --- a/templates/list.html +++ b/templates/list.html @@ -73,16 +73,14 @@
-
-
+
+
+
- - {{ percent|round(0) }}% - +
+ {% if total_expense > 0 %}
💸 Łącznie wydano: {{ '%.2f'|format(total_expense) }} PLN diff --git a/templates/main.html b/templates/main.html index 512136a..9fa1b35 100644 --- a/templates/main.html +++ b/templates/main.html @@ -99,17 +99,31 @@
-
-
+ {# Kupione #} +
+ + {# Niekupione #} + {% set not_purchased_count = l.not_purchased_count if l.total_count else 0 %} +
+ + {# Pozostałe #} +
+ + {% if percent < 50 %}text-white{% else %}text-dark{% endif %}"> Produkty: {{ purchased_count }}/{{ total_count }} ({{ percent|round(0) }}%) {% if l.total_expense > 0 %} - — 💸 {{ '%.2f'|format(l.total_expense) }} PLN + — 💸 {{ '%.2f'|format(l.total_expense) }} PLN {% endif %}
+ {% endfor %} @@ -141,17 +155,31 @@ 📄 Otwórz
-
-
+ {# Kupione #} +
+ + {# Niekupione #} + {% set not_purchased_count = l.not_purchased_count if l.total_count else 0 %} +
+ + {# Pozostałe #} +
+ + {% if percent < 50 %}text-white{% else %}text-dark{% endif %}"> Produkty: {{ purchased_count }}/{{ total_count }} ({{ percent|round(0) }}%) {% if l.total_expense > 0 %} - — 💸 {{ '%.2f'|format(l.total_expense) }} PLN + — 💸 {{ '%.2f'|format(l.total_expense) }} PLN {% endif %}
+ {% endfor %}