Dashboard
LTV promedio
${{ cohortes.ltv_promedio }}
Repeat rate
{{ cohortes.tasa_repeat_pct }}%
Repeat clients
{{ cohortes.clientes_repeat }}
Proyección mes
${{ predictivo.proyeccion_mes }}
Ingresos mes
${{ predictivo.ingresos_mes }}
Clientes en riesgo
{{ predictivo.clientes_riesgo }}
Mejor día
{{ predictivo.mejor_dia_semana }}
Ocupación en vivo
{{ ocupacionLive.en_sala }} / {{ ocupacionLive.capacidad }} salas · {{ ocupacionLive.pct }}%
{{ s.nombre }}
{{ s.turnover_post_checkout ? 'Limpieza post-checkout' : s.estado }}
{{ dashboard.error }}
Sesiones de hoy
Sin sesiones programadas hoy.
-
{{ s.cliente }} · {{ formatHoraAdmin(s.hora_inicio) }}–{{ formatHoraAdmin(s.hora_fin) }}
{{ estadoSesionHoy(s).label }}{{ s.salaNombre }} · {{ s.estado }}
+{{ s.extensiones_horas }}h extendida
Saldo efectivo: ${{ Number(s.saldo_pendiente).toFixed(2) }}
Check-in automático (kiosco). Se cerrará al salir o al terminar el horario.
Notas operador
Gestión de Salas
{{ errorSalasAdmin }}
No hay salas registradas
{{ sala.nombre }}
{{ formatMoneda(sala.precio_hora) }}/hr
| Nombre | Precio/hora | Acciones |
|---|---|---|
| No hay salas registradas | ||
| {{ sala.nombre }} | {{ formatMoneda(sala.precio_hora) }} | |
Ingenieros y PINs
Portal: ingeniero.html — login con ID + PIN de 6 dígitos
{{ errorIngenierosAdmin }}
Cargando ingenieros…
No hay ingenieros registrados
| ID | Nombre | $/hr | Comisión | Estado | PIN portal | Acciones |
|---|---|---|---|---|---|---|
| No hay ingenieros registrados | ||||||
| {{ ing.id }} | {{ ing.nombre }} | {{ formatMoneda(ing.precio_hora) }} | {{ ing.comision_pct }}% | {{ ing.activo ? 'Activo' : 'Inactivo' }} |
{{ pinVisibleIds[ing.id] ? (ing.portal_pin || '—') : '••••••' }}
|
Portal |
Catálogo comercial
Membresías, créditos, proyectos y regalo — visible en index#planes-paquetes
Solo el superadmin puede editar precios y paquetes. Puedes ver el catálogo en modo lectura.
{{ errorCatalogoAdmin }}
Cargando catálogo…
| Orden | ID | Nombre | Precio | Detalle | Marketing | Activo | Popular | Acciones |
|---|---|---|---|---|---|---|---|---|
| Sin ítems en esta categoría | ||||||||
| {{ item.id }} | {{ item.nombre }} | {{ formatMoneda(item.precio || 0) }} | {{ catalogoDetalleItem(item) }} | {{ item.marketing || '—' }} | ||||
Viene del calendario
Día: {{ formatearFechaCorta(retornoCalendario.calDiaSeleccionado) }}
Reservas
Actualizado: {{ ultimaActualizacion }}Gestión de pagos
Más recientes primero. Revisa folios duplicados y totales antes de confirmar la reservación.
El cliente puede subir comprobante en Consultar reserva (folio + teléfono); al subirlo, la solicitud pasa a revisión de pago automáticamente.
{{ errorGestionPagos }}
Cargando…
No hay reservas en gestión para el filtro «{{ filtroReservaChip }}».
{{ gp.cliente }} · {{ gp.salaNombre }}
{{ gp.fecha }} · {{ gp.hora_inicio }}–{{ gp.hora_fin }}
Folio pago: {{ gp.folio_pago || '—' }} · Res: {{ gp.folio_reservacion || '—' }}
WhatsApp: {{ gp.telefono }}
Sin teléfono registrado
{{ formatMoneda(gp.total) }} (esperado {{ formatMoneda(gp.total_esperado) }})
CRM — Ficha de cliente
{{ errorCrm }}
Confirmadas
{{ fichaCliente.stats.confirmadas }}
Canceladas
{{ fichaCliente.stats.canceladas }}
Rechazadas
{{ fichaCliente.stats.rechazadas }}
Gastado
{{ formatMoneda(fichaCliente.stats.gastado) }}
Paquete / créditos
Reservas recurrentes
- {{ rc.nombre_cliente }} · día {{ rc.dia_semana }} · {{ formatHoraAdmin(rc.hora_inicio) }}–{{ formatHoraAdmin(rc.hora_fin) }}
Nueva reserva recurrente
Historial consumos paquete
- {{ c.horas }} h · reserva #{{ c.reserva_id }} · {{ formatearFechaHoraUnix(c.creado_en) }}
Referidos venue B2B (8% comisión)
Escuelas, aliados y venues. Comparte el link con ?venue=VENUE-XXXXXX en index.html.
Nuevo código: {{ venueNuevoCodigo }} {{ venueLinkNuevo }}
| Venue | Código | Reservas | Comisión acum. |
|---|---|---|---|
| {{ v.venue_nombre }} | {{ v.codigo }} | {{ v.reservas_count }} | {{ formatMoneda(v.comision_acum) }} |
Sin venues registrados.
Historial de reservas
Reservas ya procesadas (confirmadas, rechazadas, canceladas o no-show). Toca una solicitud en gestión de pagos para ver el historial de ese teléfono.
{{ gestionClienteContexto.cliente }}
{{ gestionClienteContexto.telefono || 'Sin teléfono' }}
Cliente nuevo Cliente recurrente · {{ gestionClienteContexto.stats.confirmadas }} confirmada(s) {{ gestionClienteContexto.stats.total_reservas }} reserva(s) en total
Mostrando {{ reservas.length }} de {{ historialTotal }}
{{ errorReservas }}
No hay reservas en el historial para «{{ filtroReservaChip }}»
{{ reserva.cliente }}
{{ reserva.estado }}Folio: {{ reserva.folio_reservacion }}
WhatsApp: {{ reserva.telefono }}
Sala: {{ reserva.salaNombre }}
Fecha: {{ reserva.fecha }} · {{ reserva.hora_inicio }}–{{ reserva.hora_fin }}
Ediciones cliente: {{ reserva.ediciones_cliente ?? 0 }}/3
{{ formatMoneda(reserva.total) }}
| Artista-Banda | Contacto | Folio-Reservacion | Sala | Fecha/Hora | Total | Estado | Acciones |
|---|---|---|---|---|---|---|---|
| No hay reservas en el historial | |||||||
|
{{ reserva.cliente }} |
{{ reserva.telefono }} — | {{ reserva.folio_reservacion || '—' }} | {{ reserva.salaNombre }} | {{ reserva.fecha }} {{ reserva.hora_inicio }} - {{ reserva.hora_fin }} | {{ formatMoneda(reserva.total) }} | {{ reserva.estado }} | |
Calendario de ocupación
{{ calNombreMes }}
{{ calDiaSeleccionado ? formatearFechaCorta(calDiaSeleccionado) : 'Selecciona un día' }}
Estado: {{ calDiaInfo.estado }} · {{ calDiaInfo.motivo }}
Timeline del día
Lista de espera
Clientes que pidieron aviso cuando se libere un horario.
{{ listaEspera.error }}
Cargando…
Sin entradas activas.
-
{{ le.nombre_cliente }} · {{ le.fecha }}
{{ le.salaNombre }} · {{ le.telefono }} · {{ le.estado }}
Recordatorios pre-sesión
Sesiones confirmadas para la fecha seleccionada (por defecto: mañana).
{{ recordatorios.error }}
Cargando…
No hay sesiones confirmadas para esa fecha.
-
Enviar WhatsApp
{{ rec.cliente }} · {{ rec.salaNombre }}
{{ formatHoraAdmin(rec.hora_inicio) }}–{{ formatHoraAdmin(rec.hora_fin) }}
Historial cron (últimas ejecuciones)
Cargando…
- {{ formatearFechaHoraUnix(log.creado_en) }} · {{ log.fecha_objetivo }} · {{ log.total_sesiones }} sesión(es) · {{ log.origen }}
Sin ejecuciones registradas. Usa ./cron_recordatorios.sh en crontab.
Horarios por Sala
El horario aplica a todo el estudio (todas las salas comparten el mismo espacio).
{{ sala.nombre }}
{{ diasSemana[dia] }}
Cerrado
Fechas Bloqueadas
{{ errorFechas }}
No hay fechas bloqueadas
{{ fecha.fecha }}
{{ etiquetaTipoBloqueo(fecha) }}{{ fecha.motivo }}
| Fecha | Motivo | Tipo | Acciones |
|---|---|---|---|
| No hay fechas bloqueadas | |||
| {{ fecha.fecha }} | {{ fecha.motivo }} | {{ etiquetaTipoBloqueo(fecha) }} | |
Auditoría
-
{{ log.accion }}
{{ log.detalle }}
{{ log.admin_usuario }} · {{ formatearFechaHoraUnix(log.creado_en) }}
Configuración del sitio
Visible en la página pública de reservasEstos datos aparecen en el carrito cuando el artista o banda va a pagar, y el WhatsApp se usa al confirmar la reserva.
{{ errorConfigSitio }}
Reglas, ubicación y pagos
Mercado Pago
Checkout activo Token OK · falta activar Sin configurarCredenciales en developers.mercadopago.com → tu app → Credenciales de prueba (sandbox).
Webhook (pegar en MP → Webhooks → Pagos):
{{ reglasSitio.mp_webhook_url || '—' }}
Producción: define SITE_URL=https://tu-dominio.com en el servidor para que el webhook use la URL pública correcta.
Firma webhook: variable MERCADOPAGO_WEBHOOK_SECRET (clave en MP → Webhooks). Modo actual: {{ reglasSitio.mp_webhook_modo || 'warn_only' }}. Con MERCADOPAGO_WEBHOOK_STRICT=1 se rechazan webhooks sin secret.
SMTP: {{ saludSistema.smtp_configurado ? 'OK' : 'No' }} · WA: {{ saludSistema.whatsapp_configurado ? 'OK' : 'No' }} · WAL: {{ saludSistema.wal_mode || '—' }}
BD: {{ saludSistema.db_size_bytes ? Math.round(saludSistema.db_size_bytes/1024) + ' KB' : '—' }} · Webhook: {{ saludSistema.webhook_configurado ? 'Sí' : 'No' }}
Seguridad: SITE_URL {{ saludSistema.site_url_configurada ? '✓' : '✗' }} · APP_SECRET {{ saludSistema.app_secret_configurada ? '✓' : '✗' }} · MP webhook secret {{ saludSistema.mp_webhook_secret_configurada ? '✓' : '✗' }} ({{ saludSistema.mp_webhook_modo || 'warn_only' }})
Cron sugerido: php api/backup_db.php y php api/generar_reservas_recurrentes.php --semanas=2
- {{ cr.nombre }} · {{ formatearFechaHoraUnix(cr.creado_en) }}
Cupones de descuento
- {{ cp.codigo }} {{ cp.tipo === 'fijo' ? '$' + cp.valor : cp.valor + '%' }} · {{ cp.usos_actuales }}/{{ cp.usos_max || '∞' }}
Administradores
- {{ ad.usuario }} · {{ ad.rol }}
White-label (marca)
Muro «Grabaron aquí»
- {{ m.artista }} — {{ m.quote?.slice(0,40) }}
Open mic — curación
- {{ om.participante }} · {{ om.fecha }} · {{ om.estado }} Demo
Reportes de Ingresos
Cargando reporte…
{{ reportes.error }}
Conversión del mes
Tasa confirmación: {{ reportes.datos.conversion.tasa_confirmacion_porc != null ? reportes.datos.conversion.tasa_confirmacion_porc + '%' : '—' }}
Pendientes
{{ reportes.datos.conversion.pendientes }}
Confirmadas
{{ reportes.datos.conversion.confirmados }}
Rechazadas
{{ reportes.datos.conversion.rechazados }}
Canceladas
{{ reportes.datos.conversion.cancelados }}
Ingresos
{{ formatMoneda(reportes.datos.total_general.ingresos) }}
Ocupación por franja horaria
Reservas confirmadas vs capacidad estimada (salas × días operativos)
Sin datos
| Franja | Reservas | Cap. est. | Ocupación |
|---|---|---|---|
| Sin datos | |||
| {{ f.franja }} | {{ f.reservas }} | {{ f.capacidad_estimada }} | {{ f.ocupacion_porc }}% |
Ingresos por Día
Sin datos
{{ formatMoneda(fila.ingresos) }}
{{ fila.reservas }} res.
| Fecha | Ingreso | Reservas |
|---|---|---|
| Sin datos | ||
| {{ formatearFechaCorta(fila.fecha) }} | {{ formatMoneda(fila.ingresos) }} | {{ fila.reservas }} |
| Total | {{ formatMoneda(reportes.datos.por_dia.reduce((s,f) => s + f.ingresos, 0)) }} | {{ reportes.datos.por_dia.reduce((s,f) => s + f.reservas, 0) }} |
Top 10 Artistas-Bandas
Sin datos
{{ cliente.cliente }}
{{ cliente.telefono }}
| Artista-Banda | Reservas | Gastado |
|---|---|---|
| Sin datos | ||
|
{{ cliente.cliente }} {{ cliente.telefono }} |
{{ cliente.reservas }} | {{ formatMoneda(cliente.gastado) }} |
Día de la semana y no-shows
Reservas confirmadas por día
No-shows (cancelados + rechazados)
{{ reportes.datos.no_shows ?? 0 }}
Tasa no-show: {{ reportes.datos.tasa_no_show }}%
Embudo de conversión
Visitas
{{ reportes.datos.funnel.vista_index || 0 }}
Carrito
{{ reportes.datos.funnel.carrito_add || 0 }}
Reservas
{{ reportes.datos.funnel.reserva_creada || 0 }}
Comprobantes
{{ reportes.datos.funnel.comprobante_subido || 0 }}
Confirmadas
{{ reportes.datos.funnel.reserva_confirmada || 0 }}
Conv. reserva
{{ reportes.datos.funnel.conversion_reserva || 0 }}%
Días con baja ocupación (≤2 sesiones)
Clientes recurrentes (2+ sesiones)
Sin datos
{{ c.cliente }}
{{ c.telefono }}
{{ c.sesiones }} ses.
{{ formatMoneda(c.gastado) }}
Heatmap demanda (Round 15)
Sugerencias precio:
- Día {{ s.dow }} h{{ s.hora }} → {{ s.accion }} ({{ s.motivo }})
Sin datos o pulsa Actualizar
Pro R127–136 (Mobile-first · 520 total)
Mantenimiento salas
- {{ m.fecha }} · {{ m.salaNombre }} · {{ m.hora_inicio }}–{{ m.hora_fin }}h · {{ m.motivo }}
Pro R19
Google Calendar sync
No-show auto · grace {{ configR19.no_show_grace_min }}min · fee {{ configR19.no_show_fee_pct }}%
Pro R21
Revisiones · Mastering · Paquetes pro
Paquetes: Catálogo comercial · Vista index · Pase: pase.html
Pro R22–R25
- #{{ c.id }} {{ c.rfc_cfdi }}
Depósito daños
Proyección: ${{ forecastOps.ingreso_proyectado }}
MP ${{ conciliacionOps.mercadopago }} · Diff ${{ conciliacionOps.diferencia }}
Riesgo {{ churnOps.riesgo }} ({{ churnOps.churn_score }})
Pro R32 (Fase 9–12)
- {{ g.codigo_qr }} · {{ g.nombre }} · {{ g.estado }}
Upsell check-in
Tenant sede
{{ tenantSedeInfo.nombre }} · {{ tenantSedeInfo.salas_count }} salas
Pro R33–38 (Fase 13–18)
LTV ${{ rentScore.ltv }} · score {{ rentScore.score }}
Status pagePro R117–126 (Fase 97–106 · 470 total)
Pro R103–116 (Fase 83–96 · 420 total)
Pro R93–102 (Fase 73–82)
Pro R81–92 (Fase 61–72)
Pro R73–80 (Fase 53–60)
Pro R65–72 (Fase 45–52)
Pro R57–64 (Fase 37–44)
Pro R47–56 (Fase 27–36)
Pro R39–46 (Fase 19–26)
Pro R26–R30
Integraciones (R26–30)
Sedes
Equipos
Labels B2B
{{ margenOps.salas?.length || 0 }} salas