feat: horarios opcionales en reservas, calendarios en lunes y emails filtrados
- Reservas: campos opcionales start_time/end_time (migración 011, schema natur_reservas) + toggle en el modal y detección de solapamiento por horario cuando ambas reservas los tienen definidos. Permite encajar varios eventos el mismo día. - Calendario mensual y anual ahora empiezan en lunes; vista móvil incluida. - Celdas con varios eventos el mismo día se dividen en franjas horizontales mostrando el horario; las reservas multi-día siguen ocupando la celda completa. - Modal: reset de campos vacíos (client_name, fechas, factura) para evitar que el nombre de la última reserva se filtre al crear una nueva. - Emails: las modificaciones solo disparan correo cuando cambian fechas u horas; el correo a Teneriffa pasa a formato reducido (solo fechas + propiedad) mientras que Natur sigue recibiendo el detalle completo. Mantenimiento sin cambios. - CLAUDE.md con guía operativa (schema natur_reservas, stack, convenciones). - Scripts de preview/envío de emails para pruebas. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
43
apps/api/scripts/preview-teneriffa-email.mjs
Normal file
43
apps/api/scripts/preview-teneriffa-email.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
// Genera previews HTML del correo minimalista para Teneriffa
|
||||
// (las 2 reservas del 19 de mayo de Los Dragos).
|
||||
// Uso: node apps/api/scripts/preview-teneriffa-email.mjs
|
||||
|
||||
import { writeFileSync, mkdirSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const OUT_DIR = join(__dirname, '../preview-out');
|
||||
mkdirSync(OUT_DIR, { recursive: true });
|
||||
|
||||
function renderTeneriffaMinimal(actionLabel, dateRange, property, cancelled = false) {
|
||||
const accent = cancelled ? '#ef4444' : actionLabel === 'Nueva Reserva' ? '#3b82f6' : '#f59e0b';
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="es"><head><meta charset="UTF-8"></head>
|
||||
<body style="font-family:Arial,sans-serif;background:#f4f4f4;margin:0;padding:24px;">
|
||||
<div style="max-width:520px;margin:0 auto;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.08);">
|
||||
<div style="background:${accent};color:#fff;padding:20px 24px;">
|
||||
<p style="margin:0;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;opacity:0.85;font-weight:700;">${actionLabel}</p>
|
||||
</div>
|
||||
<div style="padding:24px;">
|
||||
<p style="margin:0 0 6px;font-size:11px;text-transform:uppercase;letter-spacing:0.06em;color:#9ca3af;font-weight:700;">Fechas</p>
|
||||
<p style="margin:0 0 18px;font-size:18px;font-weight:800;color:#111;">${dateRange}</p>
|
||||
<p style="margin:0 0 6px;font-size:11px;text-transform:uppercase;letter-spacing:0.06em;color:#9ca3af;font-weight:700;">Propiedad</p>
|
||||
<p style="margin:0;font-size:16px;font-weight:700;color:#111;">${property}</p>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>`;
|
||||
}
|
||||
|
||||
const dateRange = '19 may 2026 – 19 may 2026';
|
||||
const property = 'Los Dragos';
|
||||
|
||||
const f1 = join(OUT_DIR, 'teneriffa-email-19may-evento1.html');
|
||||
writeFileSync(f1, renderTeneriffaMinimal('Nueva Reserva', dateRange, property));
|
||||
console.log('→', f1);
|
||||
|
||||
const f2 = join(OUT_DIR, 'teneriffa-email-19may-evento2.html');
|
||||
writeFileSync(f2, renderTeneriffaMinimal('Nueva Reserva', dateRange, property));
|
||||
console.log('→', f2);
|
||||
|
||||
console.log('\nAbre los archivos en el navegador para ver cómo se renderiza el correo en Teneriffa.');
|
||||
Reference in New Issue
Block a user