38682-vm/assets/js/main.js
2026-02-22 10:13:38 +00:00

131 lines
5.0 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
let cart = [];
const cartItemsContainer = document.getElementById('cart-items');
const cartTotalPrice = document.getElementById('cart-total-price');
const checkoutBtn = document.getElementById('checkout-btn');
const mobileCartBtn = document.getElementById('mobile-cart-btn');
// Helper for currency formatting
function formatCurrency(amount) {
// Fallback if settings not defined
const settings = (typeof COMPANY_SETTINGS !== 'undefined') ? COMPANY_SETTINGS : { currency_symbol: '$', currency_decimals: 2 };
const symbol = settings.currency_symbol || '$';
const decimals = parseInt(settings.currency_decimals || 2);
return symbol + parseFloat(amount).toFixed(decimals);
}
// Add to cart
document.querySelectorAll('.add-to-cart').forEach(button => {
button.addEventListener('click', (e) => {
const product = {
id: e.target.dataset.id,
name: e.target.dataset.name,
price: parseFloat(e.target.dataset.price),
quantity: 1
};
const existing = cart.find(item => item.id === product.id);
if (existing) {
existing.quantity++;
} else {
cart.push(product);
}
updateCart();
showToast(`${product.name} added to cart!`);
});
});
function updateCart() {
if (cart.length === 0) {
cartItemsContainer.innerHTML = '<p class="text-center text-muted mt-5">Your cart is empty.</p>';
cartTotalPrice.innerText = formatCurrency(0);
checkoutBtn.disabled = true;
if (mobileCartBtn) mobileCartBtn.innerText = `View Cart (${formatCurrency(0)})`;
return;
}
cartItemsContainer.innerHTML = '';
let total = 0;
cart.forEach(item => {
const itemTotal = item.price * item.quantity;
total += itemTotal;
const div = document.createElement('div');
div.className = 'cart-item';
div.innerHTML = `
<div>
<div class="cart-item-name">${item.name} x${item.quantity}</div>
<div class="text-muted small">${formatCurrency(item.price)} ea</div>
</div>
<div class="cart-item-price">${formatCurrency(itemTotal)}</div>
`;
cartItemsContainer.appendChild(div);
});
cartTotalPrice.innerText = formatCurrency(total);
checkoutBtn.disabled = false;
if (mobileCartBtn) mobileCartBtn.innerText = `View Cart (${formatCurrency(total)})`;
}
// Checkout
checkoutBtn.addEventListener('click', () => {
if (cart.length === 0) return;
const table_id = new URLSearchParams(window.location.search).get('table') || '1';
// Calculate total
const totalAmount = cart.reduce((acc, item) => acc + (item.price * item.quantity), 0);
const orderData = {
table_number: table_id,
total_amount: totalAmount,
// Only send necessary fields
items: cart.map(item => ({
product_id: item.id,
quantity: item.quantity,
unit_price: item.price
}))
};
// Use existing api/order.php
fetch('api/order.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(orderData)
})
.then(res => res.json())
.then(data => {
if (data.success) {
cart = [];
updateCart();
showToast('Order placed successfully! Please wait for preparation.', 'success');
} else {
showToast('Error: ' + (data.error || 'Unknown error'), 'danger');
}
})
.catch(err => {
console.error(err);
showToast('Failed to place order.', 'danger');
});
});
function showToast(message, type = 'dark') {
const toastContainer = document.getElementById('toast-container');
if (!toastContainer) return;
const toastId = 'toast-' + Date.now();
const toastHtml = `
<div id="${toastId}" class="toast align-items-center text-white bg-${type} border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">${message}</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
`;
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
const toastElement = document.getElementById(toastId);
const toast = new bootstrap.Toast(toastElement);
toast.show();
toastElement.addEventListener('hidden.bs.toast', () => toastElement.remove());
}
});