Files
veille-tech-aggregator/app/templates/admin/dashboard.ejs
T
2026-10-25 20:05:12 +01:00

138 lines
8.0 KiB
Plaintext

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tableau de bord - Administration</title>
<link rel="stylesheet" href="/css/admin.css">
</head>
<body>
<header class="admin-header">
<div class="container">
<h1>Administration - Veille Tech</h1>
<nav class="admin-nav">
<a href="/admin<%= language !== 'all' ? '?language=' + encodeURIComponent(language) : '' %>" class="<%= status === 'all' ? 'active' : '' %>">Tous (<%= stats.total %>)</a>
<a href="/admin?status=pending<%= language !== 'all' ? '&language=' + encodeURIComponent(language) : '' %>" class="<%= status === 'pending' ? 'active' : '' %>">En attente (<%= stats.pending %>)</a>
<a href="/admin?status=published<%= language !== 'all' ? '&language=' + encodeURIComponent(language) : '' %>" class="<%= status === 'published' ? 'active' : '' %>">Publiés (<%= stats.published %>)</a>
<a href="/admin?status=hidden<%= language !== 'all' ? '&language=' + encodeURIComponent(language) : '' %>" class="<%= status === 'hidden' ? 'active' : '' %>">Masqués (<%= stats.hidden %>)</a>
<a href="/admin?status=rejected<%= language !== 'all' ? '&language=' + encodeURIComponent(language) : '' %>" class="<%= status === 'rejected' ? 'active' : '' %>">Rejetés (<%= stats.rejected %>)</a>
<a href="/admin/sources">Sources</a>
<a href="/admin/log">Journal</a>
<form method="POST" action="/admin/collect" style="display:inline">
<button type="submit" class="btn btn-collect">Collecter maintenant</button>
</form>
<a href="/admin/logout" class="logout">Déconnexion</a>
</nav>
</div>
</header>
<main class="container">
<% const langLabel = (l) => l === 'fr' ? 'Français' : l === 'en' ? 'Anglais' : (l || '').toUpperCase(); %>
<form method="GET" action="/admin" class="filters">
<% if (status !== 'all') { %>
<input type="hidden" name="status" value="<%= status %>">
<% } %>
<label for="language">Langue :</label>
<select id="language" name="language" onchange="this.form.submit()">
<option value="all" <%= language === 'all' ? 'selected' : '' %>>Toutes les langues</option>
<% languages.forEach(l => { %>
<option value="<%= l.lang %>" <%= language === l.lang ? 'selected' : '' %>><%= langLabel(l.lang) %> (<%= l.c %>)</option>
<% }); %>
</select>
<noscript><button type="submit" class="btn btn-filter">Filtrer</button></noscript>
</form>
<div class="stats">
<div class="stat-card">En attente: <strong><%= stats.pending %></strong></div>
<div class="stat-card">Publiés: <strong><%= stats.published %></strong></div>
<div class="stat-card">Masqués: <strong><%= stats.hidden %></strong></div>
<div class="stat-card">Rejetés: <strong><%= stats.rejected %></strong></div>
</div>
<% if (articles.length === 0) { %>
<div class="empty">Aucun article dans cette catégorie.</div>
<% } else { %>
<div class="articles-admin">
<% articles.forEach(article => { %>
<div class="article-admin-card">
<div class="article-admin-header">
<div>
<h3><%= article.title %></h3>
<div class="article-meta">
<span>Source: <%= article.source %></span> |
<span>URL: <a href="<%= article.url %>" target="_blank"><%= article.url.substring(0, 60) %>...</a></span> |
<span>Statut: <span class="badge badge-<%= article.status %>"><%= article.status %></span></span> |
<span>Langue: <%= langLabel(article.language || article.source_language || 'fr') %></span> |
<span>Collecté par: <%= article.collected_by %></span>
</div>
</div>
</div>
<% if (article.summary) { %>
<p class="article-admin-summary"><%= article.summary %></p>
<% } %>
<% if (article.status === 'pending') { %>
<form method="POST" action="/admin/article/<%= article.id %>/validate" class="validate-form">
<div class="form-row">
<input type="text" name="categories" placeholder="Catégories (séparées par virgule)"
value="<% try { const cats = JSON.parse(article.categories||'[]'); %><%= cats.join(', ') %><% } catch(e) {} %>">
<input type="text" name="summary" placeholder="Résumé à afficher (optionnel)" value="<%= article.summary || '' %>">
</div>
<button type="submit" class="btn btn-publish">Valider et publier</button>
</form>
<% } %>
<div class="article-admin-actions">
<% if (article.status !== 'published') { %>
<form method="POST" action="/admin/article/<%= article.id %>/publish" style="display:inline">
<button type="submit" class="btn btn-success">Publier</button>
</form>
<% } %>
<% if (article.status !== 'hidden') { %>
<form method="POST" action="/admin/article/<%= article.id %>/hide" style="display:inline">
<button type="submit" class="btn btn-warning">Masquer</button>
</form>
<% } %>
<% if (article.status !== 'rejected') { %>
<form method="POST" action="/admin/article/<%= article.id %>/reject" style="display:inline">
<button type="submit" class="btn btn-danger">Rejeter</button>
</form>
<% } %>
<form method="POST" action="/admin/article/<%= article.id %>/delete" style="display:inline" onsubmit="return confirm('Supprimer définitivement cet article ?')">
<button type="submit" class="btn btn-danger">Supprimer</button>
</form>
</div>
</div>
<% }); %>
</div>
<% } %>
</main>
<script>
// Conserve la position de défilement lors des actions (publier, masquer, rejeter, supprimer)
(function () {
var storageKey = 'admin-scroll:' + location.pathname + location.search;
document.querySelectorAll('form').forEach(function (form) {
if (form.method.toLowerCase() !== 'post') return;
form.addEventListener('submit', function (event) {
if (event.defaultPrevented) return; // ex. suppression annulée
sessionStorage.setItem(storageKey, String(window.scrollY));
});
});
var savedPosition = sessionStorage.getItem(storageKey);
if (savedPosition === null) return;
sessionStorage.removeItem(storageKey);
window.addEventListener('load', function () {
window.scrollTo(0, parseInt(savedPosition, 10) || 0);
});
})();
</script>
</body>
</html>