feat #58 : wizard multi-étapes création/édition d'article
Remplace le formulaire unique par un wizard 5 étapes (création) et
6 étapes (édition) avec auto-sauvegarde en brouillon, détection de
tags depuis le texte (TagSuggester), aperçu SEO, diff avant validation
et plan Markdown dynamique dans l'éditeur.
Détail des changements :
- ArticleManager : +6 méthodes (updatePartialMeta, saveDraftOverlay,
getDraftOverlay, hasDraftOverlay, discardDraftOverlay, commitDraftOverlay)
- .htaccess : routes /new/{uuid}/{1-5} et /edit/{uuid}/{1-6}
- index.php : cases create et edit réécrits en switch($step),
nouveau case autosave_draft et edit_discard_draft
- assets/js/wizard.js : autosave debounce, auto-resize textarea,
scroll curseur, plan TOC dynamique, toggle pills tags
- templates/wizard/ : nav.php + step1..6.php
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
ob_start();
|
||||
$_backUrl = $mode === 'create' ? '/new/' . rawurlencode($uuid) . '/2' : '/edit/' . rawurlencode($uuid) . '/2';
|
||||
$_formAction = $mode === 'create' ? '/new/' . rawurlencode($uuid) . '/3' : '/edit/' . rawurlencode($uuid) . '/3';
|
||||
?>
|
||||
<form method="POST" action="<?= htmlspecialchars($_formAction) ?>">
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between gap-3 mb-4 flex-wrap">
|
||||
<h1 class="h4 mb-0">Catégorie</h1>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="<?= htmlspecialchars($_backUrl) ?>" class="btn btn-outline-secondary btn-sm">← Retour</a>
|
||||
<button type="submit" class="btn btn-primary">Suivant →</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include __DIR__ . '/nav.php'; ?>
|
||||
|
||||
<div class="row justify-content-start">
|
||||
<div class="col-lg-6">
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label for="category" class="form-label fw-semibold">Catégorie</label>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<input type="text" class="form-control" id="category" name="category"
|
||||
value="<?= htmlspecialchars($category ?? '') ?>"
|
||||
placeholder="ex : informatique, loisirs, photo…"
|
||||
autocomplete="off">
|
||||
<div id="cat-swatch" title="" style="width:40px;height:36px;border-radius:6px;flex-shrink:0;background:#e5e7eb;transition:background .25s"></div>
|
||||
</div>
|
||||
<small id="cat-hint" class="text-muted d-block mt-1"></small>
|
||||
<div id="cat-free-swatches" class="d-flex flex-wrap gap-1 mt-2"></div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($allCategories)): ?>
|
||||
<div>
|
||||
<p class="small text-muted mb-2">Catégories existantes :</p>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php foreach ($allCategories as $_cat => $_count):
|
||||
$_isPriv = in_array($_cat, $privateCats ?? [], true);
|
||||
?>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary wz-cat-pick<?= ($_cat === ($category ?? '')) ? ' active' : '' ?>"
|
||||
data-cat="<?= htmlspecialchars($_cat) ?>">
|
||||
<?= htmlspecialchars($_cat) ?>
|
||||
<span class="badge bg-secondary ms-1"><?= $_count ?></span>
|
||||
<?php if ($_isPriv): ?><span title="Privée">🔒</span><?php endif; ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary wz-cat-pick<?= (($category ?? '') === '') ? ' active' : '' ?>"
|
||||
data-cat=""><em class="text-muted">Aucune</em></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="/assets/js/wizard.js"></script>
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
$title = 'Catégorie — Étape 3/' . $totalSteps;
|
||||
include BASE_PATH . '/templates/layout.php';
|
||||
Reference in New Issue
Block a user