39728-vm/assets/js/main.js
2026-04-19 02:30:10 +00:00

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();
});