- customers.min.js, fleet.min.js, inventory.min.js, pos-utils.min.js, sidebar.min.js, virtual-scroll.min.js
1 line
15 KiB
JavaScript
1 line
15 KiB
JavaScript
var Fleet=function(){"use strict";var e="/pos/api/fleet",t=localStorage.getItem("pos_token"),n=[],a=1,o=null;function l(){return{"Content-Type":"application/json",Authorization:"Bearer "+t}}function c(e){return null==e?"0":parseFloat(e).toLocaleString("es-MX")}function i(e){return null==e?"$0.00":"$"+parseFloat(e).toLocaleString("es-MX",{minimumFractionDigits:2,maximumFractionDigits:2})}function r(e){return e?new Date(e).toLocaleDateString("es-MX",{day:"2-digit",month:"short",year:"numeric"}):"—"}function d(e){if(!e)return"";var t=document.createElement("div");return t.textContent=e,t.innerHTML}function u(){fetch(e+"/stats",{headers:l()}).then((function(e){return e.json()})).then((function(e){document.getElementById("statTotal").textContent=c(e.total_vehicles),document.getElementById("statOverdue").textContent=c(e.overdue_count),document.getElementById("statUpcoming").textContent=c(e.upcoming_this_month),document.getElementById("statCost").textContent=i(e.total_cost_month)})).catch((function(){}))}function s(){var t=(document.getElementById("searchInput")||{}).value||"",o=e+"/vehicles?page="+a+"&per_page=50";t&&(o+="&q="+encodeURIComponent(t)),fetch(o,{headers:l()}).then((function(e){return e.json()})).then((function(e){var t;(function(e){var t=document.getElementById("vehicleGrid");if(!e.length)return void(t.innerHTML='<div class="empty-state"><div class="empty-state__icon">🚚</div><div class="empty-state__text">No hay vehiculos registrados</div><button class="btn btn--primary" onclick="Fleet.openVehicleModal()">+ Agregar Vehiculo</button></div>');var n="";e.forEach((function(e){var t=(e.make||"")+" "+(e.model||"");e.year&&(t+=" "+e.year),n+='<div class="vehicle-card" onclick="Fleet.viewVehicle('+e.id+')"><div class="vehicle-card__header"><span class="vehicle-card__plate">'+d(e.plate||"SIN PLACA")+'</span><span class="badge '+(e.is_active?"badge--active":"badge--inactive")+'">'+(e.is_active?"Activo":"Inactivo")+'</span></div><div class="vehicle-card__info"><div><strong>'+d(t.trim())+"</strong></div>"+(e.owner_name?"<div>"+d(e.owner_name)+"</div>":"")+(e.color?"<div>Color: "+d(e.color)+"</div>":"")+'</div><div class="vehicle-card__footer"><span>'+c(e.current_mileage)+" km</span><span>"+d(e.fuel_type||"")+"</span></div></div>"})),t.innerHTML=n})(n=e.data||[]),function(e){var t=document.getElementById("vehiclePagination");if(!e||e.total_pages<=1)return void(t.innerHTML="");t.innerHTML='<button class="pagination__btn" '+(e.page<=1?"disabled":"")+' onclick="Fleet.goPage('+(e.page-1)+')">« Anterior</button><span class="pagination__info">Pagina '+e.page+" de "+e.total_pages+" ("+e.total+' vehiculos)</span><button class="pagination__btn" '+(e.page>=e.total_pages?"disabled":"")+' onclick="Fleet.goPage('+(e.page+1)+')">Siguiente »</button>'}(e.pagination),t='<option value="">-- Seleccionar vehiculo --</option>',n.forEach((function(e){var n=(e.plate||"S/P")+" - "+(e.make||"")+" "+(e.model||"");t+='<option value="'+e.id+'">'+d(n.trim())+"</option>"})),["schedVehicleSelect","logVehicleSelect"].forEach((function(e){var n=document.getElementById(e);n&&(n.innerHTML=t)}))})).catch((function(){document.getElementById("vehicleGrid").innerHTML='<div class="empty-state"><div class="empty-state__text">Error al cargar vehiculos</div></div>'}))}function m(e){var t=document.getElementById("vehicleModal"),n=document.getElementById("vehicleModalTitle");e&&e.id?(n.textContent="Editar Vehiculo",document.getElementById("vehEditId").value=e.id,document.getElementById("vehPlate").value=e.plate||"",document.getElementById("vehVin").value=e.vin||"",document.getElementById("vehMake").value=e.make||"",document.getElementById("vehModel").value=e.model||"",document.getElementById("vehYear").value=e.year||"",document.getElementById("vehMileage").value=e.current_mileage||0,document.getElementById("vehFuel").value=e.fuel_type||"gasolina",document.getElementById("vehColor").value=e.color||"",document.getElementById("vehOwner").value=e.owner_name||"",document.getElementById("vehNotes").value=e.notes||""):(n.textContent="Nuevo Vehiculo",document.getElementById("vehEditId").value="",["vehPlate","vehVin","vehMake","vehModel","vehYear","vehColor","vehOwner","vehNotes"].forEach((function(e){document.getElementById(e).value=""})),document.getElementById("vehMileage").value="0",document.getElementById("vehFuel").value="gasolina"),t.classList.add("is-open")}function v(){document.getElementById("vehicleModal").classList.remove("is-open")}function h(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,schedules:e.data||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("maintBody"),n=[];if(e.forEach((function(e){e.schedules.forEach((function(t){n.push({vehicle:e.vehicle,schedule:t})}))})),!n.length)return void(t.innerHTML='<tr><td colspan="7" style="text-align:center;padding:var(--space-6);color:var(--color-text-muted);">No hay programas de mantenimiento.<br><button class="btn btn--primary btn--sm" style="margin-top:var(--space-3);" onclick="Fleet.openScheduleModal()">+ Crear Programa</button></td></tr>');p||(p=new VirtualScroll({container:t,rowHeight:64,buffer:3,renderRow:g,emptyHtml:'<tr><td colspan="7" style="text-align:center;padding:var(--space-6);color:var(--color-text-muted);">No hay programas de mantenimiento.</td></tr>'}));p.setData(n)}(e)})).catch((function(){document.getElementById("maintBody").innerHTML='<tr><td colspan="7" style="text-align:center;color:var(--color-text-muted);">Error al cargar</td></tr>'}))}function g(e){var t=e.vehicle,n=e.schedule,a=new Date,o=!1;n.next_due_at&&new Date(n.next_due_at)<a&&(o=!0),n.next_due_km&&n.next_due_km<=t.current_mileage&&(o=!0);var l="";n.interval_km&&(l+=c(n.interval_km)+" km"),n.interval_km&&n.interval_months&&(l+=" / "),n.interval_months&&(l+=n.interval_months+" meses");var i="";return n.next_due_at&&(i+=r(n.next_due_at)),n.next_due_at&&n.next_due_km&&(i+=" / "),n.next_due_km&&(i+=c(n.next_due_km)+" km"),"<tr><td><strong>"+d(t.plate||"S/P")+'</strong><br><span style="font-size:var(--text-caption);color:var(--color-text-muted);">'+d((t.make||"")+" "+(t.model||""))+"</span></td><td>"+d(n.maintenance_type)+'</td><td class="mono">'+(l||"—")+"</td><td>"+r(n.last_done_at)+(n.last_done_km?'<br><span class="mono" style="font-size:var(--text-caption);">'+c(n.last_done_km)+" km</span>":"")+"</td><td>"+(i||"—")+'</td><td><span class="badge '+(o?"badge--overdue":"badge--active")+'">'+(o?"Vencido":"Al dia")+'</span></td><td><button class="btn btn--sm btn--ghost" onclick="Fleet.openLogModalFor('+t.id+","+n.id+",'"+d(n.maintenance_type)+"')\">Registrar</button></td></tr>"}var p=null;function y(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id,{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,logs:e.recent_logs||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("historyBody"),n=[];if(e.forEach((function(e){e.logs.forEach((function(t){t._plate=e.vehicle.plate||"S/P",t._make=(e.vehicle.make||"")+" "+(e.vehicle.model||""),n.push(t)}))})),n.sort((function(e,t){return new Date(t.created_at)-new Date(e.created_at)})),!n.length)return void(t.innerHTML='<tr><td colspan="7" style="text-align:center;padding:var(--space-6);color:var(--color-text-muted);">No hay registros de mantenimiento</td></tr>');_||(_=new VirtualScroll({container:t,rowHeight:48,buffer:3,renderRow:f,emptyHtml:'<tr><td colspan="7" style="text-align:center;padding:var(--space-6);color:var(--color-text-muted);">No hay registros de mantenimiento</td></tr>'}));_.setData(n)}(e)})).catch((function(){document.getElementById("historyBody").innerHTML='<tr><td colspan="7" style="text-align:center;color:var(--color-text-muted);">Error al cargar</td></tr>'}))}function f(e){return"<tr><td>"+r(e.created_at)+"</td><td><strong>"+d(e._plate)+'</strong><br><span style="font-size:var(--text-caption);color:var(--color-text-muted);">'+d(e._make)+"</span></td><td>"+d(e.maintenance_type)+'</td><td class="mono">'+c(e.mileage_at)+'</td><td class="mono">'+i(e.cost)+"</td><td>"+d(e.employee_name||"—")+'</td><td style="max-width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">'+d(e.notes||"—")+"</td></tr>"}var _=null;function E(){fetch(e+"/alerts",{headers:l()}).then((function(e){return e.json()})).then((function(e){!function(e){var t=document.getElementById("alertsList");if(!e.length)return void(t.innerHTML='<div class="empty-state"><div class="empty-state__icon" style="color:#3FB950;">✓</div><div class="empty-state__text">No hay mantenimientos vencidos</div></div>');var n="";e.forEach((function(e){var t="";e.next_due_at&&(t+="Vencio: "+r(e.next_due_at)),e.next_due_km&&(t+=(t?" | ":"")+"Limite: "+c(e.next_due_km)+" km (actual: "+c(e.current_mileage)+" km)"),n+='<div class="alert-card"><div class="alert-card__info"><div class="alert-card__vehicle">'+d(e.plate||"S/P")+" — "+d((e.make||"")+" "+(e.model||""))+(e.year?" "+e.year:"")+'</div><div class="alert-card__detail"><span class="badge badge--overdue">'+d(e.maintenance_type)+"</span> "+t+'</div></div><button class="btn btn--sm btn--primary" onclick="Fleet.openLogModalFor('+e.vehicle_id+","+e.schedule_id+",'"+d(e.maintenance_type)+"')\">Registrar Mant.</button></div>"})),t.innerHTML=n}(e.data||[])})).catch((function(){document.getElementById("alertsList").innerHTML='<div class="empty-state"><div class="empty-state__text">Error al cargar alertas</div></div>'}))}function I(){document.getElementById("scheduleModal").classList.remove("is-open")}function B(){var e=document.getElementById("logModal");document.getElementById("logScheduleSelect").innerHTML='<option value="">-- Sin programa --</option>',document.getElementById("logType").value="",document.getElementById("logMileage").value="",document.getElementById("logCost").value="",document.getElementById("logParts").value="",document.getElementById("logNotes").value="",e.classList.add("is-open")}function b(){document.getElementById("logModal").classList.remove("is-open")}return document.addEventListener("DOMContentLoaded",(function(){document.querySelectorAll(".tab-btn").forEach((function(e){e.addEventListener("click",(function(){var e=this.getAttribute("data-tab");document.querySelectorAll(".tab-btn").forEach((function(e){e.classList.remove("is-active")})),document.querySelectorAll(".tab-panel").forEach((function(e){e.classList.remove("is-active")})),this.classList.add("is-active"),document.getElementById("tab-"+e).classList.add("is-active"),"maintenance"===e&&h(),"history"===e&&y(),"alerts"===e&&E()}))}));var e=document.getElementById("searchInput");e&&e.addEventListener("input",(function(){clearTimeout(o),o=setTimeout((function(){a=1,s()}),300)})),document.getElementById("btnNewVehicle").addEventListener("click",(function(){m()})),u(),s()})),{openVehicleModal:m,closeVehicleModal:v,saveVehicle:function(){var t=document.getElementById("vehEditId").value,n={plate:document.getElementById("vehPlate").value.trim(),vin:document.getElementById("vehVin").value.trim(),make:document.getElementById("vehMake").value.trim(),model:document.getElementById("vehModel").value.trim(),year:parseInt(document.getElementById("vehYear").value)||null,current_mileage:parseInt(document.getElementById("vehMileage").value)||0,fuel_type:document.getElementById("vehFuel").value,color:document.getElementById("vehColor").value.trim(),owner_name:document.getElementById("vehOwner").value.trim(),notes:document.getElementById("vehNotes").value.trim()};if(n.plate||n.vin){var a=e+"/vehicles",o="POST";t&&(a+="/"+t,o="PUT"),fetch(a,{method:o,headers:l(),body:JSON.stringify(n)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(v(),s(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Se requiere placa o VIN")},viewVehicle:function(t){fetch(e+"/vehicles/"+t,{headers:l()}).then((function(e){return e.json()})).then((function(e){m(e)}))},goPage:function(e){a=e,s()},openScheduleModal:function(e){var t=document.getElementById("scheduleModal");document.getElementById("schedType").value="",document.getElementById("schedIntervalKm").value="",document.getElementById("schedIntervalMonths").value="",document.getElementById("schedNextDate").value="",document.getElementById("schedNextKm").value="",document.getElementById("schedNotes").value="",e&&(document.getElementById("schedVehicleSelect").value=e),t.classList.add("is-open")},closeScheduleModal:I,saveSchedule:function(){var t=document.getElementById("schedVehicleSelect").value;if(t){var n=document.getElementById("schedType").value.trim();if(n){var a={maintenance_type:n,interval_km:parseInt(document.getElementById("schedIntervalKm").value)||null,interval_months:parseInt(document.getElementById("schedIntervalMonths").value)||null,next_due_at:document.getElementById("schedNextDate").value||null,next_due_km:parseInt(document.getElementById("schedNextKm").value)||null,notes:document.getElementById("schedNotes").value.trim()};fetch(e+"/vehicles/"+t+"/schedules",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(I(),h(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")},openLogModal:B,openLogModalFor:function(t,a,o){B(),document.getElementById("logVehicleSelect").value=t,o&&(document.getElementById("logType").value=o),fetch(e+"/vehicles/"+t+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){var t='<option value="">-- Sin programa --</option>';(e.data||[]).forEach((function(e){var n=e.id==a?" selected":"";t+='<option value="'+e.id+'"'+n+">"+d(e.maintenance_type)+"</option>"})),document.getElementById("logScheduleSelect").innerHTML=t}));var c=n.find((function(e){return e.id==t}));c&&(document.getElementById("logMileage").value=c.current_mileage||"")},closeLogModal:b,saveLog:function(){var t=document.getElementById("logVehicleSelect").value;if(t){var n=document.getElementById("logType").value.trim();if(n){var a={schedule_id:parseInt(document.getElementById("logScheduleSelect").value)||null,maintenance_type:n,mileage_at:parseInt(document.getElementById("logMileage").value)||null,cost:parseFloat(document.getElementById("logCost").value)||0,parts_used:document.getElementById("logParts").value.trim(),notes:document.getElementById("logNotes").value.trim()};fetch(e+"/vehicles/"+t+"/log",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){if(e.error)alert(e.error);else{b(),u();var t=document.querySelector(".tab-btn.is-active");if(t){var n=t.getAttribute("data-tab");"maintenance"===n&&h(),"history"===n&&y(),"alerts"===n&&E(),"vehicles"===n&&s()}}})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")}}}(); |