feat(master): transformar configuracao de email em card com modal e icones de acao

This commit is contained in:
Tiago
2026-10-13 17:31:56 -03:00
parent d547c2d4bb
commit 77dc5aea84
3 changed files with 398 additions and 172 deletions
+107
View File
@@ -1768,3 +1768,110 @@ th {
border: 1px solid #e5e7eb; border: 1px solid #e5e7eb;
font-size: 14px; font-size: 14px;
} }
/* Card de Configuração de E-mail */
.email-card {
background: #ffffff;
border: 1px solid var(--line, #e2e8f0);
border-radius: var(--radius-lg, 16px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
overflow: hidden;
max-width: 720px;
}
.email-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
border-color: var(--brand-light, #cbd5e1);
}
.email-card-header {
padding: 18px 20px;
border-bottom: 1px solid var(--line, #e2e8f0);
background: #fbfcfd;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.email-card-title-group {
display: flex;
align-items: center;
gap: 12px;
}
.email-icon-bubble {
width: 44px;
height: 44px;
border-radius: 12px;
background: var(--brand-soft, #dff4f1);
color: var(--brand, #0f766e);
display: grid;
place-items: center;
flex-shrink: 0;
}
.email-icon-bubble svg {
width: 24px;
height: 24px;
stroke: currentColor;
stroke-width: 2;
fill: none;
}
.email-card-user {
font-size: 16px;
font-weight: 800;
color: var(--text, #1e293b);
margin: 0;
line-height: 1.2;
}
.email-card-remetente {
font-size: 12px;
color: var(--muted-strong, #64748b);
margin-top: 3px;
display: block;
}
.email-card-badges {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
}
.email-card-body {
padding: 18px 20px;
flex: 1;
display: flex;
flex-direction: column;
gap: 12px;
}
.email-card-footer {
padding: 14px 20px;
border-top: 1px solid var(--line, #e2e8f0);
background: #fbfcfd;
display: flex;
align-items: center;
justify-content: space-between;
}
.email-card-footer .table-actions {
margin-left: auto;
}
.email-empty-card {
padding: 36px 20px;
text-align: center;
background: #ffffff;
border: 1px dashed var(--line, #e2e8f0);
border-radius: var(--radius-lg, 16px);
color: var(--muted-strong, #64748b);
max-width: 720px;
}
+118 -113
View File
@@ -16,120 +16,16 @@
<h1>Configurações</h1> <h1>Configurações</h1>
</div> </div>
<section class="email-config-panel"> <section class="panel">
<div class="email-config-header"> <div class="section-head">
<h2 class="email-config-title">Configurar Conta</h2> <h2>Configuração de E-mail</h2>
<p class="email-config-subtitle">Preencha as configurações de IMAP e SMTP abaixo para conectar sua conta.</p> <div class="section-actions">
<button class="header-add-btn" type="button" onclick="abrirModalEmail()" title="Configurar e-mail" aria-label="Configurar e-mail">
<svg viewBox="0 0 24 24" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
</button>
</div>
</div> </div>
<div id="email-card-container"></div>
<form id="email-form">
<div class="email-config-columns">
<!-- Coluna 1: Email Recebido (IMAP) -->
<div class="email-column">
<h3 class="email-section-heading">Email Recebido (IMAP):</h3>
<div class="email-field">
<label>Server:</label>
<input name="imap_host" placeholder="imap.seconectai.com.br">
</div>
<div class="email-field">
<label>Porta:</label>
<select name="imap_port" id="imap-port-select">
<option value="993">993</option>
<option value="143">143</option>
</select>
</div>
<div class="email-field">
<label>Segurança:</label>
<div class="email-security-wrap">
<select name="imap_security" id="imap-sec-select">
<option value="ssl_tls">SSL / TLS</option>
<option value="starttls">STARTTLS</option>
<option value="none">Nenhum</option>
</select>
<label class="email-checkbox-label">
<input type="checkbox" name="imap_allow_insecure_ssl" value="true">
Permitir SSL inseguro
</label>
</div>
</div>
<div class="email-field">
<label>Username:</label>
<input name="imap_user" placeholder="no_reply@seconectai.com.br">
</div>
<div class="email-field">
<label>Senha:</label>
<input name="imap_password" type="password" placeholder="••••••••••••">
</div>
</div>
<!-- Coluna 2: Email de saída (SMTP) -->
<div class="email-column">
<h3 class="email-section-heading">Email de saída (SMTP):</h3>
<div class="email-field">
<label>Server:</label>
<input name="smtp_host" placeholder="smtp.seconectai.com.br">
</div>
<div class="email-field">
<label>Porta:</label>
<select name="smtp_port" id="smtp-port-select">
<option value="465">465</option>
<option value="587">587</option>
<option value="25">25</option>
</select>
</div>
<div class="email-field">
<label>Segurança:</label>
<div class="email-security-wrap">
<select name="smtp_security" id="smtp-sec-select">
<option value="ssl_tls">SSL / TLS</option>
<option value="starttls">STARTTLS</option>
<option value="none">Nenhum</option>
</select>
<label class="email-checkbox-label">
<input type="checkbox" name="smtp_allow_insecure_ssl" value="true">
Permitir SSL inseguro
</label>
</div>
</div>
<div class="email-field">
<label>Username:</label>
<input name="smtp_user" placeholder="no_reply@seconectai.com.br">
</div>
<div class="email-field">
<label>Senha:</label>
<input name="smtp_password" type="password" placeholder="••••••••••••">
</div>
</div>
</div>
<!-- Remetente opcional -->
<div class="email-from-wrap">
<div class="email-field">
<label>Remetente de envio (From opcional):</label>
<input name="smtp_from" placeholder="Ex: no_reply@seconectai.com.br ou Notificações &lt;no_reply@seconectai.com.br&gt;">
<small style="color: var(--muted); font-size: 12px; margin-top: 4px;">Se deixado em branco, o Username SMTP será utilizado como remetente.</small>
</div>
</div>
<div class="email-actions-footer">
<button class="btn" type="submit" id="btn-salvar-email">Salvar configurações</button>
<button class="btn secondary" type="button" onclick="testarEConectarEmail()" id="btn-testar-email">Testar e Conectar</button>
<button class="btn secondary" type="button" onclick="sincronizarEmailsAgora()" id="btn-sync-email">Sincronizar Respostas Agora</button>
<span id="email-header-status-badges" style="margin-left: auto; display: flex; gap: 8px;"></span>
</div>
<div id="email-status-feedback" class="email-status-feedback-box hidden"></div>
</form>
</section> </section>
<section class="panel"> <section class="panel">
@@ -167,6 +63,115 @@
</div> </div>
</section> </section>
<!-- Modal Configuração de E-mail -->
<div id="email-modal" class="modal hidden">
<div class="modal-backdrop" onclick="fecharModalEmail()"></div>
<section class="modal-panel" style="max-width: 860px;">
<div class="modal-head">
<h2>Configuração de E-mail</h2>
<button class="btn secondary" type="button" onclick="fecharModalEmail()">✕</button>
</div>
<form id="email-form" onsubmit="salvarConfiguracaoEmail(event)">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 24px; margin-top: 10px;">
<!-- Coluna IMAP -->
<div style="background: #f8fafc; border: 1px solid var(--line); border-radius: 12px; padding: 18px;">
<h3 style="margin-top: 0; margin-bottom: 14px; font-size: 16px; color: var(--brand); display: flex; align-items: center; gap: 8px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg>
Email Recebido (IMAP)
</h3>
<div class="field" style="margin-bottom: 12px;">
<label>Servidor IMAP</label>
<input name="imap_host" placeholder="ex: imap.hostinger.com ou imap.gmail.com">
</div>
<div class="grid cols" style="margin-bottom: 12px;">
<div class="field">
<label>Porta</label>
<select name="imap_port" id="imap-port-select">
<option value="993">993 (SSL/TLS)</option>
<option value="143">143 (STARTTLS)</option>
</select>
</div>
<div class="field">
<label>Segurança</label>
<select name="imap_security" id="imap-sec-select">
<option value="ssl_tls">SSL/TLS</option>
<option value="starttls">STARTTLS</option>
</select>
</div>
</div>
<div class="field" style="margin-bottom: 12px;">
<label style="display: flex; align-items: center; gap: 8px; font-weight: normal; cursor: pointer;">
<input type="checkbox" name="imap_allow_insecure_ssl" value="true">
<span>Permitir certificados SSL inseguros</span>
</label>
</div>
<div class="field" style="margin-bottom: 12px;">
<label>Usuário / E-mail</label>
<input name="imap_user" type="email" placeholder="ex: suporte@seudominio.com.br">
</div>
<div class="field">
<label>Senha IMAP</label>
<input name="imap_password" type="password" placeholder="•••••••• (deixe em branco para manter)">
</div>
</div>
<!-- Coluna SMTP -->
<div style="background: #f8fafc; border: 1px solid var(--line); border-radius: 12px; padding: 18px;">
<h3 style="margin-top: 0; margin-bottom: 14px; font-size: 16px; color: var(--brand); display: flex; align-items: center; gap: 8px;">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
Email de Saída (SMTP)
</h3>
<div class="field" style="margin-bottom: 12px;">
<label>Servidor SMTP</label>
<input name="smtp_host" placeholder="ex: smtp.hostinger.com ou smtp.gmail.com">
</div>
<div class="grid cols" style="margin-bottom: 12px;">
<div class="field">
<label>Porta</label>
<select name="smtp_port" id="smtp-port-select">
<option value="465">465 (SSL/TLS)</option>
<option value="587">587 (STARTTLS)</option>
<option value="25">25 (Nenhuma)</option>
</select>
</div>
<div class="field">
<label>Segurança</label>
<select name="smtp_security" id="smtp-sec-select">
<option value="ssl_tls">SSL/TLS</option>
<option value="starttls">STARTTLS</option>
<option value="none">Nenhuma</option>
</select>
</div>
</div>
<div class="field" style="margin-bottom: 12px;">
<label style="display: flex; align-items: center; gap: 8px; font-weight: normal; cursor: pointer;">
<input type="checkbox" name="smtp_allow_insecure_ssl" value="true">
<span>Permitir certificados SSL inseguros</span>
</label>
</div>
<div class="field" style="margin-bottom: 12px;">
<label>Usuário / E-mail</label>
<input name="smtp_user" type="email" placeholder="ex: suporte@seudominio.com.br">
</div>
<div class="field" style="margin-bottom: 12px;">
<label>Senha SMTP</label>
<input name="smtp_password" type="password" placeholder="•••••••• (deixe em branco para manter)">
</div>
<div class="field">
<label>Remetente (Opcional)</label>
<input name="smtp_from" placeholder="ex: SeConectaí Notificações &lt;suporte@seudominio.com.br&gt;">
</div>
</div>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button class="btn secondary" type="button" onclick="fecharModalEmail()">Cancelar</button>
<button class="btn" type="submit" id="btn-modal-salvar-email">Salvar Configurações</button>
</div>
</form>
</section>
</div>
<!-- Modal Reativar para Cliente --> <!-- Modal Reativar para Cliente -->
<div id="reativar-modal" class="modal hidden"> <div id="reativar-modal" class="modal hidden">
<div class="modal-backdrop" onclick="fecharModalReativar()"></div> <div class="modal-backdrop" onclick="fecharModalReativar()"></div>
+173 -59
View File
@@ -1,4 +1,6 @@
const emailForm = document.querySelector('#email-form'), const emailForm = document.querySelector('#email-form'),
emailCardContainer = document.querySelector('#email-card-container'),
emailModal = document.querySelector('#email-modal'),
abacateForm = document.querySelector('#abacate-form'), abacateForm = document.querySelector('#abacate-form'),
emailRows = document.querySelector('#email-rows'), emailRows = document.querySelector('#email-rows'),
abacateRows = document.querySelector('#abacate-rows'), abacateRows = document.querySelector('#abacate-rows'),
@@ -15,8 +17,15 @@ const emailForm = document.querySelector('#email-form'),
qrModalTitle = document.querySelector('#qr-modal-title'); qrModalTitle = document.querySelector('#qr-modal-title');
let empresas = []; let empresas = [];
let currentEmailConfig = {};
let lastEmailStatus = null;
let lastEmailFeedback = null;
const Icons = { const Icons = {
mail: '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg>',
connect: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>',
sync: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.5 2v6h-6M2.5 22v-6h6M2 11.5a10 10 0 0 1 18.8-4.3M22 12.5a10 10 0 0 1-18.8 4.2"></path></svg>',
edit: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path></svg>',
userCheck: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><polyline points="17 11 19 13 23 9"></polyline></svg>', userCheck: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><polyline points="17 11 19 13 23 9"></polyline></svg>',
qrCode: '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect><rect x="14" y="14" width="3" height="3"></rect><rect x="18" y="18" width="3" height="3"></rect><rect x="18" y="14" width="3" height="3"></rect><rect x="14" y="18" width="3" height="3"></rect></svg>', qrCode: '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect><rect x="14" y="14" width="3" height="3"></rect><rect x="18" y="18" width="3" height="3"></rect><rect x="18" y="14" width="3" height="3"></rect><rect x="14" y="18" width="3" height="3"></rect></svg>',
restart: '<svg viewBox="0 0 24 24" aria-hidden="true"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>', restart: '<svg viewBox="0 0 24 24" aria-hidden="true"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>',
@@ -33,6 +42,121 @@ function getEmailFormData() {
return data; return data;
} }
function renderEmailCard(cfg) {
if (!emailCardContainer) return;
const isConfigured = !!(cfg && (cfg.smtp_host || cfg.imap_host || cfg.smtp_user || cfg.imap_user));
if (!isConfigured) {
emailCardContainer.innerHTML = `
<div class="email-empty-card">
<div style="display: inline-grid; place-items: center; width: 48px; height: 48px; border-radius: 12px; background: var(--bg-soft, #f4f6f8); color: var(--muted-strong, #64748b); margin: 0 auto 12px auto;">
${Icons.mail}
</div>
<h4 style="margin: 0 0 6px 0; font-size: 15px; font-weight: 700; color: var(--text, #1e293b);">Nenhuma conta de e-mail configurada</h4>
<p style="margin: 0 0 16px 0; font-size: 13px; color: var(--muted-strong, #64748b);">Clique no botão de adicionar (+) acima ou no botão abaixo para configurar o e-mail do sistema.</p>
<button class="btn secondary" type="button" onclick="abrirModalEmail()">Configurar E-mail</button>
</div>
`;
return;
}
const smtpBadge = lastEmailStatus
? `<span class="badge ${lastEmailStatus.smtpOk ? 'ok' : 'warn'}">SMTP: ${lastEmailStatus.smtpOk ? 'Conectado' : 'Erro'}</span>`
: `<span class="badge">SMTP: Não testado</span>`;
const imapBadge = lastEmailStatus
? `<span class="badge ${lastEmailStatus.imapOk ? 'ok' : 'warn'}">IMAP: ${lastEmailStatus.imapOk ? 'Conectado' : 'Erro'}</span>`
: `<span class="badge">IMAP: Não testado</span>`;
const userDisplay = cfg.smtp_user || cfg.imap_user || 'E-mail do Sistema';
const remetenteDisplay = cfg.smtp_from || 'Central de Notificações';
emailCardContainer.innerHTML = `
<article class="email-card">
<header class="email-card-header">
<div class="email-card-title-group">
<div class="email-icon-bubble">
${Icons.mail}
</div>
<div>
<h3 class="email-card-user">${esc(userDisplay)}</h3>
<span class="email-card-remetente">${esc(remetenteDisplay)}</span>
</div>
</div>
<div class="email-card-badges">
${smtpBadge}
${imapBadge}
</div>
</header>
<div class="email-card-body">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px;">
<div style="background: #f8fafc; border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px;">
<strong style="display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--brand); margin-bottom: 8px;">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
Saída (SMTP)
</strong>
<div style="font-size: 13px; display: flex; flex-direction: column; gap: 4px;">
<div><strong>Servidor:</strong> <code>${esc(cfg.smtp_host || '-')}:${esc(cfg.smtp_port || '465')}</code></div>
<div><strong>Segurança:</strong> <span class="badge" style="font-size: 11px;">${esc(String(cfg.smtp_security || 'ssl_tls').toUpperCase())}</span></div>
<div><strong>Usuário:</strong> ${esc(cfg.smtp_user || '-')}</div>
</div>
</div>
<div style="background: #f8fafc; border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px;">
<strong style="display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--brand); margin-bottom: 8px;">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg>
Recebimento (IMAP)
</strong>
<div style="font-size: 13px; display: flex; flex-direction: column; gap: 4px;">
<div><strong>Servidor:</strong> <code>${esc(cfg.imap_host || '-')}:${esc(cfg.imap_port || '993')}</code></div>
<div><strong>Segurança:</strong> <span class="badge" style="font-size: 11px;">${esc(String(cfg.imap_security || 'ssl_tls').toUpperCase())}</span></div>
<div><strong>Usuário:</strong> ${esc(cfg.imap_user || '-')}</div>
</div>
</div>
</div>
<div id="email-card-feedback" class="email-status-feedback-box ${lastEmailFeedback ? '' : 'hidden'}">
${lastEmailFeedback || ''}
</div>
</div>
<footer class="email-card-footer">
<span style="font-size: 12px; font-weight: 600; color: var(--muted-strong);">Ações:</span>
<div class="table-actions">
<button class="table-icon-btn" type="button" id="btn-icon-testar-email" onclick="testarEConectarEmail()" title="Testar e Conectar" aria-label="Testar e Conectar">
${Icons.connect}
</button>
<button class="table-icon-btn" type="button" id="btn-icon-sync-email" onclick="sincronizarEmailsAgora()" title="Sincronizar Respostas Agora" aria-label="Sincronizar Respostas Agora">
${Icons.sync}
</button>
<button class="table-icon-btn" type="button" onclick="abrirModalEmail()" title="Editar Configurações" aria-label="Editar Configurações">
${Icons.edit}
</button>
</div>
</footer>
</article>
`;
}
function abrirModalEmail() {
const modal = document.querySelector('#email-modal');
if (modal) {
if (emailForm && currentEmailConfig) {
for (const [k, v] of Object.entries(currentEmailConfig)) {
if (emailForm.elements[k]) {
if (emailForm.elements[k].type === 'checkbox') {
emailForm.elements[k].checked = (v === 'true' || v === true);
} else if (emailForm.elements[k].type !== 'password') {
emailForm.elements[k].value = v || '';
}
}
}
}
modal.classList.remove('hidden');
}
}
window.abrirModalEmail = abrirModalEmail;
function fecharModalEmail() {
document.querySelector('#email-modal')?.classList.add('hidden');
}
window.fecharModalEmail = fecharModalEmail;
const emailKeys = ['imap_host', 'imap_port', 'imap_security', 'imap_user', 'smtp_host', 'smtp_port', 'smtp_security', 'smtp_user', 'smtp_from']; const emailKeys = ['imap_host', 'imap_port', 'imap_security', 'imap_user', 'smtp_host', 'smtp_port', 'smtp_security', 'smtp_user', 'smtp_from'];
const abacateKeys = ['abacatepay_api_key', 'abacatepay_webhook_secret']; const abacateKeys = ['abacatepay_api_key', 'abacatepay_webhook_secret'];
@@ -100,6 +224,9 @@ async function load() {
try { try {
const d = await Api.get('/api/master/configuracoes'); const d = await Api.get('/api/master/configuracoes');
const cfg = d.configuracoes || {}; const cfg = d.configuracoes || {};
currentEmailConfig = cfg;
renderEmailCard(cfg);
for (const [k, v] of Object.entries(cfg)) { for (const [k, v] of Object.entries(cfg)) {
if (emailForm?.elements[k]) { if (emailForm?.elements[k]) {
if (emailForm.elements[k].type === 'checkbox') { if (emailForm.elements[k].type === 'checkbox') {
@@ -307,9 +434,9 @@ async function rejeitar(emp, id) {
} }
} }
emailForm.onsubmit = async e => { async function salvarConfiguracaoEmail(e) {
e.preventDefault(); if (e) e.preventDefault();
const btn = document.querySelector('#btn-salvar-email'); const btn = document.querySelector('#btn-modal-salvar-email');
if (btn) { if (btn) {
btn.disabled = true; btn.disabled = true;
btn.textContent = 'Salvando...'; btn.textContent = 'Salvando...';
@@ -318,6 +445,7 @@ emailForm.onsubmit = async e => {
const payload = getEmailFormData(); const payload = getEmailFormData();
await Api.put('/api/master/configuracoes', payload); await Api.put('/api/master/configuracoes', payload);
Util.toast('Configurações de e-mail salvas com sucesso!'); Util.toast('Configurações de e-mail salvas com sucesso!');
fecharModalEmail();
await load(); await load();
testarEConectarEmail(); testarEConectarEmail();
} catch (err) { } catch (err) {
@@ -325,50 +453,42 @@ emailForm.onsubmit = async e => {
} finally { } finally {
if (btn) { if (btn) {
btn.disabled = false; btn.disabled = false;
btn.textContent = 'Salvar configurações'; btn.textContent = 'Salvar Configurações';
} }
} }
}; }
window.salvarConfiguracaoEmail = salvarConfiguracaoEmail;
if (emailForm) emailForm.onsubmit = salvarConfiguracaoEmail;
window.testarEConectarEmail = async () => { window.testarEConectarEmail = async () => {
const btn = document.querySelector('#btn-testar-email'); const btn = document.querySelector('#btn-icon-testar-email');
const feedback = document.querySelector('#email-status-feedback'); if (btn) btn.disabled = true;
const headerBadges = document.querySelector('#email-header-status-badges');
if (btn) { lastEmailFeedback = '<span class="muted">Testando conexões SMTP e IMAP...</span>';
btn.disabled = true; renderEmailCard(currentEmailConfig);
btn.textContent = 'Testando conexão...';
}
if (feedback) {
feedback.classList.remove('hidden');
feedback.innerHTML = '<span class="muted">Testando conexões SMTP e IMAP...</span>';
}
try { try {
const payload = getEmailFormData(); const payload = getEmailFormData();
const res = await Api.post('/api/master/configuracoes/testar-email', payload); const dataToSend = Object.assign({}, currentEmailConfig, payload);
const res = await Api.post('/api/master/configuracoes/testar-email', dataToSend);
const smtpOk = !!res?.smtp?.ok; const smtpOk = !!res?.smtp?.ok;
const imapOk = !!res?.imap?.ok; const imapOk = !!res?.imap?.ok;
if (headerBadges) { lastEmailStatus = { smtpOk, imapOk };
headerBadges.innerHTML = `
<span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP: ${smtpOk ? 'Conectado' : 'Erro'}</span>
<span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP: ${imapOk ? 'Conectado' : 'Erro'}</span>
`;
}
if (feedback) { lastEmailFeedback = `
feedback.classList.remove('hidden'); <div style="display: flex; gap: 12px; align-items: center; margin-bottom: 8px;">
feedback.innerHTML = ` <strong>Resultado do Teste:</strong>
<div style="display: flex; gap: 12px; align-items: center; margin-bottom: 8px;"> <span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP ${smtpOk ? 'Conectado' : 'Falhou'}</span>
<strong>Status da Conexão:</strong> <span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP ${imapOk ? 'Conectado' : 'Falhou'}</span>
<span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP ${smtpOk ? 'Conectado' : 'Falhou'}</span> </div>
<span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP ${imapOk ? 'Conectado' : 'Falhou'}</span> <div style="font-size: 13px; line-height: 1.5;">
</div> <p style="margin: 3px 0;"><strong>Saída (SMTP):</strong> ${esc(res?.smtp?.mensagem || '')}</p>
<div style="font-size: 13.5px; line-height: 1.6;"> <p style="margin: 3px 0;"><strong>Recebimento (IMAP):</strong> ${esc(res?.imap?.mensagem || '')}</p>
<p style="margin: 4px 0;"><strong>Email de saída (SMTP):</strong> ${esc(res?.smtp?.mensagem || '')}</p> </div>
<p style="margin: 4px 0;"><strong>Email recebido (IMAP):</strong> ${esc(res?.imap?.mensagem || '')}</p> `;
</div>
`; renderEmailCard(currentEmailConfig);
}
if (res?.ok) { if (res?.ok) {
Util.toast('Conexão de e-mail (SMTP e IMAP) estabelecida com sucesso!'); Util.toast('Conexão de e-mail (SMTP e IMAP) estabelecida com sucesso!');
@@ -376,40 +496,34 @@ window.testarEConectarEmail = async () => {
Util.toast('Falha ao conectar em um ou mais servidores de e-mail.', true); Util.toast('Falha ao conectar em um ou mais servidores de e-mail.', true);
} }
} catch (err) { } catch (err) {
if (feedback) { lastEmailFeedback = `<span style="color:var(--danger)">Erro ao testar conexão: ${esc(err.message)}</span>`;
feedback.classList.remove('hidden'); renderEmailCard(currentEmailConfig);
feedback.innerHTML = `<span style="color:var(--danger)">Erro ao testar conexão: ${esc(err.message)}</span>`;
}
Util.toast(err.message, true); Util.toast(err.message, true);
} finally { } finally {
if (btn) { const b = document.querySelector('#btn-icon-testar-email');
btn.disabled = false; if (b) b.disabled = false;
btn.textContent = 'Testar e Conectar';
}
} }
}; };
window.sincronizarEmailsAgora = async () => { window.sincronizarEmailsAgora = async () => {
const btn = document.querySelector('#btn-sync-email'); const btn = document.querySelector('#btn-icon-sync-email');
const feedback = document.querySelector('#email-status-feedback'); if (btn) btn.disabled = true;
if (btn) {
btn.disabled = true; lastEmailFeedback = '<span class="muted">Sincronizando respostas de e-mail...</span>';
btn.textContent = 'Sincronizando...'; renderEmailCard(currentEmailConfig);
}
try { try {
const res = await Api.post('/api/master/configuracoes/sincronizar-email', {}); const res = await Api.post('/api/master/configuracoes/sincronizar-email', {});
Util.toast(res?.mensagem || 'E-mails sincronizados com sucesso.'); Util.toast(res?.mensagem || 'E-mails sincronizados com sucesso.');
if (feedback) { lastEmailFeedback = `<p style="margin: 0; color: var(--brand-strong);"><strong>Sincronização de Respostas:</strong> ${esc(res?.mensagem || '')}</p>`;
feedback.classList.remove('hidden'); renderEmailCard(currentEmailConfig);
feedback.innerHTML = `<p style="margin: 0; color: var(--brand-strong);"><strong>Sincronização de Respostas:</strong> ${esc(res?.mensagem || '')}</p>`;
}
} catch (err) { } catch (err) {
lastEmailFeedback = `<span style="color:var(--danger)">Erro na sincronização: ${esc(err.message)}</span>`;
renderEmailCard(currentEmailConfig);
Util.toast(err.message, true); Util.toast(err.message, true);
} finally { } finally {
if (btn) { const b = document.querySelector('#btn-icon-sync-email');
btn.disabled = false; if (b) b.disabled = false;
btn.textContent = 'Sincronizar Respostas Agora';
}
} }
}; };