Actualizar calendario.html
This commit is contained in:
@@ -46,7 +46,7 @@
|
|||||||
.desc-box { background: white; border: 1px solid #e2e8f0; border-radius: 1.5rem; padding: 1.25rem; }
|
.desc-box { background: white; border: 1px solid #e2e8f0; border-radius: 1.5rem; padding: 1.25rem; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="text-slate-800 font-sans antialiased h-screen flex flex-col overflow-hidden relative">
|
<body class="text-slate-800 font-sans antialiased h-screen flex flex-col overflow-hidden relative text-left">
|
||||||
|
|
||||||
<header class="bg-white px-5 pt-safe mt-6 pb-4 shadow-sm z-20 shrink-0 border-b border-slate-200">
|
<header class="bg-white px-5 pt-safe mt-6 pb-4 shadow-sm z-20 shrink-0 border-b border-slate-200">
|
||||||
<div class="flex items-center gap-3 mb-4">
|
<div class="flex items-center gap-3 mb-4">
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<i data-lucide="loader-2" class="w-8 h-8 animate-spin mx-auto text-primary-dynamic mb-2"></i>
|
<i data-lucide="loader-2" class="w-8 h-8 animate-spin mx-auto text-primary-dynamic mb-2"></i>
|
||||||
<p class="text-xs font-bold uppercase tracking-widest text-slate-400">Consultando Base de Datos...</p>
|
<p class="text-xs font-bold uppercase tracking-widest text-slate-400">Consultando Base de Datos...</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="dayTitle" class="font-black text-slate-400 uppercase tracking-widest text-[10px] mb-4 hidden">Servicios</div>
|
<div id="dayTitle" class="font-black text-slate-400 uppercase tracking-widest text-[10px] mb-4 hidden text-left">Servicios</div>
|
||||||
<div id="servicesList" class="space-y-4 hidden fade-in"></div>
|
<div id="servicesList" class="space-y-4 hidden fade-in"></div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@@ -111,17 +111,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<button onclick="quickUpdate('camino')" class="bg-white border border-slate-200 text-primary-dynamic font-black p-5 rounded-3xl flex flex-col items-center gap-2 shadow-sm active:bg-slate-50 transition-all">
|
<button onclick="quickUpdate('camino')" class="bg-white border border-slate-200 text-primary-dynamic font-black p-5 rounded-3xl flex flex-col items-center gap-2 shadow-sm active:bg-slate-50 transition-all text-center">
|
||||||
<i data-lucide="car" class="w-8 h-8"></i>
|
<i data-lucide="car" class="w-8 h-8"></i>
|
||||||
<span class="text-[10px] uppercase tracking-widest">De Camino</span>
|
<span class="text-[10px] uppercase tracking-widest">De Camino</span>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="quickUpdate('trabajando')" class="bg-white border border-slate-200 text-primary-dynamic font-black p-5 rounded-3xl flex flex-col items-center gap-2 shadow-sm active:bg-slate-50 transition-all">
|
<button onclick="quickUpdate('trabajando')" class="bg-white border border-slate-200 text-primary-dynamic font-black p-5 rounded-3xl flex flex-col items-center gap-2 shadow-sm active:bg-slate-50 transition-all text-center">
|
||||||
<i data-lucide="wrench" class="w-8 h-8"></i>
|
<i data-lucide="wrench" class="w-8 h-8"></i>
|
||||||
<span class="text-[10px] uppercase tracking-widest">He Llegado</span>
|
<span class="text-[10px] uppercase tracking-widest">He Llegado</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white p-6 rounded-[2.5rem] shadow-sm border border-slate-200">
|
<div class="bg-white p-6 rounded-[2.5rem] shadow-sm border border-slate-200 text-left">
|
||||||
<div class="flex justify-between items-start mb-1">
|
<div class="flex justify-between items-start mb-1">
|
||||||
<p class="text-[9px] font-black text-primary-dynamic uppercase tracking-widest" id="detCompany">Compañía</p>
|
<p class="text-[9px] font-black text-primary-dynamic uppercase tracking-widest" id="detCompany">Compañía</p>
|
||||||
<span id="detRef" class="text-[9px] font-black text-slate-400 uppercase"></span>
|
<span id="detRef" class="text-[9px] font-black text-slate-400 uppercase"></span>
|
||||||
@@ -131,12 +131,12 @@
|
|||||||
<button onclick="callClient()" class="w-full bg-primary-dynamic text-white font-black py-4 rounded-2xl shadow-xl flex items-center justify-center gap-3 uppercase text-sm tracking-widest active:scale-95 transition-all">
|
<button onclick="callClient()" class="w-full bg-primary-dynamic text-white font-black py-4 rounded-2xl shadow-xl flex items-center justify-center gap-3 uppercase text-sm tracking-widest active:scale-95 transition-all">
|
||||||
<i data-lucide="phone" class="w-5 h-5 fill-current"></i> Llamar al Cliente
|
<i data-lucide="phone" class="w-5 h-5 fill-current"></i> Llamar al Cliente
|
||||||
</button>
|
</button>
|
||||||
<button onclick="openWhatsApp()" class="w-full mt-3 bg-slate-50 text-slate-700 font-black py-3 rounded-2xl border border-slate-200 flex items-center justify-center gap-2 text-xs uppercase tracking-widest active:scale-95 transition-all">
|
<button onclick="openWhatsApp()" class="w-full mt-3 bg-slate-50 text-slate-700 font-black py-3 rounded-2xl border border-slate-200 flex items-center justify-center gap-2 text-xs uppercase tracking-widest active:scale-95 transition-all text-center">
|
||||||
<i data-lucide="message-circle" class="w-4 h-4 text-emerald-500"></i> WhatsApp
|
<i data-lucide="message-circle" class="w-4 h-4 text-emerald-500"></i> WhatsApp
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white p-6 rounded-[2.5rem] shadow-sm border border-slate-200 relative overflow-hidden">
|
<div class="bg-white p-6 rounded-[2.5rem] shadow-sm border border-slate-200 relative overflow-hidden text-left">
|
||||||
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest mb-2">Ubicación</p>
|
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest mb-2">Ubicación</p>
|
||||||
<p id="detAddress" class="text-base font-bold text-slate-900 uppercase leading-tight mb-6"></p>
|
<p id="detAddress" class="text-base font-bold text-slate-900 uppercase leading-tight mb-6"></p>
|
||||||
|
|
||||||
@@ -151,10 +151,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white border border-slate-200 rounded-3xl p-5 shadow-sm space-y-4">
|
<div class="bg-white border border-slate-200 rounded-3xl p-5 shadow-sm space-y-4 text-left">
|
||||||
<p class="text-[10px] font-black text-blue-600 uppercase tracking-widest border-b border-slate-100 pb-2 flex items-center gap-1.5"><i data-lucide="calendar-clock" class="w-4 h-4"></i> Asignar Fechas y Tiempos</p>
|
<p class="text-[10px] font-black text-blue-600 uppercase tracking-widest border-b border-slate-100 pb-2 flex items-center gap-1.5"><i data-lucide="calendar-clock" class="w-4 h-4"></i> Asignar Fechas y Tiempos</p>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3 text-left">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1 ml-1">Fecha</label>
|
<label class="block text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1 ml-1">Fecha</label>
|
||||||
<input type="date" id="dateInput" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-xs font-bold text-slate-700 shadow-sm outline-none focus:border-blue-400 focus:ring-2 focus:ring-blue-100 transition-all">
|
<input type="date" id="dateInput" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-xs font-bold text-slate-700 shadow-sm outline-none focus:border-blue-400 focus:ring-2 focus:ring-blue-100 transition-all">
|
||||||
@@ -166,8 +166,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1 ml-1">Duración Estimada</label>
|
<label class="block text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1 ml-1 text-left">Duración Estimada</label>
|
||||||
<div class="relative">
|
<div class="relative text-left">
|
||||||
<select id="durationInput" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-xs font-bold text-slate-700 shadow-sm outline-none focus:border-blue-400 focus:ring-2 focus:ring-blue-100 transition-all appearance-none pr-8 cursor-pointer">
|
<select id="durationInput" class="w-full bg-slate-50 border border-slate-200 p-3 rounded-xl text-xs font-bold text-slate-700 shadow-sm outline-none focus:border-blue-400 focus:ring-2 focus:ring-blue-100 transition-all appearance-none pr-8 cursor-pointer">
|
||||||
<option value="15">15 min</option>
|
<option value="15">15 min</option>
|
||||||
<option value="30">30 min</option>
|
<option value="30">30 min</option>
|
||||||
@@ -186,35 +186,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-2">
|
<div class="pt-2 text-left">
|
||||||
<p class="text-[10px] font-black text-slate-800 uppercase ml-1 flex items-center gap-1.5 mb-1.5"><i data-lucide="arrow-right-left" class="w-4 h-4 text-blue-500"></i> Cambio de Estado</p>
|
<p class="text-[10px] font-black text-slate-800 uppercase ml-1 flex items-center gap-1.5 mb-1.5"><i data-lucide="arrow-right-left" class="w-4 h-4 text-blue-500"></i> Cambio de Estado</p>
|
||||||
<div class="relative">
|
<div class="relative text-left">
|
||||||
<select id="detStatusMap" class="w-full bg-slate-800 text-white border-none p-4 rounded-xl text-xs font-bold shadow-lg outline-none cursor-pointer appearance-none pr-10">
|
<select id="detStatusMap" class="w-full bg-slate-800 text-white border-none p-4 rounded-xl text-xs font-bold shadow-lg outline-none cursor-pointer appearance-none pr-10">
|
||||||
</select>
|
</select>
|
||||||
<i data-lucide="chevron-down" class="w-4 h-4 text-slate-400 absolute right-4 top-1/2 -translate-y-1/2 pointer-events-none"></i>
|
<i data-lucide="chevron-down" class="w-4 h-4 text-slate-400 absolute right-4 top-1/2 -translate-y-1/2 pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="btnSaveAppt" onclick="saveAppointment()" class="w-full bg-blue-600 hover:bg-blue-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 mt-2">
|
<button id="btnSaveAppt" onclick="saveAppointment()" class="w-full bg-blue-600 hover:bg-blue-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 mt-2 text-center">
|
||||||
<i data-lucide="save" class="w-4 h-4"></i> Guardar Cambios
|
<i data-lucide="save" class="w-4 h-4"></i> Guardar Cambios
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="desc-box">
|
<div class="desc-box text-left">
|
||||||
<p class="text-[10px] font-black text-primary-dynamic uppercase tracking-widest mb-3 flex items-center gap-2"><i data-lucide="file-text" class="w-4 h-4"></i> Descripción Técnica</p>
|
<p class="text-[10px] font-black text-primary-dynamic uppercase tracking-widest mb-3 flex items-center gap-2"><i data-lucide="file-text" class="w-4 h-4"></i> Descripción Técnica</p>
|
||||||
<div id="detDesc" class="text-sm font-bold text-slate-600 leading-relaxed max-h-60 overflow-y-auto no-scrollbar">--</div>
|
<div id="detDesc" class="text-sm font-bold text-slate-600 leading-relaxed max-h-60 overflow-y-auto no-scrollbar">--</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white border border-slate-200 rounded-3xl overflow-hidden shadow-sm">
|
<div class="bg-white border border-slate-200 rounded-3xl overflow-hidden shadow-sm text-left">
|
||||||
<button onclick="document.getElementById('extraDataBox').classList.toggle('hidden')" class="w-full p-4 flex justify-between items-center text-[10px] font-black text-slate-500 uppercase tracking-widest bg-slate-50">
|
<button onclick="document.getElementById('extraDataBox').classList.toggle('hidden')" class="w-full p-4 flex justify-between items-center text-[10px] font-black text-slate-500 uppercase tracking-widest bg-slate-50">
|
||||||
<span>Ficha técnica completa</span>
|
<span>Ficha técnica completa</span>
|
||||||
<i data-lucide="chevron-right" class="w-4 h-4 text-slate-400"></i>
|
<i data-lucide="chevron-right" class="w-4 h-4 text-slate-400"></i>
|
||||||
</button>
|
</button>
|
||||||
<div id="extraDataBox" class="hidden p-5 space-y-3 bg-white border-t border-slate-100" id="detExtraInfo">
|
<div id="extraDataBox" class="hidden p-5 space-y-3 bg-white border-t border-slate-100">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-4">
|
<div class="pt-4 text-center">
|
||||||
<button onclick="quickUpdate('finalizado')" class="w-full bg-emerald-600 text-white font-black py-5 rounded-[2rem] shadow-xl flex items-center justify-center gap-3 uppercase text-sm tracking-widest active:scale-95 transition-all">
|
<button onclick="quickUpdate('finalizado')" class="w-full bg-emerald-600 text-white font-black py-5 rounded-[2rem] shadow-xl flex items-center justify-center gap-3 uppercase text-sm tracking-widest active:scale-95 transition-all">
|
||||||
<i data-lucide="check-circle" class="w-6 h-6"></i> Finalizar Trabajo
|
<i data-lucide="check-circle" class="w-6 h-6"></i> Finalizar Trabajo
|
||||||
</button>
|
</button>
|
||||||
@@ -237,9 +237,8 @@
|
|||||||
let systemStatuses = [];
|
let systemStatuses = [];
|
||||||
let systemGuilds = [];
|
let systemGuilds = [];
|
||||||
let currentWeekStart = new Date();
|
let currentWeekStart = new Date();
|
||||||
let selectedDateStr = "";
|
let selectedDateStr = "";
|
||||||
|
|
||||||
// --- SISTEMA DE TEMA DINÁMICO ---
|
|
||||||
async function applyTheme() {
|
async function applyTheme() {
|
||||||
try {
|
try {
|
||||||
let theme = JSON.parse(localStorage.getItem('app_theme'));
|
let theme = JSON.parse(localStorage.getItem('app_theme'));
|
||||||
@@ -338,7 +337,7 @@
|
|||||||
function selectDate(isoDate) {
|
function selectDate(isoDate) {
|
||||||
selectedDateStr = isoDate;
|
selectedDateStr = isoDate;
|
||||||
buildWeekCalendar();
|
buildWeekCalendar();
|
||||||
renderServices();
|
renderServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadStatuses() {
|
async function loadStatuses() {
|
||||||
@@ -416,11 +415,22 @@
|
|||||||
let compShort = (raw["Compañía"] || "Particular").split('-')[0].trim().substring(0, 15);
|
let compShort = (raw["Compañía"] || "Particular").split('-')[0].trim().substring(0, 15);
|
||||||
const guildObj = systemGuilds.find(g => String(g.id) === String(s.guild_id || raw.guild_id));
|
const guildObj = systemGuilds.find(g => String(g.id) === String(s.guild_id || raw.guild_id));
|
||||||
|
|
||||||
|
// LÓGICA DE ICONO SEGÚN ESTADO
|
||||||
|
let iconName = "clock";
|
||||||
|
const dbStatId = raw.status_operativo;
|
||||||
|
const statusObj = systemStatuses.find(st => String(st.id) === String(dbStatId));
|
||||||
|
const stName = (statusObj?.name || "").toLowerCase();
|
||||||
|
|
||||||
|
if (stName.includes('camino')) iconName = "car";
|
||||||
|
else if (stName.includes('trabajando') || stName.includes('llegado')) iconName = "wrench";
|
||||||
|
else if (stName.includes('incidencia') || stName.includes('pausa')) iconName = "alert-triangle";
|
||||||
|
else if (stName.includes('citado')) iconName = "calendar";
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div onclick="openService(${s.id})" class="bg-white p-6 rounded-[2.5rem] border border-slate-200 shadow-sm active:scale-95 transition-transform flex gap-4 relative overflow-hidden">
|
<div onclick="openService(${s.id})" class="bg-white p-6 rounded-[2.5rem] border border-slate-200 shadow-sm active:scale-95 transition-transform flex gap-4 relative overflow-hidden text-left">
|
||||||
${s.is_urgent ? '<div class="absolute top-0 right-0 bg-primary-dynamic text-white text-[8px] font-black px-3 py-1.5 rounded-bl-xl uppercase tracking-widest z-10">Urgente</div>' : ''}
|
${s.is_urgent ? '<div class="absolute top-0 right-0 bg-primary-dynamic text-white text-[8px] font-black px-3 py-1.5 rounded-bl-xl uppercase tracking-widest z-10">Urgente</div>' : ''}
|
||||||
<div class="flex flex-col items-center justify-center border-r border-slate-100 pr-4 shrink-0 min-w-[70px]">
|
<div class="flex flex-col items-center justify-center border-r border-slate-100 pr-4 shrink-0 min-w-[70px]">
|
||||||
<i data-lucide="clock" class="w-6 h-6 text-primary-dynamic mb-1"></i>
|
<i data-lucide="${iconName}" class="w-6 h-6 text-primary-dynamic mb-1"></i>
|
||||||
<span class="font-black text-slate-900 text-base">${time}</span>
|
<span class="font-black text-slate-900 text-base">${time}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
@@ -463,30 +473,30 @@
|
|||||||
document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "Sin notas.").replace(/\n/g, '<br>');
|
document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "Sin notas.").replace(/\n/g, '<br>');
|
||||||
|
|
||||||
const extraContainer = document.getElementById('extraDataBox');
|
const extraContainer = document.getElementById('extraDataBox');
|
||||||
|
extraContainer.innerHTML = '';
|
||||||
let detailsHtml = '';
|
let detailsHtml = '';
|
||||||
const skipKeys = ["Nombre Cliente", "CLIENTE", "Dirección", "DOMICILIO", "Población", "POBLACION-PROVINCIA", "scheduled_date", "scheduled_time", "status_operativo", "duration_minutes", "assigned_to", "guild_id", "Código Postal", "assigned_to_name", "Descripción", "DESCRIPCION", "Compañía", "COMPAÑIA"];
|
const skipKeys = ["Nombre Cliente", "CLIENTE", "Dirección", "DOMICILIO", "Población", "POBLACION-PROVINCIA", "scheduled_date", "scheduled_time", "status_operativo", "duration_minutes", "assigned_to", "guild_id", "Código Postal", "assigned_to_name", "Descripción", "DESCRIPCION", "Compañía", "COMPAÑIA", "called_times", "appointment_status"];
|
||||||
|
|
||||||
for(let key in raw) {
|
for(let key in raw) {
|
||||||
if(skipKeys.includes(key)) continue;
|
if(skipKeys.includes(key)) continue;
|
||||||
let valStr = String(raw[key] || "");
|
let valStr = String(raw[key] || "");
|
||||||
if(valStr.trim() === "") continue;
|
if(valStr.trim() === "" || valStr === "null") continue;
|
||||||
detailsHtml += `<div class="border-b border-slate-100 pb-2 mb-2 last:border-0 flex flex-col gap-0.5"><span class="text-[8px] font-black text-slate-400 uppercase tracking-widest">${key}</span><span class="text-[11px] font-bold text-slate-700 break-words">${valStr}</span></div>`;
|
detailsHtml += `<div class="border-b border-slate-100 pb-2 mb-2 last:border-0 flex flex-col gap-0.5"><span class="text-[8px] font-black text-slate-400 uppercase tracking-widest">${key}</span><span class="text-[11px] font-bold text-slate-700 break-words">${valStr}</span></div>`;
|
||||||
}
|
}
|
||||||
extraContainer.innerHTML = detailsHtml || '<p class="text-xs text-slate-400">Sin datos adicionales.</p>';
|
extraContainer.innerHTML = detailsHtml || '<p class="text-xs text-slate-400">Sin datos adicionales.</p>';
|
||||||
|
|
||||||
// CARGAMOS LA FECHA, LA HORA Y LA DURACIÓN EN EL MODAL
|
|
||||||
document.getElementById('dateInput').value = raw.scheduled_date || "";
|
document.getElementById('dateInput').value = raw.scheduled_date || "";
|
||||||
document.getElementById('timeInput').value = raw.scheduled_time || "";
|
document.getElementById('timeInput').value = raw.scheduled_time || "";
|
||||||
document.getElementById('durationInput').value = raw.duration_minutes || "60";
|
document.getElementById('durationInput').value = raw.duration_minutes || "60";
|
||||||
|
|
||||||
const dbStat = raw.status_operativo;
|
const dbStat = raw.status_operativo;
|
||||||
const foundById = systemStatuses.find(st => String(st.id) === String(dbStat));
|
if(dbStat) document.getElementById('detStatusMap').value = dbStat;
|
||||||
if(foundById) document.getElementById('detStatusMap').value = foundById.id;
|
|
||||||
|
|
||||||
const modal = document.getElementById('serviceModal');
|
const modal = document.getElementById('serviceModal');
|
||||||
modal.style.display = 'flex';
|
modal.style.display = 'flex';
|
||||||
setTimeout(() => modal.classList.remove('translate-y-full'), 10);
|
setTimeout(() => modal.classList.remove('translate-y-full'), 10);
|
||||||
calculateDistance(fullAddress);
|
calculateDistance(fullAddress);
|
||||||
|
safeLoadIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
@@ -501,6 +511,9 @@
|
|||||||
|
|
||||||
async function calculateDistance(dest) {
|
async function calculateDistance(dest) {
|
||||||
if(!navigator.geolocation) return;
|
if(!navigator.geolocation) return;
|
||||||
|
document.getElementById('gpsLoading').classList.remove('hidden');
|
||||||
|
document.getElementById('gpsResult').classList.add('hidden');
|
||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(async (pos) => {
|
navigator.geolocation.getCurrentPosition(async (pos) => {
|
||||||
const lat = pos.coords.latitude; const lon = pos.coords.longitude;
|
const lat = pos.coords.latitude; const lon = pos.coords.longitude;
|
||||||
try {
|
try {
|
||||||
@@ -540,7 +553,6 @@
|
|||||||
} catch (e) { alert("Error"); }
|
} catch (e) { alert("Error"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- FUNCIÓN ACTUALIZADA PARA CAPTURAR LA DURACIÓN ---
|
|
||||||
async function saveAppointment() {
|
async function saveAppointment() {
|
||||||
const id = document.getElementById('detId').value;
|
const id = document.getElementById('detId').value;
|
||||||
const date = document.getElementById('dateInput').value;
|
const date = document.getElementById('dateInput').value;
|
||||||
@@ -558,23 +570,30 @@
|
|||||||
const originalContent = btn.innerHTML;
|
const originalContent = btn.innerHTML;
|
||||||
btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> Guardando...`;
|
btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> Guardando...`;
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
|
safeLoadIcons();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fetch(`${API_URL}/services/set-appointment/${id}`, {
|
const res = await fetch(`${API_URL}/services/set-appointment/${id}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
|
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
|
||||||
body: JSON.stringify({ date, time, duration_minutes: duration, status_operativo: statusMap })
|
body: JSON.stringify({ date, time, duration_minutes: duration, status_operativo: statusMap })
|
||||||
});
|
});
|
||||||
|
|
||||||
closeDetailModal(); showToast("Estado actualizado"); refreshData();
|
if (res.ok) {
|
||||||
} catch (e) { alert("Error"); }
|
showToast("Estado actualizado");
|
||||||
finally { btn.innerHTML = originalContent; btn.disabled = false; }
|
closeModal();
|
||||||
|
refreshData();
|
||||||
|
} else {
|
||||||
|
alert("Error al guardar");
|
||||||
|
}
|
||||||
|
} catch (e) { alert("Error de conexión"); }
|
||||||
|
finally { btn.innerHTML = originalContent; btn.disabled = false; safeLoadIcons(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
function showToast(m) {
|
function showToast(m) {
|
||||||
const t = document.getElementById('toast'); document.getElementById('toastMsg').innerText = m;
|
const t = document.getElementById('toast'); document.getElementById('toastMsg').innerText = m;
|
||||||
t.classList.remove('opacity-0', '-translate-y-10'); t.classList.add('translate-y-0');
|
t.classList.remove('opacity-0', 'pointer-events-none', '-translate-y-10'); t.classList.add('translate-y-0');
|
||||||
setTimeout(() => { t.classList.add('opacity-0', '-translate-y-10'); t.classList.remove('translate-y-0'); }, 2000);
|
setTimeout(() => { t.classList.add('opacity-0', 'pointer-events-none', '-translate-y-10'); t.classList.remove('translate-y-0'); }, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() { localStorage.clear(); window.location.href = "index.html"; }
|
function logout() { localStorage.clear(); window.location.href = "index.html"; }
|
||||||
|
|||||||
Reference in New Issue
Block a user