Actualizar calendario.html
This commit is contained in:
105
calendario.html
105
calendario.html
@@ -16,21 +16,27 @@
|
|||||||
|
|
||||||
/* Estilos para el selector de días */
|
/* Estilos para el selector de días */
|
||||||
.day-card { transition: all 0.2s; }
|
.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; }
|
.day-inactive { background-color: white; color: #64748b; border-color: #e2e8f0; }
|
||||||
</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">
|
||||||
|
|
||||||
<header class="bg-white px-5 pt-8 pb-4 shadow-sm z-20 shrink-0 border-b border-slate-100">
|
<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 class="flex items-center gap-3 mb-4">
|
||||||
<div>
|
<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">
|
||||||
<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">
|
|
||||||
<i data-lucide="arrow-left" class="w-5 h-5"></i>
|
<i data-lucide="arrow-left" class="w-5 h-5"></i>
|
||||||
</a>
|
</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>
|
||||||
|
|
||||||
<div class="overflow-x-auto no-scrollbar py-2 -mx-5 px-5 flex gap-3" id="weekStrip">
|
<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 localServices = [];
|
||||||
let systemStatuses = [];
|
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", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
if (!localStorage.getItem("token") || localStorage.getItem("role") !== 'operario') {
|
if (!localStorage.getItem("token") || localStorage.getItem("role") !== 'operario') {
|
||||||
@@ -152,29 +176,31 @@
|
|||||||
|
|
||||||
lucide.createIcons();
|
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();
|
const today = new Date();
|
||||||
// Ajuste de zona horaria manual simple
|
currentWeekStart = getMonday(today);
|
||||||
selectedDateStr = new Date(today.getTime() - (today.getTimezoneOffset() * 60000)).toISOString().split('T')[0];
|
selectedDateStr = toISODate(today);
|
||||||
|
|
||||||
buildWeekCalendar();
|
buildWeekCalendar();
|
||||||
loadStatuses();
|
loadStatuses();
|
||||||
refreshData();
|
refreshData();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 1. CONSTRUIR EL CALENDARIO SUPERIOR (7 DÍAS)
|
// 1. CONSTRUIR EL CALENDARIO SUPERIOR (Lunes a Domingo)
|
||||||
function buildWeekCalendar() {
|
function buildWeekCalendar() {
|
||||||
const strip = document.getElementById('weekStrip');
|
const strip = document.getElementById('weekStrip');
|
||||||
strip.innerHTML = '';
|
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++) {
|
for(let i = 0; i < 7; i++) {
|
||||||
let d = new Date(today);
|
let d = new Date(currentWeekStart);
|
||||||
d.setDate(today.getDate() + i);
|
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 dayName = d.toLocaleDateString('es-ES', { weekday: 'short' }).replace('.', '');
|
||||||
const dayNum = d.getDate();
|
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">
|
<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-[9px] font-black uppercase tracking-widest opacity-80">${dayName}</span>
|
||||||
<span class="text-xl font-black leading-none mt-1">${dayNum}</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>
|
<span id="badge-${isoDate}" class="bg-rose-500 w-1.5 h-1.5 rounded-full hidden"></span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</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) {
|
function selectDate(isoDate) {
|
||||||
selectedDateStr = isoDate;
|
selectedDateStr = isoDate;
|
||||||
buildWeekCalendar(); // Re-render para aplicar estilos visuales
|
buildWeekCalendar(); // Re-render visual de la tira superior
|
||||||
renderServices(); // Filtrar las tarjetas por el día
|
renderServices(); // Filtrar las tarjetas de abajo
|
||||||
updateBadges(); // Actualizar puntitos
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadStatuses() {
|
async function loadStatuses() {
|
||||||
@@ -219,13 +258,14 @@
|
|||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
if (data.ok) {
|
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 => {
|
localServices = data.services.filter(s => {
|
||||||
const raw = s.raw_data || {};
|
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();
|
renderServices();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} 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() {
|
function updateBadges() {
|
||||||
// Limpiar todos primero
|
// Ocultar todos primero
|
||||||
document.querySelectorAll('[id^="badge-"]').forEach(el => el.classList.add('hidden'));
|
document.querySelectorAll('[id^="badge-"]').forEach(el => el.classList.add('hidden'));
|
||||||
|
|
||||||
const counts = {};
|
const counts = {};
|
||||||
localServices.forEach(s => {
|
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;
|
if(date) counts[date] = (counts[date] || 0) + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,10 +296,15 @@
|
|||||||
|
|
||||||
function renderServices() {
|
function renderServices() {
|
||||||
const container = document.getElementById('servicesList');
|
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
|
// Filtrar servicios exactos para el día seleccionado
|
||||||
const dayServices = localServices.filter(s => s.raw_data.scheduled_date === selectedDateStr);
|
const dayServices = localServices.filter(s => {
|
||||||
|
const d = (s.raw_data.scheduled_date || "").trim();
|
||||||
|
return d === selectedDateStr;
|
||||||
|
});
|
||||||
|
|
||||||
// Ordenar por hora
|
// Ordenar por hora
|
||||||
dayServices.sort((a, b) => {
|
dayServices.sort((a, b) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user