|
{% extends "admin_base.html" %}
|
|
{% block admin_content %}
|
|
<div class="admin-toolbar">
|
|
<h2>News - Curation</h2>
|
|
<span class="admin-count">{{ pagination.total }} articles</span>
|
|
</div>
|
|
|
|
<div class="admin-table-wrap">
|
|
<table class="admin-table">
|
|
<caption class="sr-only">Imported news articles with grade, status, and curation controls</caption>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="admin-news-col-title">Title</th>
|
|
<th scope="col">Source</th>
|
|
<th scope="col">Grade</th>
|
|
<th scope="col">Status</th>
|
|
<th scope="col">Img</th>
|
|
<th scope="col">Imported</th>
|
|
<th scope="col">Landing</th>
|
|
<th scope="col">Featured</th>
|
|
<th scope="col"><span class="sr-only">Actions</span></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in articles %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ item.article['url'] }}" target="_blank" rel="noopener" class="admin-news-title">
|
|
{{ render_title(item.article['title'][:80] ~ ('...' if item.article['title']|length > 80 else '')) }}
|
|
</a>
|
|
</td>
|
|
<td>{{ item.article['source_name'] }}</td>
|
|
<td>
|
|
{% if item.grade >= 9 %}
|
|
<span class="admin-grade admin-grade-top">{{ item.grade }}</span>
|
|
{% elif item.grade >= 7 %}
|
|
<span class="admin-grade admin-grade-high">{{ item.grade }}</span>
|
|
{% else %}
|
|
<span class="admin-grade">{{ item.grade }}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="admin-news-status-cell">
|
|
<form method="POST" action="/admin/news/{{ item.article['uid'] }}/publish" class="admin-inline-form">
|
|
<button type="submit" class="admin-toggle-switch {% if item.article.get('status') == 'published' %}active{% endif %}" aria-pressed="{% if item.article.get('status') == 'published' %}true{% else %}false{% endif %}" aria-label="Toggle published status">
|
|
<span class="admin-toggle-knob"></span>
|
|
</button>
|
|
</form>
|
|
<span class="admin-news-status-label">
|
|
{% if item.article.get('status') == 'published' %}Published{% else %}Draft{% endif %}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
<td class="admin-news-img-cell">
|
|
{% if item.has_image %}
|
|
<span title="Has image">🖼</span>
|
|
{% else %}
|
|
<span class="admin-news-img-empty">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="admin-news-date-cell">
|
|
{% if item.synced_at %}
|
|
{{ local_dt(item.synced_at) }}
|
|
{% else %}
|
|
{{ dt_ago(item.synced_at) if item.synced_at else item.time_ago }}
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<form method="POST" action="/admin/news/{{ item.article['uid'] }}/landing" class="admin-inline-form">
|
|
<button type="submit" class="admin-toggle-switch {% if item.article.get('show_on_landing') %}active{% endif %}" aria-pressed="{% if item.article.get('show_on_landing') %}true{% else %}false{% endif %}" aria-label="Toggle landing page placement">
|
|
<span class="admin-toggle-knob"></span>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
<td>
|
|
<form method="POST" action="/admin/news/{{ item.article['uid'] }}/toggle" class="admin-inline-form">
|
|
<button type="submit" class="admin-toggle-switch {% if item.article.get('featured') %}active{% endif %}" aria-pressed="{% if item.article.get('featured') %}true{% else %}false{% endif %}" aria-label="Toggle featured status">
|
|
<span class="admin-toggle-knob"></span>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
<td>
|
|
<form method="POST" action="/admin/news/{{ item.article['uid'] }}/delete" class="admin-inline-form">
|
|
<button type="submit" class="admin-btn admin-btn-sm admin-btn-danger-text" data-confirm="Delete this article?" aria-label="Delete article">×</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{% include "_pagination.html" %}
|
|
|
|
{% if not articles %}
|
|
<div class="admin-empty">
|
|
<p>No news articles found. The news service runs hourly and fetches articles from the configured API.</p>
|
|
<p><a href="/admin/services">Check service status</a></p>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|