feat: licence page, admin pages editor, license types, gradient card placeholders, latest-year home view

- Feature 1: public /licence.php fetches 'licenses' page from DB, renders Markdown
- Feature 1: nav.php adds 'Licence' link with active state
- Feature 2: Database::getPage(), savePage(), getAllPages() methods
- Feature 2: bundled src/Parsedown.php (MIT, zero-dependency)
- Feature 2: apropos.php now renders 'about' page content from DB via Parsedown
- Feature 2: admin/pages.php (list) + admin/pages-edit.php (EasyMDE editor)
- Feature 2: admin/actions/page.php (auth+CSRF+validation+save)
- Feature 2: admin/head.php adds 'Pages statiques' nav link
- Feature 3: storage/schema.sql seeds 8 CC license types
- Feature 3: storage/migrations/003_seed_license_types.sql (applied to live DB)
- Feature 3: Database::getLicenseTypes() / getAllLicenseTypes()
- Feature 3: admin/add.php + formulaire.php: license_id field on add form
- Feature 3: admin/edit.php: license_id field on edit form with raw FK lookup
- Feature 3: tfe.php: shows 'Licence :' meta row when non-null
- Feature 6: main.css: .card__media--gradient styles
- Feature 6: index.php: deterministic HSL gradient placeholder cards
- Feature 6: Database::getLatestYearTheses() + getLatestPublishedYear()
- Feature 6: index.php default home = random latest-year theses with info label
This commit is contained in:
Pontoporeia
2026-03-24 13:12:48 +01:00
parent 86a2082edc
commit d87348c388
20 changed files with 2553 additions and 152 deletions

View File

@@ -3,9 +3,12 @@
require_once __DIR__ . '/../config/bootstrap.php';
require_once APP_ROOT . '/src/Database.php';
$page = isset($_GET["page"]) ? intval($_GET["page"]) : 1;
$page = isset($_GET["page"]) ? max(1, intval($_GET["page"])) : 1;
$year = isset($_GET["year"]) ? intval($_GET["year"]) : null;
$itemsPerPage = 24; // bigger grid
$itemsPerPage = 24;
// Default home view: random theses from latest year (no year filter, no explicit page)
$isDefaultView = (!$year && $page === 1);
try {
$db = Database::getInstance();
@@ -14,19 +17,25 @@ try {
if ($year) {
$itemsToLoad = $db->searchTheses(['year' => $year], $itemsPerPage, $offset);
$totalItems = $db->countSearchResults(['year' => $year]);
$totalItems = $db->countSearchResults(['year' => $year]);
} elseif ($isDefaultView) {
$latestYear = $db->getLatestPublishedYear();
$itemsToLoad = $db->getLatestYearTheses($itemsPerPage);
$totalItems = count($itemsToLoad); // no pagination on default view
} else {
$itemsToLoad = $db->getPublishedTheses($itemsPerPage, $offset);
$totalItems = $db->countPublishedTheses();
$totalItems = $db->countPublishedTheses();
}
$totalPages = ceil($totalItems / $itemsPerPage);
$totalPages = $isDefaultView ? 1 : (int)ceil($totalItems / $itemsPerPage);
} catch (Exception $e) {
error_log("Error loading theses: " . $e->getMessage());
$itemsToLoad = [];
$totalPages = 0;
$totalPages = 0;
$availableYears = [];
$totalItems = 0;
$totalItems = 0;
$latestYear = null;
$isDefaultView = false;
}
$currentNav = '';
@@ -61,6 +70,10 @@ $currentNav = '';
Année : <?= htmlspecialchars($year) ?>
<a href="index.php" class="clear-filter">✕ Réinitialiser</a>
</div>
<?php elseif ($isDefaultView && !empty($latestYear)): ?>
<div class="filter-info home-latest-label">
Découvrez les TFE de <?= (int)$latestYear ?> — sélection aléatoire
</div>
<?php endif; ?>
<main class="home-main">
@@ -70,28 +83,31 @@ $currentNav = '';
<div class="card">
<div class="card__media">
<?php
// Use first image/video file as thumbnail
// Resolve thumbnail: banner_path → cover file → gradient placeholder
$thumb = null;
if (!empty($item['files'])) {
foreach ($item['files'] as $f) {
$ext = strtolower(pathinfo($f['file_path'], PATHINFO_EXTENSION));
if (in_array($ext, ['jpg','jpeg','png','gif','webp'])) {
$thumb = $f['file_path'];
break;
}
}
}
// Also check cover image
if (!$thumb && !empty($item['cover_image'])) {
$thumb = $item['cover_image'];
// 1. Banner path (dedicated home thumbnail)
if (!empty($item['banner_path'])) {
$thumb = $item['banner_path'];
}
// 2. Cover image from thesis_files (not returned by view — skip for now)
// 3. Fall through to gradient
?>
<?php if ($thumb): ?>
<img src="/media.php?path=<?= urlencode($thumb) ?>"
alt="<?= htmlspecialchars($item['title']) ?>"
loading="lazy">
<?php else: ?>
<div class="card__media--placeholder">◻</div>
<?php
$hue = ($item['id'] * 47 + 160) % 360;
$hue2 = ($hue + 40) % 360;
?>
<div class="card__media--gradient"
style="background:linear-gradient(135deg,hsl(<?= $hue ?>,60%,65%),hsl(<?= $hue2 ?>,55%,45%));">
<span class="card__gradient-author"><?= htmlspecialchars($item['authors'] ?? '') ?></span>
<span class="card__gradient-title"><?= htmlspecialchars($item['title']) ?></span>
</div>
<?php endif; ?>
</div>
<div class="card__info">