Autosave: 20260218-145439
This commit is contained in:
parent
af4b79251b
commit
2621002fde
@ -137,8 +137,11 @@
|
||||
<div class="logo">
|
||||
<i class="bi bi-cart4 me-2"></i>Customer Display
|
||||
</div>
|
||||
<div id="customerName" class="badge bg-light text-dark fs-6 fw-normal border">
|
||||
Welcome
|
||||
<div class="d-flex align-items-center">
|
||||
<div id="debugInfo" class="me-3 badge bg-secondary" style="display: none;">Items: 0</div>
|
||||
<div id="customerName" class="badge bg-light text-dark fs-6 fw-normal border">
|
||||
Welcome
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -181,17 +184,29 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let lastTimestamp = 0;
|
||||
|
||||
function formatMoney(amount) {
|
||||
return 'OMR ' + parseFloat(amount).toFixed(3);
|
||||
}
|
||||
|
||||
function updateDisplay(data) {
|
||||
if (!data) return;
|
||||
lastTimestamp = data.timestamp || 0;
|
||||
|
||||
// Debug info
|
||||
const debugEl = document.getElementById('debugInfo');
|
||||
if (debugEl) {
|
||||
debugEl.innerText = 'Items: ' + (data.items ? data.items.length : 0);
|
||||
// debugEl.style.display = 'block'; // Uncomment to show always
|
||||
}
|
||||
|
||||
// Update Theme
|
||||
if (data.theme) {
|
||||
document.body.className = data.theme;
|
||||
}
|
||||
|
||||
if (!data || !data.items || data.items.length === 0) {
|
||||
if (!Array.isArray(data.items) || data.items.length === 0) {
|
||||
document.getElementById('activeCart').style.display = 'none';
|
||||
document.getElementById('welcomeScreen').style.display = 'flex';
|
||||
document.getElementById('customerName').innerText = 'Welcome';
|
||||
@ -208,43 +223,67 @@
|
||||
document.getElementById('customerName').innerText = 'Welcome';
|
||||
}
|
||||
|
||||
// Update Items
|
||||
// Update Items (Safer rendering)
|
||||
const itemsList = document.getElementById('itemsList');
|
||||
itemsList.innerHTML = data.items.map(item => `
|
||||
<div class="cart-item">
|
||||
<div>
|
||||
<div class="item-name">${item.name}</div>
|
||||
<div class="item-details">
|
||||
${item.qty} x ${formatMoney(item.price)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-price">
|
||||
${formatMoney(item.qty * item.price)}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
if (itemsList) {
|
||||
itemsList.innerHTML = ''; // Clear existing
|
||||
|
||||
data.items.forEach(item => {
|
||||
try {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'cart-item';
|
||||
|
||||
const name = item.name || 'Item';
|
||||
const price = parseFloat(item.price) || 0;
|
||||
const qty = parseFloat(item.qty) || 0;
|
||||
const total = price * qty;
|
||||
|
||||
// Scroll to bottom of list
|
||||
itemsList.scrollTop = itemsList.scrollHeight;
|
||||
row.innerHTML = `
|
||||
<div>
|
||||
<div class="item-name"></div>
|
||||
<div class="item-details">
|
||||
${qty} x ${formatMoney(price)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-price">
|
||||
${formatMoney(total)}
|
||||
</div>
|
||||
`;
|
||||
// Set text content safely
|
||||
const nameEl = row.querySelector('.item-name');
|
||||
if (nameEl) nameEl.textContent = name;
|
||||
itemsList.appendChild(row);
|
||||
} catch (err) {
|
||||
console.error('Error rendering item:', err);
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll to bottom of list
|
||||
requestAnimationFrame(() => {
|
||||
itemsList.scrollTop = itemsList.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
// Update Totals
|
||||
document.getElementById('displaySubtotal').innerText = formatMoney(data.subtotal);
|
||||
document.getElementById('displaySubtotal').innerText = formatMoney(data.subtotal || 0);
|
||||
|
||||
if (data.discount > 0) {
|
||||
const discount = parseFloat(data.discount) || 0;
|
||||
if (discount > 0) {
|
||||
document.getElementById('displayDiscountRow').style.display = 'flex';
|
||||
document.getElementById('displayDiscount').innerText = '- ' + formatMoney(data.discount);
|
||||
document.getElementById('displayDiscount').innerText = '- ' + formatMoney(discount);
|
||||
} else {
|
||||
document.getElementById('displayDiscountRow').style.display = 'none';
|
||||
}
|
||||
|
||||
if (data.loyalty > 0) {
|
||||
const loyalty = parseFloat(data.loyalty) || 0;
|
||||
if (loyalty > 0) {
|
||||
document.getElementById('displayLoyaltyRow').style.display = 'flex';
|
||||
document.getElementById('displayLoyalty').innerText = '- ' + formatMoney(data.loyalty);
|
||||
document.getElementById('displayLoyalty').innerText = '- ' + formatMoney(loyalty);
|
||||
} else {
|
||||
document.getElementById('displayLoyaltyRow').style.display = 'none';
|
||||
}
|
||||
|
||||
document.getElementById('displayTotal').innerText = formatMoney(data.total);
|
||||
document.getElementById('displayTotal').innerText = formatMoney(data.total || 0);
|
||||
}
|
||||
|
||||
// Listen for storage events
|
||||
@ -259,6 +298,19 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Polling fallback (every 1 second)
|
||||
setInterval(() => {
|
||||
const stored = localStorage.getItem('pos_cart_update');
|
||||
if (stored) {
|
||||
try {
|
||||
const data = JSON.parse(stored);
|
||||
if (data.timestamp && data.timestamp !== lastTimestamp) {
|
||||
updateDisplay(data);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Initial check
|
||||
const stored = localStorage.getItem('pos_cart_update');
|
||||
if (stored) {
|
||||
|
||||
21
index.php
21
index.php
@ -2868,7 +2868,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
<div class="p-3 border-bottom d-flex justify-content-between align-items-center">
|
||||
<h6 class="m-0 fw-bold"><i class="bi bi-cart3 me-2"></i>Cart</h6>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-sm btn-outline-info" onclick="window.open('customer-display.php', 'CustomerDisplay', 'width=1000,height=800')" title="Customer Display"><i class="bi bi-display me-1"></i> Customer Screen</button>
|
||||
<button class="btn btn-sm btn-outline-info" onclick="window.open('customer-display.php?v=<?= time() ?>', 'CustomerDisplay', 'width=1000,height=800')" title="Customer Display"><i class="bi bi-display me-1"></i> Customer Screen</button>
|
||||
<button class="btn btn-sm btn-outline-warning" onclick="cart.openHeldCartsModal()" title="Held List"><i class="bi bi-list-task"></i></button>
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="cart.hold()" title="Hold Cart"><i class="bi bi-pause-circle"></i></button>
|
||||
<button class="btn btn-sm btn-outline-danger" onclick="cart.clear()" title="Clear Cart"><i class="bi bi-trash"></i></button>
|
||||
@ -2968,7 +2968,10 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
?>,
|
||||
broadcast() {
|
||||
try {
|
||||
const subtotal = this.items.reduce((sum, item) => sum + (parseFloat(item.price) * item.qty), 0);
|
||||
// Ensure items is an array
|
||||
if (!Array.isArray(this.items)) this.items = [];
|
||||
|
||||
const subtotal = this.items.reduce((sum, item) => sum + (parseFloat(item.price) * parseFloat(item.qty)), 0);
|
||||
let discountAmount = 0;
|
||||
if (this.discount) {
|
||||
discountAmount = this.discount.type === 'percentage' ? subtotal * (parseFloat(this.discount.value) / 100) : parseFloat(this.discount.value);
|
||||
@ -2983,14 +2986,14 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
||||
|
||||
const payload = {
|
||||
items: this.items.map(i => ({
|
||||
name: (document.documentElement.lang === 'ar' ? (i.nameAr || i.nameEn) : (i.nameEn || i.nameAr)),
|
||||
price: parseFloat(i.price),
|
||||
qty: parseFloat(i.qty)
|
||||
name: (document.documentElement.lang === 'ar' ? (i.nameAr || i.nameEn) : (i.nameEn || i.nameAr)) || 'Unknown Item',
|
||||
price: parseFloat(i.price) || 0,
|
||||
qty: parseFloat(i.qty) || 0
|
||||
})),
|
||||
subtotal: subtotal,
|
||||
discount: discountAmount,
|
||||
loyalty: loyaltyRedeemed,
|
||||
total: total,
|
||||
subtotal: parseFloat(subtotal) || 0,
|
||||
discount: parseFloat(discountAmount) || 0,
|
||||
loyalty: parseFloat(loyaltyRedeemed) || 0,
|
||||
total: parseFloat(total) || 0,
|
||||
customerName: customerName,
|
||||
theme: document.body.className,
|
||||
timestamp: Date.now()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user