|
{% 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">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 30%;">Title</th>
|
|
<th>Source</th>
|
|
<th>Grade</th>
|
|
<th>Status</th>
|
|
<th>Img</th>
|
|
<th>Imported</th>
|
|
<th>Landing</th>
|
|
<th>Featured</th>
|
|
<th></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 style="display: flex; align-items: center; gap: 0.375rem;">
|
|
<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 %}">
|
|
<span class="admin-toggle-knob"></span>
|
|
</button>
|
|
</form>
|
|
<span style="font-size: 0.6875rem; font-weight: 600; color: var(--text-muted); white-space: nowrap;">
|
|
{% if item.article.get('status') == 'published' %}Published{% else %}Draft{% endif %}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
<td style="text-align: center; font-size: 0.8125rem;">
|
|
{% if item.has_image %}
|
|
<span title="Has image">🖼</span>
|
|
{% else %}
|
|
<span style="opacity: 0.2;">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td style="white-space: nowrap; font-size: 0.75rem; color: var(--text-muted);">
|
|
{% 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 %}">
|
|
<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 %}">
|
|
<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" style="color: var(--danger);" data-confirm="Delete this 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 %}
|