feat: page profil public /profil/{slug} avec liste des articles

This commit is contained in:
Cedric Abonnel
2026-05-12 23:49:21 +02:00
parent e1c179b536
commit 654542f13b
7 changed files with 195 additions and 8 deletions
+3
View File
@@ -41,6 +41,9 @@ RewriteRule ^categories/?$ /index.php?action=categories [L,QSA]
RewriteRule ^profile/?$ /index.php?action=profile [L,QSA]
RewriteRule ^search/?$ /index.php?action=search [L,QSA]
# Profil public auteur
RewriteRule ^profil/([a-z0-9][a-z0-9-]*)/?$ /index.php?action=author&slug=$1 [L,QSA]
# Pages statiques
RewriteRule ^about/?$ /index.php?action=about [L,QSA]
RewriteRule ^legal/?$ /index.php?action=legal [L,QSA]
+35
View File
@@ -1242,3 +1242,38 @@ footer.mt-5 { margin-top: 0 !important; }
}
.tag-cloud-reset:hover { color: var(--vl-accent); }
/* ─── Profil public auteur ───────────────── */
.author-profile-hero {
display: flex;
align-items: center;
gap: 1.5rem;
}
.author-avatar {
flex-shrink: 0;
width: 4rem;
height: 4rem;
border-radius: 50%;
background: var(--vl-accent);
color: #fff;
font-size: 1.75rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
.author-profile-name {
font-size: 1.5rem;
font-weight: 700;
margin: 0 0 .25rem;
}
.author-profile-link {
font-size: .875rem;
color: var(--vl-muted);
}
.author-profile-link:hover { color: var(--vl-accent); }
+35 -4
View File
@@ -851,6 +851,36 @@ switch ($action) {
header('Location: /categories');
exit;
case 'author':
$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();
$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;
}
));
include BASE_PATH . '/templates/author_profile.php';
break;
case 'about':
include BASE_PATH . '/templates/about.php';
break;
@@ -1785,12 +1815,13 @@ switch ($action) {
$pdo = dbPdo();
if ($pdo) {
try {
$newSlug = slugify($newName);
$st = $pdo->prepare(
'INSERT INTO user_profiles (email, display_name, profile_url, updated_at)
VALUES (:e, :n, :u, now())
ON CONFLICT (email) DO UPDATE SET display_name = :n, profile_url = :u, updated_at = now()'
'INSERT INTO user_profiles (email, display_name, profile_url, profile_slug, updated_at)
VALUES (:e, :n, :u, :s, now())
ON CONFLICT (email) DO UPDATE SET display_name = :n, profile_url = :u, profile_slug = :s, updated_at = now()'
);
$st->execute([':e' => currentUserEmail(), ':n' => $newName, ':u' => $newUrl]);
$st->execute([':e' => currentUserEmail(), ':n' => $newName, ':u' => $newUrl, ':s' => $newSlug]);
$_SESSION['user_display_name'] = $newName;
$profileSuccess = true;
} catch (\Throwable $ex) {