/** * Café Bach Email Generator - Form Handling & Preview Logic */ document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('emailForm'); const previewBtn = document.getElementById('previewBtn'); const descCount = document.getElementById('desc-count'); const descriptionField = document.getElementById('description'); // Character counter for description field if (descriptionField && descCount) { descriptionField.addEventListener('input', function() { const currentLength = this.value.length; const maxLength = this.maxLength; descCount.textContent = `${currentLength}/${maxLength}`; if (currentLength > maxLength * 0.9) { descCount.style.color = '#e74c3c'; } else { descCount.style.color = '#95a5a6'; } }); } // Form submission handler if (form) { form.addEventListener('submit', async function(e) { e.preventDefault(); if (validateForm()) { const formData = getFormData(); await submitFormData(formData); } }); } // Preview button handler if (previewBtn) { previewBtn.addEventListener('click', function() { if (validateForm()) { const formData = getFormData(); showPreview(formData); } }); } // Clear form handler const clearBtn = document.querySelector('button[type="reset"]'); if (clearBtn) { clearBtn.addEventListener('click', function() { resetForm(); }); } // Real-time validation on blur const inputs = form ? form.querySelectorAll('input, textarea') : []; inputs.forEach(input => { input.addEventListener('blur', function() { validateField(this); }); }); // Real-time validation on input inputs.forEach(input => { if (input.required) { input.addEventListener('input', function() { if (this.classList.contains('error')) { validateField(this); } }); } }); }); /** * Validate the entire form */ function validateForm() { const form = document.getElementById('emailForm'); const inputs = form.querySelectorAll('input[required], textarea[required]'); let isValid = true; inputs.forEach(input => { if (!validateField(input)) { isValid = false; } }); // Validate URLs if provided const urlFields = ['image_url', 'button_url', 'next_event_url']; urlFields.forEach(fieldName => { const field = document.getElementById(fieldName); if (field && field.value && !isValidUrl(field.value)) { showError(fieldName, 'Please enter a valid URL'); isValid = false; } }); return isValid; } /** * Validate a single field */ function validateField(field) { const fieldName = field.id; const value = field.value.trim(); // Clear previous error clearError(fieldName); // Required field check if (field.required && !value) { showError(fieldName, 'This field is required'); field.classList.add('error'); return false; } // Length validation if (value && field.maxLength) { if (value.length > field.maxLength) { showError(fieldName, `Must be less than ${field.maxLength} characters`); field.classList.add('error'); return false; } } field.classList.remove('error'); return true; } /** * Show error message for a field */ function showError(fieldName, message) { const errorElement = document.getElementById(`${fieldName}-error`); if (errorElement) { errorElement.textContent = message; } } /** * Clear error message for a field */ function clearError(fieldName) { const errorElement = document.getElementById(`${fieldName}-error`); if (errorElement) { errorElement.textContent = ''; } } /** * Validate URL format */ function isValidUrl(string) { try { new URL(string); return true; } catch (_) { return false; } } /** * Get form data as object */ function getFormData() { const form = document.getElementById('emailForm'); const formData = new FormData(form); const data = {}; for (let [key, value] of formData.entries()) { data[key] = value; } // Convert to JSON string for display data.jsonString = JSON.stringify(data, null, 2); return data; } /** * Submit form data to backend */ async function submitFormData(data) { try { const response = await fetch('/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (response.ok) { const result = await response.json(); console.log('Form submitted successfully:', result); alert('Email generated successfully!'); } else { console.error('Submission failed'); alert('Failed to generate email. Please try again.'); } } catch (error) { console.error('Submission error:', error); alert('Network error. Please check your connection and try again.'); } } /** * Show preview of email */ function showPreview(data) { const previewContainer = document.getElementById('emailPreview'); // Format date for display let formattedDate = ''; if (data.date_time) { const date = new Date(data.date_time); formattedDate = date.toLocaleString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } // Build HTML preview const previewHTML = `

${escapeHtml(data.title)}

${data.image_url ? `Event Image` : ''}
📅 Date & Time

${formattedDate || escapeHtml(data.date_time)}

📍 Location

${escapeHtml(data.location)}

📝 Description

${escapeHtml(data.description)}

${escapeHtml(data.button_text)} ${data.next_event_text ? `

Next Event: ${escapeHtml(data.next_event_text)}

${data.next_event_url ? `Learn More` : ''}
` : ''}
`; previewContainer.innerHTML = previewHTML; // Scroll to preview previewContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); } /** * Reset form to initial state */ function resetForm() { const form = document.getElementById('emailForm'); form.reset(); // Clear all error messages const errorMessages = document.querySelectorAll('.error-message'); errorMessages.forEach(el => el.textContent = ''); // Remove error classes const inputs = form.querySelectorAll('input, textarea'); inputs.forEach(input => input.classList.remove('error')); // Reset character counter const descCount = document.getElementById('desc-count'); if (descCount) { descCount.textContent = '0/2000'; descCount.style.color = '#95a5a6'; } } /** * Escape HTML to prevent XSS */ function escapeHtml(text) { if (!text) return ''; const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } /** * Copy to clipboard functionality */ function copyToClipboard() { const previewContent = document.getElementById('emailPreview').innerHTML; navigator.clipboard.writeText(previewContent).then(() => { const btn = document.getElementById('copyBtn'); if (btn) { btn.textContent = '✓ Copied to Clipboard!'; setTimeout(() => { btn.textContent = 'Copy HTML to Clipboard'; }, 2000); } }).catch(err => { console.error('Failed to copy:', err); alert('Failed to copy to clipboard. Please select and copy manually.'); }); } // Export functions for global access window.copyToClipboard = copyToClipboard;