ux i funkcja masowego dodwania produktu

This commit is contained in:
Mateusz Gruszczyński
2025-07-09 10:22:35 +02:00
parent 1dfbdb1eea
commit 1561ea1ab6
4 changed files with 113 additions and 50 deletions

View File

@@ -1,38 +1,77 @@
document.addEventListener('DOMContentLoaded', function () {
const modal = document.getElementById('massAddModal');
const productList = document.getElementById('mass-add-list');
let addedProducts = new Set();
document.querySelectorAll('#items li').forEach(li => {
if (li.dataset.name) addedProducts.add(li.dataset.name.toLowerCase());
});
modal.addEventListener('show.bs.modal', async function () {
// 🔥 Za każdym razem od nowa budujemy zbiór produktów już na liście
let addedProducts = new Set();
document.querySelectorAll('#items li').forEach(li => {
if (li.dataset.name) {
addedProducts.add(li.dataset.name.toLowerCase());
}
});
productList.innerHTML = '<li class="list-group-item bg-dark text-light">Ładowanie...</li>';
try {
const res = await fetch('/all_products');
const suggestions = await res.json();
const data = await res.json();
const allproducts = data.allproducts;
productList.innerHTML = '';
suggestions.forEach(name => {
allproducts.forEach(name => {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center bg-dark text-light';
li.textContent = name;
if (addedProducts.has(name.toLowerCase())) {
li.classList.add('active');
li.innerHTML += '<span class="ms-2 text-success">&#10003;</span>';
// Produkt już dodany — oznacz jako nieaktywny
li.classList.add('opacity-50');
const badge = document.createElement('span');
badge.className = 'badge bg-success ms-auto';
badge.textContent = 'Dodano';
li.appendChild(badge);
} else {
// Pole do ilości
// Kontener na minus, pole i plus
const qtyWrapper = document.createElement('div');
qtyWrapper.className = 'd-flex align-items-center ms-2';
// Minus
const minusBtn = document.createElement('button');
minusBtn.type = 'button';
minusBtn.className = 'btn btn-outline-light btn-sm px-2';
minusBtn.textContent = '';
minusBtn.onclick = () => {
qty.value = Math.max(1, parseInt(qty.value) - 1);
};
// Pole ilości
const qty = document.createElement('input');
qty.type = 'number';
qty.min = 1;
qty.value = 1;
qty.className = 'quantity-input ms-2';
qty.className = 'form-control text-center p-1';
qty.classList.add('rounded');
qty.style.width = '50px';
qty.style.flex = '0 0 auto';
qty.style.margin = '0 2px';
qty.title = 'Ilość';
// Plus
const plusBtn = document.createElement('button');
plusBtn.type = 'button';
plusBtn.className = 'btn btn-outline-light btn-sm px-2';
plusBtn.textContent = '+';
plusBtn.onclick = () => {
qty.value = parseInt(qty.value) + 1;
};
// Dodajemy przyciski i input do wrappera
qtyWrapper.appendChild(minusBtn);
qtyWrapper.appendChild(qty);
qtyWrapper.appendChild(plusBtn);
// Przycisk dodania
const btn = document.createElement('button');
btn.className = 'btn btn-sm btn-primary add-btn';
btn.className = 'btn btn-sm btn-primary ms-2';
btn.textContent = '+';
btn.onclick = () => {
const quantity = parseInt(qty.value) || 1;
@@ -40,7 +79,7 @@ document.addEventListener('DOMContentLoaded', function () {
};
li.textContent = name;
li.appendChild(qty);
li.appendChild(qtyWrapper);
li.appendChild(btn);
}
productList.appendChild(li);
@@ -50,39 +89,32 @@ document.addEventListener('DOMContentLoaded', function () {
}
});
// 🔥 Aktualizacja na żywo po dodaniu
socket.on('item_added', data => {
document.querySelectorAll('#mass-add-list li').forEach(li => {
if (li.textContent.trim().startsWith(data.name) && !li.classList.contains('active')) {
li.classList.add('active');
li.innerHTML = `${data.name} <span class="ms-2 text-success">&#10003;</span>`;
const itemName = li.firstChild.textContent.trim();
if (itemName === data.name && !li.classList.contains('opacity-50')) {
// Usuń wszystkie dzieci
while (li.firstChild) {
li.removeChild(li.firstChild);
}
// Ustaw nazwę
li.textContent = data.name;
// Dodaj klasę wyszarzenia
li.classList.add('opacity-50');
// Dodaj badge
const badge = document.createElement('span');
badge.className = 'badge bg-success ms-auto';
badge.textContent = 'Dodano';
li.appendChild(badge);
// Zablokuj kliknięcia
li.onclick = null;
}
});
const itemsContainer = document.getElementById('items');
if (!itemsContainer) return;
if (document.getElementById(`item-${data.id}`)) return;
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center flex-wrap item-not-checked';
li.id = `item-${data.id}`;
li.dataset.name = data.name;
let quantityBadge = '';
if (data.quantity && data.quantity > 1) {
quantityBadge = `<span class="badge bg-secondary ms-2">${data.quantity}×</span>`;
}
li.innerHTML = `
<div class="form-check">
<input class="form-check-input" type="checkbox" id="check-${data.id}">
<label class="form-check-label" for="check-${data.id}">
${data.name}
</label>
${quantityBadge}
</div>
`;
itemsContainer.appendChild(li);
addedProducts.add(data.name.toLowerCase());
});
});