feat(zopk): Rozszerzony widok aktualności ze statystykami czasowymi

- Dodano pasek statystyk newsów (łącznie, dzień, tydzień, miesiąc)
- Zwiększono limit wyświetlanych newsów z 10 do 25
- Usunięto przycisk "Zobacz wszystkie" - pełny widok od razu
- Przycisk "Starsze aktualności" pojawia się gdy jest więcej niż 25

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-15 05:56:00 +01:00
parent 489f04d04d
commit 819192bdad
2 changed files with 96 additions and 5 deletions

36
app.py
View File

@ -10001,19 +10001,46 @@ def zopk_index():
).order_by(ZOPKStakeholder.importance.desc(), ZOPKStakeholder.name).limit(10).all()
# Get approved news (both manually approved and AI auto-approved)
# Show more news on main page (expanded view)
news_items = db.query(ZOPKNews).filter(
ZOPKNews.status.in_(['approved', 'auto_approved'])
).order_by(ZOPKNews.published_at.desc()).limit(10).all()
).order_by(ZOPKNews.published_at.desc()).limit(25).all()
# Get featured resources
resources = db.query(ZOPKResource).filter(
ZOPKResource.status == 'approved'
).order_by(ZOPKResource.sort_order, ZOPKResource.created_at.desc()).limit(12).all()
# Stats
# News time-based statistics
from datetime import datetime, timedelta
now = datetime.now()
day_ago = now - timedelta(days=1)
week_ago = now - timedelta(days=7)
month_ago = now - timedelta(days=30)
approved_news_filter = ZOPKNews.status.in_(['approved', 'auto_approved'])
total_news = db.query(ZOPKNews).filter(approved_news_filter).count()
news_stats = {
'total': total_news,
'last_day': db.query(ZOPKNews).filter(
approved_news_filter,
ZOPKNews.published_at >= day_ago
).count(),
'last_week': db.query(ZOPKNews).filter(
approved_news_filter,
ZOPKNews.published_at >= week_ago
).count(),
'last_month': db.query(ZOPKNews).filter(
approved_news_filter,
ZOPKNews.published_at >= month_ago
).count()
}
# General stats
stats = {
'total_projects': len(projects),
'total_news': db.query(ZOPKNews).filter(ZOPKNews.status.in_(['approved', 'auto_approved'])).count(),
'total_news': total_news,
'total_resources': db.query(ZOPKResource).filter(ZOPKResource.status == 'approved').count(),
'total_stakeholders': db.query(ZOPKStakeholder).filter(ZOPKStakeholder.is_active == True).count()
}
@ -10023,7 +10050,8 @@ def zopk_index():
stakeholders=stakeholders,
news_items=news_items,
resources=resources,
stats=stats
stats=stats,
news_stats=news_stats
)
finally:

View File

@ -184,6 +184,40 @@
.category-local_authority { background: #dbeafe; color: #1e40af; }
.category-business { background: #dcfce7; color: #166534; }
/* News Statistics Bar */
.news-stats-bar {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
padding: var(--spacing-md) var(--spacing-lg);
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
border-radius: var(--radius);
border: 1px solid #86efac;
}
.news-stat-item {
display: flex;
align-items: center;
gap: var(--spacing-xs);
font-size: var(--font-size-sm);
}
.news-stat-item .stat-value {
font-weight: 700;
color: var(--primary);
}
.news-stat-item .stat-label {
color: var(--text-secondary);
}
.news-stat-item:not(:last-child)::after {
content: "•";
margin-left: var(--spacing-lg);
color: var(--border);
}
/* News */
.news-grid {
display: grid;
@ -423,9 +457,30 @@
<section>
<div class="section-header">
<h2>Aktualności</h2>
<a href="{{ url_for('zopk_news_list') }}" class="btn btn-secondary btn-sm">Zobacz wszystkie</a>
</div>
<!-- News Statistics Bar -->
{% if news_stats %}
<div class="news-stats-bar">
<div class="news-stat-item">
<span class="stat-value">{{ news_stats.total }}</span>
<span class="stat-label">łącznie</span>
</div>
<div class="news-stat-item">
<span class="stat-value">{{ news_stats.last_day }}</span>
<span class="stat-label">ostatni dzień</span>
</div>
<div class="news-stat-item">
<span class="stat-value">{{ news_stats.last_week }}</span>
<span class="stat-label">ostatni tydzień</span>
</div>
<div class="news-stat-item">
<span class="stat-value">{{ news_stats.last_month }}</span>
<span class="stat-label">ostatni miesiąc</span>
</div>
</div>
{% endif %}
{% if news_items %}
<div class="news-grid">
{% for news in news_items %}
@ -450,6 +505,14 @@
</a>
{% endfor %}
</div>
{% if news_stats and news_stats.total > 25 %}
<div style="text-align: center; margin-top: var(--spacing-lg);">
<a href="{{ url_for('zopk_news_list') }}" class="btn btn-secondary">
Zobacz starsze aktualności ({{ news_stats.total - 25 }} więcej)
</a>
</div>
{% endif %}
{% else %}
<div class="empty-state">
<p>Brak aktualności. Wkrótce pojawią się nowe informacje.</p>