// Email Composer Module class EmailComposer { constructor() { this.modal = document.getElementById('email-modal'); this.previewModal = document.getElementById('email-preview-modal'); this.form = document.getElementById('email-form'); this.closeBtn = document.getElementById('close-modal'); this.closePreviewBtn = document.getElementById('close-preview-modal'); this.cancelBtn = document.getElementById('cancel-email'); this.cancelPreviewBtn = document.getElementById('cancel-preview'); this.editBtn = document.getElementById('edit-email'); this.confirmSendBtn = document.getElementById('confirm-send'); this.messageTextarea = document.getElementById('email-message'); this.charCounter = document.querySelector('.char-counter'); this.currentRecipient = null; this.currentEmailData = null; this.lastPreviewTime = 0; // Track last preview request time this.init(); } init() { // Modal controls this.closeBtn.addEventListener('click', () => this.closeModal()); this.closePreviewBtn.addEventListener('click', () => this.closePreviewModal()); this.cancelBtn.addEventListener('click', () => this.closeModal()); this.cancelPreviewBtn.addEventListener('click', () => this.closePreviewModal()); this.editBtn.addEventListener('click', () => this.editEmail()); this.confirmSendBtn.addEventListener('click', () => this.confirmSend()); // Click outside modal to close this.modal.addEventListener('click', (e) => { if (e.target === this.modal) this.closeModal(); }); this.previewModal.addEventListener('click', (e) => { if (e.target === this.previewModal) this.closePreviewModal(); }); // Form handling - now shows preview instead of sending directly this.form.addEventListener('submit', (e) => this.handlePreview(e)); // Character counter this.messageTextarea.addEventListener('input', () => this.updateCharCounter()); // Add event listener to sender name field to update subject dynamically const senderNameField = document.getElementById('sender-name'); const subjectField = document.getElementById('email-subject'); const postalCodeField = document.getElementById('sender-postal-code'); senderNameField.addEventListener('input', () => { const senderName = senderNameField.value.trim() || 'your constituent'; const postalCode = postalCodeField.value.trim(); if (postalCode) { subjectField.value = `Message from ${senderName} from ${postalCode}`; } }); // Escape key to close modals document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { if (this.previewModal.style.display === 'block') { this.closePreviewModal(); } else if (this.modal.style.display === 'block') { this.closeModal(); } } }); } openModal(recipient) { this.currentRecipient = recipient; // Populate recipient info document.getElementById('recipient-email').value = recipient.email; document.getElementById('recipient-info').innerHTML = ` ${recipient.name}
${recipient.office}
${recipient.district}
${recipient.email} `; // Set postal code from current lookup const postalCode = window.postalLookup ? window.postalLookup.currentPostalCode : ''; document.getElementById('sender-postal-code').value = postalCode; // Clear form fields document.getElementById('sender-name').value = ''; document.getElementById('sender-email').value = ''; document.getElementById('email-subject').value = ''; document.getElementById('email-message').value = ''; // Set default subject document.getElementById('email-subject').value = `Message from your constituent from ${postalCode}`; this.updateCharCounter(); this.modal.style.display = 'block'; // Focus on first input document.getElementById('sender-name').focus(); } closeModal() { this.modal.style.display = 'none'; // Only clear data if we're not showing preview (user is canceling) if (this.previewModal.style.display !== 'block') { this.currentRecipient = null; this.currentEmailData = null; } } closePreviewModal() { this.previewModal.style.display = 'none'; // Clear email data when closing preview (user canceling) this.currentRecipient = null; this.currentEmailData = null; } editEmail() { // Close preview modal and return to compose modal without clearing data this.previewModal.style.display = 'none'; this.modal.style.display = 'block'; } updateCharCounter() { const maxLength = 5000; const currentLength = this.messageTextarea.value.length; const remaining = maxLength - currentLength; this.charCounter.textContent = `${remaining} characters remaining`; if (remaining < 100) { this.charCounter.style.color = '#dc3545'; // Red } else if (remaining < 500) { this.charCounter.style.color = '#ffc107'; // Yellow } else { this.charCounter.style.color = '#666'; // Default } } validateForm() { const errors = []; const senderName = document.getElementById('sender-name').value.trim(); const senderEmail = document.getElementById('sender-email').value.trim(); const subject = document.getElementById('email-subject').value.trim(); const message = document.getElementById('email-message').value.trim(); if (!senderName) { errors.push('Your name is required'); } if (!senderEmail) { errors.push('Your email is required'); } else if (!this.validateEmail(senderEmail)) { errors.push('Please enter a valid email address'); } if (!subject) { errors.push('Subject is required'); } if (!message) { errors.push('Message is required'); } else if (message.length < 10) { errors.push('Message must be at least 10 characters long'); } // Check for suspicious content if (this.containsSuspiciousContent(message) || this.containsSuspiciousContent(subject)) { errors.push('Your message contains content that may not be appropriate'); } return errors; } validateEmail(email) { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); } containsSuspiciousContent(text) { const suspiciousPatterns = [ /