/* ═══════════════════════════════════════════ ADMIN DASHBOARD JS ═══════════════════════════════════════════ */ let ALL_ADMIN_ORDERS = []; let ADMIN_STATS = { low_stock: 0, low_stock_items: [], revenue: 0, total_orders: 0 }; function switchAdminTab(tab, btn = null) { document.querySelectorAll('.admin-tab-content').forEach(c => c.classList.remove('active')); document.querySelectorAll('.admin-nav-btn').forEach(b => b.classList.remove('active')); document.getElementById('admin-tab-' + tab).classList.add('active'); if (btn) { btn.classList.add('active'); } else { // Find the button manually if called programmatically const btns = document.querySelectorAll('.admin-nav-btn'); btns.forEach(b => { const oc = b.getAttribute('onclick'); if (oc && oc.includes(`'${tab}'`)) b.classList.add('active'); }); } const titles = { 'dash': 'Admin Dashboard', 'menu': 'Manage Menu', 'stock': 'Stock Manager', 'orders': 'Active Orders' }; document.getElementById('admin-tab-title').textContent = titles[tab]; if (tab === 'dash') loadAdminStats(); if (tab === 'menu') { // Clear search and show all items by default when switching tabs normally const searchInput = document.querySelector('.menu-search'); if (searchInput) searchInput.value = ''; loadAdminMenu(); } if (tab === 'stock') loadStockManager(); if (tab === 'orders') loadAdminOrders(); } function loadAdminStats() { fetch('api/admin_stats.php') .then(res => res.json()) .then(data => { if (data.status === 'success') { ADMIN_STATS = data.stats; document.getElementById('stat-revenue').textContent = '₹' + (data.stats.revenue || 0).toFixed(0); document.getElementById('stat-today-revenue').textContent = '₹' + (data.stats.today_revenue || 0).toFixed(0); document.getElementById('stat-orders').textContent = data.stats.total_orders || 0; document.getElementById('stat-today-orders').textContent = data.stats.today_orders || 0; document.getElementById('stat-lowstock').textContent = data.stats.low_stock || 0; document.getElementById('stat-pending').textContent = data.stats.pending_orders || 0; // Frequent items const freqList = document.getElementById('frequent-items-list'); if (data.stats.frequent_items && data.stats.frequent_items.length > 0) { freqList.innerHTML = data.stats.frequent_items.map((item, i) => `
No orders yet
'; } // Recent orders const list = document.getElementById('admin-recent-orders-list'); if (data.recent_orders.length === 0) { list.innerHTML = 'No recent orders
'; } else { list.innerHTML = data.recent_orders.map(o => `No items found
'; return; } let filteredMenu = MENU; if (filterLowStock) { filteredMenu = MENU.filter(item => parseInt(item.stock) < 5); } list.innerHTML = filteredMenu.map(item => `No low stock items! 🎉
'; } }); } function showLowStockItems() { if (!ADMIN_STATS || !ADMIN_STATS.low_stock_items) return; const lowStockItems = ADMIN_STATS.low_stock_items; const list = document.getElementById('low-stock-list'); if (lowStockItems.length === 0) { list.innerHTML = 'All items are well stocked! 🎉
'; } else { list.innerHTML = lowStockItems.map(item => `Loading orders...
'; fetch('api/get_orders.php?admin=1') .then(res => res.json()) .then(data => { if (data.status === 'success') { ALL_ADMIN_ORDERS = data.orders; renderAdminOrders(); } else { list.innerHTML = 'Error loading orders
'; } }) .catch(err => { console.error(err); list.innerHTML = 'Error loading orders
'; }); } function renderAdminOrders() { const list = document.getElementById('admin-orders-list'); const statusFilter = document.getElementById('order-status-filter').value; let filtered = ALL_ADMIN_ORDERS; if (statusFilter !== 'All') { filtered = ALL_ADMIN_ORDERS.filter(o => o.status === statusFilter); } if (filtered.length > 0) { list.innerHTML = filtered.map(o => `User: ${o.user_name}
Total: ₹${o.total}
Payment: ${o.payment_method}
Date: ${new Date(o.created_at).toLocaleString()}
No ${statusFilter === 'All' ? '' : statusFilter} orders found
`; } } function filterAdminMenu(q) { q = q.toLowerCase(); const rows = document.querySelectorAll('.admin-item-row'); rows.forEach(row => { const name = row.querySelector('.ai-name').textContent.toLowerCase(); row.style.display = name.includes(q) ? 'flex' : 'none'; }); } function updateOrderStatus(orderId, status) { const formData = new FormData(); formData.append('action', 'update_status'); formData.append('order_id', orderId); formData.append('status', status); fetch('api/admin_order_actions.php', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => { if (data.status === 'success') { toast('✅ Status updated'); loadAdminOrders(); } else { toast('❌ ' + data.message); } }); } function showAddItemModal() { document.getElementById('item-modal-title').textContent = 'Add New Item'; document.getElementById('edit-item-id').value = ''; document.getElementById('item-name').value = ''; document.getElementById('item-desc').value = ''; document.getElementById('item-price').value = ''; document.getElementById('item-stock').value = ''; document.getElementById('item-category').value = ''; document.getElementById('item-image').value = ''; document.getElementById('admin-item-modal').classList.add('show'); } function showEditItemModal(item) { document.getElementById('item-modal-title').textContent = 'Edit Item'; document.getElementById('edit-item-id').value = item.id; document.getElementById('item-name').value = item.name; document.getElementById('item-desc').value = item.sub || item.description || ''; document.getElementById('item-price').value = item.price; document.getElementById('item-stock').value = item.stock; document.getElementById('item-category').value = item.cat || item.category || ''; document.getElementById('item-image').value = item.img || item.image_url || ''; document.getElementById('admin-item-modal').classList.add('show'); } function saveItemFromModal() { const id = document.getElementById('edit-item-id').value; const name = document.getElementById('item-name').value.trim(); const desc = document.getElementById('item-desc').value.trim(); const price = document.getElementById('item-price').value; const stock = document.getElementById('item-stock').value; const category = document.getElementById('item-category').value; const image = document.getElementById('item-image').value.trim(); if (!name || !price || !category || stock === '') { toast('⚠️ Please fill all required fields'); return; } const formData = new FormData(); const isEdit = id !== ''; if (isEdit) { formData.append('action', 'update'); formData.append('id', id); } else { formData.append('action', 'add'); } formData.append('name', name); formData.append('description', desc); formData.append('price', price); formData.append('category', category); formData.append('image_url', image); formData.append('stock', stock); fetch('api/admin_menu_actions.php', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => { if (data.status === 'success') { toast(isEdit ? '✅ Item updated' : '✅ Item added'); closeModal('admin-item-modal'); fetchMenuData().then(() => loadAdminMenu()); } else { toast('❌ ' + data.message); } }) .catch(err => { console.error(err); toast('❌ Error saving item'); }); } function editItem(id) { const item = MENU.find(m => m.id === id); if (!item) return; showEditItemModal(item); } function deleteItem(id) { if (!confirm('Delete this item?')) return; const formData = new FormData(); formData.append('action', 'delete'); formData.append('id', id); fetch('api/admin_menu_actions.php', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => { if (data.status === 'success') { toast('✅ Item deleted'); fetchMenuData().then(() => loadAdminMenu()); } else { toast('❌ ' + data.message); } }); } /* ═══════════════════════════════════════════ STOCK MANAGER ═══════════════════════════════════════════ */ function loadStockManager() { fetchMenuData().then(() => { const list = document.getElementById('stock-manager-list'); if (MENU.length === 0) { list.innerHTML = 'No items found
'; return; } // Sort by stock level (low to high) const sorted = [...MENU].sort((a, b) => parseInt(a.stock) - parseInt(b.stock)); list.innerHTML = sorted.map(item => { const isLow = parseInt(item.stock) < 5; const isOut = parseInt(item.stock) <= 0; return `