Eventos del Widget

Callbacks y eventos para responder a las acciones del usuario y personalizar el flujo de reservas.

Introducción

El widget emite eventos en diferentes momentos del flujo de reservas. Puedes suscribirte a estos eventos mediante callbacks en la configuración inicial:

JavaScript
SalonBookIt.init({
    apiKey: 'hh_pub_live_...',
    container: '#widget',

    // Callbacks de eventos
    onReady: (business) => { /* ... */ },
    onStepChange: (step, data) => { /* ... */ },
    onServiceSelect: (service) => { /* ... */ },
    onBookingComplete: (booking) => { /* ... */ },
    onError: (error) => { /* ... */ }
});

Referencia de eventos

onReady

Se dispara cuando el widget ha cargado completamente y está listo para usarse.

Parámetros

Parámetro Tipo Descripción
business object Información del negocio cargado

Ejemplo

JavaScript
onReady: (business) => {
    console.log('Negocio:', business.nombre);
    console.log('Servicios disponibles:', business.servicios_count);

    // Actualizar UI externa
    document.querySelector('.loading').style.display = 'none';
}

Objeto business

JSON
{
    "id": "uuid-del-tenant",
    "nombre": "Mi Salon",
    "telefono": "+34612345678",
    "email": "info@misalon.com",
    "direccion": "Calle Principal 123",
    "logo_url": "https://...",
    "servicios_count": 12,
    "profesionales_count": 5,
    "moneda": "EUR",
    "simbolo_moneda": "€"
}

onStepChange

Se dispara cuando el usuario avanza o retrocede en el flujo de reservas.

Parámetros

Parámetro Tipo Descripción
step string Nombre del paso actual
data object Datos acumulados hasta el momento

Pasos disponibles

  • 'services' - Selección de servicios
  • 'staff' - Selección de profesional
  • 'datetime' - Selección de fecha y hora
  • 'customer' - Datos del cliente
  • 'payment' - Pago (si aplica)
  • 'confirmation' - Confirmación final

Ejemplo

JavaScript
onStepChange: (step, data) => {
    console.log('Paso actual:', step);

    // Analytics
    gtag('event', 'booking_step', {
        'step_name': step,
        'services_selected': data.services?.length || 0
    });

    // Actualizar breadcrumbs externos
    updateBreadcrumbs(step);
}

onServiceSelect

Se dispara cuando el usuario selecciona o deselecciona un servicio.

Parámetros

Parámetro Tipo Descripción
service object Servicio seleccionado
selected boolean Si fue seleccionado o deseleccionado
allSelected array Todos los servicios seleccionados actualmente

Ejemplo

JavaScript
onServiceSelect: (service, selected, allSelected) => {
    console.log(selected ? 'Añadido:' : 'Eliminado:', service.nombre);

    // Actualizar precio total en UI externa
    const total = allSelected.reduce((sum, s) => sum + s.precio, 0);
    document.querySelector('.total-price').textContent = `€${total}`;
}

onStaffSelect

Se dispara cuando el usuario selecciona un profesional.

Ejemplo

JavaScript
onStaffSelect: (staff) => {
    console.log('Profesional:', staff.nombre);
    // staff = { id, nombre, imagen_url, especialidades }
}

onDateSelect

Se dispara cuando el usuario selecciona una fecha y hora.

Ejemplo

JavaScript
onDateSelect: (datetime) => {
    console.log('Fecha:', datetime.fecha);  // '2024-01-20'
    console.log('Hora:', datetime.hora);    // '10:30'
}

onBookingComplete

Se dispara cuando la reserva se ha creado exitosamente (antes del pago si aplica).

Ejemplo

JavaScript
onBookingComplete: (booking) => {
    console.log('Reserva creada:', booking.id);

    // Analytics
    gtag('event', 'purchase', {
        'transaction_id': booking.id,
        'value': booking.total,
        'currency': 'EUR'
    });

    // Redirigir a página de confirmación
    window.location.href = `/reserva-confirmada/${booking.id}`;
}

Objeto booking

JSON
{
    "id": 12345,
    "codigo": "ABC123",
    "fecha": "2024-01-20",
    "hora_inicio": "10:30",
    "hora_fin": "11:00",
    "servicios": [
        { "id": 1, "nombre": "Corte clásico", "precio": 25.00 }
    ],
    "profesional": {
        "id": 5,
        "nombre": "Carlos Garcia"
    },
    "cliente": {
        "nombre": "Juan Perez",
        "email": "juan@email.com",
        "telefono": "+34612345678"
    },
    "total": 25.00,
    "estado": "confirmada",
    "pago_pendiente": true
}

onPaymentComplete

Se dispara cuando el pago se ha completado exitosamente.

Ejemplo

JavaScript
onPaymentComplete: (payment) => {
    console.log('Pago completado');
    console.log('ID:', payment.payment_intent_id);
    console.log('Monto:', payment.amount);

    // Mostrar mensaje de éxito
    showSuccessMessage('¡Pago recibido!');
}

onError

Se dispara cuando ocurre un error en cualquier punto del flujo.

Ejemplo

JavaScript
onError: (error) => {
    console.error('Error:', error.code, error.message);

    // Reportar a sistema de errores
    Sentry.captureException(error);

    // Mostrar mensaje al usuario
    if (error.code === 'SLOT_UNAVAILABLE') {
        alert('Lo sentimos, ese horario ya no está disponible.');
    }
}

Códigos de error comunes

Código Descripción
INVALID_API_KEY API Key inválida
NETWORK_ERROR Error de conexión
SLOT_UNAVAILABLE Horario ya no disponible
PAYMENT_FAILED Error en el pago
VALIDATION_ERROR Datos del formulario inválidos

onClose

Se dispara cuando el usuario cierra el widget (solo en modo modal).

Ejemplo

JavaScript
onClose: () => {
    console.log('Widget cerrado');

    // Preguntar si quiere guardar borrador
    if (hasUnsavedData()) {
        saveBookingDraft();
    }
}

Métodos del Widget

Además de los eventos, puedes controlar el widget programáticamente:

JavaScript
// Obtener referencia al widget
const widget = SalonBookIt.init({ ... });

// Abrir modal (solo en modo modal/button)
widget.open();

// Cerrar modal
widget.close();

// Ir a un paso específico
widget.goToStep('services');

// Reiniciar el widget
widget.reset();

// Destruir el widget
widget.destroy();