const API = '/api/pendientes'; let currentDate = new Date(); let todosPendientes = []; const monthNames = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre']; async function cargarPendientes() { const res = await fetch(API); todosPendientes = await res.json(); renderCalendar(); renderLista(); } function formatearFecha(fechaStr) { const partes = fechaStr.split('-'); return partes[2] + '-' + partes[1] + '-' + partes[0]; } function hoyStr() { const hoy = new Date(); return hoy.getFullYear() + '-' + String(hoy.getMonth() + 1).padStart(2, '0') + '-' + String(hoy.getDate()).padStart(2, '0'); } function esVencido(p) { if (p.estado === 'completado') return false; return p.fecha < hoyStr(); } function renderCalendar() { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); document.getElementById('monthYear').textContent = monthNames[month] + ' ' + year; const firstDay = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); const grid = document.getElementById('calendarGrid'); grid.innerHTML = ''; for (let i = 0; i < firstDay; i++) { grid.appendChild(document.createElement('div')); } for (let d = 1; d <= daysInMonth; d++) { const dateStr = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(d).padStart(2, '0'); const delDia = todosPendientes.filter(function(p) { return p.fecha === dateStr; }); const dayEl = document.createElement('div'); dayEl.className = 'day'; dayEl.innerHTML = '' + d + ''; if (delDia.length) { const dots = document.createElement('div'); dots.className = 'day-dots'; delDia.slice(0, 4).forEach(function(p) { const dot = document.createElement('span'); dot.className = 'dot ' + (esVencido(p) ? 'alta' : p.urgencia); dots.appendChild(dot); }); dayEl.appendChild(dots); } dayEl.onclick = function() { abrirModalDia(dateStr, delDia); }; grid.appendChild(dayEl); } } function abrirModalDia(fecha, pendientes) { document.getElementById('modalTitulo').textContent = 'Pendientes del ' + formatearFecha(fecha); const cont = document.getElementById('modalPendientes'); cont.innerHTML = ''; if (!pendientes.length) { cont.innerHTML = '

No hay pendientes para este dia.

'; } else { pendientes.forEach(function(p) { const div = crearCardPendiente(p); cont.appendChild(div); }); } document.getElementById('modalDia').classList.remove('hidden'); } function crearCardPendiente(p) { const vencido = esVencido(p); const div = document.createElement('div'); div.className = 'pendiente-card ' + (vencido ? 'vencido' : p.urgencia); let html = '
' + '
' + escaparHtml(p.descripcion) + ''; if (vencido) { html += 'Vencido'; } html += '
' + '
' + formatearFecha(p.fecha) + ' - ' + p.estado + ' - Urgencia: ' + p.urgencia + '
' + '
' + '
' + '' + '' + '
'; div.innerHTML = html; return div; } function escaparHtml(texto) { const div = document.createElement('div'); div.textContent = texto; return div.innerHTML; } document.getElementById('cerrarModal').onclick = function() { document.getElementById('modalDia').classList.add('hidden'); }; document.getElementById('prevMonth').onclick = function() { currentDate.setMonth(currentDate.getMonth() - 1); renderCalendar(); }; document.getElementById('nextMonth').onclick = function() { currentDate.setMonth(currentDate.getMonth() + 1); renderCalendar(); }; document.querySelectorAll('.tab').forEach(function(tab) { tab.onclick = function() { document.querySelectorAll('.tab').forEach(function(t) { t.classList.remove('active'); }); document.querySelectorAll('.section').forEach(function(s) { s.classList.remove('active'); }); tab.classList.add('active'); document.getElementById(tab.dataset.tab).classList.add('active'); }; }); document.getElementById('formPendiente').onsubmit = async function(e) { e.preventDefault(); const id = document.getElementById('pendienteId').value; const body = { descripcion: document.getElementById('descripcion').value, fecha: document.getElementById('fecha').value, estado: document.getElementById('estado').value, urgencia: document.getElementById('urgencia').value }; if (id) { await fetch(API + '/' + id, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); } else { await fetch(API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); } resetForm(); cargarPendientes(); }; document.getElementById('btnCancelar').onclick = resetForm; function resetForm() { document.getElementById('formPendiente').reset(); document.getElementById('pendienteId').value = ''; document.getElementById('btnGuardar').textContent = 'Guardar'; document.getElementById('btnCancelar').classList.add('hidden'); } function renderLista() { const cont = document.getElementById('listaPendientes'); cont.innerHTML = ''; const vencidos = todosPendientes.filter(function(p) { return esVencido(p); }); const normales = todosPendientes.filter(function(p) { return !esVencido(p); }); if (!todosPendientes.length) { cont.innerHTML = '

No hay pendientes aun.

'; return; } if (vencidos.length) { const titVencidos = document.createElement('div'); titVencidos.className = 'subtitulo'; titVencidos.textContent = 'Vencidos / Prioritarios (' + vencidos.length + ')'; cont.appendChild(titVencidos); vencidos.forEach(function(p) { cont.appendChild(crearCardPendiente(p)); }); } if (normales.length) { const titNormales = document.createElement('div'); titNormales.className = 'subtitulo'; titNormales.textContent = 'Pendientes (' + normales.length + ')'; cont.appendChild(titNormales); normales.forEach(function(p) { cont.appendChild(crearCardPendiente(p)); }); } } async function editarPendiente(id) { const p = todosPendientes.find(function(x) { return x.id === id; }); if (!p) return; document.getElementById('pendienteId').value = p.id; document.getElementById('descripcion').value = p.descripcion; document.getElementById('fecha').value = p.fecha; document.getElementById('estado').value = p.estado; document.getElementById('urgencia').value = p.urgencia; document.getElementById('btnGuardar').textContent = 'Actualizar'; document.getElementById('btnCancelar').classList.remove('hidden'); document.querySelector('.tab[data-tab=pendientes]').click(); } async function eliminarPendiente(id) { if (!confirm('Eliminar este pendiente?')) return; await fetch(API + '/' + id, { method: 'DELETE' }); cargarPendientes(); } cargarPendientes();