232 lines
13 KiB
HTML
232 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Importar TO&DO - IntegraRepara</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://unpkg.com/lucide@latest"></script>
|
|
<style>
|
|
.fade-in { animation: fadeIn 0.3s ease-in-out; }
|
|
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-50 text-slate-800 font-sans antialiased min-h-screen p-6">
|
|
|
|
<div class="max-w-3xl mx-auto fade-in">
|
|
|
|
<div class="flex items-center gap-4 mb-8">
|
|
<button onclick="window.close()" class="w-10 h-10 bg-white border border-slate-200 rounded-full flex items-center justify-center hover:bg-slate-50 transition-colors shadow-sm">
|
|
<i data-lucide="arrow-left" class="w-5 h-5 text-slate-600"></i>
|
|
</button>
|
|
<div>
|
|
<h1 class="text-2xl font-black text-slate-800 flex items-center gap-2">
|
|
<i data-lucide="mail-plus" class="w-6 h-6 text-teal-600"></i> Importador TO&DO
|
|
</h1>
|
|
<p class="text-xs text-slate-500 font-bold uppercase tracking-widest mt-1">Pega el texto del correo y revisa los datos</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white p-6 rounded-3xl border border-slate-200 shadow-sm mb-6">
|
|
<label class="text-[10px] font-black text-teal-600 uppercase tracking-widest mb-2 flex items-center gap-1.5"><i data-lucide="clipboard" class="w-3 h-3"></i> Texto del Correo</label>
|
|
<textarea id="rawText" rows="6" class="w-full bg-slate-50 border border-slate-200 rounded-2xl p-4 text-xs font-mono text-slate-600 outline-none focus:ring-2 focus:ring-teal-500 transition-all resize-none shadow-inner" placeholder="Pega aquí todo el texto del correo electrónico..."></textarea>
|
|
|
|
<button onclick="analizarTexto()" class="mt-4 w-full bg-teal-600 hover:bg-teal-700 text-white font-black py-3.5 rounded-xl shadow-lg transition-all uppercase tracking-widest text-xs flex items-center justify-center gap-2">
|
|
<i data-lucide="scan-text" class="w-4 h-4"></i> Analizar Datos
|
|
</button>
|
|
</div>
|
|
|
|
<div id="previewSection" class="hidden bg-white p-6 rounded-3xl border border-slate-200 shadow-sm fade-in space-y-4">
|
|
<div class="flex items-center justify-between border-b border-slate-100 pb-4 mb-4">
|
|
<h2 class="text-sm font-black text-slate-800 uppercase tracking-widest flex items-center gap-2"><i data-lucide="check-circle-2" class="w-5 h-5 text-emerald-500"></i> Revisión de Datos</h2>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Referencia</label>
|
|
<input type="text" id="f_ref" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
</div>
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Compañía</label>
|
|
<input type="text" id="f_cia" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold text-blue-600 outline-none focus:border-teal-500">
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Asegurado</label>
|
|
<input type="text" id="f_name" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Teléfono</label>
|
|
<input type="text" id="f_phone" class="w-full bg-emerald-50 border border-emerald-100 p-3 rounded-xl text-sm font-black text-emerald-700 outline-none focus:border-emerald-500">
|
|
</div>
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Prioridad</label>
|
|
<select id="f_urgent" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
<option value="false">Normal</option>
|
|
<option value="true">🚨 Urgente</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Dirección Completa</label>
|
|
<input type="text" id="f_address" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Población</label>
|
|
<input type="text" id="f_pop" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
</div>
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Código Postal</label>
|
|
<input type="text" id="f_cp" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-bold outline-none focus:border-teal-500">
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Avería / Descripción</label>
|
|
<textarea id="f_desc" rows="3" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-sm font-medium outline-none focus:border-teal-500 resize-none"></textarea>
|
|
</div>
|
|
|
|
<button id="btnSave" onclick="guardarExpediente()" class="w-full mt-2 bg-slate-900 hover:bg-black text-white font-black py-4 rounded-xl shadow-xl transition-all uppercase tracking-[0.15em] text-xs flex items-center justify-center gap-2 active:scale-95">
|
|
<i data-lucide="upload-cloud" class="w-4 h-4"></i> Insertar en el Buzón
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="toast" class="fixed bottom-8 right-8 bg-slate-900 text-white px-8 py-4 rounded-2xl shadow-2xl hidden z-50 border border-white/10">
|
|
<span id="toastMsg" class="font-bold text-sm"></span>
|
|
</div>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
const API_URL = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
|
|
? 'http://localhost:3000'
|
|
: 'https://integrarepara-api.integrarepara.es';
|
|
|
|
// 🧠 EL CEREBRO: Analiza el texto del correo
|
|
function analizarTexto() {
|
|
const text = document.getElementById("rawText").value;
|
|
if(!text.trim()) return;
|
|
|
|
// Función para extraer una línea usando una expresión regular
|
|
const ext = (regex) => (text.match(regex) || [])[1]?.trim() || "";
|
|
|
|
let ref = ext(/NUMERO_PARTE:\s*(.+)/i) || ext(/EXPEDIENTE:\s*(.+)/i);
|
|
let name = ext(/ASEGURADO:\s*(.+)/i).replace(/^\.\s*/, ''); // Limpia el punto inicial si lo hay
|
|
let address = ext(/DIRECCION:\s*(.+)/i) || ext(/CALLE:\s*(.+)/i);
|
|
let cp = ext(/CODIGO_POSTAL:\s*(\d{5})/i) || ext(/CP\s*(\d{5})/i);
|
|
let pop = ext(/LOCALIDAD:\s*(.+)/i) || ext(/Población:\s*([^,]+)/i);
|
|
|
|
// Busca varios teléfonos y coge el primero válido
|
|
let phone1 = ext(/TELEFONO1:\s*(\d+)/i);
|
|
let phone2 = ext(/TIPO:\s*MOVIL\s*\nNUMERO:\s*(\d+)/i);
|
|
let phone = phone1 || phone2;
|
|
|
|
let urgent = ext(/URGENTE:\s*(SI|NO)/i);
|
|
let cia = ext(/CLIENTE:\s*(.+)/i);
|
|
|
|
// Extraer la descripción (Busca desde DESCRIPCION: hasta el siguiente apartado en mayúsculas)
|
|
let desc = "";
|
|
let descMatch = text.match(/DESCRIPCION:\s*\n(.*?)(?=\n[A-Z_]+:|$)/is);
|
|
if (descMatch) desc = descMatch[1].trim();
|
|
else desc = ext(/DESCRIPCION_DEL_SINIESTRO:\s*(.+)/i);
|
|
|
|
// Rellenar formulario
|
|
document.getElementById("f_ref").value = ref || "FALTA_REFERENCIA";
|
|
document.getElementById("f_name").value = name;
|
|
document.getElementById("f_address").value = address;
|
|
document.getElementById("f_cp").value = cp;
|
|
document.getElementById("f_pop").value = pop;
|
|
document.getElementById("f_phone").value = phone;
|
|
// 🛑 CORRECCIÓN: Asegurarnos de limpiar espacios antes de comparar
|
|
document.getElementById("f_urgent").value = (urgent.toUpperCase().trim() === 'SI') ? 'true' : 'false'; document.getElementById("f_cia").value = cia ? ("TO&DO " + cia) : "TO&DO";
|
|
document.getElementById("f_desc").value = desc;
|
|
|
|
document.getElementById("previewSection").classList.remove("hidden");
|
|
setTimeout(() => {
|
|
document.getElementById("previewSection").scrollIntoView({ behavior: 'smooth', block: 'end' });
|
|
}, 100);
|
|
}
|
|
|
|
// 🚀 ENVIAR A LA BASE DE DATOS
|
|
async function guardarExpediente() {
|
|
const btn = document.getElementById('btnSave');
|
|
btn.disabled = true;
|
|
btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> Guardando...`;
|
|
lucide.createIcons();
|
|
|
|
const ref = document.getElementById("f_ref").value;
|
|
const isUrgent = document.getElementById("f_urgent").value === 'true';
|
|
|
|
// 🛑 CORRECCIÓN: Hacemos el paquete "plano" para que la BD lo trague directo
|
|
const rawData = {
|
|
"service_ref": ref,
|
|
"status": "pending",
|
|
"is_urgent": isUrgent,
|
|
"Referencia": ref,
|
|
"Nombre Cliente": document.getElementById("f_name").value,
|
|
"Teléfono": document.getElementById("f_phone").value,
|
|
"Dirección": document.getElementById("f_address").value,
|
|
"Población": document.getElementById("f_pop").value,
|
|
"Código Postal": document.getElementById("f_cp").value,
|
|
"Compañía": document.getElementById("f_cia").value,
|
|
"Descripción": document.getElementById("f_desc").value,
|
|
"Urgente": isUrgent ? "Sí" : "No",
|
|
"Origen": "Importador Manual"
|
|
};
|
|
|
|
const payload = {
|
|
provider: "todo",
|
|
services: [ rawData ] // Lo mandamos sin envoltorios extra
|
|
};
|
|
|
|
try {
|
|
// Usamos el mismo endpoint que el robot. ¡El servidor se encargará del resto!
|
|
const res = await fetch(`${API_URL}/providers/scraped`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${localStorage.getItem("token")}`
|
|
},
|
|
body: JSON.stringify(payload)
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
if (data.ok) {
|
|
showToast("✅ Expediente insertado con éxito en el buzón");
|
|
setTimeout(() => {
|
|
window.close(); // Cerramos la ventana y volvemos a proveedores
|
|
}, 1500);
|
|
} else {
|
|
showToast("❌ Error al guardar en base de datos", true);
|
|
btn.disabled = false;
|
|
btn.innerHTML = `<i data-lucide="upload-cloud" class="w-4 h-4"></i> Insertar en el Buzón`;
|
|
lucide.createIcons();
|
|
}
|
|
} catch (e) {
|
|
showToast("❌ Error de red", true);
|
|
btn.disabled = false;
|
|
btn.innerHTML = `<i data-lucide="upload-cloud" class="w-4 h-4"></i> Insertar en el Buzón`;
|
|
lucide.createIcons();
|
|
}
|
|
}
|
|
|
|
function showToast(msg, isError = false) {
|
|
const t = document.getElementById('toast');
|
|
const m = document.getElementById('toastMsg');
|
|
t.className = `fixed bottom-8 right-8 px-8 py-4 rounded-2xl shadow-2xl z-50 flex items-center gap-3 transition-all ${isError ? 'bg-red-600' : 'bg-slate-900'} text-white`;
|
|
m.innerText = msg;
|
|
t.classList.remove('hidden');
|
|
setTimeout(() => t.classList.add('hidden'), 3500);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |