125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
// Basic logic for cart interactions
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const saleForm = document.querySelector('[data-sale-form]');
|
|
if (!saleForm) return;
|
|
|
|
let cart = [];
|
|
const cartJsonInput = document.getElementById('cart_json');
|
|
const cartLinesContainer = document.getElementById('cart-lines');
|
|
const cartEmptyState = document.getElementById('cart-empty-state');
|
|
const cartCountLabel = document.getElementById('cart-count-label');
|
|
const cartSubtotalLabel = document.getElementById('cart-subtotal');
|
|
const cartTotalLabel = document.getElementById('cart-total');
|
|
|
|
function renderCart() {
|
|
if (cart.length === 0) {
|
|
cartEmptyState.style.display = 'block';
|
|
cartLinesContainer.innerHTML = '';
|
|
cartCountLabel.textContent = '0 ' + (window.saleLabels ? window.saleLabels.empty : 'items');
|
|
cartSubtotalLabel.textContent = '0.00';
|
|
cartTotalLabel.textContent = '0.00';
|
|
cartJsonInput.value = '[]';
|
|
return;
|
|
}
|
|
|
|
cartEmptyState.style.display = 'none';
|
|
let html = '';
|
|
let totalItems = 0;
|
|
let subtotal = 0;
|
|
|
|
cart.forEach((item, index) => {
|
|
const lineTotal = item.qty * item.price;
|
|
totalItems += item.qty;
|
|
subtotal += lineTotal;
|
|
|
|
html += `
|
|
<div class="cart-line mb-2 p-2 border rounded bg-white shadow-sm d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<div class="fw-semibold small">${item.name}</div>
|
|
<div class="text-muted" style="font-size: 0.75rem;">${item.qty} x ${item.price.toFixed(3)}</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="fw-bold text-primary">${lineTotal.toFixed(3)}</span>
|
|
<div class="btn-group btn-group-sm">
|
|
<button type="button" class="btn btn-outline-secondary" onclick="updateCartQty(${index}, -1)">-</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="updateCartQty(${index}, 1)">+</button>
|
|
<button type="button" class="btn btn-outline-danger" onclick="removeCartItem(${index})"><i class="bi bi-trash"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
});
|
|
|
|
cartLinesContainer.innerHTML = html;
|
|
cartCountLabel.textContent = totalItems + ' items';
|
|
cartSubtotalLabel.textContent = subtotal.toFixed(3);
|
|
cartTotalLabel.textContent = subtotal.toFixed(3);
|
|
cartJsonInput.value = JSON.stringify(cart);
|
|
}
|
|
|
|
window.updateCartQty = function(index, delta) {
|
|
if (cart[index]) {
|
|
cart[index].qty += delta;
|
|
if (cart[index].qty <= 0) {
|
|
cart.splice(index, 1);
|
|
}
|
|
renderCart();
|
|
}
|
|
};
|
|
|
|
window.removeCartItem = function(index) {
|
|
cart.splice(index, 1);
|
|
renderCart();
|
|
};
|
|
|
|
document.querySelectorAll('[data-add-product]').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
const sku = btn.dataset.sku;
|
|
const name = btn.dataset.name;
|
|
const price = parseFloat(btn.dataset.price);
|
|
|
|
const existing = cart.find(i => i.sku === sku);
|
|
if (existing) {
|
|
existing.qty++;
|
|
} else {
|
|
cart.push({ sku, name, price, qty: 1 });
|
|
}
|
|
|
|
// SweetAlert2 Toast for adding product
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire({
|
|
toast: true,
|
|
position: 'top-end',
|
|
icon: 'success',
|
|
title: name + ' added',
|
|
showConfirmButton: false,
|
|
timer: 1500
|
|
});
|
|
}
|
|
|
|
renderCart();
|
|
});
|
|
});
|
|
|
|
const clearBtn = document.querySelector('[data-clear-cart]');
|
|
if (clearBtn) {
|
|
clearBtn.addEventListener('click', () => {
|
|
cart = [];
|
|
renderCart();
|
|
});
|
|
}
|
|
|
|
// Handle form submission warning if empty
|
|
saleForm.addEventListener('submit', (e) => {
|
|
if (cart.length === 0) {
|
|
e.preventDefault();
|
|
if (typeof Swal !== 'undefined') {
|
|
Swal.fire('Empty Cart', 'Please add items before saving.', 'warning');
|
|
} else {
|
|
alert('Cart is empty');
|
|
}
|
|
}
|
|
});
|
|
|
|
renderCart();
|
|
}); |