Catálogo, Reservas y Estado del Huésped
La aplicación `@pamaconu/client` ofrece a los huéspedes del hotel una experiencia nativa móvil para explorar el catálogo de actividades, gestionar reservas de experiencias, configurar perfiles de usuario y comunicarse.
Arquitectura Técnica
Client está construido bajo una arquitectura modular y reactiva, desacoplada al 100% de infraestructuras de base de datos directas en el frontend como Firebase Client. Todas las interacciones pasan a través del API REST unificada.
Pilares del Framework
AuthContext.
tokens.css local. Además, el cliente utiliza sus propias primitivas visuales locales (@/components/ui) desacopladas de core para asegurar consistencia visual y soporte para branding por hotel.
Rutas y Flujos de la Aplicación
El App Router organiza las rutas principales en dos categorías: públicas (búsqueda y checkout sin registro previo) y privadas (historial, perfil del huésped y dashboard).
Redirección Raíz
Evalúa el estado y redirige de inmediato a /public/experiences usando un loader adaptativo mobile-first para optimizar el historial.
Catálogo de Actividades
Panel de exploración para huéspedes. Ofrece buscador predictivo, filtrado por categorías (Gastronomía, Bienestar, Aventura),
ordenación por precio o fecha de creación, y favoritos. Admite renderizado embebido con ?embed=true.
Checkout de Experiencias
Asistente de reserva en 3 pasos: (1) Selección de opción del catálogo y participantes (limitación dinámica por capacidad).
(2) Método de pago (Cargo a habitación room o Pago en mostrador counter) y comentarios.
(3) Revisión del resumen y envío.
Acceso de Huéspedes
Formulario de autenticación universal. Si un huésped anónimo inicia un checkout, la aplicación guarda el estado de la reserva
en sessionStorage, redirige al login y, una vez autenticado, completa automáticamente la reserva pendiente.
Panel de Control Privado
Área de clientes autenticados. Muestra reservas activas, solicitudes de tareas del hotel asignadas, historial completo y enlaces a configuración.
Configuración del Perfil
Permite al huésped actualizar sus datos personales (nombre, apellidos, idioma de comunicación, fecha de nacimiento, avatar) y preferencias.
Mis Solicitudes
Bandeja de entrada del huésped para solicitudes especiales. Permite ver el listado, abrir el formulario de nueva solicitud y cancelarlas de forma directa.
Detalle de Solicitud (Autenticado)
Espacio de seguimiento donde el usuario puede chatear en tiempo real con el equipo del hotel para concretar los detalles de su experiencia.
Detalle de Solicitud (Público)
Acceso sin credenciales protegido por token de seguridad. Ideal para huéspedes que realizaron peticiones rápidas y quieren chatear con el hotel.
Servicios e Integración con Backend
La capa de servicios en src/services/ actúa como el puente de red. Utiliza la clase ApiClient
de @pamaconu/core para configurar las cabeceras JWT y resolver las peticiones REST.
Catálogo de Servicios
| Servicio | Ruta Endpoint | Método | Descripción / Mapeos |
|---|---|---|---|
| AuthService | /auth/login/auth/register |
POST | Inicia sesión y crea cuentas asociando el rol client por defecto. Guarda la sesión JWT en LocalStorage. |
| ExperiencesService | /experiences/experiences/:id |
GET | Consulta de experiencias activas de manera pública. Mapea campos localizados de texto (ej. título en español o inglés). |
| ReservationService | /reservations/user/:userId/reservations/:id |
GET |
Mapea el esquema PostgreSQL del backend a la interfaz del frontend:
|
| ReservationService | /reservations/:id/cancel |
PATCH | Permite la cancelación inmediata de una reserva desde el panel del usuario por el motivo "Cancelado por el huésped". |
| UserService | /users/me |
GET PUT |
Consulta y actualización de perfil. Centraliza la estructura de preferencias en metadatos anidados en PostgreSQL. |
Flujo de Datos (Checkout con Autenticación Diferida)
El siguiente flujo muestra cómo interactúan los componentes cuando un huésped anónimo completa una pre-reserva:
2. Valida formulario localmente → ¿Sesión activa? NO → Guarda datos de reserva en sessionStorage('reserveData')
3. Redirección a /public/login → El usuario inicia sesión o se registra exitosamente
4. El AuthContext guarda el JWT → Redirección automática de vuelta a la experiencia con sesión activa
5. Recupera sessionStorage('reserveData') → Lanza POST a /api/reservas/pre (Proxy de Next.js)
6. El Proxy Next.js crea la reserva en Backend → Envía email de cortesía → Registra notificación de hotel
7. Éxito → Redirección a /public/reserve/[id]/confirmation
Branding y Tematización por Hotel
La aplicación del cliente está diseñada para presentarse de manera personalizada para cada hotel de forma dinámica.
Esto se logra a través del sistema de variables de entorno CSS cargadas en el DOM mediante el atributo
[data-theme].
Inyección Dinámica
El componente ClientHotelBranding lee el identificador del hotel desde los parámetros de búsqueda o la configuración de la experiencia.
Establece el atributo en el DOM raíz:
document.documentElement.dataset.theme = hotel.slug;
Herencia de Tokens
Los componentes visuales de la aplicación (Button, Card, Modal, Chip) utilizan las clases de utilidad de Tailwind que referencian
variables CSS HSL globales. Al activar el tema específico, solo cambian las variables del acento primario
(--accent y --accent-soft), mientras que las superficies y el contraste general se mantienen legibles.
Internacionalización (i18n)
Para soportar huéspedes internacionales, Client cuenta con una capa nativa de traducción:
- I18nProvider: Envuelve la aplicación cargando los diccionarios locales de forma perezosa.
- Idiomas Soportados: Español (
es), Inglés (en) y Catalán (ca). - Helper de Traducción de Catálogo: Dado que el catálogo del hotel almacena los campos descriptivos en objetos multilingües, el helper
getLocalizedTextextrae de manera segura la cadena adecuada según el idioma activo del cliente o un fallback genérico.
Mejoras y Refactorizaciones Recientes
Se han realizado varias optimizaciones clave tanto en la estructura de maquetación general como en la migración de páginas secundarias al sistema de diseño unificado:
Alineación del Dashboard (Desktop)
Se resolvió el apilamiento vertical y desalineación del menú lateral en pantallas grandes aplicando un contenedor lg:flex en el layout raíz de /dashboard.
Además, se eliminó el padding offset manual de lg:pl-64 y se reemplazó por un comportamiento de flujo natural con flex-1 min-w-0, garantizando que el contenido se centre y alinee de forma impecable con el menú.
Migración del Módulo de Solicitudes (Requests)
El flujo de solicitudes de experiencias especiales (vistas de listado, detalles, chat y formulario) fue migrado íntegramente a los componentes del sistema de diseño local (@/components/ui), eliminando importaciones visuales heredadas de core.
Los campos heredaron los tokens de color correctos (border-border, bg-surface y acentos locales) y se simplificaron las estructuras utilizando propiedades directas de Input.