mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
Remove five presentational classes from admin forms and replace with structural CSS selectors scoped to .admin-form: - .admin-form-row → .admin-form > div:not(.admin-submit-wrap) Grid layout (260px label col + 1fr input col) applied directly to div children of the form; submit-wrap div excluded via :not(). - .admin-label → .admin-form > div:not(.admin-submit-wrap) > label Scoped to the direct label child of each form row div; does not bleed into nested checkbox labels inside .admin-checkbox-list. - .admin-input / .admin-select / .admin-textarea → .admin-form input:not([type=checkbox|radio|file|hidden|submit]) → .admin-form select → .admin-form textarea Also extended to .admin-inline-form input/select (tags page) so the tags table inputs retain identical base styling and focus colour. Templates updated: add.php, edit.php, login.php, account.php, pages-edit.php, import.php, tags.php, templates/partials/form/jury-fieldset.php — all class= attributes for the five removed classes stripped. import.php: added 'admin-form' class alongside 'admin-import-area' so its single file-input row gets the grid row treatment; submit div was already using admin-submit-wrap so it is correctly excluded. No visual change — selectors target the same elements as before.
107 lines
8.3 KiB
PHP
107 lines
8.3 KiB
PHP
<?php
|
||
require_once __DIR__ . "/../../config/bootstrap.php";
|
||
require_once __DIR__ . '/../../src/AdminAuth.php';
|
||
AdminAuth::requireLogin();
|
||
|
||
if (empty($_SESSION['csrf_token'])) {
|
||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||
}
|
||
|
||
require_once __DIR__ . '/../../src/Database.php';
|
||
|
||
$allowedSlugs = ['about', 'licenses', 'charte', 'contact'];
|
||
$slug = $_GET['slug'] ?? '';
|
||
|
||
if (!in_array($slug, $allowedSlugs)) {
|
||
header('Location: /admin/pages.php');
|
||
exit;
|
||
}
|
||
|
||
try {
|
||
$db = new Database();
|
||
$page = $db->getPage($slug);
|
||
if (!$page) {
|
||
die("Page introuvable.");
|
||
}
|
||
} catch (Exception $e) {
|
||
die("Erreur: " . htmlspecialchars($e->getMessage()));
|
||
}
|
||
|
||
$pageTitle = "Éditer : " . htmlspecialchars($page['title']);
|
||
$extraCss = ['/assets/css/easymde.min.css'];
|
||
$extraJs = ['/assets/js/easymde.min.js'];
|
||
// SVG icons for each toolbar button — eliminates the Font Awesome dependency entirely.
|
||
// Paths sourced from Tabler Icons (MIT). 20×20 viewBox, stroke-based, no fill.
|
||
$extraJsInline = <<<'JS'
|
||
var SVG = {
|
||
bold: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h8a4 4 0 0 1 0 8H6z"/><path d="M6 12h9a4 4 0 0 1 0 8H6z"/></svg>',
|
||
italic: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg>',
|
||
heading: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4v16"/><path d="M18 4v16"/><path d="M6 12h12"/></svg>',
|
||
quote: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z"/><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z"/></svg>',
|
||
"unordered-list": '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="9" y1="6" x2="20" y2="6"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="18" x2="20" y2="18"/><circle cx="4" cy="6" r="1" fill="currentColor" stroke="none"/><circle cx="4" cy="12" r="1" fill="currentColor" stroke="none"/><circle cx="4" cy="18" r="1" fill="currentColor" stroke="none"/></svg>',
|
||
"ordered-list": '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/></svg>',
|
||
link: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>',
|
||
image: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="M21 15l-5-5L5 21"/></svg>',
|
||
preview: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>',
|
||
"side-by-side": '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="18" rx="1"/><rect x="14" y="3" width="7" height="18" rx="1"/></svg>',
|
||
fullscreen: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/><path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/></svg>',
|
||
guide: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>'
|
||
};
|
||
|
||
var toolbar = [
|
||
{ name: 'bold', action: EasyMDE.toggleBold, icon: SVG.bold, title: 'Gras (Ctrl+B)' },
|
||
{ name: 'italic', action: EasyMDE.toggleItalic, icon: SVG.italic, title: 'Italique (Ctrl+I)' },
|
||
{ name: 'heading', action: EasyMDE.toggleHeadingSmaller, icon: SVG.heading, title: 'Titre' },
|
||
'|',
|
||
{ name: 'quote', action: EasyMDE.toggleBlockquote, icon: SVG.quote, title: 'Citation' },
|
||
{ name: 'unordered-list', action: EasyMDE.toggleUnorderedList, icon: SVG['unordered-list'], title: 'Liste à puces' },
|
||
{ name: 'ordered-list', action: EasyMDE.toggleOrderedList, icon: SVG['ordered-list'], title: 'Liste numérotée' },
|
||
'|',
|
||
{ name: 'link', action: EasyMDE.drawLink, icon: SVG.link, title: 'Insérer un lien (Ctrl+K)'},
|
||
{ name: 'image', action: EasyMDE.drawImage, icon: SVG.image, title: 'Insérer une image' },
|
||
'|',
|
||
{ name: 'preview', action: EasyMDE.togglePreview, icon: SVG.preview, title: 'Aperçu (Ctrl+P)', noDisable: true },
|
||
{ name: 'side-by-side', action: EasyMDE.toggleSideBySide, icon: SVG['side-by-side'], title: 'Côte à côte (F9)', noDisable: true, noMobile: true },
|
||
{ name: 'fullscreen', action: EasyMDE.toggleFullScreen, icon: SVG.fullscreen, title: 'Plein écran (F11)', noDisable: true, noMobile: true },
|
||
'|',
|
||
{ name: 'guide', action: 'https://www.markdownguide.org/basic-syntax/', icon: SVG.guide, title: 'Guide Markdown', noDisable: true }
|
||
];
|
||
|
||
var easyMDE = new EasyMDE({
|
||
element: document.getElementById('content'),
|
||
autoDownloadFontAwesome: false,
|
||
toolbar: toolbar,
|
||
spellChecker: false,
|
||
status: ['lines', 'words'],
|
||
minHeight: '400px',
|
||
toolbarTips: true
|
||
});
|
||
JS;
|
||
?>
|
||
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
|
||
<?php include APP_ROOT . '/templates/header.php'; ?>
|
||
|
||
<main id="main-content">
|
||
<h1>Éditer : <?= htmlspecialchars($page['title']) ?></h1>
|
||
|
||
<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($slug) ?>">
|
||
|
||
<div>
|
||
<label for="content">Contenu (Markdown) :</label>
|
||
<div>
|
||
<textarea id="content" name="content"
|
||
rows="20"><?= htmlspecialchars($page['content'] ?? '') ?></textarea>
|
||
<small>Appuyez sur <kbd>Échap</kbd> pour quitter l'éditeur au clavier.</small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="admin-submit-wrap">
|
||
<button type="submit" class="admin-btn">Enregistrer</button>
|
||
<a href="/admin/pages.php" class="admin-btn-secondary admin-cancel-link">Annuler</a>
|
||
</div>
|
||
</form>
|
||
</main>
|
||
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>
|