Actualizar configuracion.html

This commit is contained in:
2026-02-17 22:00:59 +00:00
parent f8c16bfb71
commit 0b8e56eee8

View File

@@ -83,39 +83,130 @@
</div>
</div>
<div id="view-whatsapp" class="tab-content hidden h-full fade-in">
<div class="max-w-2xl mx-auto mt-10">
<div class="bg-white rounded-xl shadow-lg border border-gray-100 p-8 flex flex-col items-center text-center">
<div class="w-16 h-16 bg-blue-50 rounded-full flex items-center justify-center mb-6">
<i data-lucide="smartphone" class="w-8 h-8 text-blue-600"></i>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Conexión con WhatsApp</h2>
<p class="text-gray-500 mb-8 max-w-md">Escanea el código QR para vincular tu número de empresa.</p>
<div id="waStatusContainer" class="w-full flex flex-col items-center justify-center min-h-[250px] bg-gray-50 rounded-xl border-2 border-dashed border-gray-200 p-6 mb-6">
<div class="animate-pulse flex flex-col items-center">
<div class="w-10 h-10 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mb-4"></div>
<span class="text-sm font-bold text-gray-400">Iniciando instancia segura...</span>
</div>
</div>
<button onclick="checkWhatsappStatus()" class="bg-slate-800 hover:bg-slate-700 text-white font-bold py-3 px-8 rounded-xl transition shadow-lg flex items-center gap-2 mb-8">
<i data-lucide="refresh-cw" class="w-4 h-4"></i> Actualizar Estado
</button>
<div id="view-whatsapp" class="tab-content hidden h-full fade-in overflow-y-auto scroller pb-10">
<div class="max-w-5xl mx-auto mt-6">
<div class="mb-8">
<h2 class="text-2xl font-black text-slate-800 tracking-tight flex items-center gap-3">
<span class="bg-green-100 p-2.5 rounded-xl text-green-600 shadow-sm"><i data-lucide="message-circle"></i></span>
Centro de Notificaciones Automáticas
</h2>
<p class="text-sm text-slate-500 mt-2 font-medium">Vincula tu número y decide qué eventos disparan un mensaje al cliente.</p>
</div>
<div class="w-full border-t border-gray-100 pt-6 mt-2 flex items-center justify-between px-4">
<div class="text-left">
<h4 class="font-bold text-gray-800 flex items-center gap-2">
<i data-lucide="bot" class="w-4 h-4 text-blue-600"></i> Modo "Escribiendo..."
</h4>
<p class="text-xs text-gray-500 mt-1 max-w-[250px]">Simula que un humano está tecleando el mensaje. Si lo desactivas, los mensajes llegarán de forma instantánea.</p>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="bg-white rounded-3xl shadow-sm border border-slate-100 p-8 flex flex-col h-fit">
<h3 class="text-lg font-bold text-slate-800 border-b border-slate-100 pb-4 mb-6 flex items-center gap-2">
<i data-lucide="smartphone" class="w-5 h-5 text-blue-600"></i> Estado del Dispositivo
</h3>
<div id="waStatusContainer" class="w-full flex flex-col items-center justify-center min-h-[200px] bg-slate-50 rounded-2xl border-2 border-dashed border-slate-200 p-6 mb-6">
<div class="animate-pulse flex flex-col items-center">
<div class="w-10 h-10 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mb-4"></div>
<span class="text-sm font-bold text-slate-400">Iniciando instancia...</span>
</div>
</div>
<div class="relative inline-block w-12 mr-2 align-middle select-none transition duration-200 ease-in">
<input type="checkbox" name="toggle" id="waDelayToggle" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="waDelayToggle" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
<button onclick="checkWhatsappStatus()" class="w-full bg-slate-800 hover:bg-slate-700 text-white font-bold py-3 px-6 rounded-xl transition shadow-md flex items-center justify-center gap-2">
<i data-lucide="refresh-cw" class="w-4 h-4"></i> Actualizar Estado de Conexión
</button>
</div>
<div class="bg-white rounded-3xl shadow-sm border border-slate-100 overflow-hidden flex flex-col h-fit">
<div class="p-6 border-b border-slate-100 bg-slate-50/50 flex justify-between items-center">
<h3 class="text-lg font-bold text-slate-800 flex items-center gap-2">
<i data-lucide="zap" class="w-5 h-5 text-amber-500"></i> Reglas de Envío
</h3>
<button onclick="saveWaSettings()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-xs font-bold shadow-md transition-all active:scale-95 flex items-center gap-2">
<i data-lucide="save" class="w-3.5 h-3.5"></i> Guardar Ajustes
</button>
</div>
<div class="p-2">
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between border-b border-slate-100">
<div>
<p class="font-bold text-slate-700 text-sm">Modo "Escribiendo..."</p>
<p class="text-xs text-slate-400 mt-0.5">Añade un retraso natural antes de enviar.</p>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_delay" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_delay" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between border-b border-slate-100">
<div class="flex items-start gap-3">
<div class="bg-blue-100 p-2 rounded-lg text-blue-600 mt-0.5"><i data-lucide="user-plus" class="w-4 h-4"></i></div>
<div>
<p class="font-bold text-slate-700 text-sm">Mensaje de Bienvenida</p>
<p class="text-xs text-slate-400 mt-0.5">Al registrar el servicio en el sistema.</p>
</div>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_evt_welcome" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_evt_welcome" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between border-b border-slate-100">
<div class="flex items-start gap-3">
<div class="bg-purple-100 p-2 rounded-lg text-purple-600 mt-0.5"><i data-lucide="calendar-clock" class="w-4 h-4"></i></div>
<div>
<p class="font-bold text-slate-700 text-sm">Cambio de Cita</p>
<p class="text-xs text-slate-400 mt-0.5">Cuando se agenda o modifica la fecha de visita.</p>
</div>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_evt_date" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_evt_date" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between border-b border-slate-100">
<div class="flex items-start gap-3">
<div class="bg-amber-100 p-2 rounded-lg text-amber-600 mt-0.5"><i data-lucide="car" class="w-4 h-4"></i></div>
<div>
<p class="font-bold text-slate-700 text-sm">Técnico de Camino</p>
<p class="text-xs text-slate-400 mt-0.5">Avisa al cliente minutos antes de llegar.</p>
</div>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_evt_onway" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_evt_onway" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between border-b border-slate-100">
<div class="flex items-start gap-3">
<div class="bg-emerald-100 p-2 rounded-lg text-emerald-600 mt-0.5"><i data-lucide="check-circle" class="w-4 h-4"></i></div>
<div>
<p class="font-bold text-slate-700 text-sm">Servicio Finalizado</p>
<p class="text-xs text-slate-400 mt-0.5">Notifica el cierre de la avería.</p>
</div>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_evt_finished" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_evt_finished" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
<div class="p-4 hover:bg-slate-50 transition-colors flex items-center justify-between">
<div class="flex items-start gap-3">
<div class="bg-rose-100 p-2 rounded-lg text-rose-600 mt-0.5"><i data-lucide="star" class="w-4 h-4"></i></div>
<div>
<p class="font-bold text-slate-700 text-sm">Encuesta de Calidad</p>
<p class="text-xs text-slate-400 mt-0.5">Se envía automáticamente tras finalizar.</p>
</div>
</div>
<div class="relative inline-block w-12 align-middle select-none">
<input type="checkbox" id="cfg_evt_survey" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
<label for="cfg_evt_survey" class="toggle-label block overflow-hidden h-6 rounded-full bg-slate-200 cursor-pointer"></label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -224,18 +315,55 @@
showTab('templates');
loadTemplates();
// Cargar preferencia de delay de WhatsApp
const toggle = document.getElementById('waDelayToggle');
const savedSetting = localStorage.getItem('wa_delay_enabled');
// Por defecto activo si no hay ajuste guardado
toggle.checked = savedSetting === null ? true : savedSetting === 'true';
toggle.addEventListener('change', (e) => {
localStorage.setItem('wa_delay_enabled', e.target.checked);
showToast(`Modo "Escribiendo" ${e.target.checked ? 'Activado' : 'Desactivado'}`);
});
// Cargar configuración de eventos de WhatsApp al inicio
loadWaSettings();
});
function loadWaSettings() {
// Lee del LocalStorage.
// TODO: En el futuro, cambiar esto por un fetch a la BD (ej. /config/whatsapp)
const getCfg = (key, defaultVal) => {
const val = localStorage.getItem(key);
return val === null ? defaultVal : val === 'true';
};
document.getElementById('cfg_delay').checked = getCfg('wa_delay_enabled', true);
document.getElementById('cfg_evt_welcome').checked = getCfg('wa_evt_welcome', true);
document.getElementById('cfg_evt_date').checked = getCfg('wa_evt_date', true);
document.getElementById('cfg_evt_onway').checked = getCfg('wa_evt_onway', true);
document.getElementById('cfg_evt_finished').checked = getCfg('wa_evt_finished', false);
document.getElementById('cfg_evt_survey').checked = getCfg('wa_evt_survey', false);
}
async function saveWaSettings() {
// Guarda los valores actuales de los switches
const settings = {
wa_delay_enabled: document.getElementById('cfg_delay').checked,
wa_evt_welcome: document.getElementById('cfg_evt_welcome').checked,
wa_evt_date: document.getElementById('cfg_evt_date').checked,
wa_evt_onway: document.getElementById('cfg_evt_onway').checked,
wa_evt_finished: document.getElementById('cfg_evt_finished').checked,
wa_evt_survey: document.getElementById('cfg_evt_survey').checked
};
// Guarda en LocalStorage
for (const [key, value] of Object.entries(settings)) {
localStorage.setItem(key, value);
}
// TODO: Aquí pondrías la llamada al Backend para guardar en PostgreSQL
/*
await fetch(`${API_URL}/config/whatsapp`, {
method: 'POST',
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
body: JSON.stringify(settings)
});
*/
showToast("Ajustes de WhatsApp guardados");
}
function showTab(tabId) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
document.getElementById(`view-${tabId}`).classList.remove('hidden');
@@ -298,7 +426,7 @@
async function checkWhatsappStatus() {
const container = document.getElementById('waStatusContainer');
container.innerHTML = `<div class="flex flex-col items-center animate-pulse"><i data-lucide="loader-2" class="w-8 h-8 text-blue-500 animate-spin mb-3"></i><span class="text-sm text-blue-600 font-medium">Verificando instancia...</span></div>`;
container.innerHTML = `<div class="flex flex-col items-center animate-pulse"><div class="w-10 h-10 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mb-4"></div><span class="text-sm font-bold text-slate-400">Verificando instancia...</span></div>`;
lucide.createIcons();
try {
@@ -308,10 +436,10 @@
if (!data.ok) throw new Error(data.error || "Error desconocido");
if (data.state === "open") {
container.innerHTML = `<div class="flex flex-col items-center"><div class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mb-4 shadow-sm border border-green-200"><i data-lucide="check" class="w-10 h-10 text-green-600"></i></div><h4 class="text-xl font-bold text-green-700">Conectado</h4><p class="text-sm text-green-600 mt-1 font-medium">Instancia: ${data.instanceName}</p></div>`;
container.innerHTML = `<div class="flex flex-col items-center"><div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4 shadow-sm border border-green-200"><i data-lucide="check" class="w-8 h-8 text-green-600"></i></div><h4 class="text-xl font-bold text-green-700">Conectado</h4><p class="text-xs text-green-600 mt-1 font-medium bg-green-50 px-2 py-1 rounded">Instancia: ${data.instanceName}</p></div>`;
} else if (data.qr) {
container.innerHTML = `<div class="flex flex-col items-center w-full"><div id="qrcode" class="bg-white p-3 border rounded-lg shadow-sm"></div><p class="text-xs text-orange-500 mt-4 font-bold animate-pulse">Esperando escaneo...</p></div>`;
if(data.qr.startsWith('data:image')) { document.getElementById('qrcode').innerHTML = `<img src="${data.qr}" class="w-48 h-48">`; }
container.innerHTML = `<div class="flex flex-col items-center w-full"><div id="qrcode" class="bg-white p-3 border rounded-xl shadow-sm"></div><p class="text-xs text-orange-500 mt-4 font-bold animate-pulse">Esperando escaneo...</p></div>`;
if(data.qr.startsWith('data:image')) { document.getElementById('qrcode').innerHTML = `<img src="${data.qr}" class="w-48 h-48 rounded-lg">`; }
else { new QRCode(document.getElementById("qrcode"), { text: data.qr, width: 180, height: 180 }); }
} else { container.innerHTML = `<p class="text-orange-500 font-bold">Iniciando... intenta de nuevo en unos segundos.</p>`; }
} catch(e) {