/** * emailCompose.js * Modal per la composizione e invio email dal contesto di un ticket. * Utilizza Quill.js per l'editor HTML, supporta allegati e immagini inline. */ const EmailCompose = (() => { let quillEditor = null; let attachmentsList = []; let currentOptions = {}; // ── CSS ────────────────────────────────────────────────────────────────────── function injectStyles() { if (document.getElementById('email-compose-styles')) return; const style = document.createElement('style'); style.id = 'email-compose-styles'; style.textContent = ` #email-compose-overlay { position: fixed; inset: 0; z-index: 9000; background: rgba(0,0,0,0.55); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; animation: fadeIn 0.15s ease; } @keyframes fadeIn { from { opacity:0 } to { opacity:1 } } #email-compose-modal { background: var(--bg-card); border: 1px solid var(--border-light); border-radius: var(--radius-xl, 14px); box-shadow: 0 24px 80px rgba(0,0,0,0.35); width: min(860px, 95vw); max-height: 92vh; display: flex; flex-direction: column; animation: slideUp 0.18s ease; } @keyframes slideUp { from { transform: translateY(20px); opacity:0 } to { transform: translateY(0); opacity:1 } } #email-compose-modal .ec-header { padding: 16px 20px 12px; border-bottom: 1px solid var(--border-subtle); display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; } #email-compose-modal .ec-title { font-size: 1rem; font-weight: 600; color: var(--text-primary); display: flex; align-items: center; gap: 8px; } #email-compose-modal .ec-body { padding: 16px 20px; overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 12px; } #email-compose-modal .ec-field { display: flex; flex-direction: column; gap: 4px; } #email-compose-modal .ec-label { font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; } #email-compose-modal .ec-tags-input { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; background: var(--bg-tertiary); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 6px 10px; min-height: 36px; cursor: text; } #email-compose-modal .ec-tags-input:focus-within { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(var(--accent-rgb,99,102,241),0.12); } #email-compose-modal .ec-tag { display: inline-flex; align-items: center; gap: 4px; background: var(--accent-primary); color: #fff; border-radius: 4px; padding: 2px 6px; font-size: 0.78rem; } #email-compose-modal .ec-tag button { background: none; border: none; color: rgba(255,255,255,0.8); cursor: pointer; padding: 0; line-height: 1; font-size: 0.9rem; } #email-compose-modal .ec-tag button:hover { color: #fff; } #email-compose-modal .ec-tag-input { border: none; outline: none; background: transparent; font-size: 0.88rem; color: var(--text-primary); min-width: 160px; flex: 1; } #email-compose-modal .ec-editor-wrapper { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); overflow: hidden; background: var(--bg-tertiary); } #email-compose-modal .ec-editor-wrapper .ql-toolbar { border: none; border-bottom: 1px solid var(--border-subtle); background: var(--bg-secondary); } #email-compose-modal .ec-editor-wrapper .ql-container { border: none; min-height: 220px; font-size: 0.9rem; } #email-compose-modal .ec-attachments-zone { border: 2px dashed var(--border-subtle); border-radius: var(--radius-md); padding: 12px 14px; text-align: center; cursor: pointer; transition: border-color 0.15s, background 0.15s; font-size: 0.82rem; color: var(--text-muted); } #email-compose-modal .ec-attachments-zone:hover, #email-compose-modal .ec-attachments-zone.drag-over { border-color: var(--accent-primary); background: rgba(var(--accent-rgb,99,102,241),0.06); color: var(--text-secondary); } #email-compose-modal .ec-file-list { display: flex; flex-direction: column; gap: 4px; } #email-compose-modal .ec-file-item { display: flex; align-items: center; gap: 8px; font-size: 0.82rem; padding: 4px 8px; background: var(--bg-secondary); border-radius: var(--radius-sm); color: var(--text-secondary); } #email-compose-modal .ec-file-item button { margin-left: auto; background: none; border: none; cursor: pointer; color: var(--text-muted); font-size: 0.85rem; padding: 0 2px; } #email-compose-modal .ec-file-item button:hover { color: var(--error); } #email-compose-modal .ec-footer { padding: 12px 20px; border-top: 1px solid var(--border-subtle); display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; gap: 10px; } #email-compose-modal select.ec-select { background: var(--bg-tertiary); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 6px 12px; font-size: 0.85rem; color: var(--text-primary); min-width: 180px; } `; document.head.appendChild(style); } // ── Tag Input Helper ────────────────────────────────────────────────────────── function makeTagInput(containerId, initialEmails = []) { const container = document.getElementById(containerId); const tags = [...initialEmails]; function render() { const inputEl = container.querySelector('.ec-tag-input'); const currentVal = inputEl ? inputEl.value : ''; container.innerHTML = ''; tags.forEach((email, idx) => { const tagEl = document.createElement('span'); tagEl.className = 'ec-tag'; tagEl.innerHTML = `${App.escapeHtml(email)}`; tagEl.querySelector('button').addEventListener('click', () => { tags.splice(idx, 1); render(); }); container.appendChild(tagEl); }); const input = document.createElement('input'); input.className = 'ec-tag-input'; input.type = 'text'; input.placeholder = tags.length ? '' : 'email@esempio.com, premi Invio'; input.value = currentVal; input.addEventListener('keydown', (e) => { if ((e.key === 'Enter' || e.key === ',') && input.value.trim()) { e.preventDefault(); const val = input.value.trim().replace(/,$/, ''); if (val && !tags.includes(val)) tags.push(val); input.value = ''; render(); } else if (e.key === 'Backspace' && !input.value && tags.length) { tags.pop(); render(); } }); input.addEventListener('blur', () => { if (input.value.trim()) { const val = input.value.trim().replace(/,$/, ''); if (val && !tags.includes(val)) tags.push(val); input.value = ''; render(); } }); container.appendChild(input); container.addEventListener('click', () => input.focus()); } render(); return { getTags: () => [...tags], addTag: (email) => { if (!tags.includes(email)) { tags.push(email); render(); } } }; } // ── Build Modal HTML ────────────────────────────────────────────────────────── function buildModal() { const overlay = document.createElement('div'); overlay.id = 'email-compose-overlay'; overlay.innerHTML = `