feat: nova conversa com número avulso + normalização WhatsApp + dark mode no modal

- Botão '+' na sidebar para iniciar conversa com qualquer número
- Busca automática: cliente → dependente → número novo
- Campo de mensagem inicial personalizável no modal
- Normalização de número (DDI 55) ao enviar via Evolution API
- Modal de nova conversa com suporte a dark mode
- Correção: foto do cliente não é mais atualizada a cada mensagem
- Correção: triagem não processa respostas se já tem atendente+equipe
This commit is contained in:
2026-06-24 16:52:48 +00:00
parent 29190cd71c
commit bb80be896f
4 changed files with 222 additions and 8 deletions
+121
View File
@@ -884,6 +884,7 @@ body.dark-mode .msg.enviando { opacity: 0.4; }
</div>
<div class="search-box">
<input type="text" id="searchConv" placeholder="🔍 Buscar conversas..." onkeyup="carregarConversas()">
<button id="btnNovaConversa" onclick="mostrarModalNovaConversa()" title="Nova conversa" style="background:rgba(255,255,255,0.12);border:1px solid rgba(255,255,255,0.2);color:#fff;border-radius:8px;width:32px;height:32px;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .15s" onmouseover="this.style.background='rgba(255,255,255,0.22)'" onmouseout="this.style.background='rgba(255,255,255,0.12)'">+</button>
<label>
<input type="checkbox" id="chkFinalizadas" onchange="carregarConversas()"> Finalizadas
</label>
@@ -2132,6 +2133,61 @@ carregarConfigResolucao().then(function() {
if (conversaId) abrirConversa(parseInt(conversaId));
});
// ===== NOVA CONVERSA (número não cadastrado) =====
window.mostrarModalNovaConversa = function() {
document.getElementById('modalNovaConversa').style.display = 'flex';
document.getElementById('novoNumero').value = '';
document.getElementById('novoNome').value = '';
document.getElementById('novoMensagem').value = '';
document.getElementById('novoNumero').focus();
}
window.fecharModalNovaConversa = function() {
document.getElementById('modalNovaConversa').style.display = 'none';
}
window.criarNovaConversa = async function() {
const numero = document.getElementById('novoNumero').value.replace(/\D/g, '');
const nome = document.getElementById('novoNome').value.trim() || numero;
const mensagem = document.getElementById('novoMensagem').value.trim() || '👋 Olá! Em que posso ajudar?';
if (!numero || numero.length < 10) {
if (Chatc2Toast) Chatc2Toast.warn('Informe um número de WhatsApp válido.');
return;
}
const btn = document.getElementById('btnCriarConversa');
btn.disabled = true;
btn.textContent = 'Criando...';
try {
const res = await fetch('/api/' + alias + '/conversations/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
body: JSON.stringify({
empresaId: empresaId,
numero: numero,
nomeContato: nome,
mensagem: mensagem,
instanciaId: null
})
});
const data = await res.json();
if (data.success) {
fecharModalNovaConversa();
await carregarConversas();
abrirConversa(data.data.id);
if (Chatc2Toast) Chatc2Toast.success('Conversa iniciada com ' + nome);
} else {
if (Chatc2Toast) Chatc2Toast.error(data.error || 'Erro ao criar conversa');
}
} catch(e) {
if (Chatc2Toast) Chatc2Toast.error('Erro de conexão ao criar conversa');
}
btn.disabled = false;
btn.textContent = 'Iniciar conversa';
}
// ===== LOGOUT =====
window.logout = function() {
['chatc2_token','chatc2_alias','chatc2_user'].forEach(function(k) { localStorage.removeItem(k); });
@@ -2170,6 +2226,71 @@ document.getElementById('msgInput').addEventListener('input', function() {
})();
</script>
<style>
/* Dark mode para o modal Nova Conversa */
body.dark-mode #modalNovaConversa > div {
background: #1e1e2e !important;
box-shadow: 0 20px 60px rgba(0,0,0,0.5) !important;
}
body.dark-mode #modalNovaConversa h3 {
color: #e0e0e0 !important;
}
body.dark-mode #modalNovaConversa p {
color: #9ca3af !important;
}
body.dark-mode #modalNovaConversa label {
color: #d1d5db !important;
}
body.dark-mode #modalNovaConversa input,
body.dark-mode #modalNovaConversa textarea {
background: #2a2a3e !important;
border-color: #3f3f5a !important;
color: #e0e0e0 !important;
}
body.dark-mode #modalNovaConversa input:focus,
body.dark-mode #modalNovaConversa textarea:focus {
border-color: #818cf8 !important;
background: #2a2a3e !important;
box-shadow: 0 0 0 3px rgba(129,140,248,0.15) !important;
}
body.dark-mode #modalNovaConversa input::placeholder,
body.dark-mode #modalNovaConversa textarea::placeholder {
color: #6b7280 !important;
}
body.dark-mode #modalNovaConversa button {
color: #d1d5db !important;
}
/* Botão Cancelar no dark mode */
body.dark-mode #btnCancelarConversa {
background: #2a2a3e !important;
border-color: #3f3f5a !important;
color: #d1d5db !important;
}
</style>
<!-- Modal: Nova Conversa -->
<div id="modalNovaConversa" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:10000;align-items:center;justify-content:center" onclick="if(event.target===this) fecharModalNovaConversa()">
<div style="background:#fff;border-radius:16px;padding:32px 28px 24px;width:100%;max-width:420px;box-shadow:0 20px 60px rgba(0,0,0,0.18)" onclick="event.stopPropagation()">
<h3 style="margin:0 0 6px;font-size:18px;font-weight:700;color:#111827">Nova conversa</h3>
<p style="margin:0 0 18px;font-size:13px;color:#6b7280">Inicie um atendimento para um número que ainda não está no sistema.</p>
<div class="form-group" style="margin-bottom:14px">
<label style="display:block;font-size:13px;font-weight:600;color:#374151;margin-bottom:5px">Número (WhatsApp) *</label>
<input type="tel" id="novoNumero" placeholder="(11) 99999-9999" style="width:100%;padding:10px 14px;border:2px solid #e5e7eb;border-radius:8px;font-size:14px;outline:none;background:#f9fafb;transition:all .15s" onfocus="this.style.borderColor='#667eea';this.style.background='#fff'" onblur="this.style.borderColor='#e5e7eb';this.style.background='#f9fafb'">
</div>
<div class="form-group" style="margin-bottom:14px">
<label style="display:block;font-size:13px;font-weight:600;color:#374151;margin-bottom:5px">Nome do contato</label>
<input type="text" id="novoNome" placeholder="Nome (opcional)" style="width:100%;padding:10px 14px;border:2px solid #e5e7eb;border-radius:8px;font-size:14px;outline:none;background:#f9fafb;transition:all .15s" onfocus="this.style.borderColor='#667eea';this.style.background='#fff'" onblur="this.style.borderColor='#e5e7eb';this.style.background='#f9fafb'">
</div>
<div class="form-group" style="margin-bottom:14px">
<label style="display:block;font-size:13px;font-weight:600;color:#374151;margin-bottom:5px">Mensagem inicial</label>
<textarea id="novoMensagem" rows="3" placeholder="👋 Olá! Em que posso ajudar?" style="width:100%;padding:10px 14px;border:2px solid #e5e7eb;border-radius:8px;font-size:14px;outline:none;background:#f9fafb;resize:vertical;font-family:inherit;transition:all .15s" onfocus="this.style.borderColor='#667eea';this.style.background='#fff'" onblur="this.style.borderColor='#e5e7eb';this.style.background='#f9fafb'"></textarea>
</div>
<div style="display:flex;gap:10px;justify-content:flex-end;margin-top:20px">
<button id="btnCancelarConversa" onclick="fecharModalNovaConversa()" style="padding:10px 20px;border:1px solid #e5e7eb;border-radius:8px;background:#fff;color:#374151;font-size:14px;font-weight:600;cursor:pointer">Cancelar</button>
<button id="btnCriarConversa" onclick="criarNovaConversa()" style="padding:10px 20px;border:none;border-radius:8px;background:#667eea;color:#fff;font-size:14px;font-weight:600;cursor:pointer;transition:all .15s" onmouseover="this.style.background='#5a67d8'" onmouseout="this.style.background='#667eea'">Iniciar conversa</button>
</div>
</div>
</div>
<script src="/js/dark-mode.js"></script>
<script src="/js/notifications.js"></script>
<script src="/js/toast.js"></script>