Refactor about.php

- Hardcode source code URL and credits in about template, remove from DB/admin interface; only contacts remains editable
- Merge apropos editables into one À propos section, remove charte, add editable source code URL
This commit is contained in:
Pontoporeia
2026-05-07 18:44:30 +02:00
parent 24d68dda59
commit e0c748d8e7
15 changed files with 259 additions and 250 deletions

View File

@@ -0,0 +1,115 @@
<?php
/**
* Reusable partial for apropos contacts groups form.
* Expected variables:
* $aproposKey string 'contacts'
* $groups array Existing groups data
*/
?>
<form action="/admin/actions/apropos.php" method="post" class="admin-form" id="apropos-form-<?= $aproposKey ?>">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="apropos_key" value="<?= htmlspecialchars($aproposKey) ?>">
<?php foreach ($groups as $gi => $group): ?>
<fieldset class="apropos-group">
<legend>Contact <?= $gi + 1 ?></legend>
<label for="group_f_<?= $aproposKey ?>_<?= $gi ?>_role">Rôle :</label>
<input type="text" id="group_f_<?= $aproposKey ?>_<?= $gi ?>_role"
name="groups[<?= $gi ?>][role]"
value="<?= htmlspecialchars($group['role'] ?? '') ?>">
<?php $entries = is_array($group['entries'] ?? null) ? $group['entries'] : []; ?>
<?php foreach ($entries as $ei => $entry): ?>
<div class="apropos-entry">
<label for="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_text">Nom :</label>
<input type="text" id="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_text"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][text]"
value="<?= htmlspecialchars($entry['text'] ?? '') ?>">
<label for="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_email">Email :</label>
<input type="email" id="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_email"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][email]"
value="<?= htmlspecialchars($entry['email'] ?? '') ?>">
<label for="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_url">Lien (optionnel) :</label>
<input type="url" id="entry_f_<?= $aproposKey ?>_<?= $gi ?>_<?= $ei ?>_url"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][url]"
value="<?= htmlspecialchars($entry['url'] ?? '') ?>">
</div>
<?php endforeach; ?>
<button type="button" class="btn btn--primary btn--sm add-entry-btn-f"
data-group="<?= $gi ?>"
data-key="<?= $aproposKey ?>">+ Ajouter une entrée</button>
</fieldset>
<?php endforeach; ?>
<button type="button" class="btn btn--primary add-group-btn-f"
data-key="<?= $aproposKey ?>">+ Ajouter un contact</button>
<div class="admin-form-footer">
<button type="submit" class="btn btn--primary">Enregistrer</button>
<a href="/admin/contenus.php" class="btn btn--secondary admin-cancel-link">Annuler</a>
</div>
<template id="entry-template-f-<?= $aproposKey ?>">
<div class="apropos-entry">
<label>Entrée :</label>
<input type="text" name="groups[{{gi}}][entries][{{ei}}][text]">
<label>Email :</label>
<input type="email" name="groups[{{gi}}][entries][{{ei}}][email]">
<label>Lien (optionnel) :</label>
<input type="url" name="groups[{{gi}}][entries][{{ei}}][url]">
</div>
</template>
<template id="group-template-f-<?= $aproposKey ?>">
<fieldset class="apropos-group">
<legend>Contact {{gi}}</legend>
<label>Rôle :</label>
<input type="text" name="groups[{{gi}}][role]">
<button type="button" class="btn btn--primary btn--sm add-entry-btn-f"
data-group="{{gi}}"
data-key="<?= $aproposKey ?>">+ Ajouter une entrée</button>
</fieldset>
</template>
</form>
<script>
(function() {
var key = '<?= $aproposKey ?>';
var form = document.getElementById('apropos-form-' + key);
var groupCount = <?= count($groups) ?>;
var entryTpl = document.getElementById('entry-template-f-' + key).innerHTML;
var groupTpl = document.getElementById('group-template-f-' + key).innerHTML;
form.querySelectorAll('.add-entry-btn-f').forEach(function(btn) {
btn.addEventListener('click', function() {
var gi = parseInt(this.dataset.group);
var fieldset = this.closest('fieldset');
var entryCount = fieldset.querySelectorAll('.apropos-entry').length;
var html = entryTpl.replaceAll('{{gi}}', gi).replaceAll('{{ei}}', entryCount);
this.insertAdjacentHTML('beforebegin', html);
});
});
form.querySelector('.add-group-btn-f').addEventListener('click', function() {
groupCount++;
var html = groupTpl.replaceAll('{{gi}}', groupCount);
this.insertAdjacentHTML('beforebegin', html);
var newGroup = this.previousElementSibling;
if (newGroup && newGroup.classList.contains('apropos-group')) {
var btn = newGroup.querySelector('.add-entry-btn-f');
if (btn) {
btn.dataset.group = groupCount;
btn.addEventListener('click', function() {
var gi = parseInt(this.dataset.group);
var fieldset = this.closest('fieldset');
var entryCount = fieldset.querySelectorAll('.apropos-entry').length;
var html = entryTpl.replaceAll('{{gi}}', gi).replaceAll('{{ei}}', entryCount);
this.insertAdjacentHTML('beforebegin', html);
});
}
}
});
})();
</script>

View File

@@ -1,7 +1,34 @@
<main id="main-content">
<h1>Éditer : <?= htmlspecialchars($editTitle) ?></h1>
<?php if ($editType === 'page'): ?>
<?php if ($editType === 'about_page'): ?>
<!-- ── Markdown content ──────────────────────────────────────────────── -->
<h2>Contenu de la page</h2>
<form action="/admin/actions/page.php" method="post" class="admin-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION["csrf_token"]) ?>">
<input type="hidden" name="slug" value="about">
<label for="editor">Contenu (Markdown) :</label>
<input type="hidden" id="content" name="content"
value="<?= htmlspecialchars($initialContent) ?>">
<div id="editor"></div>
<div class="admin-form-footer">
<button type="submit" class="btn btn--primary">Enregistrer</button>
<a href="/admin/contenus.php" class="btn btn--secondary admin-cancel-link">Annuler</a>
</div>
</form>
<!-- ── Contacts ──────────────────────────────────────────────────────── -->
<h2 style="margin-top:3rem;">Contacts</h2>
<?php
$aproposKey = 'contacts';
$groups = $aboutContacts ?? [];
include APP_ROOT . '/templates/admin/apropos-groups-form.php';
?>
<?php elseif ($editType === 'page' && $pageSlug !== 'about'): ?>
<form action="/admin/actions/page.php" method="post" class="admin-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION["csrf_token"]) ?>">
<input type="hidden" name="slug" value="<?= htmlspecialchars($pageSlug) ?>">
@@ -38,125 +65,6 @@
<?php
$groups = is_array($value) ? $value : [];
?>
<form action="/admin/actions/apropos.php" method="post" class="admin-form" id="apropos-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION["csrf_token"]) ?>">
<input type="hidden" name="apropos_key" value="<?= htmlspecialchars($aproposKey) ?>">
<?php foreach ($groups as $gi => $group): ?>
<fieldset class="apropos-group">
<legend><?= htmlspecialchars($aproposKey === 'contacts' ? 'Contact' : 'Crédit') ?> <?= $gi + 1 ?></legend>
<?php if ($aproposKey === 'contacts'): ?>
<label for="group_<?= $gi ?>_role">Rôle :</label>
<input type="text" id="group_<?= $gi ?>_role"
name="groups[<?= $gi ?>][role]"
value="<?= htmlspecialchars($group['role'] ?? '') ?>">
<?php else: ?>
<label for="group_<?= $gi ?>_label">Label :</label>
<input type="text" id="group_<?= $gi ?>_label"
name="groups[<?= $gi ?>][label]"
value="<?= htmlspecialchars($group['label'] ?? '') ?>">
<?php endif; ?>
<?php $entries = is_array($group['entries'] ?? null) ? $group['entries'] : []; ?>
<?php foreach ($entries as $ei => $entry): ?>
<div class="apropos-entry">
<label for="entry_<?= $gi ?>_<?= $ei ?>_text"><?= $aproposKey === 'contacts' ? 'Nom' : 'Texte' ?> :</label>
<input type="text" id="entry_<?= $gi ?>_<?= $ei ?>_text"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][text]"
value="<?= htmlspecialchars($entry['text'] ?? '') ?>">
<?php if ($aproposKey === 'contacts'): ?>
<label for="entry_<?= $gi ?>_<?= $ei ?>_email">Email :</label>
<input type="email" id="entry_<?= $gi ?>_<?= $ei ?>_email"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][email]"
value="<?= htmlspecialchars($entry['email'] ?? '') ?>">
<?php endif; ?>
<label for="entry_<?= $gi ?>_<?= $ei ?>_url">Lien (optionnel) :</label>
<input type="url" id="entry_<?= $gi ?>_<?= $ei ?>_url"
name="groups[<?= $gi ?>][entries][<?= $ei ?>][url]"
value="<?= htmlspecialchars($entry['url'] ?? '') ?>">
</div>
<?php endforeach; ?>
<button type="button" class="btn btn--primary btn--sm add-entry-btn" data-group="<?= $gi ?>">+ Ajouter une entrée</button>
</fieldset>
<?php endforeach; ?>
<button type="button" class="btn btn--primary" id="add-group-btn">+ Ajouter un <?= $aproposKey === 'contacts' ? 'contact' : 'groupe de crédit' ?></button>
<div class="admin-form-footer">
<button type="submit" class="btn btn--primary">Enregistrer</button>
<a href="/admin/contenus.php" class="btn btn--secondary admin-cancel-link">Annuler</a>
</div>
<template id="entry-template-<?= $aproposKey ?>">
<div class="apropos-entry">
<label>Entrée :</label>
<input type="text" name="groups[{{gi}}][entries][{{ei}}][text]">
<?php if ($aproposKey === 'contacts'): ?>
<label>Email :</label>
<input type="email" name="groups[{{gi}}][entries][{{ei}}][email]">
<?php endif; ?>
<label>Lien (optionnel) :</label>
<input type="url" name="groups[{{gi}}][entries][{{ei}}][url]">
</div>
</template>
<template id="group-template-<?= $aproposKey ?>">
<fieldset class="apropos-group">
<legend><?= htmlspecialchars($aproposKey === 'contacts' ? 'Contact' : 'Crédit') ?> {{gi}}</legend>
<?php if ($aproposKey === 'contacts'): ?>
<label>Rôle :</label>
<input type="text" name="groups[{{gi}}][role]">
<?php else: ?>
<label>Label :</label>
<input type="text" name="groups[{{gi}}][label]">
<?php endif; ?>
<button type="button" class="btn btn--primary btn--sm add-entry-btn" data-group="{{gi}}">+ Ajouter une entrée</button>
</fieldset>
</template>
</form>
<script>
(function() {
const aproposKey = '<?= $aproposKey ?>';
let groupCount = <?= count($groups) ?>;
const entryTpl = document.getElementById('entry-template-' + aproposKey).innerHTML;
const groupTpl = document.getElementById('group-template-' + aproposKey).innerHTML;
// Add entry to a group
document.querySelectorAll('.add-entry-btn').forEach(btn => {
btn.addEventListener('click', function() {
const gi = parseInt(this.dataset.group);
const fieldset = this.closest('fieldset');
const entryCount = fieldset.querySelectorAll('.apropos-entry').length;
const html = entryTpl.replaceAll('{{gi}}', gi).replaceAll('{{ei}}', entryCount);
this.insertAdjacentHTML('beforebegin', html);
});
});
// Add new group
document.getElementById('add-group-btn').addEventListener('click', function() {
groupCount++;
const html = groupTpl.replaceAll('{{gi}}', groupCount);
this.insertAdjacentHTML('beforebegin', html);
// Re-bind add-entry buttons for the new group
const newGroup = this.previousElementSibling;
if (newGroup && newGroup.classList.contains('apropos-group')) {
const btn = newGroup.querySelector('.add-entry-btn');
if (btn) {
btn.dataset.group = groupCount;
btn.addEventListener('click', function() {
const gi = parseInt(this.dataset.group);
const fieldset = this.closest('fieldset');
const entryCount = fieldset.querySelectorAll('.apropos-entry').length;
const html = entryTpl.replaceAll('{{gi}}', gi).replaceAll('{{ei}}', entryCount);
this.insertAdjacentHTML('beforebegin', html);
});
}
}
});
})();
</script>
<?php include APP_ROOT . '/templates/admin/apropos-groups-form.php'; ?>
<?php endif; ?>
</main>

View File

@@ -37,38 +37,6 @@
</tbody>
</table>
<h2 style="margin-top:2rem;">À propos</h2>
<table>
<thead>
<tr>
<th scope="col">Clé</th>
<th scope="col">Type</th>
<th scope="col">Mis à jour</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($aproposKeys as $a): ?>
<?php
$typeLabel = match($a['key']) {
'contacts' => 'Contacts',
'credits' => 'Crédits',
};
?>
<tr>
<td><code><?= htmlspecialchars($a['key']) ?></code></td>
<td><?= htmlspecialchars($typeLabel) ?></td>
<td><?= htmlspecialchars($a['updated_at'] ?? '—') ?></td>
<td>
<a href="/admin/contenus-edit.php?apropos=<?= urlencode($a['key']) ?>"
class="btn btn--primary btn--sm">Éditer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- ═══════════════════════════════════════════════════════════════════
Blocs d'aide du formulaire étudiant·e
═══════════════════════════════════════════════════════════════════ -->