feat: filtres et suppression massive dans admin/articles, profil auteur amélioré

- Admin articles : filtres auteur/catégorie/statut par GET, compteur de résultats
- Admin articles : suppression massive avec checkboxes, confirmation JS, contrôle d'ownership
- Profil auteur : bio tronquée à 3 lignes avec bouton 'plus', limite à 6 articles affichés
- Profil auteur : bouton CTA pill 'Mes liens' vers /liens/{slug}
- Page liens : boutons pill colorés (palette auto par index), fond gris clair, grand avatar
This commit is contained in:
Cedric Abonnel
2026-05-13 00:57:02 +02:00
parent f3584159c1
commit a926e1825d
11 changed files with 350 additions and 51 deletions
+101
View File
@@ -881,6 +881,55 @@ switch ($action) {
include BASE_PATH . '/templates/author_profile.php';
break;
case 'author_articles':
$authorSlug = trim($_GET['slug'] ?? '');
$authorRow = profileBySlug($authorSlug);
if (!$authorRow) {
http_response_code(404);
$content = '<div class="container py-5"><p class="text-muted">Profil introuvable.</p></div>';
$title = 'Profil introuvable';
include BASE_PATH . '/templates/layout.php';
break;
}
$privateCats = $articles->getPrivateCategories();
$allCats = $articles->getCategories();
$authorArticles = array_values(array_filter(
$articles->getAll(publishedOnly: true),
static function (array $a) use ($authorRow, $privateCats): bool {
if (($a['author'] ?? '') !== $authorRow['email']) {
return false;
}
$cat = trim($a['category'] ?? '');
if ($cat !== '' && in_array($cat, $privateCats, true) && !isLoggedIn()) {
return false;
}
if (strtotime((string)($a['published_at'] ?? '')) > time() && !hasCapability('view_previews')) {
return false;
}
return true;
}
));
$perPage = postsPerPage();
$cursor = trim($_GET['cursor'] ?? '');
$offset = 0;
if ($cursor !== '') {
foreach ($authorArticles as $i => $a) {
if ($a['uuid'] === $cursor) {
$offset = $i + 1;
break;
}
}
}
$posts = array_slice($authorArticles, $offset, $perPage);
$nextCursor = count($posts) === $perPage ? end($posts)['uuid'] : null;
$prevCursor = null;
if ($offset > 0) {
$prevOffset = max(0, $offset - $perPage);
$prevCursor = $prevOffset > 0 ? $authorArticles[$prevOffset - 1]['uuid'] : '';
}
include BASE_PATH . '/templates/author_articles.php';
break;
case 'liens':
$liensSlug = trim($_GET['slug'] ?? '');
$liensRow = profileBySlug($liensSlug);
@@ -1622,6 +1671,34 @@ switch ($action) {
$allArticles = array_values(array_filter($allArticles, fn ($a) => ($a['author'] ?? '') === $me));
}
usort($allArticles, fn ($a, $b) => strcmp($b['updated_at'] ?? '', $a['updated_at'] ?? ''));
$adminData['filter_authors'] = array_values(array_unique(array_filter(array_column($allArticles, 'author'))));
$adminData['filter_categories'] = array_values(array_unique(array_filter(array_column($allArticles, 'category'))));
sort($adminData['filter_authors']);
sort($adminData['filter_categories']);
$filterAuthor = trim($_GET['filter_author'] ?? '');
$filterCategory = trim($_GET['filter_category'] ?? '');
$filterStatus = trim($_GET['filter_status'] ?? '');
$adminData['filter_author'] = $filterAuthor;
$adminData['filter_category'] = $filterCategory;
$adminData['filter_status'] = $filterStatus;
$nowTs = time();
if ($filterAuthor !== '') {
$allArticles = array_values(array_filter($allArticles, fn ($a) => ($a['author'] ?? '') === $filterAuthor));
}
if ($filterCategory !== '') {
$allArticles = array_values(array_filter($allArticles, fn ($a) => trim($a['category'] ?? '') === $filterCategory));
}
if ($filterStatus === 'published') {
$allArticles = array_values(array_filter($allArticles, fn ($a) => $a['published'] && strtotime((string)($a['published_at'] ?? '')) <= $nowTs));
} elseif ($filterStatus === 'draft') {
$allArticles = array_values(array_filter($allArticles, fn ($a) => !$a['published']));
} elseif ($filterStatus === 'preview') {
$allArticles = array_values(array_filter($allArticles, fn ($a) => $a['published'] && strtotime((string)($a['published_at'] ?? '')) > $nowTs));
}
$adminData['articles'] = $allArticles;
}
@@ -1706,6 +1783,30 @@ switch ($action) {
include BASE_PATH . '/templates/admin.php';
break;
case 'admin_bulk_delete':
requireAuth();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uuids = $_POST['uuids'] ?? [];
if (is_array($uuids)) {
$me = currentUserEmail() ?? '';
foreach ($uuids as $uid) {
$uid = trim((string)$uid);
if ($uid === '') {
continue;
}
$art = $articles->getByUuid($uid);
if (!$art) {
continue;
}
if (isAdmin() || ($art['author'] ?? '') === $me) {
$articles->delete($uid);
}
}
}
}
header('Location: /admin/articles');
exit;
case 'admin_grant_role':
requireAuth();
if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') {