Vega Booking

Panel de administración

Acceso seguro

Introduce el WhatsApp autorizado del admin. Recibirás un código temporal.


  

Ayuda rápida


Enviar incidencia


`; const win = window.open('', '_blank'); if (!win) { alert('El navegador ha bloqueado la ventana de impresión.'); return; } win.document.open(); win.document.write(html); win.document.close(); setTimeout(() => win.print(), 300); } catch(e) { alert('Error cargando ticket: ' + e.message); } } function escapeHtml(value){ return String(value ?? '').replace(/[&<>"']/g, function(c){ return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; }); } function exportCsv(){ const qs = new URLSearchParams({from:$('fromDate').value,to:$('toDate').value,staff_id:$('reportStaffFilter').value,service_id:$('serviceFilter').value,payment_method:$('paymentFilter').value,format:'csv',token:state.token}); } function toggleSupport(force) { const panel = $('supportPanel'); const open = typeof force === 'boolean' ? force : !panel.classList.contains('active'); panel.classList.toggle('active', open); if (open) loadSupportFaq(); } async function loadSupportFaq() { const q = $('supportSearch')?.value || ''; const el = $('supportFaq'); if (!el) return; el.innerHTML = '
Buscando...
'; try { el.innerHTML = data.results.length : '
No encuentro una respuesta. Envía una incidencia.
'; } catch (err) { } } async function sendIncident() { $('incidentResult').textContent = 'Enviando...'; try { method: 'POST', body: JSON.stringify({ type: $('incidentType').value, priority: $('incidentPriority').value, title: $('incidentTitle').value, message: $('incidentMessage').value, page: location.href, user_agent: navigator.userAgent, admin_phone: $('adminPhone')?.value || '' }) }); $('incidentResult').textContent = 'Incidencia enviada.\nID: ' + data.incident.incident_id + '\n' + (data.sent_to_whatsapp ? 'Enviada por WhatsApp.' : 'Guardada. No se confirmó envío por WhatsApp.'); } catch (err) { $('incidentResult').textContent = 'Error: ' + err.message; } } // VEGA_AI_LOGIC_LIGHT_V1 function escapeHtml(value) { return String(value ?? '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function highlightText(value) { const q = ($('searchText')?.value || '').trim(); const raw = escapeHtml(value); if (!q || q.length < 2) return raw; const safe = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function getBookingEndMs(booking) { const value = booking.end_time || booking.start_time; const time = new Date(value || 0).getTime(); return Number.isFinite(time) ? time : 0; } function isPastUnclosed(booking) { return booking.status !== 'closed' && booking.status !== 'cancelled' && getBookingEndMs(booking) && getBookingEndMs(booking) < Date.now(); } function getAllVisibleBookingsFromGroups(groups) { return (groups || []).flatMap(group => group.bookings || []); } function buildSmartDailySummary(groups) { const bookings = getAllVisibleBookingsFromGroups(groups); const total = bookings.length; const pending = bookings.filter(b => b.status === 'pending').length; const doing = bookings.filter(b => b.status === 'doing').length; const closed = bookings.filter(b => b.status === 'closed').length; const pastUnclosed = bookings.filter(isPastUnclosed); const expected = bookings .filter(b => b.status !== 'cancelled') .reduce((sum, b) => sum + Number(b.amount || 0), 0); const lines = []; lines.push(`
IA
`); if (pastUnclosed.length) { lines.push(`
IA
`); } const next = bookings .filter(b => b.status !== 'closed' && b.status !== 'cancelled') .filter(b => new Date(b.start_time || 0).getTime() >= Date.now()) .sort((a, b) => new Date(a.start_time || 0) - new Date(b.start_time || 0))[0]; if (next) { lines.push(`
IA
`); } } function skeletonList(label = 'Cargando datos inteligentes...') { return `
`; } function buildSmartReportSummary(data) { const payment = data.by_payment_method || {}; const dominant = Object.entries(payment).sort((a, b) => Number(b[1]) - Number(a[1]))[0]; const staffTop = Object.entries(data.by_staff || {}).sort((a, b) => Number(b[1].total) - Number(a[1].total))[0]; const serviceTop = Object.entries(data.by_service || {}).sort((a, b) => Number(b[1].total) - Number(a[1].total))[0]; const lines = []; lines.push(`
IA
`); if (dominant) { lines.push(`
IA
`); } if (staffTop) { lines.push(`
IA
`); } if (serviceTop) { lines.push(`
IA
`); } } // VEGA_ADMIN_AUTO_REFRESH_V2 setInterval(() => { if (document.visibilityState === 'visible' && $('appScreen')?.style.display !== 'none') { const active = document.querySelector('.tab.active')?.id || ''; if (active.includes('bookings')) loadBookings(); if (active.includes('cash')) loadReport(); } }, 45000); if(state.token){ initApp(); }