Actualizar calendario.html

This commit is contained in:
2026-02-22 16:30:06 +00:00
parent 633e584329
commit 934c9a84fd

View File

@@ -16,21 +16,27 @@
/* Estilos para el selector de días */
.day-card { transition: all 0.2s; }
.day-active { background-color: #2563eb; color: white; border-color: #2563eb; transform: scale(1.05); shadow: 0 10px 15px -3px rgba(37,99,235,0.4); }
.day-active { background-color: #2563eb; color: white; border-color: #2563eb; transform: scale(1.05); box-shadow: 0 10px 15px -3px rgba(37,99,235,0.4); }
.day-inactive { background-color: white; color: #64748b; border-color: #e2e8f0; }
</style>
</head>
<body class="text-slate-800 font-sans antialiased h-screen flex flex-col overflow-hidden relative">
<header class="bg-white px-5 pt-8 pb-4 shadow-sm z-20 shrink-0 border-b border-slate-100">
<div class="flex justify-between items-center mb-4">
<div>
<p class="text-[10px] font-black text-blue-500 uppercase tracking-widest mb-0.5">Planificación</p>
<h1 class="text-2xl font-black tracking-tight text-slate-800 leading-none">Mi Calendario</h1>
</div>
<a href="menu.html" class="w-10 h-10 bg-slate-50 rounded-full flex items-center justify-center text-slate-600 border border-slate-200 active:bg-slate-100">
<div class="flex items-center gap-3 mb-4">
<a href="menu.html" class="w-10 h-10 shrink-0 bg-slate-50 rounded-full flex items-center justify-center text-slate-600 border border-slate-200 active:bg-slate-100">
<i data-lucide="arrow-left" class="w-5 h-5"></i>
</a>
<div class="flex-1 min-w-0">
<p class="text-[10px] font-black text-blue-500 uppercase tracking-widest mb-0.5 truncate" id="monthYearDisplay">Cargando...</p>
<h1 class="text-xl font-black tracking-tight text-slate-800 leading-none truncate">Mi Agenda</h1>
</div>
<div class="flex gap-1 shrink-0">
<button onclick="changeWeek(-1)" class="w-10 h-10 bg-white rounded-full flex items-center justify-center text-slate-600 border border-slate-200 active:bg-slate-50 shadow-sm active:scale-95 transition-transform"><i data-lucide="chevron-left" class="w-5 h-5"></i></button>
<button onclick="changeWeek(1)" class="w-10 h-10 bg-white rounded-full flex items-center justify-center text-slate-600 border border-slate-200 active:bg-slate-50 shadow-sm active:scale-95 transition-transform"><i data-lucide="chevron-right" class="w-5 h-5"></i></button>
</div>
</div>
<div class="overflow-x-auto no-scrollbar py-2 -mx-5 px-5 flex gap-3" id="weekStrip">
@@ -143,7 +149,25 @@
let localServices = [];
let systemStatuses = [];
let selectedDateStr = "";
let currentWeekStart = new Date(); // Lunes de la semana que estamos viendo
let selectedDateStr = ""; // Día exacto que el usuario ha pinchado
// Formateador seguro a YYYY-MM-DD
function toISODate(dateObj) {
const y = dateObj.getFullYear();
const m = String(dateObj.getMonth() + 1).padStart(2, '0');
const d = String(dateObj.getDate()).padStart(2, '0');
return `${y}-${m}-${d}`;
}
// Obtener el Lunes de cualquier fecha
function getMonday(d) {
const date = new Date(d);
const day = date.getDay();
const diff = date.getDate() - day + (day === 0 ? -6 : 1); // Ajuste si es Domingo (0)
return new Date(date.setDate(diff));
}
document.addEventListener("DOMContentLoaded", () => {
if (!localStorage.getItem("token") || localStorage.getItem("role") !== 'operario') {
@@ -152,29 +176,31 @@
lucide.createIcons();
// Establecer el día de hoy por defecto (YYYY-MM-DD)
// Iniciamos con la semana actual y el día de hoy seleccionado
const today = new Date();
// Ajuste de zona horaria manual simple
selectedDateStr = new Date(today.getTime() - (today.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
currentWeekStart = getMonday(today);
selectedDateStr = toISODate(today);
buildWeekCalendar();
loadStatuses();
refreshData();
});
// 1. CONSTRUIR EL CALENDARIO SUPERIOR (7 DÍAS)
// 1. CONSTRUIR EL CALENDARIO SUPERIOR (Lunes a Domingo)
function buildWeekCalendar() {
const strip = document.getElementById('weekStrip');
strip.innerHTML = '';
const today = new Date();
// Actualizar etiqueta del mes arriba
const monthName = currentWeekStart.toLocaleDateString('es-ES', { month: 'long', year: 'numeric' });
document.getElementById('monthYearDisplay').innerText = monthName;
// Generar hoy + 6 días próximos
// Generar 7 días desde el Lunes
for(let i = 0; i < 7; i++) {
let d = new Date(today);
d.setDate(today.getDate() + i);
let d = new Date(currentWeekStart);
d.setDate(currentWeekStart.getDate() + i);
const isoDate = new Date(d.getTime() - (d.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
const isoDate = toISODate(d);
const dayName = d.toLocaleDateString('es-ES', { weekday: 'short' }).replace('.', '');
const dayNum = d.getDate();
@@ -185,19 +211,32 @@
<button onclick="selectDate('${isoDate}')" id="btn-date-${isoDate}" class="day-card ${baseClass} border min-w-[4rem] rounded-2xl p-3 flex flex-col items-center justify-center shrink-0">
<span class="text-[9px] font-black uppercase tracking-widest opacity-80">${dayName}</span>
<span class="text-xl font-black leading-none mt-1">${dayNum}</span>
<div class="mt-2 w-full flex justify-center">
<div class="mt-2 w-full flex justify-center h-1.5">
<span id="badge-${isoDate}" class="bg-rose-500 w-1.5 h-1.5 rounded-full hidden"></span>
</div>
</button>
`;
}
// Asegurarnos de pintar los puntitos rojos en la nueva semana si ya hay datos
if(localServices.length > 0) updateBadges();
}
// Función para los botones de < y > de las semanas
function changeWeek(offsetWeeks) {
// Sumamos o restamos 7 días al Lunes actual
currentWeekStart.setDate(currentWeekStart.getDate() + (offsetWeeks * 7));
// Auto-seleccionar el Lunes de esa nueva semana
selectedDateStr = toISODate(currentWeekStart);
buildWeekCalendar();
renderServices();
}
function selectDate(isoDate) {
selectedDateStr = isoDate;
buildWeekCalendar(); // Re-render para aplicar estilos visuales
renderServices(); // Filtrar las tarjetas por el día
updateBadges(); // Actualizar puntitos
buildWeekCalendar(); // Re-render visual de la tira superior
renderServices(); // Filtrar las tarjetas de abajo
}
async function loadStatuses() {
@@ -219,13 +258,14 @@
const data = await res.json();
if (data.ok) {
// Filtramos y nos quedamos SOLO con los que tienen FECHA (son los del calendario)
// Filtramos: Solo servicios que NO sean bloqueos y que SÍ tengan fecha
localServices = data.services.filter(s => {
const raw = s.raw_data || {};
return s.provider !== 'SYSTEM_BLOCK' && raw.scheduled_date;
const hasDate = raw.scheduled_date && raw.scheduled_date.trim() !== "";
return s.provider !== 'SYSTEM_BLOCK' && hasDate;
});
updateBadges();
buildWeekCalendar(); // Actualiza puntitos de la semana vista
renderServices();
}
} catch (e) {
@@ -237,14 +277,14 @@
}
}
// Poner el puntito rojo bajo los días que tengan trabajo
// Poner el puntito rojo bajo los días que tengan trabajo en la semana actual
function updateBadges() {
// Limpiar todos primero
// Ocultar todos primero
document.querySelectorAll('[id^="badge-"]').forEach(el => el.classList.add('hidden'));
const counts = {};
localServices.forEach(s => {
const date = s.raw_data.scheduled_date;
const date = (s.raw_data.scheduled_date || "").trim();
if(date) counts[date] = (counts[date] || 0) + 1;
});
@@ -256,10 +296,15 @@
function renderServices() {
const container = document.getElementById('servicesList');
document.getElementById('dayTitle').innerText = `Servicios del ${selectedDateStr.split('-').reverse().join('/')}`;
// Formatear fecha para el título (DD/MM/YYYY)
const displayDate = selectedDateStr.split('-').reverse().join('/');
document.getElementById('dayTitle').innerText = `Servicios del ${displayDate}`;
// Filtrar servicios solo para el día seleccionado
const dayServices = localServices.filter(s => s.raw_data.scheduled_date === selectedDateStr);
// Filtrar servicios exactos para el día seleccionado
const dayServices = localServices.filter(s => {
const d = (s.raw_data.scheduled_date || "").trim();
return d === selectedDateStr;
});
// Ordenar por hora
dayServices.sort((a, b) => {