feat(master): transformar configuracao de email em card com modal e icones de acao
This commit is contained in:
@@ -1768,3 +1768,110 @@ th {
|
||||
border: 1px solid #e5e7eb;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -16,120 +16,16 @@
|
||||
<h1>Configurações</h1>
|
||||
</div>
|
||||
|
||||
<section class="email-config-panel">
|
||||
<div class="email-config-header">
|
||||
<h2 class="email-config-title">Configurar Conta</h2>
|
||||
<p class="email-config-subtitle">Preencha as configurações de IMAP e SMTP abaixo para conectar sua conta.</p>
|
||||
<section class="panel">
|
||||
<div class="section-head">
|
||||
<h2>Configuração de E-mail</h2>
|
||||
<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>
|
||||
|
||||
<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 <no_reply@seconectai.com.br>">
|
||||
<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>
|
||||
<div id="email-card-container"></div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
@@ -167,6 +63,115 @@
|
||||
</div>
|
||||
</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 <suporte@seudominio.com.br>">
|
||||
</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 -->
|
||||
<div id="reativar-modal" class="modal hidden">
|
||||
<div class="modal-backdrop" onclick="fecharModalReativar()"></div>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const emailForm = document.querySelector('#email-form'),
|
||||
emailCardContainer = document.querySelector('#email-card-container'),
|
||||
emailModal = document.querySelector('#email-modal'),
|
||||
abacateForm = document.querySelector('#abacate-form'),
|
||||
emailRows = document.querySelector('#email-rows'),
|
||||
abacateRows = document.querySelector('#abacate-rows'),
|
||||
@@ -15,8 +17,15 @@ const emailForm = document.querySelector('#email-form'),
|
||||
qrModalTitle = document.querySelector('#qr-modal-title');
|
||||
|
||||
let empresas = [];
|
||||
let currentEmailConfig = {};
|
||||
let lastEmailStatus = null;
|
||||
let lastEmailFeedback = null;
|
||||
|
||||
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>',
|
||||
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>',
|
||||
@@ -33,6 +42,121 @@ function getEmailFormData() {
|
||||
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 abacateKeys = ['abacatepay_api_key', 'abacatepay_webhook_secret'];
|
||||
|
||||
@@ -100,6 +224,9 @@ async function load() {
|
||||
try {
|
||||
const d = await Api.get('/api/master/configuracoes');
|
||||
const cfg = d.configuracoes || {};
|
||||
currentEmailConfig = cfg;
|
||||
renderEmailCard(cfg);
|
||||
|
||||
for (const [k, v] of Object.entries(cfg)) {
|
||||
if (emailForm?.elements[k]) {
|
||||
if (emailForm.elements[k].type === 'checkbox') {
|
||||
@@ -307,9 +434,9 @@ async function rejeitar(emp, id) {
|
||||
}
|
||||
}
|
||||
|
||||
emailForm.onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
const btn = document.querySelector('#btn-salvar-email');
|
||||
async function salvarConfiguracaoEmail(e) {
|
||||
if (e) e.preventDefault();
|
||||
const btn = document.querySelector('#btn-modal-salvar-email');
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Salvando...';
|
||||
@@ -318,6 +445,7 @@ emailForm.onsubmit = async e => {
|
||||
const payload = getEmailFormData();
|
||||
await Api.put('/api/master/configuracoes', payload);
|
||||
Util.toast('Configurações de e-mail salvas com sucesso!');
|
||||
fecharModalEmail();
|
||||
await load();
|
||||
testarEConectarEmail();
|
||||
} catch (err) {
|
||||
@@ -325,50 +453,42 @@ emailForm.onsubmit = async e => {
|
||||
} finally {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Salvar configurações';
|
||||
btn.textContent = 'Salvar Configurações';
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
window.salvarConfiguracaoEmail = salvarConfiguracaoEmail;
|
||||
if (emailForm) emailForm.onsubmit = salvarConfiguracaoEmail;
|
||||
|
||||
window.testarEConectarEmail = async () => {
|
||||
const btn = document.querySelector('#btn-testar-email');
|
||||
const feedback = document.querySelector('#email-status-feedback');
|
||||
const headerBadges = document.querySelector('#email-header-status-badges');
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Testando conexão...';
|
||||
}
|
||||
if (feedback) {
|
||||
feedback.classList.remove('hidden');
|
||||
feedback.innerHTML = '<span class="muted">Testando conexões SMTP e IMAP...</span>';
|
||||
}
|
||||
const btn = document.querySelector('#btn-icon-testar-email');
|
||||
if (btn) btn.disabled = true;
|
||||
|
||||
lastEmailFeedback = '<span class="muted">Testando conexões SMTP e IMAP...</span>';
|
||||
renderEmailCard(currentEmailConfig);
|
||||
|
||||
try {
|
||||
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 imapOk = !!res?.imap?.ok;
|
||||
|
||||
if (headerBadges) {
|
||||
headerBadges.innerHTML = `
|
||||
<span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP: ${smtpOk ? 'Conectado' : 'Erro'}</span>
|
||||
<span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP: ${imapOk ? 'Conectado' : 'Erro'}</span>
|
||||
`;
|
||||
}
|
||||
lastEmailStatus = { smtpOk, imapOk };
|
||||
|
||||
if (feedback) {
|
||||
feedback.classList.remove('hidden');
|
||||
feedback.innerHTML = `
|
||||
<div style="display: flex; gap: 12px; align-items: center; margin-bottom: 8px;">
|
||||
<strong>Status da Conexão:</strong>
|
||||
<span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP ${smtpOk ? 'Conectado' : 'Falhou'}</span>
|
||||
<span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP ${imapOk ? 'Conectado' : 'Falhou'}</span>
|
||||
</div>
|
||||
<div style="font-size: 13.5px; line-height: 1.6;">
|
||||
<p style="margin: 4px 0;"><strong>Email de saída (SMTP):</strong> ${esc(res?.smtp?.mensagem || '')}</p>
|
||||
<p style="margin: 4px 0;"><strong>Email recebido (IMAP):</strong> ${esc(res?.imap?.mensagem || '')}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
lastEmailFeedback = `
|
||||
<div style="display: flex; gap: 12px; align-items: center; margin-bottom: 8px;">
|
||||
<strong>Resultado do Teste:</strong>
|
||||
<span class="badge ${smtpOk ? 'ok' : 'warn'}">SMTP ${smtpOk ? 'Conectado' : 'Falhou'}</span>
|
||||
<span class="badge ${imapOk ? 'ok' : 'warn'}">IMAP ${imapOk ? 'Conectado' : 'Falhou'}</span>
|
||||
</div>
|
||||
<div style="font-size: 13px; line-height: 1.5;">
|
||||
<p style="margin: 3px 0;"><strong>Saída (SMTP):</strong> ${esc(res?.smtp?.mensagem || '')}</p>
|
||||
<p style="margin: 3px 0;"><strong>Recebimento (IMAP):</strong> ${esc(res?.imap?.mensagem || '')}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
renderEmailCard(currentEmailConfig);
|
||||
|
||||
if (res?.ok) {
|
||||
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);
|
||||
}
|
||||
} catch (err) {
|
||||
if (feedback) {
|
||||
feedback.classList.remove('hidden');
|
||||
feedback.innerHTML = `<span style="color:var(--danger)">Erro ao testar conexão: ${esc(err.message)}</span>`;
|
||||
}
|
||||
lastEmailFeedback = `<span style="color:var(--danger)">Erro ao testar conexão: ${esc(err.message)}</span>`;
|
||||
renderEmailCard(currentEmailConfig);
|
||||
Util.toast(err.message, true);
|
||||
} finally {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Testar e Conectar';
|
||||
}
|
||||
const b = document.querySelector('#btn-icon-testar-email');
|
||||
if (b) b.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
window.sincronizarEmailsAgora = async () => {
|
||||
const btn = document.querySelector('#btn-sync-email');
|
||||
const feedback = document.querySelector('#email-status-feedback');
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Sincronizando...';
|
||||
}
|
||||
const btn = document.querySelector('#btn-icon-sync-email');
|
||||
if (btn) btn.disabled = true;
|
||||
|
||||
lastEmailFeedback = '<span class="muted">Sincronizando respostas de e-mail...</span>';
|
||||
renderEmailCard(currentEmailConfig);
|
||||
|
||||
try {
|
||||
const res = await Api.post('/api/master/configuracoes/sincronizar-email', {});
|
||||
Util.toast(res?.mensagem || 'E-mails sincronizados com sucesso.');
|
||||
if (feedback) {
|
||||
feedback.classList.remove('hidden');
|
||||
feedback.innerHTML = `<p style="margin: 0; color: var(--brand-strong);"><strong>Sincronização de Respostas:</strong> ${esc(res?.mensagem || '')}</p>`;
|
||||
}
|
||||
lastEmailFeedback = `<p style="margin: 0; color: var(--brand-strong);"><strong>Sincronização de Respostas:</strong> ${esc(res?.mensagem || '')}</p>`;
|
||||
renderEmailCard(currentEmailConfig);
|
||||
} catch (err) {
|
||||
lastEmailFeedback = `<span style="color:var(--danger)">Erro na sincronização: ${esc(err.message)}</span>`;
|
||||
renderEmailCard(currentEmailConfig);
|
||||
Util.toast(err.message, true);
|
||||
} finally {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Sincronizar Respostas Agora';
|
||||
}
|
||||
const b = document.querySelector('#btn-icon-sync-email');
|
||||
if (b) b.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user