diff --git a/servicios.html b/servicios.html
index 22f7c13..8e5196e 100644
--- a/servicios.html
+++ b/servicios.html
@@ -27,6 +27,10 @@
/* Estilos base para formularios mejorados */
.input-modern { @apply w-full bg-slate-50 border border-slate-200 px-4 py-3 rounded-xl text-sm font-semibold text-slate-700 outline-none transition-all focus:border-blue-500 focus:bg-white focus:ring-2 focus:ring-blue-100; }
.label-modern { @apply block text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1.5 ml-1; }
+
+ /* Estilos para el Modo Edición del Modal */
+ .input-editable { border-bottom: 2px solid #3b82f6 !important; background: #eff6ff !important; border-radius: 0.5rem !important; padding: 4px 8px !important; pointer-events: auto !important; }
+ .input-readonly { border: none !important; background: transparent !important; pointer-events: none; outline: none; }
@@ -132,7 +136,6 @@
-
-
-
${s.assigned_name || 'Sin asignar'}
+
+
+
+
${s.assigned_name || 'Sin asignar'}
+
+
+
+
+
+
+
+
+
+ ${raw.scheduled_date ? cita.split('|')[0] : 'Pte. Cita'}
- ${raw.scheduled_date ? `
-
-
- ${cita}
-
` : ''}
`;
}
@@ -698,7 +717,7 @@
setTimeout(() => { toast.classList.add('hidden'); }, 3500);
}
- function openDetail(id) {
+ function openDetail(id, startInEditMode = false) {
const s = localData.find(x => x.id === id);
if (!s) return;
const raw = s.raw_data;
@@ -708,26 +727,21 @@
const companyName = raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || "Particular";
document.getElementById('detCompany').innerText = companyName;
- document.getElementById('detName').innerText = raw["Nombre Cliente"] || raw["CLIENTE"] || "Asegurado Sin Nombre";
+
+ // RELLENADO DE CAMPOS PARA EL EDITOR Y VISTA
+ const clientName = raw["Nombre Cliente"] || raw["CLIENTE"] || "Asegurado Sin Nombre";
+ if(document.getElementById('editName')) document.getElementById('editName').value = clientName;
const rawPhone = raw["Teléfono"] || raw["TELEFONOS"] || raw["TELEFONO"] || "";
const matchPhone = rawPhone.toString().match(/[6789]\d{8}/);
const singlePhone = matchPhone ? matchPhone[0] : "";
+ if(document.getElementById('editPhone')) document.getElementById('editPhone').value = singlePhone;
- if (singlePhone) {
- document.getElementById('detPhone').innerText = singlePhone;
- document.getElementById('detPhoneLink').href = `tel:+34${singlePhone}`;
- document.getElementById('detPhoneLink').classList.remove('text-slate-400', 'pointer-events-none');
- document.getElementById('detPhoneLink').classList.add('text-blue-600');
- } else {
- document.getElementById('detPhone').innerText = "Sin Teléfono";
- document.getElementById('detPhoneLink').href = "#";
- document.getElementById('detPhoneLink').classList.remove('text-blue-600');
- document.getElementById('detPhoneLink').classList.add('text-slate-400', 'pointer-events-none');
- }
+ const fullAddr = `${raw["Dirección"] || ""} ${raw["Población"] || ""}`.trim();
+ if(document.getElementById('editAddr')) document.getElementById('editAddr').value = fullAddr;
- document.getElementById('detAddrText').innerText = `${raw["Dirección"] || "Dirección no especificada"} ${raw["Población"] || ""}`;
- document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "Sin notas.").replace(/\n/g, '
');
+ const descContent = raw["Descripción"] || raw["DESCRIPCION"] || "Sin notas.";
+ if(document.getElementById('editDesc')) document.getElementById('editDesc').value = descContent;
const stateInfo = s._stateInfo;
@@ -761,6 +775,13 @@
}
document.getElementById('detailModal').classList.remove('hidden');
+
+ if (startInEditMode) {
+ enableEditing();
+ } else {
+ cancelEditing();
+ }
+
lucide.createIcons();
}
@@ -876,6 +897,8 @@
async function saveNewService(e) {
e.preventDefault();
const action = e.submitter.value;
+ const is_company = document.getElementById('isCompanyCheck').checked;
+
const data = {
phone: document.getElementById('nPhone').value,
name: document.getElementById('nName').value,
@@ -883,19 +906,70 @@
description: document.getElementById('nDesc').value,
guild_id: document.getElementById('nGuild').value,
assigned_to: document.getElementById('nWorker').value || null,
- duration_minutes: document.getElementById('nDuration').value // <--- CAPTURA DE DURACIÓN
+ duration_minutes: document.getElementById('nDuration').value,
+ is_company: is_company,
+ company_name: is_company ? document.getElementById('nCompanySelect').value : 'Particular',
+ company_ref: is_company ? document.getElementById('nExpRef').value : null,
+ mode: action
};
+
try {
const res = await fetch(`${API_URL}/services/manual-high`, {
method: 'POST', headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
- body: JSON.stringify({ ...data, mode: action })
+ body: JSON.stringify(data)
});
- if (res.ok) { closeCreateModal(); refreshPanel(); }
+ if (res.ok) { closeCreateModal(); refreshPanel(); showToast("✅ Servicio guardado correctamente"); }
} catch(e) { alert("Error al guardar"); }
}
function closeDetailModal() { document.getElementById('detailModal').classList.add('hidden'); }
- function openCreateModal() { document.getElementById('createModal').classList.remove('hidden'); }
+
+ async function openCreateModal() {
+ document.getElementById('createModal').classList.remove('hidden');
+ document.getElementById('isCompanyCheck').checked = false;
+ toggleCompanyFields(false);
+
+ try {
+ const res = await fetch(`${API_URL}/companies`, {
+ headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
+ });
+ const data = await res.json();
+ const sel = document.getElementById('nCompanySelect');
+ sel.innerHTML = '
';
+ data.companies.forEach(c => {
+ sel.innerHTML += `
`;
+ });
+ } catch(e) {}
+ lucide.createIcons();
+ }
+
+ function toggleCompanyFields(show) {
+ const fields = document.getElementById('companyFields');
+ fields.classList.toggle('hidden', !show);
+ if(!show) {
+ document.getElementById('nExpRef').value = "";
+ document.getElementById('refAlert').classList.add('hidden');
+ }
+ }
+
+ async function checkDuplicateRef(ref) {
+ if(!ref) return;
+ const res = await fetch(`${API_URL}/services/check-ref?ref=${ref}`, {
+ headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
+ });
+ const data = await res.json();
+ const alertEl = document.getElementById('refAlert');
+ const inputEl = document.getElementById('nExpRef');
+
+ if(data.exists) {
+ alertEl.classList.remove('hidden');
+ inputEl.classList.add('border-red-500', 'bg-red-50');
+ } else {
+ alertEl.classList.add('hidden');
+ inputEl.classList.remove('border-red-500', 'bg-red-50');
+ }
+ }
+
function closeCreateModal() { document.getElementById('createModal').classList.add('hidden'); }
async function loadGuilds() {
@@ -917,9 +991,9 @@
}
async function copyClientPortalLink() {
- const phone = document.getElementById('detPhone').innerText;
- const name = document.getElementById('detName').innerText;
- const addr = document.getElementById('detAddrText').innerText;
+ const phone = document.getElementById('editPhone').value;
+ const name = document.getElementById('editName').value;
+ const addr = document.getElementById('editAddr').value;
if (!phone || phone === "Sin Teléfono") {
showToast("No hay un teléfono válido para este cliente.", "warning");
@@ -955,7 +1029,7 @@
setTimeout(() => {
btn.innerHTML = originalHtml;
- btn.className = "text-[10px] font-black bg-blue-50 border border-blue-100 hover:bg-blue-600 hover:text-white text-blue-600 px-3 py-1.5 rounded-lg flex items-center gap-1.5 transition-all shadow-sm active:scale-95";
+ btn.className = "text-[10px] font-black bg-blue-50 border border-blue-100 hover:bg-blue-600 hover:text-white text-blue-600 px-3 py-1.5 rounded-lg flex items-center gap-1.5 transition-all shadow-sm active:scale-95 shrink-0";
lucide.createIcons();
}, 3000);
} else {
@@ -970,6 +1044,88 @@
lucide.createIcons();
}
}
+
+ async function searchClientByPhone(phone) {
+ if (phone.length < 9) {
+ document.getElementById('addrSuggestions').classList.add('hidden');
+ return;
+ }
+ try {
+ const res = await fetch(`${API_URL}/clients/search?phone=${phone}`, {
+ headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
+ });
+ const data = await res.json();
+
+ if (data.ok && data.client) {
+ const nameInput = document.getElementById('nName');
+ if (!nameInput.value) {
+ nameInput.value = data.client.full_name;
+ nameInput.classList.add('bg-emerald-50');
+ }
+
+ const addrDiv = document.getElementById('addrSuggestions');
+ if (data.client.addresses && data.client.addresses.length > 0) {
+ addrDiv.classList.remove('hidden');
+ if (!document.getElementById('nAddr').value) {
+ document.getElementById('nAddr').value = data.client.addresses[0];
+ }
+ }
+ }
+ } catch (e) { console.error("Error en buscador rápido:", e); }
+ }
+
+ // --- FUNCIONES DEL EDITOR ---
+
+ function enableEditing() {
+ document.getElementById('viewActions').classList.add('hidden');
+ document.getElementById('editActions').classList.remove('hidden');
+
+ ['editName', 'editPhone', 'editAddr', 'editDesc'].forEach(id => {
+ const el = document.getElementById(id);
+ if(el) {
+ el.readOnly = false;
+ el.classList.add('input-editable');
+ el.classList.remove('input-readonly');
+ }
+ });
+ }
+
+ function cancelEditing() {
+ document.getElementById('viewActions').classList.remove('hidden');
+ document.getElementById('editActions').classList.add('hidden');
+
+ ['editName', 'editPhone', 'editAddr', 'editDesc'].forEach(id => {
+ const el = document.getElementById(id);
+ if(el) {
+ el.readOnly = true;
+ el.classList.add('input-readonly');
+ el.classList.remove('input-editable');
+ }
+ });
+ }
+
+ async function saveFullEdit() {
+ const id = document.getElementById('detId').value;
+ const payload = {
+ name: document.getElementById('editName').value,
+ phone: document.getElementById('editPhone').value,
+ address: document.getElementById('editAddr').value,
+ description: document.getElementById('editDesc').value
+ };
+ try {
+ const res = await fetch(`${API_URL}/providers/scraped/${id}`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem("token")}` },
+ body: JSON.stringify(payload)
+ });
+ if (res.ok) {
+ showToast("✅ Ficha actualizada");
+ cancelEditing();
+ refreshPanel();
+ }
+ } catch (e) { showToast("Error al guardar", "warning"); }
+ }
+