โ†

Bar Par List

Item Size Par On Hand Need
const defaultParList = [ { type: 'category', name: 'CUT FRUIT' }, { type: 'item', item: 'Limes', par: 0, size: 'wedges', onHand: 0 }, { type: 'item', item: 'Lemons', par: 0, size: 'wedges', onHand: 0 }, { type: 'item', item: 'Oranges', par: 0, size: 'wheels', onHand: 0 }, { type: 'category', name: 'BATCH DRINKS' }, { type: 'item', item: 'Margarita Batch', par: 0, size: 'quarts', onHand: 0 }, { type: 'item', item: 'Bloody Mary Mix', par: 0, size: 'quarts', onHand: 0 }, { type: 'item', item: 'Simple Syrup', par: 0, size: 'bottles', onHand: 0 }, { type: 'category', name: 'GARNISH & MISC' }, { type: 'item', item: 'Cocktail Cherries', par: 0, size: 'jars', onHand: 0 }, { type: 'item', item: 'Olives', par: 0, size: 'jars', onHand: 0 }, { type: 'item', item: 'Jalapeรฑos', par: 0, size: 'jars', onHand: 0 }, ]; let currentParList = []; let isEditMode = false; function checkAdminAccess() { const hasAdminAccess = canEdit('bar'); document.getElementById('edit-btn').style.display = hasAdminAccess ? '' : 'none'; } window.addEventListener('auth-state-changed', checkAdminAccess); setTimeout(() => { checkAdminAccess(); }, 500); setTimeout(() => { checkAdminAccess(); }, 1500); setTimeout(() => { checkAdminAccess(); }, 3000); window.addEventListener('storage', checkAdminAccess); const STORAGE_KEY = 'wcp-bar-par-list'; function saveToLocalStorage() { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(currentParList)); } catch(e) {} } function loadFromLocalStorage() { try { const s = localStorage.getItem(STORAGE_KEY); return s ? JSON.parse(s) : null; } catch(e) { return null; } } function clearLocalStorage() { try { localStorage.removeItem(STORAGE_KEY); } catch(e) {} } async function loadParList() { try { const snap = await getDoc(doc(db, PAR_LIST_DOC)); if (snap.exists() && Array.isArray(snap.data().items)) { currentParList = snap.data().items; } else { currentParList = [...defaultParList]; } } catch (err) { currentParList = [...defaultParList]; } const saved = loadFromLocalStorage(); if (saved) currentParList = saved; renderTable(); } function renderTable() { const tbody = document.getElementById('par-tbody'); tbody.innerHTML = ""; document.getElementById('delete-col-header').style.display = isEditMode ? '' : 'none'; document.getElementById('move-col-header').style.display = isEditMode ? '' : 'none'; currentParList.forEach((row, i) => { const tr = document.createElement('tr'); tr.setAttribute('data-index', i); if (!row.type) { row.type = row.name && !row.item ? 'category' : 'item'; } if (row.type === 'category') { tr.className = "category-row"; if (isEditMode) { tr.innerHTML = ` โ‹ฎ โ€” `; } else { tr.innerHTML = `${row.name || "[Category]"}`; } } else { if (isEditMode) { tr.innerHTML = ` โ‹ฎ ${Math.max(0, (row.par || 0) - (row.onHand || 0))} `; } else { const need = Math.max(0, (row.par || 0) - (row.onHand || 0)); tr.innerHTML = ` ${row.item || ''} ${row.par || 0} ${row.size || ''} ${need} `; } } tbody.appendChild(tr); }); if (isEditMode) { const tbody = document.getElementById('par-tbody'); if (tbody.sortableInstance) { tbody.sortableInstance.destroy(); tbody.sortableInstance = null; } tbody.sortableInstance = Sortable.create(tbody, { animation: 150, ghostClass: 'sortable-ghost', dragClass: 'sortable-drag', handle: '.drag-handle', onEnd: function() { const newOrder = []; document.querySelectorAll('#par-tbody tr').forEach(row => { const idx = +row.getAttribute('data-index'); if (!isNaN(idx)) newOrder.push(currentParList[idx]); }); currentParList = newOrder; saveToLocalStorage(); renderTable(); } }); } document.querySelectorAll('.input-current').forEach(input => { input.addEventListener('input', function() { const idx = +this.dataset.index; const row = currentParList[idx]; if (row && row.type === 'item') { row.onHand = parseFloat(this.value) || 0; const need = Math.max(0, (row.par || 0) - row.onHand); const needSpan = document.getElementById(`need-${idx}`); if (needSpan) needSpan.textContent = need; if (!isEditMode) saveToLocalStorage(); } }); }); if (isEditMode) { document.querySelectorAll('input[data-field]').forEach(input => { input.addEventListener('input', function() { const idx = +this.dataset.index; const field = this.dataset.field; const value = field === 'par' ? parseFloat(this.value) || 0 : this.value; currentParList[idx][field] = value; if (field === 'par') { const row = currentParList[idx]; if (row && row.type === 'item') { const need = Math.max(0, row.par - (row.onHand || 0)); const needSpan = document.getElementById(`need-${idx}`); if (needSpan) needSpan.textContent = need; } } saveToLocalStorage(); }); }); document.querySelectorAll('.category-input').forEach(input => { input.addEventListener('input', function() { const idx = +this.dataset.index; currentParList[idx].name = this.value; }); }); document.querySelectorAll('.move-up').forEach(btn => { btn.addEventListener('click', function() { const idx = +this.dataset.index; if (idx > 0) { [currentParList[idx - 1], currentParList[idx]] = [currentParList[idx], currentParList[idx - 1]]; saveToLocalStorage(); renderTable(); } }); }); document.querySelectorAll('.move-down').forEach(btn => { btn.addEventListener('click', function() { const idx = +this.dataset.index; if (idx < currentParList.length - 1) { [currentParList[idx], currentParList[idx + 1]] = [currentParList[idx + 1], currentParList[idx]]; saveToLocalStorage(); renderTable(); } }); }); document.querySelectorAll('.delete-btn').forEach(btn => { btn.addEventListener('click', function() { const idx = +this.dataset.index; if (confirm('Delete this item?')) { currentParList.splice(idx, 1); saveToLocalStorage(); renderTable(); } }); }); } } document.getElementById('edit-btn').addEventListener('click', function() { isEditMode = true; document.body.classList.add('edit-mode'); renderTable(); this.style.display = 'none'; document.getElementById('edit-controls').style.display = 'flex'; }); document.getElementById('cancel-btn').addEventListener('click', async function() { isEditMode = false; document.body.classList.remove('edit-mode'); await loadParList(); document.getElementById('edit-btn').style.display = ''; document.getElementById('edit-controls').style.display = 'none'; }); document.getElementById('save-btn').addEventListener('click', async function() { const filtered = currentParList.filter(r => r.type === "category" || (r.type === "item" && r.item && r.item.trim().length > 0) ); if (filtered.length === 0) { alert("Cannot save an empty list."); return; } try { await setDoc(doc(db, PAR_LIST_DOC), { items: filtered, updated: new Date().toISOString() }); currentParList = filtered; isEditMode = false; document.body.classList.remove('edit-mode'); clearLocalStorage(); renderTable(); document.getElementById('edit-btn').style.display = ''; document.getElementById('edit-controls').style.display = 'none'; alert("Bar par list saved!"); } catch (err) { alert("Failed to save: " + err.message); } }); document.getElementById('add-category-btn').addEventListener('click', function() { currentParList.push({ type: 'category', name: '' }); saveToLocalStorage(); renderTable(); }); document.getElementById('add-item-btn').addEventListener('click', function() { currentParList.push({ type: 'item', item: '', par: 0, size: '', onHand: 0 }); saveToLocalStorage(); renderTable(); }); document.getElementById('print-btn').addEventListener('click', function() { window.print(); }); loadParList();