arreglada la visualizacion, añadido busqueda por fechas y palabras clave

This commit is contained in:
jlimolina 2025-06-12 18:29:08 +02:00
parent 0433b3b004
commit ce19d301e6
3 changed files with 179 additions and 112 deletions

View file

@ -0,0 +1,24 @@
<div class="noticias-list">
{% for noticia in noticias %}
<article class="noticia-item">
{% if noticia.imagen_url %}
<div class="noticia-imagen">
<a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer"><img src="{{ noticia.imagen_url }}" alt="{{ noticia.titulo }}" loading="lazy"></a>
</div>
{% endif %}
<div class="noticia-texto">
<h3><a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer">{{ noticia.titulo }}</a></h3>
<div class="noticia-meta">
<span><i class="far fa-calendar-alt"></i> {{ noticia.fecha.strftime('%d-%m-%Y %H:%M') if noticia.fecha else 'N/D' }}</span> |
<span><i class="fas fa-tag"></i> {{ noticia.categoria or 'N/A' }}</span> |
<span><i class="fas fa-globe-americas"></i> {{ noticia.pais or 'Global' }}</span>
</div>
<p>{{ noticia.resumen | striptags | safe_html | truncate(280) }}</p>
</div>
</article>
{% else %}
<div class="card" style="text-align:center;">
<p><i class="fas fa-info-circle"></i> No hay noticias que mostrar con los filtros seleccionados.</p>
</div>
{% endfor %}
</div>

View file

@ -3,110 +3,116 @@
{% block title %}Últimas Noticias RSS{% endblock %}
{% block content %}
<header>
<h1>Agregador de Noticias</h1>
<p class="subtitle">Tus fuentes de información, en un solo lugar.</p>
<a href="{{ url_for('dashboard') }}" class="top-link" style="margin-top:15px;">⚙️ Gestionar Feeds</a>
</header>
<header>
<h1>Agregador de Noticias</h1>
<p class="subtitle">Tus fuentes de información, en un solo lugar.</p>
<a href="{{ url_for('dashboard') }}" class="top-link" style="margin-top:15px;">
<i class="fas fa-cogs"></i> Gestionar Feeds
</a>
</header>
<div class="card">
<h2>Filtrar Noticias</h2>
<form method="get" action="{{ url_for('home') }}">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; align-items: flex-end;">
<div>
<label for="categoria_id">Categoría</label>
<select name="categoria_id" id="categoria_id">
<option value="">— Todas —</option>
{% for cat in categorias %}
<option value="{{ cat.id }}" {% if cat_id == cat.id %}selected{% endif %}>{{ cat.nombre }}</option>
{% endfor %}
</select>
</div>
<div>
<label for="continente_id">Continente</label>
<select name="continente_id" id="continente_id" onchange="filtrarPaises()">
<option value="">— Todos —</option>
{% for cont in continentes %}
<option value="{{ cont.id }}" {% if cont_id == cont.id %}selected{% endif %}>{{ cont.nombre }}</option>
{% endfor %}
</select>
</div>
<div>
<label for="pais_id">País</label>
<select name="pais_id" id="pais_id">
<option value="">— Todos —</option>
{# El JavaScript llenará esto dinámicamente, pero mostramos el seleccionado si existe #}
{% for pais in paises %}
{% if pais_id == pais.id %}
<option value="{{ pais.id }}" selected>{{ pais.nombre }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div>
<button type="submit" class="btn">Filtrar</button>
</div>
<div class="card">
<h2><i class="fas fa-filter" style="color: var(--secondary-color); margin-right: 10px;"></i>Filtrar Noticias</h2>
<form method="get" action="{{ url_for('home') }}" id="filter-form">
<div style="margin-bottom: 20px;">
<label for="q">Buscar por palabra clave</label>
<input type="search" name="q" id="q" placeholder="Ej: Trump, California, IA..." value="{{ q or '' }}">
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; align-items: flex-end; border-top: 1px solid var(--border-color); padding-top: 20px;">
<div>
<label for="categoria_id">Categoría</label>
<select name="categoria_id" id="categoria_id">
<option value="">— Todas —</option>
{% for cat in categorias %}
<option value="{{ cat.id }}" {% if cat_id == cat.id %}selected{% endif %}>{{ cat.nombre }}</option>
{% endfor %}
</select>
</div>
</form>
</div>
<div class="noticias-list">
{% for noticia in noticias %}
<article class="noticia-item">
{% if noticia.imagen_url %}
<div class="noticia-imagen">
<a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer"><img src="{{ noticia.imagen_url }}" alt="{{ noticia.titulo }}"></a>
</div>
{% endif %}
<div class="noticia-texto">
<h3><a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer">{{ noticia.titulo }}</a></h3>
<div class="noticia-meta">
<span>🗓️ {{ noticia.fecha.strftime('%d-%m-%Y %H:%M') if noticia.fecha else 'Fecha no disponible' }}</span> |
<span>{{ noticia.categoria or 'N/A' }}</span> |
<span>{{ noticia.pais or 'Global' }}</span>
</div>
<p>{{ noticia.resumen | striptags | safe_html | truncate(280) }}</p>
</div>
</article>
{% else %}
<div class="card" style="text-align:center;">
<p>No hay noticias que mostrar con los filtros seleccionados.</p>
<div>
<label for="continente_id">Continente</label>
<select name="continente_id" id="continente_id">
<option value="">— Todos —</option>
{% for cont in continentes %}
<option value="{{ cont.id }}" {% if cont_id == cont.id %}selected{% endif %}>{{ cont.nombre }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
</div>
<div>
<label for="pais_id">País</label>
<select name="pais_id" id="pais_id">
<option value="">— Todos —</option>
{% for pais in paises %}
<option value="{{ pais.id }}" data-continente-id="{{ pais.continente_id }}" {% if pais_id == pais.id %}selected{% endif %}>
{{ pais.nombre }}
</option>
{% endfor %}
</select>
</div>
<div>
<label for="fecha">Fecha</label>
<input type="date" name="fecha" id="fecha" value="{{ fecha_filtro or '' }}">
</div>
<div style="display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px;">
<button type="submit" class="btn"><i class="fas fa-search"></i> Filtrar</button>
<a href="{{ url_for('home') }}" class="btn btn-secondary"><i class="fas fa-eraser"></i> Limpiar</a>
</div>
</div>
</form>
</div>
<script type="application/json" id="paises-data">{{ paises | tojson }}</script>
<script>
const todosLosPaises = JSON.parse(document.getElementById('paises-data').textContent);
const continenteSelect = document.getElementById('continente_id');
const paisSelect = document.getElementById('pais_id');
const paisSeleccionadoId = '{{ pais_id or '' }}';
<div id="noticias-container">
{% include '_noticias_list.html' %}
</div>
function filtrarPaises() {
const continenteId = continenteSelect.value;
// Guardamos el valor actual por si necesitamos restaurarlo
const valorActualPais = paisSelect.value;
paisSelect.innerHTML = '<option value="">— Todos —</option>'; // Opción por defecto
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('filter-form');
const continenteSelect = document.getElementById('continente_id');
const paisSelect = document.getElementById('pais_id');
if (todosLosPaises) {
todosLosPaises.forEach(pais => {
if (!continenteId || pais.continente_id == continenteId) {
const option = document.createElement('option');
option.value = pais.id;
option.textContent = pais.nombre;
// Si el ID del país coincide con el que estaba seleccionado, lo volvemos a seleccionar
if (pais.id == valorActualPais || pais.id == paisSeleccionadoId) {
option.selected = true;
}
paisSelect.appendChild(option);
}
});
}
// Lógica para filtrar países al cambiar el continente
function filtrarPaises() {
const continenteId = continenteSelect.value;
for (let i = 1; i < paisSelect.options.length; i++) {
const option = paisSelect.options[i];
const paisContinenteId = option.getAttribute('data-continente-id');
option.style.display = (!continenteId || paisContinenteId === continenteId) ? '' : 'none';
}
const opcionSeleccionada = paisSelect.options[paisSelect.selectedIndex];
if (opcionSeleccionada && opcionSeleccionada.style.display === 'none') {
paisSelect.value = '';
}
}
// Ejecutamos la función una vez al cargar la página para inicializar el select de países
// según el continente que ya esté seleccionado.
document.addEventListener('DOMContentLoaded', filtrarPaises);
</script>
// Lógica para enviar el formulario con AJAX
async function actualizarNoticias(event) {
if (event) event.preventDefault();
const formData = new FormData(form);
const params = new URLSearchParams(formData);
const newUrl = `${form.action}?${params.toString()}`;
const container = document.getElementById('noticias-container');
container.style.opacity = '0.5';
container.innerHTML = '<div style="text-align:center; padding: 40px;"><i class="fas fa-spinner fa-spin fa-2x"></i></div>';
try {
const response = await fetch(newUrl, {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
const html = await response.text();
container.innerHTML = html;
window.history.pushState({path: newUrl}, '', newUrl);
} catch (error) {
console.error('Error al filtrar noticias:', error);
container.innerHTML = '<p style="color:var(--error-color); text-align:center;">Error al cargar las noticias.</p>';
} finally {
container.style.opacity = '1';
}
}
// Asignar los eventos
continenteSelect.addEventListener('change', filtrarPaises);
form.addEventListener('submit', actualizarNoticias);
filtrarPaises(); // Ejecutar al inicio
});
</script>
{% endblock %}