// ================================ // DIARIO DE ORACIÓN // Persistencia en API (con fallback a localStorage si no hay conexión). // Requiere: api-config.js, auth.js // ================================ const ESTADOS_DIARIO = { paz: { icono: '🕊️', label: 'Paz' }, gratitud: { icono: '🙏', label: 'Gratitud' }, lucha: { icono: '😔', label: 'Lucha' }, gozo: { icono: '✨', label: 'Gozo' }, silencio: { icono: '🌿', label: 'Silencio' } }; let _usuario = null; let _fechaSeleccionada = null; // Cache en memoria para evitar peticiones redundantes durante la sesión. const _cache = {}; // ── INICIALIZACIÓN ────────────────────────────────────────── document.addEventListener("DOMContentLoaded", () => { _usuario = verificarAuth(); if (!_usuario) return; const hoy = new Date(); _fechaSeleccionada = toFechaISO(hoy); document.getElementById('saludo-usuario').textContent = saludoPersonal(_usuario.nombre, hoy); document.getElementById('fecha-entrada').value = _fechaSeleccionada; cargarEntrada(_fechaSeleccionada); cargarListaEntradas(); document.getElementById('btn-guardar-entrada').addEventListener('click', guardarEntrada); document.getElementById('btn-borrar-entrada').addEventListener('click', borrarEntrada); document.getElementById('btn-anterior').addEventListener('click', () => navegarFecha(-1)); document.getElementById('btn-siguiente').addEventListener('click', () => navegarFecha(1)); document.getElementById('fecha-entrada').addEventListener('change', e => { _fechaSeleccionada = e.target.value; cargarEntrada(_fechaSeleccionada); }); document.querySelectorAll('.btn-estado').forEach(btn => { btn.addEventListener('click', () => seleccionarEstado(btn.dataset.estado)); }); }); // ── SALUDO ────────────────────────────────────────────────── function saludoPersonal(nombre, fecha) { const h = fecha.getHours(); const franja = h < 13 ? 'Buenos días' : h < 20 ? 'Buenas tardes' : 'Buenas noches'; return `${franja}, ${nombre}. Un momento de silencio contigo.`; } // ── API ───────────────────────────────────────────────────── async function _apiGetEntrada(fecha) { try { const res = await apiCall(`/diario/${fecha}`); if (!res) return null; if (res.status === 404) return null; if (!res.ok) throw new Error('Error al cargar entrada'); return await res.json(); } catch (e) { return _localGetEntrada(fecha); } } async function _apiGetTodas() { try { const res = await apiCall('/diario'); if (!res || !res.ok) throw new Error('Error al cargar entradas'); return await res.json(); } catch (e) { return _localGetTodas(); } } async function _apiGuardar(fecha, titulo, texto, estado) { try { const res = await apiCall('/diario', { method: 'POST', body: JSON.stringify({ fecha, titulo, texto, estado }) }); if (!res || !res.ok) throw new Error('Error al guardar'); const dto = await res.json(); _localSetEntrada(fecha, { id: dto.id, fecha, titulo, texto, estado }); return dto; } catch (e) { _localSetEntrada(fecha, { fecha, titulo, texto, estado }); return { fecha, titulo, texto, estado }; } } async function _apiEliminar(fecha) { const entrada = _cache[fecha] || _localGetEntrada(fecha); if (entrada?.id) { try { await apiCall(`/diario/${entrada.id}`, { method: 'DELETE' }); } catch (e) { /* sin conexión: eliminar solo local */ } } _localEliminarEntrada(fecha); delete _cache[fecha]; } // ── LOCALSTORAGE (fallback / caché offline) ───────────────── function _lsKey() { return `diario_${_usuario.id}`; } function _localGetTodas() { try { const data = localStorage.getItem(_lsKey()); const obj = data ? JSON.parse(data) : {}; return Object.values(obj); } catch (e) { return []; } } function _localGetEntrada(fecha) { try { const data = localStorage.getItem(_lsKey()); const obj = data ? JSON.parse(data) : {}; return obj[fecha] || null; } catch (e) { return null; } } function _localSetEntrada(fecha, entrada) { try { const data = localStorage.getItem(_lsKey()); const obj = data ? JSON.parse(data) : {}; obj[fecha] = entrada; localStorage.setItem(_lsKey(), JSON.stringify(obj)); } catch (e) { /* sin espacio */ } } function _localEliminarEntrada(fecha) { try { const data = localStorage.getItem(_lsKey()); const obj = data ? JSON.parse(data) : {}; delete obj[fecha]; localStorage.setItem(_lsKey(), JSON.stringify(obj)); } catch (e) { /* noop */ } } // ── CARGAR ENTRADA ────────────────────────────────────────── async function cargarEntrada(fecha) { actualizarFechaDisplay(fecha); document.getElementById('titulo-entrada').value = ''; document.getElementById('texto-entrada').value = ''; document.querySelectorAll('.btn-estado').forEach(b => b.classList.remove('activo')); document.getElementById('btn-borrar-entrada').style.display = 'none'; const entrada = await _apiGetEntrada(fecha); _cache[fecha] = entrada; if (entrada) { document.getElementById('titulo-entrada').value = entrada.titulo || ''; document.getElementById('texto-entrada').value = entrada.texto || ''; if (entrada.estado) { const btn = document.querySelector(`.btn-estado[data-estado="${entrada.estado}"]`); if (btn) btn.classList.add('activo'); } document.getElementById('btn-borrar-entrada').style.display = 'inline-block'; } } // ── GUARDAR ───────────────────────────────────────────────── async function guardarEntrada() { const titulo = document.getElementById('titulo-entrada').value.trim(); const texto = document.getElementById('texto-entrada').value.trim(); const estado = getEstadoSeleccionado(); const btn = document.getElementById('btn-guardar-entrada'); if (!texto) { mostrarMensajeDiario('Escribe algo antes de guardar 🙏', 'error'); return; } btn.disabled = true; btn.textContent = 'Guardando…'; const dto = await _apiGuardar(_fechaSeleccionada, titulo, texto, estado); _cache[_fechaSeleccionada] = dto; btn.disabled = false; btn.textContent = 'Guardar ✝'; document.getElementById('btn-borrar-entrada').style.display = 'inline-block'; cargarListaEntradas(); mostrarMensajeDiario('Entrada guardada ✝', 'success'); } // ── BORRAR ─────────────────────────────────────────────────── async function borrarEntrada() { if (!confirm('¿Eliminar esta entrada del diario?')) return; await _apiEliminar(_fechaSeleccionada); document.getElementById('titulo-entrada').value = ''; document.getElementById('texto-entrada').value = ''; document.querySelectorAll('.btn-estado').forEach(b => b.classList.remove('activo')); document.getElementById('btn-borrar-entrada').style.display = 'none'; cargarListaEntradas(); mostrarMensajeDiario('Entrada eliminada', 'info'); } // ── ESTADOS DE ÁNIMO ──────────────────────────────────────── function seleccionarEstado(estado) { const btn = document.querySelector(`.btn-estado[data-estado="${estado}"]`); if (!btn) return; const yaActivo = btn.classList.contains('activo'); document.querySelectorAll('.btn-estado').forEach(b => b.classList.remove('activo')); if (!yaActivo) btn.classList.add('activo'); } function getEstadoSeleccionado() { const activo = document.querySelector('.btn-estado.activo'); return activo ? activo.dataset.estado : null; } // ── NAVEGACIÓN ─────────────────────────────────────────────── function navegarFecha(delta) { const d = new Date(_fechaSeleccionada + 'T12:00:00'); d.setDate(d.getDate() + delta); _fechaSeleccionada = toFechaISO(d); document.getElementById('fecha-entrada').value = _fechaSeleccionada; cargarEntrada(_fechaSeleccionada); } function actualizarFechaDisplay(fecha) { const d = new Date(fecha + 'T12:00:00'); const opts = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; document.getElementById('display-fecha').textContent = d.toLocaleDateString('es-ES', opts); const hoy = toFechaISO(new Date()); document.getElementById('btn-siguiente').disabled = fecha >= hoy; } // ── LISTA DE ENTRADAS ─────────────────────────────────────── async function cargarListaEntradas() { const lista = document.getElementById('lista-entradas'); const sinElem = document.getElementById('sin-entradas'); const entradas = await _apiGetTodas(); const lista_sorted = entradas .filter(e => e && e.fecha) .sort((a, b) => b.fecha.localeCompare(a.fecha)); if (lista_sorted.length === 0) { lista.innerHTML = ''; sinElem.style.display = 'block'; return; } sinElem.style.display = 'none'; const hoy = toFechaISO(new Date()); lista.innerHTML = lista_sorted.map(e => { const fecha = e.fecha; const d = new Date(fecha + 'T12:00:00'); const fechaStr = d.toLocaleDateString('es-ES', { weekday: 'short', day: 'numeric', month: 'long' }); const icono = ESTADOS_DIARIO[e.estado]?.icono || '🕯'; const preview = (e.texto || '').substring(0, 80) + ((e.texto || '').length > 80 ? '…' : ''); const esHoy = fecha === hoy; return `