import { api } from '../api'; import { renderNavbar, toast } from '../utils'; let previousItemIdsByStatus: Map> = new Map(); let audioCtx: AudioContext | null = null; function playNotificationSound() { try { if (!audioCtx) audioCtx = new AudioContext(); if (audioCtx.state === 'suspended') audioCtx.resume(); const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.connect(gain); gain.connect(audioCtx.destination); osc.type = 'sine'; osc.frequency.setValueAtTime(800, audioCtx.currentTime); osc.frequency.setValueAtTime(1000, audioCtx.currentTime + 0.1); osc.frequency.setValueAtTime(800, audioCtx.currentTime + 0.2); gain.gain.setValueAtTime(0.3, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.4); osc.start(audioCtx.currentTime); osc.stop(audioCtx.currentTime + 0.4); } catch (e) { // Audio not supported, silently fail } } export async function renderKitchen(container: HTMLElement) { container.innerHTML = ` ${renderNavbar('/kitchen')}

Carregando pedidos...

`; let currentStatus = 'PENDENTE'; let currentFilter = ''; let autoRefreshInterval: ReturnType | null = null; let requestId = 0; const loadItems = async () => { const grid = document.getElementById('items-grid')!; grid.innerHTML = '

Carregando...

'; const myRequestId = ++requestId; try { let url = `/painel/itens?status=${currentStatus}`; if (currentFilter !== '') url += `&itemCozinha=${currentFilter}`; const items = await api.get(url); if (myRequestId !== requestId) return; const currentIds = new Set(items.map((i: any) => i.id)); const previousIds = previousItemIdsByStatus.get(currentStatus); if (previousIds && previousIds.size > 0) { const newItems = items.filter((i: any) => !previousIds.has(i.id)); if (newItems.length > 0) { playNotificationSound(); toast(`${newItems.length} novo(s) pedido(s) recebido(s)!`, 'success'); } } previousItemIdsByStatus.set(currentStatus, currentIds); if (!items.length) { grid.innerHTML = `

Nenhum pedido com status ${currentStatus} 🎉

`; return; } const statusActions: Record = { PENDENTE: { label: '▶ Iniciar Preparo', next: 'PREPARANDO' }, PREPARANDO: { label: '✔ Marcar Pronto', next: 'PRONTO' }, PRONTO: { label: '🚀 Marcar Entregue', next: 'ENTREGUE' }, ENTREGUE: { label: '', next: '' }, }; grid.innerHTML = items.map((item: any) => { const action = statusActions[item.status]; return `
${item.produto.itemCozinha ? '🍳 Cozinha' : '🍹 Bar'} Mesa: ${item.comanda.identificador}

${item.quantidade}× ${item.produto.nome}

${item.observacao ? `

⚠️ ${item.observacao}

` : ''}

Pedido às ${new Date(item.criadoEm).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}

${item.usuario ? `

Adicionado por: ${item.usuario.nome}

` : '

'} ${action.label ? ` ` : `

✅ Entregue

`}
`; }).join(''); } catch (err: any) { grid.innerHTML = `

Erro: ${err.message}

`; } }; const startAutoRefresh = () => { stopAutoRefresh(); autoRefreshInterval = setInterval(loadItems, 10000); }; const stopAutoRefresh = () => { if (autoRefreshInterval) { clearInterval(autoRefreshInterval); autoRefreshInterval = null; } }; // Tab switching document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentStatus = (btn as HTMLElement).dataset.status!; loadItems(); }); }); // Filter buttons document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentFilter = (btn as HTMLElement).dataset.filter!; loadItems(); }); }); document.getElementById('btn-refresh')?.addEventListener('click', loadItems); document.getElementById('auto-refresh-toggle')?.addEventListener('change', (e) => { if ((e.target as HTMLInputElement).checked) startAutoRefresh(); else stopAutoRefresh(); }); // Event delegation for advance buttons document.getElementById('items-grid')?.addEventListener('click', async (e) => { const btn = (e.target as HTMLElement).closest('[data-action="advance"]') as HTMLElement | null; if (!btn) return; const id = btn.dataset.itemId!; const status = btn.dataset.nextStatus!; try { await api.patch(`/painel/itens/${id}/status`, { status }); toast('Status atualizado!', 'success'); loadItems(); } catch (err: any) { toast(err.message, 'error'); } }); // Pause auto-refresh when tab is hidden const handleVisibilityChange = () => { if (document.hidden) { stopAutoRefresh(); } else { const checkbox = document.getElementById('auto-refresh-toggle') as HTMLInputElement | null; if (checkbox?.checked) startAutoRefresh(); } }; document.addEventListener('visibilitychange', handleVisibilityChange); // Cleanup on navigation const cleanup = () => { stopAutoRefresh(); previousItemIdsByStatus.clear(); document.removeEventListener('visibilitychange', handleVisibilityChange); audioCtx?.close(); audioCtx = null; }; window.addEventListener('popstate', cleanup); await loadItems(); startAutoRefresh(); }