diff --git a/src/main/webapp/css/app.css b/src/main/webapp/css/app.css
index fe2317b..e6e1c17 100644
--- a/src/main/webapp/css/app.css
+++ b/src/main/webapp/css/app.css
@@ -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;
+}
diff --git a/src/main/webapp/master/configuracoes.html b/src/main/webapp/master/configuracoes.html
index 1563f5e..5653fda 100644
--- a/src/main/webapp/master/configuracoes.html
+++ b/src/main/webapp/master/configuracoes.html
@@ -16,120 +16,16 @@
diff --git a/src/main/webapp/master/configuracoes.js b/src/main/webapp/master/configuracoes.js
index e84cfa6..1f45a80 100644
--- a/src/main/webapp/master/configuracoes.js
+++ b/src/main/webapp/master/configuracoes.js
@@ -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: '
',
+ connect: '
',
+ sync: '
',
+ edit: '
',
userCheck: '
',
qrCode: '
',
restart: '
',
@@ -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 = `
+
+
+ ${Icons.mail}
+
+
Nenhuma conta de e-mail configurada
+
Clique no botão de adicionar (+) acima ou no botão abaixo para configurar o e-mail do sistema.
+
+
+ `;
+ return;
+ }
+
+ const smtpBadge = lastEmailStatus
+ ? `
SMTP: ${lastEmailStatus.smtpOk ? 'Conectado' : 'Erro'}`
+ : `
SMTP: Não testado`;
+ const imapBadge = lastEmailStatus
+ ? `
IMAP: ${lastEmailStatus.imapOk ? 'Conectado' : 'Erro'}`
+ : `
IMAP: Não testado`;
+
+ const userDisplay = cfg.smtp_user || cfg.imap_user || 'E-mail do Sistema';
+ const remetenteDisplay = cfg.smtp_from || 'Central de Notificações';
+
+ emailCardContainer.innerHTML = `
+
+
+
+
+
+
+
+ Saída (SMTP)
+
+
+
Servidor: ${esc(cfg.smtp_host || '-')}:${esc(cfg.smtp_port || '465')}
+
Segurança: ${esc(String(cfg.smtp_security || 'ssl_tls').toUpperCase())}
+
Usuário: ${esc(cfg.smtp_user || '-')}
+
+
+
+
+
+ Recebimento (IMAP)
+
+
+
Servidor: ${esc(cfg.imap_host || '-')}:${esc(cfg.imap_port || '993')}
+
Segurança: ${esc(String(cfg.imap_security || 'ssl_tls').toUpperCase())}
+
Usuário: ${esc(cfg.imap_user || '-')}
+
+
+
+
+ ${lastEmailFeedback || ''}
+
+
+
+
+ `;
+}
+
+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 = '
Testando conexões SMTP e IMAP...';
- }
+ const btn = document.querySelector('#btn-icon-testar-email');
+ if (btn) btn.disabled = true;
+
+ lastEmailFeedback = '
Testando conexões SMTP e IMAP...';
+ 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 = `
-
SMTP: ${smtpOk ? 'Conectado' : 'Erro'}
-
IMAP: ${imapOk ? 'Conectado' : 'Erro'}
- `;
- }
+ lastEmailStatus = { smtpOk, imapOk };
- if (feedback) {
- feedback.classList.remove('hidden');
- feedback.innerHTML = `
-
- Status da Conexão:
- SMTP ${smtpOk ? 'Conectado' : 'Falhou'}
- IMAP ${imapOk ? 'Conectado' : 'Falhou'}
-
-
-
Email de saída (SMTP): ${esc(res?.smtp?.mensagem || '')}
-
Email recebido (IMAP): ${esc(res?.imap?.mensagem || '')}
-
- `;
- }
+ lastEmailFeedback = `
+
+ Resultado do Teste:
+ SMTP ${smtpOk ? 'Conectado' : 'Falhou'}
+ IMAP ${imapOk ? 'Conectado' : 'Falhou'}
+
+
+
Saída (SMTP): ${esc(res?.smtp?.mensagem || '')}
+
Recebimento (IMAP): ${esc(res?.imap?.mensagem || '')}
+
+ `;
+
+ 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 = `
Erro ao testar conexão: ${esc(err.message)}`;
- }
+ lastEmailFeedback = `
Erro ao testar conexão: ${esc(err.message)}`;
+ 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 = '
Sincronizando respostas de e-mail...';
+ 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 = `
Sincronização de Respostas: ${esc(res?.mensagem || '')}
`;
- }
+ lastEmailFeedback = `
Sincronização de Respostas: ${esc(res?.mensagem || '')}
`;
+ renderEmailCard(currentEmailConfig);
} catch (err) {
+ lastEmailFeedback = `
Erro na sincronização: ${esc(err.message)}`;
+ 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;
}
};