Grill & Taste Lisbon AG

Insira o PIN de acesso

Grill & Taste Lisbon AG

Command Center v3.0
-
Reservas Hoje
-
Take Away Pendentes
-
Ajustes Pendentes
-
Membros VIP
Próximas Reservas
A carregar...
Todas as Reservas
A carregar...
🥡 Encomendas Take Away
A carregar...
💬 Mensagens — Caixa Unificada
A carregar...
Nova Reserva
🍰 Encomendas Padaria / Pastelaria
A carregar...
Detalhe

🗺️ Sala

Livre Ocupada A Pedir Conta Reservada Grupo
▐▐▐ JANELAS ▐▐▐
▐▐▐ SALA 1 — PRINCIPAL ▐▐▐

📋 Encomendas & Pedidos

📚 Conhecimento IA

🤖 Testar Assistente IA
A carregar...
// ═══════════════════════════════════════════════════════════════════ // ═══ ENCOMENDAS TAB — Full order management // ═══════════════════════════════════════════════════════════════════ let currentEncType = 'reservas'; let currentEncStatus = 'all'; let encData = {}; function switchEncType(btn) { document.querySelectorAll('#enc-type-filter .filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentEncType = btn.dataset.encType; renderEncList(); } function switchEncStatus(btn) { document.querySelectorAll('#enc-status-filter .filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentEncStatus = btn.dataset.encStatus; renderEncList(); } async function loadEncomendas() { const listEl = document.getElementById('enc-list'); listEl.innerHTML = '
A carregar encomendas...
'; try { const [resRes, cakeRes, leitaoRes, takeawayRes, eventRes] = await Promise.all([ fetch('/api/reservations?date_filter=future').then(r => r.json()), fetch('/api/cake-orders?date=future').then(r => r.json()), fetch('/api/leitao-orders?date=future').then(r => r.json()), fetch('/api/takeaway-orders?date=future').then(r => r.json()), fetch('/api/event-bookings?date=future').then(r => r.json()), ]); encData = { reservas: Array.isArray(resRes) ? resRes : (resRes.reservations || []), bolos: Array.isArray(cakeRes) ? cakeRes : [], leitao: Array.isArray(leitaoRes) ? leitaoRes : [], takeaway: Array.isArray(takeawayRes) ? takeawayRes : [], eventos: Array.isArray(eventRes) ? eventRes : [], }; renderEncList(); } catch (err) { listEl.innerHTML = '

Erro ao carregar encomendas

'; console.error('Encomendas load error:', err); } } function getStatusBadge(status) { switch ((status || '').toLowerCase()) { case 'pending': return '🟡 Pendente'; case 'confirmed': return '✅ Confirmado'; case 'cancelled': return '❌ Cancelado'; default: return '' + (status || '-') + ''; } } function formatEncDate(d) { if (!d) return '-'; const dt = new Date(d); return dt.toLocaleDateString('pt-PT', { day: '2-digit', month: '2-digit', year: 'numeric' }); } function renderEncList() { const listEl = document.getElementById('enc-list'); let items = encData[currentEncType] || []; // Filter by status if (currentEncStatus !== 'all') { items = items.filter(i => (i.status || '').toLowerCase() === currentEncStatus); } if (items.length === 0) { listEl.innerHTML = '
Sem encomendas nesta categoria
'; return; } let html = ''; switch (currentEncType) { case 'reservas': items.forEach(item => { const date = formatEncDate(item.reservation_date || item.date); const time = item.reservation_time || item.time || '-'; const name = item.customer_name || '-'; const phone = item.phone || item.wa_phone || '-'; const loc = item.location || item.restaurant || '-'; const pax = item.party_size || '-'; html += renderEncCard(item.id, 'reservas', date, time, name, phone, loc + ' | ' + pax + ' pax', item.status, item.notes); }); break; case 'bolos': items.forEach(item => { const date = formatEncDate(item.date_needed); const name = item.customer_name || '-'; const phone = item.wa_phone || '-'; const details = (item.flavor || '-') + ' | ' + (item.people_count || '-') + ' pax | "' + (item.cake_message || '') + '"'; html += renderEncCard(item.id, 'bolos', date, '-', name, phone, details, item.status, item.notes); }); break; case 'leitao': items.forEach(item => { const date = formatEncDate(item.date_needed); const time = item.pickup_time || '-'; const name = item.customer_name || '-'; const phone = item.wa_phone || '-'; const details = 'Qty: ' + (item.quantity || '-') + ' | Levantar: ' + time; html += renderEncCard(item.id, 'leitao', date, time, name, phone, details, item.status, item.notes); }); break; case 'takeaway': items.forEach(item => { const date = formatEncDate(item.date_needed); const time = item.pickup_time || '-'; const name = item.customer_name || '-'; const phone = item.wa_phone || '-'; const details = (item.items || '-').substring(0, 80); html += renderEncCard(item.id, 'takeaway', date, time, name, phone, details, item.status, item.notes); }); break; case 'eventos': items.forEach(item => { const date = formatEncDate(item.event_date); const time = item.event_time || '-'; const name = item.customer_name || '-'; const phone = item.wa_phone || '-'; const details = (item.event_type || '-') + ' | ' + (item.guests || '-') + ' convidados | ' + (item.restaurant || '-'); html += renderEncCard(item.id, 'eventos', date, time, name, phone, details, item.status, item.notes); }); break; } listEl.innerHTML = html; } function renderEncCard(id, type, date, time, name, phone, details, status, notes) { const isAdmin = currentUser && currentUser.role === 'admin'; const actions = isAdmin ? `
` : ''; return `
${date} ${time !== '-' ? '• ' + time : ''} ${getStatusBadge(status)}
${name} 📱 ${phone}
${details}
${notes ? '
📝 ' + notes + '
' : ''} ${actions}
`; } async function updateEncStatus(type, id, newStatus) { const endpoints = { reservas: '/api/reservations/', bolos: '/api/cake-orders/', leitao: '/api/leitao-orders/', takeaway: '/api/takeaway-orders/', eventos: '/api/event-bookings/', }; try { const res = await fetch(endpoints[type] + id, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }), }); if (res.ok) { showToast(newStatus === 'confirmed' ? '✅ Confirmado!' : '❌ Cancelado!', newStatus === 'confirmed' ? 'var(--green)' : 'var(--red)'); loadEncomendas(); } else { showToast('Erro ao atualizar', 'var(--red)'); } } catch (err) { showToast('Erro de ligação', 'var(--red)'); } }