merge head/nav templates into unified head.php + header.php; semantic CSS for nav

This commit is contained in:
Pontoporeia
2026-03-31 22:22:56 +02:00
parent 4ff959a72d
commit 780b1b2a13
24 changed files with 162 additions and 137 deletions

22
TODO.md
View File

@@ -1,15 +1,11 @@
# TODO # TODO
## Done ## Completed
- [x] Replace unicode left arrow (←) with SVG arrow icon in admin nav logo - [x] Merge public and admin head/nav templates into unified `templates/head.php` and `templates/header.php`
- `templates/head.php` — outputs `<!DOCTYPE html>…</head><body class="…">`, reads `$bodyClass`, `$isAdmin`; handles admin title suffix, admin.css prepend, and OG tag suppression internally
## Fixes - `templates/header.php` — outputs `<header>…</header>` with public nav + search bar or admin nav depending on `$isAdmin`
- [x] Fix CSV import UNIQUE constraint crash: skip rows whose identifier already exists in DB - Deleted: `templates/public/head.php`, `templates/admin/head.php`, `templates/nav.php`, `templates/admin/nav.php`
- [x] Auto-migrate both test.db and posterg.db on `just serve` via scripts/migrate.sh - All 11 admin pages and 5 public pages updated to set `$bodyClass` / `$isAdmin` and include new templates
- [x] Fix wrong `require_once` depth in `public/admin/actions/page.php` (`../../``../../../`) - [x] Replace nav/header BEM custom classes with semantic HTML targeting in CSS
- [x] Fix same path depth bug in `formulaire.php` and `publish.php` - `common.css`: `.site-nav``header nav`, `.site-nav__logo``header nav > a`, etc.
- [x] Fix CSV import: imported theses not visible on public site (is_published defaulted to 0, access_type_id never set) - `admin.css`: `.admin-nav``.admin-body header nav`, logout via `[data-nav-logout]` attribute
- [x] Fix DB routing: local dev (php -S) auto-uses test.db, production (nginx/fpm) uses posterg.db — no env var needed
- [x] migrate.sh auto-initialises DB from schema when absent/empty; existing DBs untouched
- [x] Consolidate admin/public templates: shared head.php, admin/nav.php partial, common.css loaded first in admin, removed duplicate a11y CSS
- [x] admin/head.php now includes public/head.php as base (single source of boilerplate); removed duplicate font-family from .admin-body; wired templates/footer.php to all public pages; fixed duplicate body{} in common.css

View File

@@ -16,7 +16,8 @@ if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
} }
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Compte administrateur</h1> <h1 class="admin-page-title">Compte administrateur</h1>

View File

@@ -39,7 +39,8 @@ function wasSelected($key, $value) {
return $formData[$key] == $value; return $formData[$key] == $value;
} }
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Ajouter un TFE</h1> <h1 class="admin-page-title">Ajouter un TFE</h1>

View File

@@ -61,7 +61,8 @@ try {
die("Erreur lors du chargement: " . $e->getMessage()); die("Erreur lors du chargement: " . $e->getMessage());
} }
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Modifier un TFE</h1> <h1 class="admin-page-title">Modifier un TFE</h1>

View File

@@ -317,7 +317,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
} }
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Importer une liste de TFE</h1> <h1 class="admin-page-title">Importer une liste de TFE</h1>

View File

@@ -30,7 +30,8 @@ try {
die("Erreur lors du chargement de la liste."); die("Erreur lors du chargement de la liste.");
} }
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<script> <script>
function toggleAll(src) { function toggleAll(src) {

View File

@@ -23,7 +23,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pageTitle = 'Connexion'; $pageTitle = 'Connexion';
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<div class="admin-login-wrap"> <div class="admin-login-wrap">
<div class="admin-login-box"> <div class="admin-login-box">

View File

@@ -78,7 +78,8 @@ var easyMDE = new EasyMDE({
}); });
JS; JS;
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Éditer : <?= htmlspecialchars($page['title']) ?></h1> <h1 class="admin-page-title">Éditer : <?= htmlspecialchars($page['title']) ?></h1>

View File

@@ -18,7 +18,8 @@ try {
$success = $_SESSION['success'] ?? null; $success = $_SESSION['success'] ?? null;
unset($_SESSION['success']); unset($_SESSION['success']);
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Pages statiques</h1> <h1 class="admin-page-title">Pages statiques</h1>

View File

@@ -313,8 +313,9 @@ if ($activeTab === 'nginx_config') {
} }
} }
require_once APP_ROOT . '/templates/admin/head.php'; $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php';
?> ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<style> <style>
/* ── System page tabs ──────────────────────────────────────────────────── */ /* ── System page tabs ──────────────────────────────────────────────────── */

View File

@@ -22,7 +22,8 @@ $error = $_SESSION['admin_error'] ?? null;
$success = $_SESSION['admin_success'] ?? null; $success = $_SESSION['admin_success'] ?? null;
unset($_SESSION['admin_error'], $_SESSION['admin_success']); unset($_SESSION['admin_error'], $_SESSION['admin_success']);
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Mots-clés (<?= count($tags) ?>)</h1> <h1 class="admin-page-title">Mots-clés (<?= count($tags) ?>)</h1>

View File

@@ -62,7 +62,8 @@ function formatFileSize($bytes) {
// Set page title for header // Set page title for header
$pageTitle = "Récapitulatif TFE"; $pageTitle = "Récapitulatif TFE";
?> ?>
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?> <?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<main class="admin-main" id="main-content"> <main class="admin-main" id="main-content">
<h1 class="admin-page-title">Récapitulatif TFE</h1> <h1 class="admin-page-title">Récapitulatif TFE</h1>

View File

@@ -34,13 +34,10 @@ $ogTags = [
'site_name' => 'Posterg ERG', 'site_name' => 'Posterg ERG',
]; ];
$extraCss = ['/assets/css/apropos.css']; $extraCss = ['/assets/css/apropos.css'];
$bodyClass = 'apropos-body';
?> ?>
<?php include APP_ROOT . '/templates/public/head.php'; ?> <?php include APP_ROOT . '/templates/head.php'; ?>
<body class="apropos-body"> <?php include APP_ROOT . '/templates/header.php'; ?>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/nav.php'; ?>
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
<main class="apropos-main" id="main-content"> <main class="apropos-main" id="main-content">
<div class="apropos-layout"> <div class="apropos-layout">

View File

@@ -21,8 +21,12 @@
/* font-family inherited from common.css body */ /* font-family inherited from common.css body */
} }
/* Admin nav (dark version of site-nav) */ /* Admin header / nav */
.admin-nav { .admin-body header {
flex-shrink: 0;
}
.admin-body header nav {
background: linear-gradient( background: linear-gradient(
to bottom, to bottom,
var(--admin-purple) 0%, var(--admin-purple) 0%,
@@ -32,10 +36,9 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 2.5rem; gap: 2.5rem;
flex-shrink: 0;
} }
.admin-nav__logo { .admin-body header nav > a {
font-size: 0.88rem; font-size: 0.88rem;
letter-spacing: 0.12em; letter-spacing: 0.12em;
text-transform: uppercase; text-transform: uppercase;
@@ -44,8 +47,7 @@
font-weight: 400; font-weight: 400;
} }
/* Nav link list */ .admin-body header nav ul {
.admin-nav__list {
list-style: none; list-style: none;
margin: 0 0 0 auto; margin: 0 0 0 auto;
padding: 0; padding: 0;
@@ -54,7 +56,7 @@
gap: 2.5rem; gap: 2.5rem;
} }
.admin-nav__list a { .admin-body header nav ul a {
font-size: 0.85rem; font-size: 0.85rem;
letter-spacing: 0.1em; letter-spacing: 0.1em;
text-transform: uppercase; text-transform: uppercase;
@@ -64,23 +66,23 @@
transition: opacity 0.15s; transition: opacity 0.15s;
} }
.admin-nav__list a:hover, .admin-body header nav ul a:hover,
.admin-nav__list a[aria-current="page"] { .admin-body header nav ul a[aria-current="page"] {
opacity: 1; opacity: 1;
color: #fff; color: #fff;
} }
.admin-nav__list a[aria-current="page"] { .admin-body header nav ul a[aria-current="page"] {
border-bottom: 1px solid rgba(255, 255, 255, 0.6); border-bottom: 1px solid rgba(255, 255, 255, 0.6);
padding-bottom: 1px; padding-bottom: 1px;
} }
/* Logout link — visually subdued, last in list */ /* Logout — visually subdued */
.admin-nav__logout a { .admin-body header nav ul [data-nav-logout] a {
opacity: 0.6; opacity: 0.6;
} }
.admin-nav__logout a:hover { .admin-body header nav ul [data-nav-logout] a:hover {
opacity: 1; opacity: 1;
} }

View File

@@ -49,9 +49,13 @@ a:hover {
} }
/* ============================================================ /* ============================================================
NAV BAR (shared across all public pages) HEADER / NAV BAR (public pages)
============================================================ */ ============================================================ */
.site-nav { header {
flex-shrink: 0;
}
header nav {
background: linear-gradient( background: linear-gradient(
to bottom, to bottom,
var(--purple) 0%, var(--purple) 0%,
@@ -61,11 +65,9 @@ a:hover {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
flex-shrink: 0;
/* height: 3ch; */
} }
.site-nav__logo { header nav > a {
font-family: "police1", sans-serif; font-family: "police1", sans-serif;
font-size: 0.95rem; font-size: 0.95rem;
letter-spacing: 0.12em; letter-spacing: 0.12em;
@@ -75,7 +77,7 @@ a:hover {
font-weight: 400; font-weight: 400;
} }
.site-nav ul { header nav ul {
display: flex; display: flex;
gap: 3rem; gap: 3rem;
align-items: center; align-items: center;
@@ -84,7 +86,7 @@ a:hover {
padding: 0; padding: 0;
} }
.site-nav ul a { header nav ul a {
font-size: 0.85rem; font-size: 0.85rem;
letter-spacing: 0.12em; letter-spacing: 0.12em;
text-transform: uppercase; text-transform: uppercase;
@@ -94,11 +96,11 @@ a:hover {
transition: opacity 0.15s; transition: opacity 0.15s;
} }
.site-nav ul a:hover { header nav ul a:hover {
opacity: 1; opacity: 1;
} }
.site-nav ul a[aria-current="page"] { header nav ul a[aria-current="page"] {
opacity: 1; opacity: 1;
border-bottom: 1px solid rgba(255, 255, 255, 0.6); border-bottom: 1px solid rgba(255, 255, 255, 0.6);
padding-bottom: 1px; padding-bottom: 1px;

View File

@@ -60,13 +60,10 @@ $ogTags = [
'site_name' => 'Posterg ERG', 'site_name' => 'Posterg ERG',
]; ];
$extraCss = ['/assets/css/main.css']; $extraCss = ['/assets/css/main.css'];
$bodyClass = 'home-body';
?> ?>
<?php include APP_ROOT . '/templates/public/head.php'; ?> <?php include APP_ROOT . '/templates/head.php'; ?>
<body class="home-body"> <?php include APP_ROOT . '/templates/header.php'; ?>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/nav.php'; ?>
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
<?php if ($year): ?> <?php if ($year): ?>
<p class="filter-info" role="status"> <p class="filter-info" role="status">

View File

@@ -30,13 +30,10 @@ $ogTags = [
'site_name' => 'Posterg ERG', 'site_name' => 'Posterg ERG',
]; ];
$extraCss = ['/assets/css/apropos.css']; $extraCss = ['/assets/css/apropos.css'];
$bodyClass = 'apropos-body';
?> ?>
<?php include APP_ROOT . '/templates/public/head.php'; ?> <?php include APP_ROOT . '/templates/head.php'; ?>
<body class="apropos-body"> <?php include APP_ROOT . '/templates/header.php'; ?>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/nav.php'; ?>
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
<main class="apropos-main" id="main-content"> <main class="apropos-main" id="main-content">
<div class="prose apropos-single"> <div class="prose apropos-single">

View File

@@ -110,13 +110,10 @@ $ogTags = [
'site_name' => 'Posterg ERG', 'site_name' => 'Posterg ERG',
]; ];
$extraCss = ['/assets/css/search.css']; $extraCss = ['/assets/css/search.css'];
$bodyClass = 'search-body';
?> ?>
<?php include APP_ROOT . '/templates/public/head.php'; ?> <?php include APP_ROOT . '/templates/head.php'; ?>
<body class="search-body"> <?php include APP_ROOT . '/templates/header.php'; ?>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/nav.php'; ?>
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
<?php if ($validationError): ?> <?php if ($validationError): ?>
<div class="search-error">⚠ <?= htmlspecialchars($validationError) ?></div> <div class="search-error">⚠ <?= htmlspecialchars($validationError) ?></div>

View File

@@ -57,13 +57,10 @@ unset($_ogBaseUrl, $_ogImage);
// --- End Open Graph ---------------------------------------------------------- // --- End Open Graph ----------------------------------------------------------
$extraCss = ['/assets/css/tfe.css']; $extraCss = ['/assets/css/tfe.css'];
$bodyClass = 'tfe-body';
?> ?>
<?php include APP_ROOT . '/templates/public/head.php'; ?> <?php include APP_ROOT . '/templates/head.php'; ?>
<body class="tfe-body"> <?php include APP_ROOT . '/templates/header.php'; ?>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/nav.php'; ?>
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
<main class="tfe-main" id="main-content"> <main class="tfe-main" id="main-content">
<article class="tfe-layout"> <article class="tfe-layout">

View File

@@ -1,11 +0,0 @@
<?php
// Admin head: builds on the shared public head.
// Sets admin defaults then delegates to public/head.php for the full <head> block.
$pageTitle = isset($pageTitle) ? $pageTitle . ' Admin' : 'Admin';
$extraCss = array_merge(['/assets/css/admin.css'], $extraCss ?? []);
$_adminHead = true; // flag so public/head.php knows to skip OG/meta
?>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="admin-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php include APP_ROOT . '/templates/admin/nav.php'; ?>

View File

@@ -1,26 +0,0 @@
<?php
// admin/nav.php — admin navigation bar
// Reads $pageTitle (set by each page) and $_GET['id'] for context-sensitive edit link.
$_adminCurrentPage = basename($_SERVER['PHP_SELF']);
$_adminThesisId = $_GET['id'] ?? null;
?>
<nav class="admin-nav" aria-label="Navigation admin">
<a href="/" class="admin-nav__logo" target="_blank" rel="noopener noreferrer">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" style="vertical-align:middle;margin-right:0.4em"><path d="M208,72H128V32a8,8,0,0,0-13.66-5.66l-96,96a8,8,0,0,0,0,11.32l96,96A8,8,0,0,0,128,224V184h80a16,16,0,0,0,16-16V88A16,16,0,0,0,208,72Zm0,96H120a8,8,0,0,0-8,8v28.69L35.31,128,112,51.31V80a8,8,0,0,0,8,8h88Z"></path></svg>Posterg<span class="sr-only"> (site public, nouvel onglet)</span>
</a>
<ul class="admin-nav__list">
<li><a href="/admin/" <?= $_adminCurrentPage === 'index.php' ? 'aria-current="page"' : '' ?>>Liste des TFE</a></li>
<li><a href="/admin/add.php" <?= $_adminCurrentPage === 'add.php' ? 'aria-current="page"' : '' ?>>Ajouter un TFE</a></li>
<li><a href="/admin/import.php" <?= $_adminCurrentPage === 'import.php' ? 'aria-current="page"' : '' ?>>Importer une liste de TFE</a></li>
<li><a href="/admin/pages.php" <?= in_array($_adminCurrentPage, ['pages.php', 'pages-edit.php']) ? 'aria-current="page"' : '' ?>>Pages statiques</a></li>
<li><a href="/admin/tags.php" <?= $_adminCurrentPage === 'tags.php' ? 'aria-current="page"' : '' ?>>Mots-clés</a></li>
<li><a href="/admin/system.php" <?= in_array($_adminCurrentPage, ['system.php', 'status.php', 'logs.php']) ? 'aria-current="page"' : '' ?>>Système</a></li>
<li><a href="/admin/account.php" <?= $_adminCurrentPage === 'account.php' ? 'aria-current="page"' : '' ?>>Compte</a></li>
<?php if ($_adminThesisId && in_array($_adminCurrentPage, ['edit.php', 'thanks.php'])): ?>
<li><a href="/admin/edit.php?id=<?= intval($_adminThesisId) ?>" <?= $_adminCurrentPage === 'edit.php' ? 'aria-current="page"' : '' ?>>Modifier</a></li>
<?php endif; ?>
<?php if (defined('ADMIN_PASSWORD_HASH')): ?>
<li class="admin-nav__logout"><a href="/admin/logout.php">Déconnexion</a></li>
<?php endif; ?>
</ul>
</nav>

View File

@@ -3,8 +3,15 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<?php
// Admin: append suffix to title and prepend admin.css
if (!empty($isAdmin)) {
$pageTitle = isset($pageTitle) ? $pageTitle . ' Admin' : 'Admin';
$extraCss = array_merge(['/assets/css/admin.css'], $extraCss ?? []);
}
?>
<title><?= htmlspecialchars($pageTitle ?? 'Posterg') ?></title> <title><?= htmlspecialchars($pageTitle ?? 'Posterg') ?></title>
<?php if (!empty($_adminHead)) { $ogTags = []; $metaDescription = ''; } ?> <?php if (empty($isAdmin)): ?>
<?php if (!empty($metaDescription)): ?> <?php if (!empty($metaDescription)): ?>
<meta name="description" content="<?= htmlspecialchars($metaDescription) ?>"> <meta name="description" content="<?= htmlspecialchars($metaDescription) ?>">
<?php endif; ?> <?php endif; ?>
@@ -49,6 +56,7 @@
<meta name="twitter:image:alt" content="<?= htmlspecialchars($ogImageAlt) ?>"> <meta name="twitter:image:alt" content="<?= htmlspecialchars($ogImageAlt) ?>">
<?php endif; ?> <?php endif; ?>
<?php endif; ?> <?php endif; ?>
<?php endif; ?>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg"> <link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="/assets/css/modern-normalize.min.css"> <link rel="stylesheet" href="/assets/css/modern-normalize.min.css">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
@@ -65,3 +73,4 @@
</script> </script>
<?php endif; ?> <?php endif; ?>
</head> </head>
<body class="<?= htmlspecialchars($bodyClass ?? '') ?>">

80
templates/header.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
// header.php — unified site header for public and admin sections.
// Reads: $isAdmin (bool), $currentNav (string, public only)
$_isAdmin = !empty($isAdmin);
$_navCurrent = $currentNav ?? '';
$_currentPage = basename($_SERVER['PHP_SELF']);
$_thesisId = $_GET['id'] ?? null;
?>
<header>
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
<?php if ($_isAdmin): ?>
<nav aria-label="Navigation admin">
<a href="/" target="_blank" rel="noopener noreferrer">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" style="vertical-align:middle;margin-right:0.4em"><path d="M208,72H128V32a8,8,0,0,0-13.66-5.66l-96,96a8,8,0,0,0,0,11.32l96,96A8,8,0,0,0,128,224V184h80a16,16,0,0,0,16-16V88A16,16,0,0,0,208,72Zm0,96H120a8,8,0,0,0-8,8v28.69L35.31,128,112,51.31V80a8,8,0,0,0,8,8h88Z"></path></svg>Posterg<span class="sr-only"> (site public, nouvel onglet)</span>
</a>
<ul>
<li><a href="/admin/" <?= $_currentPage === 'index.php' ? 'aria-current="page"' : '' ?>>Liste des TFE</a></li>
<li><a href="/admin/add.php" <?= $_currentPage === 'add.php' ? 'aria-current="page"' : '' ?>>Ajouter un TFE</a></li>
<li><a href="/admin/import.php" <?= $_currentPage === 'import.php' ? 'aria-current="page"' : '' ?>>Importer une liste de TFE</a></li>
<li><a href="/admin/pages.php" <?= in_array($_currentPage, ['pages.php', 'pages-edit.php']) ? 'aria-current="page"' : '' ?>>Pages statiques</a></li>
<li><a href="/admin/tags.php" <?= $_currentPage === 'tags.php' ? 'aria-current="page"' : '' ?>>Mots-clés</a></li>
<li><a href="/admin/system.php" <?= in_array($_currentPage, ['system.php', 'status.php', 'logs.php']) ? 'aria-current="page"' : '' ?>>Système</a></li>
<li><a href="/admin/account.php" <?= $_currentPage === 'account.php' ? 'aria-current="page"' : '' ?>>Compte</a></li>
<?php if ($_thesisId && in_array($_currentPage, ['edit.php', 'thanks.php'])): ?>
<li><a href="/admin/edit.php?id=<?= intval($_thesisId) ?>" <?= $_currentPage === 'edit.php' ? 'aria-current="page"' : '' ?>>Modifier</a></li>
<?php endif; ?>
<?php if (defined('ADMIN_PASSWORD_HASH')): ?>
<li data-nav-logout><a href="/admin/logout.php">Déconnexion</a></li>
<?php endif; ?>
</ul>
</nav>
<?php else: ?>
<nav aria-label="Navigation principale">
<a href="/index.php">Posterg</a>
<ul>
<li>
<a href="/search.php"
<?= ($_navCurrent === 'repertoire') ? 'aria-current="page"' : '' ?>>Répertoire</a>
</li>
<li>
<a href="/licence.php"
<?= ($_navCurrent === 'licence') ? 'aria-current="page"' : '' ?>>Licence</a>
</li>
<li>
<a href="/apropos.php"
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
</li>
</ul>
</nav>
<?php
// Search bar — public section only
$searchBarValue = $searchBarValue ?? $_GET['query'] ?? '';
?>
<form class="site-search" method="GET" action="/search.php"
role="search" aria-label="Recherche">
<label for="site-search-input" class="sr-only">Recherche</label>
<svg class="site-search__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
aria-hidden="true" focusable="false">
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
<input
id="site-search-input"
class="site-search__input"
type="text"
name="query"
placeholder="Recherche..."
value="<?= htmlspecialchars($searchBarValue) ?>"
autocomplete="off"
>
</form>
<?php endif; ?>
</header>

View File

@@ -1,23 +0,0 @@
<?php
// nav.php — shared public navigation bar
// Usage: include this partial from any public page
// Provide $currentNav variable to mark active links (optional)
$_navCurrent = $currentNav ?? '';
?>
<nav class="site-nav" aria-label="Navigation principale">
<a class="site-nav__logo" href="/index.php">Posterg</a>
<ul role="list">
<li>
<a href="/search.php"
<?= ($_navCurrent === 'repertoire') ? 'aria-current="page"' : '' ?>>Répertoire</a>
</li>
<li>
<a href="/licence.php"
<?= ($_navCurrent === 'licence') ? 'aria-current="page"' : '' ?>>Licence</a>
</li>
<li>
<a href="/apropos.php"
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
</li>
</ul>
</nav>