/** * Migration: Update appointment email templates with modern styling * * Updates all appointment-related email templates across all languages to use * the same modern visual design as ticket notification templates (gradient header, * proper table layout, styled footer). * * Languages: en, de, es, fr, it, nl * Templates: appointment-request-received, appointment-request-approved, * appointment-request-declined, new-appointment-request */ // Template translations for each language const translations = { en: { requestReceived: { subject: 'Appointment Request Received - {{serviceName}}', header: 'Appointment Request Received', greeting: 'Hello{{#if requesterName}} {{requesterName}}{{/if}}, thank you for submitting your appointment request. We have received your request and our team will review it shortly.', refLabel: 'Ref', serviceLabel: 'Service', requestedDateLabel: 'Requested Date', requestedTimeLabel: 'Requested Time', durationLabel: 'Duration', durationUnit: 'minutes', whatNextTitle: 'What happens next?', whatNextText: 'Our team will review your request and confirm availability. You will receive an email notification once your appointment has been approved or if any changes are needed. We typically respond within {{responseTime}}.', contactText: 'If you have any questions, please contact us at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}.', viewPortalButton: 'View in Portal' }, requestApproved: { subject: 'Appointment Confirmed - {{serviceName}} on {{appointmentDate}}', header: 'Appointment Confirmed', greeting: 'Hello{{#if requesterName}} {{requesterName}}{{/if}}, great news! Your appointment request has been approved.', confirmedBadge: 'Confirmed', serviceLabel: 'Service', dateLabel: 'Date', timeLabel: 'Time', durationLabel: 'Duration', durationUnit: 'minutes', technicianLabel: 'Technician', importantTitle: 'Important Information', importantText: 'Please arrive a few minutes early. If you need to reschedule or cancel, please give us at least {{minimumNoticeHours}} hours notice.', addCalendarButton: 'Add to Calendar', contactText: 'Questions? Contact us at {{contactEmail}}{{#if contactPhone}} or {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Appointment Request Update - {{serviceName}}', header: 'Appointment Request Update', greeting: 'Hello{{#if requesterName}} {{requesterName}}{{/if}}, unfortunately we were unable to accommodate your appointment request at the requested time.', declinedBadge: 'Unable to Schedule', serviceLabel: 'Service', requestedDateLabel: 'Requested Date', requestedTimeLabel: 'Requested Time', reasonTitle: 'Reason', apologyText: 'We apologize for any inconvenience. Please feel free to submit a new request for a different time.', newRequestButton: 'Request New Appointment', contactText: 'Questions? Contact us at {{contactEmail}}{{#if contactPhone}} or {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'New Appointment Request - {{serviceName}} from {{requesterName}}', header: 'New Appointment Request', greeting: 'A new appointment request has been submitted{{#if clientName}} for {{clientName}}{{/if}}. Please review and take appropriate action.', greetingText: 'A new appointment request has been submitted{{#if clientName}} for {{clientName}}{{/if}}. Please review and take appropriate action.', pendingBadge: 'Pending Review', requesterLabel: 'Requester', companyLabel: 'Company', serviceLabel: 'Service', requestedDateLabel: 'Requested Date', requestedTimeLabel: 'Requested Time', durationLabel: 'Duration', durationUnit: 'minutes', preferredTechLabel: 'Preferred Technician', notesTitle: 'Additional Notes', actionText: 'Please review this request and take appropriate action. The requester is waiting for confirmation.', reviewButton: 'Review & Approve' }, footer: 'Powered by Alga PSA' }, de: { requestReceived: { subject: 'Terminanfrage eingegangen - {{serviceName}}', header: 'Terminanfrage eingegangen', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, vielen Dank für Ihre Terminanfrage. Wir haben Ihre Anfrage erhalten und unser Team wird sie in Kürze prüfen.', refLabel: 'Ref', serviceLabel: 'Service', requestedDateLabel: 'Gewünschtes Datum', requestedTimeLabel: 'Gewünschte Uhrzeit', durationLabel: 'Dauer', durationUnit: 'Minuten', whatNextTitle: 'Was passiert als Nächstes?', whatNextText: 'Unser Team wird Ihre Anfrage prüfen und die Verfügbarkeit bestätigen. Sie erhalten eine E-Mail-Benachrichtigung, sobald Ihr Termin genehmigt wurde oder falls Änderungen erforderlich sind. Wir antworten normalerweise innerhalb von {{responseTime}}.', contactText: 'Bei Fragen kontaktieren Sie uns bitte unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie {{contactPhone}} an{{/if}}.', viewPortalButton: 'Im Portal anzeigen' }, requestApproved: { subject: 'Termin bestätigt - {{serviceName}} am {{appointmentDate}}', header: 'Termin bestätigt', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, gute Nachrichten! Ihre Terminanfrage wurde genehmigt.', confirmedBadge: 'Bestätigt', serviceLabel: 'Service', dateLabel: 'Datum', timeLabel: 'Uhrzeit', durationLabel: 'Dauer', durationUnit: 'Minuten', technicianLabel: 'Techniker', importantTitle: 'Wichtige Informationen', importantText: 'Bitte erscheinen Sie einige Minuten früher. Wenn Sie umbuchen oder stornieren müssen, geben Sie uns bitte mindestens {{minimumNoticeHours}} Stunden Vorlaufzeit.', addCalendarButton: 'Zum Kalender hinzufügen', contactText: 'Fragen? Kontaktieren Sie uns unter {{contactEmail}}{{#if contactPhone}} oder {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Update zur Terminanfrage - {{serviceName}}', header: 'Update zur Terminanfrage', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, leider konnten wir Ihre Terminanfrage zum gewünschten Zeitpunkt nicht berücksichtigen.', declinedBadge: 'Nicht möglich', serviceLabel: 'Service', requestedDateLabel: 'Gewünschtes Datum', requestedTimeLabel: 'Gewünschte Uhrzeit', reasonTitle: 'Grund', apologyText: 'Wir entschuldigen uns für etwaige Unannehmlichkeiten. Sie können gerne eine neue Anfrage für einen anderen Zeitpunkt einreichen.', newRequestButton: 'Neuen Termin anfragen', contactText: 'Fragen? Kontaktieren Sie uns unter {{contactEmail}}{{#if contactPhone}} oder {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'Neue Terminanfrage - {{serviceName}} von {{requesterName}}', header: 'Neue Terminanfrage', greeting: 'Eine neue Terminanfrage wurde eingereicht{{#if clientName}} für {{clientName}}{{/if}}. Bitte prüfen und entsprechend handeln.', greetingText: 'Eine neue Terminanfrage wurde eingereicht{{#if clientName}} für {{clientName}}{{/if}}. Bitte prüfen und entsprechend handeln.', pendingBadge: 'Prüfung ausstehend', requesterLabel: 'Anfragender', companyLabel: 'Unternehmen', serviceLabel: 'Service', requestedDateLabel: 'Gewünschtes Datum', requestedTimeLabel: 'Gewünschte Uhrzeit', durationLabel: 'Dauer', durationUnit: 'Minuten', preferredTechLabel: 'Bevorzugter Techniker', notesTitle: 'Zusätzliche Anmerkungen', actionText: 'Bitte prüfen Sie diese Anfrage und handeln Sie entsprechend. Der Anfragende wartet auf eine Bestätigung.', reviewButton: 'Prüfen & Genehmigen' }, footer: 'Powered by Alga PSA' }, es: { requestReceived: { subject: 'Solicitud de cita recibida - {{serviceName}}', header: 'Solicitud de cita recibida', greeting: 'Hola{{#if requesterName}} {{requesterName}}{{/if}}, gracias por enviar su solicitud de cita. Hemos recibido su solicitud y nuestro equipo la revisará en breve.', refLabel: 'Ref', serviceLabel: 'Servicio', requestedDateLabel: 'Fecha solicitada', requestedTimeLabel: 'Hora solicitada', durationLabel: 'Duración', durationUnit: 'minutos', whatNextTitle: '¿Qué sigue?', whatNextText: 'Nuestro equipo revisará su solicitud y confirmará la disponibilidad. Recibirá una notificación por correo electrónico una vez que su cita haya sido aprobada o si se necesitan cambios. Normalmente respondemos dentro de {{responseTime}}.', contactText: 'Si tiene alguna pregunta, contáctenos en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.', viewPortalButton: 'Ver en el Portal' }, requestApproved: { subject: 'Cita confirmada - {{serviceName}} el {{appointmentDate}}', header: 'Cita confirmada', greeting: 'Hola{{#if requesterName}} {{requesterName}}{{/if}}, ¡buenas noticias! Su solicitud de cita ha sido aprobada.', confirmedBadge: 'Confirmada', serviceLabel: 'Servicio', dateLabel: 'Fecha', timeLabel: 'Hora', durationLabel: 'Duración', durationUnit: 'minutos', technicianLabel: 'Técnico', importantTitle: 'Información importante', importantText: 'Por favor llegue unos minutos antes. Si necesita reprogramar o cancelar, avísenos con al menos {{minimumNoticeHours}} horas de anticipación.', addCalendarButton: 'Agregar al calendario', contactText: '¿Preguntas? Contáctenos en {{contactEmail}}{{#if contactPhone}} o {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Actualización de solicitud de cita - {{serviceName}}', header: 'Actualización de solicitud de cita', greeting: 'Hola{{#if requesterName}} {{requesterName}}{{/if}}, lamentablemente no pudimos acomodar su solicitud de cita en el horario solicitado.', declinedBadge: 'No disponible', serviceLabel: 'Servicio', requestedDateLabel: 'Fecha solicitada', requestedTimeLabel: 'Hora solicitada', reasonTitle: 'Motivo', apologyText: 'Nos disculpamos por cualquier inconveniente. No dude en enviar una nueva solicitud para un horario diferente.', newRequestButton: 'Solicitar nueva cita', contactText: '¿Preguntas? Contáctenos en {{contactEmail}}{{#if contactPhone}} o {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'Nueva solicitud de cita - {{serviceName}} de {{requesterName}}', header: 'Nueva solicitud de cita', greeting: 'Se ha enviado una nueva solicitud de cita{{#if clientName}} para {{clientName}}{{/if}}. Por favor revise y tome las medidas apropiadas.', greetingText: 'Se ha enviado una nueva solicitud de cita{{#if clientName}} para {{clientName}}{{/if}}. Por favor revise y tome las medidas apropiadas.', pendingBadge: 'Revisión pendiente', requesterLabel: 'Solicitante', companyLabel: 'Empresa', serviceLabel: 'Servicio', requestedDateLabel: 'Fecha solicitada', requestedTimeLabel: 'Hora solicitada', durationLabel: 'Duración', durationUnit: 'minutos', preferredTechLabel: 'Técnico preferido', notesTitle: 'Notas adicionales', actionText: 'Por favor revise esta solicitud y tome las medidas apropiadas. El solicitante está esperando confirmación.', reviewButton: 'Revisar y aprobar' }, footer: 'Powered by Alga PSA' }, fr: { requestReceived: { subject: 'Demande de rendez-vous reçue - {{serviceName}}', header: 'Demande de rendez-vous reçue', greeting: 'Bonjour{{#if requesterName}} {{requesterName}}{{/if}}, merci d\'avoir soumis votre demande de rendez-vous. Nous avons reçu votre demande et notre équipe l\'examinera sous peu.', refLabel: 'Réf', serviceLabel: 'Service', requestedDateLabel: 'Date demandée', requestedTimeLabel: 'Heure demandée', durationLabel: 'Durée', durationUnit: 'minutes', whatNextTitle: 'Quelle est la suite ?', whatNextText: 'Notre équipe examinera votre demande et confirmera la disponibilité. Vous recevrez une notification par e-mail une fois votre rendez-vous approuvé ou si des modifications sont nécessaires. Nous répondons généralement dans les {{responseTime}}.', contactText: 'Si vous avez des questions, contactez-nous à {{contactEmail}}{{#if contactPhone}} ou appelez le {{contactPhone}}{{/if}}.', viewPortalButton: 'Voir dans le portail' }, requestApproved: { subject: 'Rendez-vous confirmé - {{serviceName}} le {{appointmentDate}}', header: 'Rendez-vous confirmé', greeting: 'Bonjour{{#if requesterName}} {{requesterName}}{{/if}}, bonne nouvelle ! Votre demande de rendez-vous a été approuvée.', confirmedBadge: 'Confirmé', serviceLabel: 'Service', dateLabel: 'Date', timeLabel: 'Heure', durationLabel: 'Durée', durationUnit: 'minutes', technicianLabel: 'Technicien', importantTitle: 'Informations importantes', importantText: 'Veuillez arriver quelques minutes en avance. Si vous devez reporter ou annuler, veuillez nous prévenir au moins {{minimumNoticeHours}} heures à l\'avance.', addCalendarButton: 'Ajouter au calendrier', contactText: 'Questions ? Contactez-nous à {{contactEmail}}{{#if contactPhone}} ou {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Mise à jour de la demande de rendez-vous - {{serviceName}}', header: 'Mise à jour de la demande de rendez-vous', greeting: 'Bonjour{{#if requesterName}} {{requesterName}}{{/if}}, malheureusement nous n\'avons pas pu accommoder votre demande de rendez-vous à l\'heure demandée.', declinedBadge: 'Non disponible', serviceLabel: 'Service', requestedDateLabel: 'Date demandée', requestedTimeLabel: 'Heure demandée', reasonTitle: 'Raison', apologyText: 'Nous nous excusons pour tout inconvénient. N\'hésitez pas à soumettre une nouvelle demande pour un autre créneau.', newRequestButton: 'Demander un nouveau rendez-vous', contactText: 'Questions ? Contactez-nous à {{contactEmail}}{{#if contactPhone}} ou {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'Nouvelle demande de rendez-vous - {{serviceName}} de {{requesterName}}', header: 'Nouvelle demande de rendez-vous', greeting: 'Une nouvelle demande de rendez-vous a été soumise{{#if clientName}} pour {{clientName}}{{/if}}. Veuillez examiner et prendre les mesures appropriées.', greetingText: 'Une nouvelle demande de rendez-vous a été soumise{{#if clientName}} pour {{clientName}}{{/if}}. Veuillez examiner et prendre les mesures appropriées.', pendingBadge: 'En attente de révision', requesterLabel: 'Demandeur', companyLabel: 'Entreprise', serviceLabel: 'Service', requestedDateLabel: 'Date demandée', requestedTimeLabel: 'Heure demandée', durationLabel: 'Durée', durationUnit: 'minutes', preferredTechLabel: 'Technicien préféré', notesTitle: 'Notes supplémentaires', actionText: 'Veuillez examiner cette demande et prendre les mesures appropriées. Le demandeur attend une confirmation.', reviewButton: 'Examiner et approuver' }, footer: 'Powered by Alga PSA' }, it: { requestReceived: { subject: 'Richiesta appuntamento ricevuta - {{serviceName}}', header: 'Richiesta appuntamento ricevuta', greeting: 'Ciao{{#if requesterName}} {{requesterName}}{{/if}}, grazie per aver inviato la richiesta di appuntamento. Abbiamo ricevuto la tua richiesta e il nostro team la esaminerà a breve.', refLabel: 'Rif', serviceLabel: 'Servizio', requestedDateLabel: 'Data richiesta', requestedTimeLabel: 'Ora richiesta', durationLabel: 'Durata', durationUnit: 'minuti', whatNextTitle: 'Cosa succede dopo?', whatNextText: 'Il nostro team esaminerà la tua richiesta e confermerà la disponibilità. Riceverai una notifica via email una volta che il tuo appuntamento sarà approvato o se saranno necessarie modifiche. Di solito rispondiamo entro {{responseTime}}.', contactText: 'Per qualsiasi domanda, contattaci all\'indirizzo {{contactEmail}}{{#if contactPhone}} o chiama il {{contactPhone}}{{/if}}.', viewPortalButton: 'Visualizza nel portale' }, requestApproved: { subject: 'Appuntamento confermato - {{serviceName}} il {{appointmentDate}}', header: 'Appuntamento confermato', greeting: 'Ciao{{#if requesterName}} {{requesterName}}{{/if}}, ottime notizie! La tua richiesta di appuntamento è stata approvata.', confirmedBadge: 'Confermato', serviceLabel: 'Servizio', dateLabel: 'Data', timeLabel: 'Ora', durationLabel: 'Durata', durationUnit: 'minuti', technicianLabel: 'Tecnico', importantTitle: 'Informazioni importanti', importantText: 'Per favore arriva qualche minuto prima. Se hai bisogno di riprogrammare o cancellare, avvisaci con almeno {{minimumNoticeHours}} ore di anticipo.', addCalendarButton: 'Aggiungi al calendario', contactText: 'Domande? Contattaci a {{contactEmail}}{{#if contactPhone}} o {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Aggiornamento richiesta appuntamento - {{serviceName}}', header: 'Aggiornamento richiesta appuntamento', greeting: 'Ciao{{#if requesterName}} {{requesterName}}{{/if}}, purtroppo non siamo riusciti ad accogliere la tua richiesta di appuntamento all\'orario richiesto.', declinedBadge: 'Non disponibile', serviceLabel: 'Servizio', requestedDateLabel: 'Data richiesta', requestedTimeLabel: 'Ora richiesta', reasonTitle: 'Motivo', apologyText: 'Ci scusiamo per l\'inconveniente. Sentiti libero di inviare una nuova richiesta per un orario diverso.', newRequestButton: 'Richiedi nuovo appuntamento', contactText: 'Domande? Contattaci a {{contactEmail}}{{#if contactPhone}} o {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'Nuova richiesta appuntamento - {{serviceName}} da {{requesterName}}', header: 'Nuova richiesta appuntamento', greeting: 'È stata inviata una nuova richiesta di appuntamento{{#if clientName}} per {{clientName}}{{/if}}. Per favore esamina e agisci di conseguenza.', greetingText: 'È stata inviata una nuova richiesta di appuntamento{{#if clientName}} per {{clientName}}{{/if}}. Per favore esamina e agisci di conseguenza.', pendingBadge: 'In attesa di revisione', requesterLabel: 'Richiedente', companyLabel: 'Azienda', serviceLabel: 'Servizio', requestedDateLabel: 'Data richiesta', requestedTimeLabel: 'Ora richiesta', durationLabel: 'Durata', durationUnit: 'minuti', preferredTechLabel: 'Tecnico preferito', notesTitle: 'Note aggiuntive', actionText: 'Per favore esamina questa richiesta e agisci di conseguenza. Il richiedente è in attesa di conferma.', reviewButton: 'Esamina e approva' }, footer: 'Powered by Alga PSA' }, nl: { requestReceived: { subject: 'Afspraakverzoek ontvangen - {{serviceName}}', header: 'Afspraakverzoek ontvangen', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, bedankt voor het indienen van uw afspraakverzoek. We hebben uw verzoek ontvangen en ons team zal het spoedig bekijken.', refLabel: 'Ref', serviceLabel: 'Service', requestedDateLabel: 'Gewenste datum', requestedTimeLabel: 'Gewenste tijd', durationLabel: 'Duur', durationUnit: 'minuten', whatNextTitle: 'Wat gebeurt er nu?', whatNextText: 'Ons team zal uw verzoek bekijken en de beschikbaarheid bevestigen. U ontvangt een e-mailmelding zodra uw afspraak is goedgekeurd of als er wijzigingen nodig zijn. We reageren doorgaans binnen {{responseTime}}.', contactText: 'Heeft u vragen? Neem contact met ons op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.', viewPortalButton: 'Bekijken in portal' }, requestApproved: { subject: 'Afspraak bevestigd - {{serviceName}} op {{appointmentDate}}', header: 'Afspraak bevestigd', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, goed nieuws! Uw afspraakverzoek is goedgekeurd.', confirmedBadge: 'Bevestigd', serviceLabel: 'Service', dateLabel: 'Datum', timeLabel: 'Tijd', durationLabel: 'Duur', durationUnit: 'minuten', technicianLabel: 'Technicus', importantTitle: 'Belangrijke informatie', importantText: 'Kom alstublieft een paar minuten eerder. Als u moet verzetten of annuleren, geef ons dan minimaal {{minimumNoticeHours}} uur van tevoren door.', addCalendarButton: 'Toevoegen aan agenda', contactText: 'Vragen? Neem contact met ons op via {{contactEmail}}{{#if contactPhone}} of {{contactPhone}}{{/if}}.' }, requestDeclined: { subject: 'Update afspraakverzoek - {{serviceName}}', header: 'Update afspraakverzoek', greeting: 'Hallo{{#if requesterName}} {{requesterName}}{{/if}}, helaas konden we uw afspraakverzoek op het gewenste tijdstip niet accommoderen.', declinedBadge: 'Niet beschikbaar', serviceLabel: 'Service', requestedDateLabel: 'Gewenste datum', requestedTimeLabel: 'Gewenste tijd', reasonTitle: 'Reden', apologyText: 'Onze excuses voor het ongemak. U kunt gerust een nieuw verzoek indienen voor een ander tijdstip.', newRequestButton: 'Nieuwe afspraak aanvragen', contactText: 'Vragen? Neem contact met ons op via {{contactEmail}}{{#if contactPhone}} of {{contactPhone}}{{/if}}.' }, newRequest: { subject: 'Nieuw afspraakverzoek - {{serviceName}} van {{requesterName}}', header: 'Nieuw afspraakverzoek', greeting: 'Er is een nieuw afspraakverzoek ingediend{{#if clientName}} voor {{clientName}}{{/if}}. Bekijk dit en neem passende actie.', greetingText: 'Er is een nieuw afspraakverzoek ingediend{{#if clientName}} voor {{clientName}}{{/if}}. Bekijk dit en neem passende actie.', pendingBadge: 'Wacht op beoordeling', requesterLabel: 'Aanvrager', companyLabel: 'Bedrijf', serviceLabel: 'Service', requestedDateLabel: 'Gewenste datum', requestedTimeLabel: 'Gewenste tijd', durationLabel: 'Duur', durationUnit: 'minuten', preferredTechLabel: 'Voorkeurstechnicus', notesTitle: 'Aanvullende opmerkingen', actionText: 'Bekijk dit verzoek en neem passende actie. De aanvrager wacht op bevestiging.', reviewButton: 'Beoordelen en goedkeuren' }, footer: 'Powered by Alga PSA' } }; // Generate HTML for appointment-request-received function generateRequestReceivedHtml(t) { return `