86 lines
4.9 KiB
Plaintext
86 lines
4.9 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Agrégateur d'Actualités Informatiques</title>
|
|
<link rel="stylesheet" href="/css/style.css">
|
|
</head>
|
|
<body>
|
|
<header class="header">
|
|
<div class="container">
|
|
<h1 class="logo">💻 Veille Tech</h1>
|
|
<p class="subtitle">Agrégateur d'actualités informatiques</p>
|
|
<% if (typeof languages !== 'undefined' && languages.length > 0) { %>
|
|
<div class="lang-filter">
|
|
<span>Langue:</span>
|
|
<a href="/?sort=<%= sort %><%= selectedCategory ? '&category=' + encodeURIComponent(selectedCategory) : '' %>" class="<%= !selectedLang ? 'active' : '' %>">Toutes</a>
|
|
<% languages.forEach(l => { %>
|
|
<a href="/?lang=<%= encodeURIComponent(l) %>&sort=<%= sort %><%= selectedCategory ? '&category=' + encodeURIComponent(selectedCategory) : '' %>" class="<%= selectedLang === l ? 'active' : '' %>"><%= l === 'fr' ? 'Français' : l === 'en' ? 'English' : l.toUpperCase() %></a>
|
|
<% }); %>
|
|
</div>
|
|
<% } %>
|
|
<nav class="nav">
|
|
<a href="/?sort=<%= sort %><%= selectedLang ? '&lang=' + encodeURIComponent(selectedLang) : '' %>" class="<%= !selectedCategory ? 'active' : '' %>">Tous</a>
|
|
<% categories.forEach(cat => { %>
|
|
<a href="/?category=<%= encodeURIComponent(cat) %>&sort=<%= sort %><%= selectedLang ? '&lang=' + encodeURIComponent(selectedLang) : '' %>" class="<%= selectedCategory === cat ? 'active' : '' %>"><%= cat %></a>
|
|
<% }); %>
|
|
</nav>
|
|
<div class="sort">
|
|
<span>Trier par date:</span>
|
|
<a href="/?sort=desc<%= selectedCategory ? '&category=' + encodeURIComponent(selectedCategory) : '' %><%= selectedLang ? '&lang=' + encodeURIComponent(selectedLang) : '' %>" class="<%= sort === 'desc' ? 'active' : '' %>">Plus récent</a>
|
|
<a href="/?sort=asc<%= selectedCategory ? '&category=' + encodeURIComponent(selectedCategory) : '' %><%= selectedLang ? '&lang=' + encodeURIComponent(selectedLang) : '' %>" class="<%= sort === 'asc' ? 'active' : '' %>">Plus ancien</a>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="container">
|
|
<% if (articles.length === 0) { %>
|
|
<div class="empty">
|
|
<p>Aucun article publié pour le moment.</p>
|
|
<p class="small">Les articles en attente doivent être validés depuis l'<a href="/admin">interface d'administration</a>.</p>
|
|
</div>
|
|
<% } else { %>
|
|
<div class="articles">
|
|
<% articles.forEach(article => { %>
|
|
<article class="article-card">
|
|
<div class="article-header">
|
|
<span class="article-source"><%= article.source || 'Source inconnue' %> <% if (article.language || article.source_language) { %><span class="lang-badge"><%= (article.language || article.source_language) === 'fr' ? 'FR' : (article.language || article.source_language).toUpperCase() %></span><% } %></span>
|
|
<span class="article-date">
|
|
<%= article.published_at ? new Date(article.published_at).toLocaleDateString('fr-FR', { year: 'numeric', month: 'long', day: 'numeric' }) : '' %>
|
|
</span>
|
|
</div>
|
|
<h2 class="article-title"><%= article.title %></h2>
|
|
<% if (article.summary) { %>
|
|
<p class="article-summary"><%= article.summary %></p>
|
|
<% } %>
|
|
<% if (article.categories) { %>
|
|
<div class="article-categories">
|
|
<% try {
|
|
const cats = JSON.parse(article.categories);
|
|
if (Array.isArray(cats)) {
|
|
cats.forEach(cat => { %>
|
|
<span class="category-tag"><%= cat %></span>
|
|
<% });
|
|
}
|
|
} catch(e) {} %>
|
|
</div>
|
|
<% } %>
|
|
<a href="<%= article.url %>" target="_blank" rel="noopener noreferrer" class="article-link">
|
|
Lire l'article original ↗
|
|
</a>
|
|
</article>
|
|
<% }); %>
|
|
</div>
|
|
<% } %>
|
|
</main>
|
|
|
|
<footer class="footer">
|
|
<div class="container">
|
|
<p>Veille Tech - Agrégateur d'actualités informatiques</p>
|
|
<p class="small"><a href="/admin">Administration</a></p>
|
|
</div>
|
|
</footer>
|
|
</body>
|
|
</html>
|