Añade modo "obra de varios días" con fecha/hora de fin, sin tope de 4h
This commit is contained in:
@@ -380,9 +380,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-end gap-3 mt-4">
|
||||
<label class="flex items-center gap-2 bg-amber-50 border border-amber-100 rounded-xl px-3 py-2 mt-4 cursor-pointer w-fit">
|
||||
<input type="checkbox" id="multiDayToggle" onchange="toggleMultiDay(this.checked)" class="w-3.5 h-3.5 rounded text-amber-600">
|
||||
<span class="text-[9px] font-black text-amber-700 uppercase tracking-widest">Obra / instalación de varios días</span>
|
||||
</label>
|
||||
<div class="flex items-end gap-3 mt-2">
|
||||
<div class="flex-1 space-y-1.5">
|
||||
<p class="text-[9px] font-black text-blue-600 uppercase tracking-widest flex items-center gap-1"><i data-lucide="calendar-clock" class="w-3 h-3"></i> Cita</p>
|
||||
<p class="text-[9px] font-black text-blue-600 uppercase tracking-widest flex items-center gap-1"><i data-lucide="calendar-clock" class="w-3 h-3"></i> Cita <span id="apptFromLabel" class="hidden normal-case font-medium text-slate-400">(desde)</span></p>
|
||||
<div class="flex gap-2">
|
||||
<input type="date" id="dateInput" class="w-full bg-white border border-slate-200 p-2.5 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="time" id="timeInput" class="w-24 bg-white border border-slate-200 p-2.5 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">
|
||||
@@ -392,6 +396,13 @@
|
||||
<i data-lucide="save" class="w-3 h-3"></i> Guardar
|
||||
</button>
|
||||
</div>
|
||||
<div id="multiDayFields" class="hidden mt-2 space-y-1.5">
|
||||
<p class="text-[9px] font-black text-blue-600 uppercase tracking-widest flex items-center gap-1"><i data-lucide="calendar-clock" class="w-3 h-3"></i> Hasta</p>
|
||||
<div class="flex gap-2">
|
||||
<input type="date" id="endDateInput" class="w-full bg-white border border-slate-200 p-2.5 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="time" id="endTimeInput" value="18:00" class="w-24 bg-white border border-slate-200 p-2.5 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">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="panelSinAsignar" class="bg-blue-50/40 p-4 rounded-[1rem] border border-blue-100 flex flex-col shadow-sm shrink-0 hidden">
|
||||
@@ -1026,6 +1037,20 @@
|
||||
document.getElementById('dateInput').value = raw.scheduled_date || "";
|
||||
document.getElementById('timeInput').value = raw.scheduled_time || "";
|
||||
document.getElementById('detStatusMap').value = statusObj.id;
|
||||
|
||||
// 🏗️ Si la duración guardada no cabe en el mismo día (obra de varios días),
|
||||
// abrimos ya en modo "varios días" con la fecha/hora de fin calculada.
|
||||
const existingDuration = parseInt(raw.duration_minutes || 60);
|
||||
if (raw.scheduled_date && raw.scheduled_time && existingDuration > 240) {
|
||||
const startDT = new Date(`${raw.scheduled_date}T${raw.scheduled_time}`);
|
||||
const endDT = new Date(startDT.getTime() + existingDuration * 60000);
|
||||
document.getElementById('multiDayToggle').checked = true;
|
||||
document.getElementById('endDateInput').value = `${endDT.getFullYear()}-${String(endDT.getMonth()+1).padStart(2,'0')}-${String(endDT.getDate()).padStart(2,'0')}`;
|
||||
document.getElementById('endTimeInput').value = `${String(endDT.getHours()).padStart(2,'0')}:${String(endDT.getMinutes()).padStart(2,'0')}`;
|
||||
} else {
|
||||
document.getElementById('multiDayToggle').checked = false;
|
||||
}
|
||||
toggleMultiDay(document.getElementById('multiDayToggle').checked);
|
||||
} else {
|
||||
document.getElementById('panelEnBolsa').classList.add('hidden');
|
||||
document.getElementById('panelAsignado').classList.add('hidden');
|
||||
@@ -1186,12 +1211,33 @@
|
||||
} catch (e) { alert("Error al detener el automatismo."); }
|
||||
}
|
||||
|
||||
// 🏗️ Obras/instalaciones de varios días: en vez de dejar la duración con el valor
|
||||
// que tuviera (normalmente 1h, o lo que se puso al crear el servicio, tope 4h),
|
||||
// permitimos indicar la fecha/hora de FIN (puede ser un día distinto) y calculamos
|
||||
// la duración real en minutos entre inicio y fin. Seguimos usando el mismo modelo
|
||||
// de siempre (scheduled_date + scheduled_time + duration_minutes), sin tope.
|
||||
function toggleMultiDay(checked) {
|
||||
document.getElementById('multiDayFields').classList.toggle('hidden', !checked);
|
||||
document.getElementById('apptFromLabel').classList.toggle('hidden', !checked);
|
||||
}
|
||||
|
||||
async function saveAppointment() {
|
||||
const id = document.getElementById('detId').value;
|
||||
const date = document.getElementById('dateInput').value;
|
||||
const time = document.getElementById('timeInput').value;
|
||||
let statusMap = document.getElementById('detStatusMap').value;
|
||||
|
||||
let durationMinutes = null;
|
||||
if (document.getElementById('multiDayToggle').checked) {
|
||||
const endDate = document.getElementById('endDateInput').value;
|
||||
const endTime = document.getElementById('endTimeInput').value || "18:00";
|
||||
if (!date || !time || !endDate) { alert("Revisa las fechas/horas de inicio y fin de la obra."); return; }
|
||||
const start = new Date(`${date}T${time}`);
|
||||
const end = new Date(`${endDate}T${endTime}`);
|
||||
if (isNaN(start) || isNaN(end) || end <= start) { alert("La fecha/hora de fin tiene que ser posterior al inicio."); return; }
|
||||
durationMinutes = Math.round((end - start) / 60000);
|
||||
}
|
||||
|
||||
// Auto-Citado Mágico
|
||||
const currentSt = systemStatuses.find(st => String(st.id) === String(statusMap));
|
||||
if (date && currentSt && currentSt.name.toLowerCase().includes('asignado')) {
|
||||
@@ -1220,10 +1266,12 @@
|
||||
btn.disabled = true;
|
||||
|
||||
try {
|
||||
const payload = { date, time, status_operativo: statusMap, skip_survey: skipSurvey };
|
||||
if (durationMinutes !== null) payload.duration_minutes = durationMinutes;
|
||||
const res = await fetch(`${API_URL}/services/set-appointment/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
|
||||
body: JSON.stringify({ date, time, status_operativo: statusMap, skip_survey: skipSurvey })
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user