From 29b7ccf02fbb65ff70816caceb5b5044d1a0c399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Wed, 13 Aug 2025 13:43:54 +0200 Subject: [PATCH] fix mass add --- static/js/functions.js | 13 +++-- static/js/mass_add.js | 118 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 115 insertions(+), 16 deletions(-) diff --git a/static/js/functions.js b/static/js/functions.js index ee88791..43ab3c0 100644 --- a/static/js/functions.js +++ b/static/js/functions.js @@ -24,6 +24,7 @@ function updateProgressBar() { const barNotPurchased = document.getElementById('progress-bar-not-purchased'); const barRemaining = document.getElementById('progress-bar-remaining'); const progressLabel = document.getElementById('progress-label'); + const percentValueEl = document.getElementById('percent-value'); if (!barPurchased || !barNotPurchased || !barRemaining || !progressLabel) { return; @@ -40,18 +41,22 @@ function updateProgressBar() { const percentNotPurchased = total > 0 ? (notPurchased / total) * 100 : 0; const percentRemaining = total > 0 ? (remaining / total) * 100 : 0; + const percent = total > 0 ? Math.round((purchased / total) * 100) : 0; + barPurchased.style.width = `${percentPurchased}%`; barNotPurchased.style.width = `${percentNotPurchased}%`; barRemaining.style.width = `${percentRemaining}%`; - const percent = total > 0 ? Math.round((purchased / total) * 100) : 0; progressLabel.textContent = `${percent}%`; progressLabel.classList.toggle('text-white', percent < 51); progressLabel.classList.toggle('text-dark', percent >= 51); - document.getElementById('purchased-count').textContent = purchased; - document.getElementById('total-count').textContent = total; - document.getElementById('percent-value').textContent = percent; + const purchasedCountEl = document.getElementById('purchased-count'); + const totalCountEl = document.getElementById('total-count'); + + if (purchasedCountEl) purchasedCountEl.textContent = purchased; + if (totalCountEl) totalCountEl.textContent = total; + if (percentValueEl) percentValueEl.textContent = percent; } function addItem(listId) { diff --git a/static/js/mass_add.js b/static/js/mass_add.js index 8b925ee..b573fb1 100644 --- a/static/js/mass_add.js +++ b/static/js/mass_add.js @@ -76,10 +76,10 @@ document.addEventListener('DOMContentLoaded', function () { const btn = document.createElement('button'); btn.className = 'btn btn-sm btn-primary ms-4'; btn.textContent = '+'; + btn.onclick = () => { const quantity = parseInt(qty.value) || 1; socket.emit('add_item', { list_id: LIST_ID, name: name, quantity: quantity }); - socket.emit('request_full_list', { list_id: LIST_ID }); }; li.appendChild(qtyWrapper); @@ -95,23 +95,117 @@ document.addEventListener('DOMContentLoaded', function () { socket.on('item_added', data => { document.querySelectorAll('#mass-add-list li').forEach(li => { - const itemName = li.firstChild.textContent.trim(); + const itemName = li.firstChild?.textContent.trim(); if (normalize(itemName) === normalize(data.name) && !li.classList.contains('opacity-50')) { - while (li.firstChild) { - li.removeChild(li.firstChild); - } - - li.textContent = data.name; li.classList.add('opacity-50'); - const badge = document.createElement('span'); - badge.className = 'badge bg-success ms-auto'; - badge.textContent = 'Dodano'; - li.appendChild(badge); + // Usuń poprzednie przyciski + li.querySelectorAll('button').forEach(btn => btn.remove()); + const quantityControls = li.querySelector('.quantity-controls'); + if (quantityControls) quantityControls.remove(); - li.onclick = null; + // Badge "Dodano" + const badge = document.createElement('span'); + badge.className = 'badge bg-success'; + badge.textContent = 'Dodano'; + + // Grupowanie przycisku + licznika + const btnGroup = document.createElement('div'); + btnGroup.className = 'btn-group btn-group-sm me-2'; + btnGroup.role = 'group'; + + const undoBtn = document.createElement('button'); + undoBtn.className = 'btn btn-outline-warning'; + undoBtn.innerHTML = '⟳ Cofnij'; + + const timerBtn = document.createElement('button'); + timerBtn.className = 'btn btn-outline-secondary disabled'; + let secondsLeft = 15; + timerBtn.textContent = `${secondsLeft}s`; + + btnGroup.appendChild(undoBtn); + btnGroup.appendChild(timerBtn); + + // Kontener na prawą stronę + const rightWrapper = document.createElement('div'); + rightWrapper.className = 'd-flex align-items-center gap-2 ms-auto'; + rightWrapper.appendChild(btnGroup); + rightWrapper.appendChild(badge); + li.appendChild(rightWrapper); + + // Odliczanie + const intervalId = setInterval(() => { + secondsLeft--; + if (secondsLeft > 0) { + timerBtn.textContent = `${secondsLeft}s`; + } else { + clearInterval(intervalId); + btnGroup.remove(); + } + }, 1000); + + // Obsługa cofnięcia + undoBtn.onclick = () => { + clearInterval(intervalId); + btnGroup.remove(); + badge.remove(); + li.classList.remove('opacity-50'); + + // Przywróć kontrolki ilości + const qtyWrapper = document.createElement('div'); + qtyWrapper.className = 'd-flex align-items-center ms-2 quantity-controls'; + + const minusBtn = document.createElement('button'); + minusBtn.type = 'button'; + minusBtn.className = 'btn btn-outline-light btn-sm px-2'; + minusBtn.textContent = '−'; + + const qty = document.createElement('input'); + qty.type = 'number'; + qty.min = 1; + qty.value = 1; + qty.className = 'form-control text-center p-1 rounded'; + qty.style.width = '50px'; + qty.style.margin = '0 2px'; + qty.title = 'Ilość'; + + const plusBtn = document.createElement('button'); + plusBtn.type = 'button'; + plusBtn.className = 'btn btn-outline-light btn-sm px-2'; + plusBtn.textContent = '+'; + + minusBtn.onclick = () => { + qty.value = Math.max(1, parseInt(qty.value) - 1); + }; + plusBtn.onclick = () => { + qty.value = parseInt(qty.value) + 1; + }; + + qtyWrapper.append(minusBtn, qty, plusBtn); + li.appendChild(qtyWrapper); + + // Dodaj przycisk dodawania + const addBtn = document.createElement('button'); + addBtn.className = 'btn btn-sm btn-primary ms-4'; + addBtn.textContent = '+'; + addBtn.onclick = () => { + const quantity = parseInt(qty.value) || 1; + socket.emit('add_item', { + list_id: LIST_ID, + name: data.name, + quantity: quantity + }); + }; + li.appendChild(addBtn); + + // Usuń z listy + socket.emit('delete_item', { item_id: data.id }); + }; } }); }); + + }); +