2026-07-19 16:27:22 +02:00
2026-07-19 16:27:22 +02:00
2026-07-12 10:47:25 +02:00
2026-06-21 17:29:16 +02:00
2026-07-09 16:55:39 +02:00
2026-06-21 17:29:16 +02:00
2026-07-09 16:55:39 +02:00
2026-06-18 17:08:26 +02:00
2026-06-21 17:29:16 +02:00
2026-06-18 17:08:26 +02:00
2026-07-12 10:47:25 +02:00
2026-07-12 10:47:25 +02:00
2026-07-12 10:47:25 +02:00

MAY Studio — Landing Page + EasyAppointments

Landing page bonita para MAY Studio (Horta, Barcelona) con reservas gestionadas por EasyAppointments.

El frontend (HTML/JS puro) sigue siendo el de la landing, pero las reservas, clientes y servicios se gestionan completamente con EasyAppointments.

Stack actual

  • Web (estático): Go + proxy reverso a EasyAppointments API
  • Gestión de citas, clientes y servicios: EasyAppointments (PHP + MySQL)
  • Base de datos: MySQL (para EA)
  • Docker Compose: todo junto (web + easyappointments + mysql)

Cómo ejecutar (Desarrollo y Producción)

1. Configurar secretos

cp .env.example .env
# Edita .env: pon tu EA_API_KEY y una MYSQL_ROOT_PASSWORD fuerte.

.env está en .gitignore y nunca se sube al repositorio.

2. Levantar todo

docker compose up -d --build

3. Primer arranque (importante)

  1. Abre http://localhost:8888
  2. Completa el asistente de instalación de EasyAppointments.
  3. Crea un usuario administrador.
  4. Ve a Providers → crea al menos un proveedor (ej. "May").
  5. Ve a Services → crea tus servicios (puedes usar la lista anterior de servicios como referencia).
  6. Asigna los servicios al proveedor.
  7. Configura el Working Plan del proveedor (horario).
  8. Anota el ID del Provider (normalmente 1) y edita static/index.html → línea const PROVIDER_ID = 1;

Variables (en .env)

  • EA_API_KEY — token de API de EasyAppointments (Settings → API en el panel).
  • MYSQL_ROOT_PASSWORD — contraseña de la base de datos.
  • EA_BASE_URL — URL pública del panel de EA (cámbiala en producción).

Actualizar

git pull
docker compose up -d --build

Notas sobre la integración

EasyAppointments es la única fuente de verdad. El servidor Go no guarda nada: ni clientes, ni citas, ni servicios. Todo se lee y se escribe contra la API de EA.

  • Los servicios y la disponibilidad los lee el frontend de EA (a través del proxy de solo lectura).
  • El calendario deshabilita los días sin ningún hueco vía GET /api/month-availability (agregado server-side día a día contra EA, con caché de 10 min por mes+servicio).
  • Al reservar, el navegador envía la selección a POST /api/book y el servidor:
    • lee los servicios de EA (fuente de verdad de nombre y duración),
    • busca o crea el cliente por teléfono (identifica al cliente; el email es opcional),
    • crea una cita con el servicio de mayor duración y el bloque total en las notas.
  • La gestión completa (clientes, servicios, citas, proveedores, etc.) se hace desde http://localhost:8888

Seguridad del proxy

El servidor Go no expone la API de EasyAppointments tal cual:

  • El proxy /ea-api/ solo deja pasar lecturas no sensibles (categorías, servicios, proveedor, disponibilidad), añadiendo la auth admin en el servidor. La lista blanca está en main.go (eaAllowedRoutes); cualquier otra ruta/método recibe 404 antes de inyectar credenciales.
  • Las escrituras y la búsqueda de clientes no pasan por el proxy: se orquestan server-side en POST /api/book. Así el navegador nunca puede listar/borrar/modificar clientes ni citas, ni volcar datos personales de EA.

Comportamiento multiservicio

El formulario permite seleccionar varios servicios (multi-checkbox).

Cómo funciona actualmente con EasyAppointments:

  • UI: Puedes seleccionar múltiples servicios. Se muestra el resumen con nombres unidos por "+" y la duración total sumada.
  • Comprobación de disponibilidad: Se consulta el endpoint de EA usando el servicio de mayor duración de los seleccionados. Luego se filtra client-side para exigir un bloque contiguo de la duración total (suma de todos).
    • Ejemplo: servicios de 45min + 30min → total 75 min. Solo se ofrecen horas de inicio desde las que quepan 75 min seguidos sin solape.
  • Al crear la reserva:
    • Se crea una sola cita en EasyAppointments.
    • Se usa como serviceId el servicio de mayor duración (para que coincida con la disponibilidad consultada).
    • Se calcula la hora de fin sumando la duración total de todos los servicios seleccionados y se envía explícitamente el campo end. Así EA bloquea el tiempo completo en el calendario de la empleada.
    • Solo una empleada (May) por ahora → el bloque queda reservado y no se puede reservar otra cosa en ese intervalo.
    • En el campo notes se guarda el detalle completo:
      Nombre: ...
      Teléfono: ...
      Email: ...        (solo si el cliente lo dio)
      Servicios: Corte + Tinte + ...
      Duración total: 120 min
      Mensaje: ...
      

Limitación: EasyAppointments modela una cita = un servicio principal. Los servicios adicionales quedan documentados en las notas del cliente y de la cita. No se crean múltiples registros de cita.

Recomendación: Si usas combinaciones frecuentes, crea "servicios combinados" directamente en EasyAppointments (ej. "Corte + Tinte Señora - 120min").

S
Description
No description provided
Readme
1.7 MiB
Languages
HTML 41.3%
Go 41.2%
CSS 15.5%
Shell 1.7%
Dockerfile 0.3%