Rework contenus-edit: auto-save, OverType toolbar, dynamic sidebar links

- Auto-save: new autosave.js with 1.5s debounce, watches all forms with
  data-autosave, POSTs to form action with Accept: application/json, shows
  saving/saved/error status indicator
- All action handlers (page.php, apropos.php, form-help.php) now detect
  JSON Accept header and return {success, csrf_token} or {error} responses
- OverType toolbar enabled (toolbar:true) on all three markdown editors
  (page, about_page, form_help)
- Sidebar links: replaced fixed erg_site_url / source_code_url rows with
  dynamic sidebar_links array of {label, url} objects. Add/remove via JS.
  Fallback migration reads legacy keys if sidebar_links is empty.
- Updated AboutController and about.php template to render dynamic links
- Updated apropos.css: unified .apropos-toc-link replacing .apropos-toc-erg
  and .apropos-toc-source
- New CSS: autosave-status states, sidebar-link-row layout
- Removed all Enregistrer + Annuler buttons — auto-save and h1 back-arrow
  make them redundant
This commit is contained in:
Pontoporeia
2026-06-09 17:10:49 +02:00
parent a45a2c9ac4
commit c4a550f9d1
13 changed files with 441 additions and 93 deletions

View File

@@ -24,16 +24,26 @@ class AboutController
if (empty(trim($rawContent)) || trim($rawContent) === 'Contenu à venir') {
$rawContent = $this->defaultContent;
}
$contacts = $db->getAproposContent('contacts');
$contacts = is_array($contacts) && !empty($contacts) ? $contacts : null;
$ergSiteUrl = $db->getAproposContent('erg_site_url');
$sourceCodeUrl = $db->getAproposContent('source_code_url');
$contacts = $db->getAproposContent('contacts');
$contacts = is_array($contacts) && !empty($contacts) ? $contacts : null;
$sidebarLinks = $db->getAproposContent('sidebar_links');
$sidebarLinks = is_array($sidebarLinks) ? $sidebarLinks : [];
// Fallback: migrate legacy individual sidebar link keys
if (empty($sidebarLinks)) {
$ergSiteUrl = $db->getAproposContent('erg_site_url');
$sourceCodeUrl = $db->getAproposContent('source_code_url');
if ($ergSiteUrl) {
$sidebarLinks[] = ['label' => 'Site de l\'erg', 'url' => $ergSiteUrl];
}
if ($sourceCodeUrl) {
$sidebarLinks[] = ['label' => 'Code source', 'url' => $sourceCodeUrl];
}
}
} catch (Exception $e) {
ErrorHandler::log('about_page', $e);
$rawContent = $this->defaultContent;
$contacts = null;
$ergSiteUrl = null;
$sourceCodeUrl = null;
$rawContent = $this->defaultContent;
$contacts = null;
$sidebarLinks = [];
}
$converter = new CommonMarkConverter(['html_input' => 'strip']);
@@ -42,8 +52,7 @@ class AboutController
'currentNav' => 'apropos',
'aboutHtml' => EmailObfuscator::obfuscateHtml($converter->convert($rawContent)->getContent()),
'contacts' => $contacts,
'ergSiteUrl' => $ergSiteUrl,
'sourceCodeUrl' => $sourceCodeUrl,
'sidebarLinks' => $sidebarLinks,
'pageTitle' => 'À Propos XAMXAM',
'metaDescription' => "À propos de XAMXAM, le répertoire des mémoires de fin d'études de l'erg École de Recherches Graphiques de Bruxelles.",
'extraCss' => ['/assets/css/apropos.css'],