Actualizar configuracion.html
This commit is contained in:
@@ -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 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>
|
||||
<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="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-gray-400">Iniciando instancia segura...</span>
|
||||
<span class="text-sm font-bold text-slate-400">Iniciando instancia...</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 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 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>
|
||||
|
||||
<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>
|
||||
<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,17 +315,54 @@
|
||||
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';
|
||||
// Cargar configuración de eventos de WhatsApp al inicio
|
||||
loadWaSettings();
|
||||
});
|
||||
|
||||
toggle.addEventListener('change', (e) => {
|
||||
localStorage.setItem('wa_delay_enabled', e.target.checked);
|
||||
showToast(`Modo "Escribiendo" ${e.target.checked ? 'Activado' : 'Desactivado'}`);
|
||||
});
|
||||
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'));
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user