Ajout mode présentation

This commit is contained in:
Esteban committed 2026-08-28 00:04:48 +02:00
1 parent 4862d61ccd
commit 08875d3b5a
18 files changed
+1781 -270

No files matched your search

+181 -45
View File
@@ -14,6 +14,7 @@ require_once('../functions/listSchool.php');
require_once('../functions/listSkills.php');
require_once('../functions/listSettings.php');
require_once('../functions/listLogos.php');
require_once('../functions/presentationAuth.php');
// L'utilisateur doit être administrateur
@@ -62,6 +63,11 @@ $contactAddressLine1 = recupererSetting('contact_address_line1') ?? '20 Grande r
$contactAddressLine2 = recupererSetting('contact_address_line2') ?? '52500 Broncourt';
$contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
// Contenu markdown actuel du mode présentation (voir pages/presentation.php)
// Le code PIN, lui, n'est jamais relu ici : seul son hash est en base, impossible à
// retransformer en code lisible (voir functions/presentationAuth.php)
$presentationMarkdown = recupererSetting('presentation_markdown') ?? '';
// Page du panneau d'administration
?>
@@ -79,6 +85,7 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<a href="#admin-experiences"><i class="fa-solid fa-briefcase"></i> Expériences</a>
<a href="#admin-ecoles"><i class="fa-solid fa-graduation-cap"></i> Écoles</a>
<a href="#admin-competences"><i class="fa-solid fa-code"></i> Compétences</a>
<a href="#admin-presentation"><i class="fa-solid fa-lock"></i> Mode présentation</a>
<a href="#admin-logos"><i class="fa-solid fa-images"></i> Logos</a>
<a href="#admin-contact"><i class="fa-solid fa-address-card"></i> Contact</a>
<a href="#admin-notification"><i class="fa-solid fa-bell"></i> Notification</a>
@@ -101,9 +108,13 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<form method="POST" enctype="multipart/form-data" action="<?php echo $projetAModifier ? '../scripts/updateProject.php' : '../scripts/addProject.php'; ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<?php if ($projetAModifier): ?>
<input type="hidden" name="id" value="<?php echo (int) $projetAModifier['id']; ?>">
<?php endif; ?>
<?php
// En mode modification, on transmet l'id de la ligne à mettre à jour.
// En mode ajout la variable est vide : pas de champ caché, donc pas d'id envoyé.
if ($projetAModifier) {
echo '<input type="hidden" name="id" value="' . (int) $projetAModifier['id'] . '">';
}
?>
<label>Titre *</label>
<input type="text" name="title" required value="<?php echo $projetAModifier ? htmlspecialchars($projetAModifier['title']) : ''; ?>">
@@ -124,16 +135,22 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<textarea name="markdown" class="markdown-textarea" placeholder="# Mon projet&#10;&#10;Description complète en **markdown**..."><?php echo $projetAModifier ? htmlspecialchars($projetAModifier['markdown'] ?? '') : ''; ?></textarea>
<label>Document PDF (optionnel, utilisé si pas de markdown)</label>
<?php if ($projetAModifier && !empty($projetAModifier['pdf_filename'])): ?>
<div class="pdf-current">
<i class="fa-solid fa-file-pdf"></i>
<span><?php echo htmlspecialchars($projetAModifier['pdf_filename']); ?></span>
<a href="../scripts/viewPdf.php?type=projet&id=<?php echo (int) $projetAModifier['id']; ?>" target="_blank" rel="noopener noreferrer">Voir</a>
<label class="checkbox-row pdf-remove-row">
<input type="checkbox" name="remove_pdf"> Supprimer ce PDF
</label>
</div>
<?php endif; ?>
<?php
// Si un PDF est déjà enregistré, on le rappelle avec un lien pour le consulter
// et une case à cocher pour le supprimer à l'enregistrement du formulaire.
if ($projetAModifier && !empty($projetAModifier['pdf_filename'])) {
$lienPdf = '../scripts/viewPdf.php?type=projet&id=' . (int) $projetAModifier['id'];
echo '<div class="pdf-current">';
echo '<i class="fa-solid fa-file-pdf"></i>';
echo '<span>' . htmlspecialchars($projetAModifier['pdf_filename']) . '</span>';
echo '<a href="' . $lienPdf . '" target="_blank" rel="noopener noreferrer">Voir</a>';
echo '<label class="checkbox-row pdf-remove-row">';
echo '<input type="checkbox" name="remove_pdf"> Supprimer ce PDF';
echo '</label>';
echo '</div>';
}
?>
<div class="pdf-dropzone" data-input="pdf-project">
<i class="fa-solid fa-cloud-arrow-up"></i>
<p>Glisse un PDF ici, ou <span class="pdf-dropzone-browse">clique pour choisir un fichier</span></p>
@@ -166,9 +183,13 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<form method="POST" enctype="multipart/form-data" action="<?php echo $xpAModifier ? '../scripts/updateXP.php' : '../scripts/addXP.php'; ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<?php if ($xpAModifier): ?>
<input type="hidden" name="id" value="<?php echo (int) $xpAModifier['id']; ?>">
<?php endif; ?>
<?php
// En mode modification, on transmet l'id de la ligne à mettre à jour.
// En mode ajout la variable est vide : pas de champ caché, donc pas d'id envoyé.
if ($xpAModifier) {
echo '<input type="hidden" name="id" value="' . (int) $xpAModifier['id'] . '">';
}
?>
<label>Titre *</label>
<input type="text" name="title" required value="<?php echo $xpAModifier ? htmlspecialchars($xpAModifier['title']) : ''; ?>">
@@ -195,16 +216,22 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<textarea name="markdown" class="markdown-textarea" placeholder="# Mon expérience&#10;&#10;Description complète en **markdown**..."><?php echo $xpAModifier ? htmlspecialchars($xpAModifier['markdown'] ?? '') : ''; ?></textarea>
<label>Document PDF (optionnel, utilisé si pas de markdown)</label>
<?php if ($xpAModifier && !empty($xpAModifier['pdf_filename'])): ?>
<div class="pdf-current">
<i class="fa-solid fa-file-pdf"></i>
<span><?php echo htmlspecialchars($xpAModifier['pdf_filename']); ?></span>
<a href="../scripts/viewPdf.php?type=experience&id=<?php echo (int) $xpAModifier['id']; ?>" target="_blank" rel="noopener noreferrer">Voir</a>
<label class="checkbox-row pdf-remove-row">
<input type="checkbox" name="remove_pdf"> Supprimer ce PDF
</label>
</div>
<?php endif; ?>
<?php
// Si un PDF est déjà enregistré, on le rappelle avec un lien pour le consulter
// et une case à cocher pour le supprimer à l'enregistrement du formulaire.
if ($xpAModifier && !empty($xpAModifier['pdf_filename'])) {
$lienPdf = '../scripts/viewPdf.php?type=experience&id=' . (int) $xpAModifier['id'];
echo '<div class="pdf-current">';
echo '<i class="fa-solid fa-file-pdf"></i>';
echo '<span>' . htmlspecialchars($xpAModifier['pdf_filename']) . '</span>';
echo '<a href="' . $lienPdf . '" target="_blank" rel="noopener noreferrer">Voir</a>';
echo '<label class="checkbox-row pdf-remove-row">';
echo '<input type="checkbox" name="remove_pdf"> Supprimer ce PDF';
echo '</label>';
echo '</div>';
}
?>
<div class="pdf-dropzone" data-input="pdf-xp">
<i class="fa-solid fa-cloud-arrow-up"></i>
<p>Glisse un PDF ici, ou <span class="pdf-dropzone-browse">clique pour choisir un fichier</span></p>
@@ -237,9 +264,13 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<form method="POST" enctype="multipart/form-data" action="<?php echo $ecoleAModifier ? '../scripts/updateSchool.php' : '../scripts/addSchool.php'; ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<?php if ($ecoleAModifier): ?>
<input type="hidden" name="id" value="<?php echo (int) $ecoleAModifier['id']; ?>">
<?php endif; ?>
<?php
// En mode modification, on transmet l'id de la ligne à mettre à jour.
// En mode ajout la variable est vide : pas de champ caché, donc pas d'id envoyé.
if ($ecoleAModifier) {
echo '<input type="hidden" name="id" value="' . (int) $ecoleAModifier['id'] . '">';
}
?>
<label>Nom de l'école *</label>
<input type="text" name="title" required value="<?php echo $ecoleAModifier ? htmlspecialchars($ecoleAModifier['title']) : ''; ?>">
@@ -263,16 +294,22 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<textarea name="markdown" class="markdown-textarea" placeholder="# Mon école&#10;&#10;Description complète en **markdown**..."><?php echo $ecoleAModifier ? htmlspecialchars($ecoleAModifier['markdown'] ?? '') : ''; ?></textarea>
<label>Document PDF (optionnel, utilisé si pas de markdown)</label>
<?php if ($ecoleAModifier && !empty($ecoleAModifier['pdf_filename'])): ?>
<div class="pdf-current">
<i class="fa-solid fa-file-pdf"></i>
<span><?php echo htmlspecialchars($ecoleAModifier['pdf_filename']); ?></span>
<a href="../scripts/viewPdf.php?type=ecole&id=<?php echo (int) $ecoleAModifier['id']; ?>" target="_blank" rel="noopener noreferrer">Voir</a>
<label class="checkbox-row pdf-remove-row">
<input type="checkbox" name="remove_pdf"> Supprimer ce PDF
</label>
</div>
<?php endif; ?>
<?php
// Si un PDF est déjà enregistré, on le rappelle avec un lien pour le consulter
// et une case à cocher pour le supprimer à l'enregistrement du formulaire.
if ($ecoleAModifier && !empty($ecoleAModifier['pdf_filename'])) {
$lienPdf = '../scripts/viewPdf.php?type=ecole&id=' . (int) $ecoleAModifier['id'];
echo '<div class="pdf-current">';
echo '<i class="fa-solid fa-file-pdf"></i>';
echo '<span>' . htmlspecialchars($ecoleAModifier['pdf_filename']) . '</span>';
echo '<a href="' . $lienPdf . '" target="_blank" rel="noopener noreferrer">Voir</a>';
echo '<label class="checkbox-row pdf-remove-row">';
echo '<input type="checkbox" name="remove_pdf"> Supprimer ce PDF';
echo '</label>';
echo '</div>';
}
?>
<div class="pdf-dropzone" data-input="pdf-school">
<i class="fa-solid fa-cloud-arrow-up"></i>
<p>Glisse un PDF ici, ou <span class="pdf-dropzone-browse">clique pour choisir un fichier</span></p>
@@ -305,9 +342,13 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<form method="POST" action="<?php echo $skillAModifier ? '../scripts/updateSkill.php' : '../scripts/addSkill.php'; ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<?php if ($skillAModifier): ?>
<input type="hidden" name="id" value="<?php echo (int) $skillAModifier['id']; ?>">
<?php endif; ?>
<?php
// En mode modification, on transmet l'id de la ligne à mettre à jour.
// En mode ajout la variable est vide : pas de champ caché, donc pas d'id envoyé.
if ($skillAModifier) {
echo '<input type="hidden" name="id" value="' . (int) $skillAModifier['id'] . '">';
}
?>
<label>Titre de la catégorie *</label>
<input type="text" name="title" required value="<?php echo $skillAModifier ? htmlspecialchars($skillAModifier['title']) : ''; ?>">
@@ -333,6 +374,67 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
</div>
</section>
<!-- ========== SECTION MODE PRÉSENTATION ========== -->
<section id="admin-presentation" class="admin-section">
<h2 class="admin-section-title"><i class="fa-solid fa-lock"></i> Mode présentation</h2>
<!-- Contenu affiché une fois le code PIN entré (voir pages/presentation.php) :
même principe que le markdown des projets/expériences/écoles, avec les mêmes
images possibles via ![légende](url) -->
<div class="project-container">
<div class="project-form-card">
<!-- on envoie les données à updateSettings.php -->
<form method="POST" action="../scripts/updateSettings.php">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<input type="hidden" name="settings_group" value="presentation">
<label>Contenu (markdown, comme pour les fiches projets)</label>
<!-- Petit bouton d'aide : insère la syntaxe markdown d'une image au
curseur, pour ne pas avoir à s'en souvenir -->
<div class="markdown-toolbar">
<button type="button" class="markdown-insert-image" data-target="presentation_markdown">
<i class="fa-solid fa-image"></i> Insérer une image
</button>
</div>
<textarea name="presentation_markdown" id="presentation_markdown" class="markdown-textarea" placeholder="# Titre&#10;&#10;Texte de présentation en **markdown**...&#10;&#10;![Légende de l'image](https://...)"><?php echo htmlspecialchars($presentationMarkdown); ?></textarea>
<input type="submit" name="submitsettings" value="Enregistrer le contenu" class="btn-submit">
</form>
</div>
</div>
<!-- Code PIN à part : formulaire séparé car il doit être haché avant d'être
enregistré (voir scripts/updatePresentationPin.php), contrairement au markdown
juste au-dessus qui est stocké tel quel -->
<div class="project-container">
<div class="project-form-card">
<form method="POST" action="../scripts/updatePresentationPin.php">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<label>Code PIN (exactement 9 chiffres)</label>
<input type="text" name="pin" inputmode="numeric" pattern="\d{9}" minlength="9" maxlength="9" placeholder="9 chiffres" required>
<input type="submit" value="Changer le code PIN" class="btn-submit">
</form>
<!-- Le code actuel n'est jamais réaffiché : seul son hash est stocké en
base, impossible à relire (comme un mot de passe) -->
<p class="admin-data-text">Le code actuel n'apparaît jamais ici, seul son hash est stocké en base.</p>
</div>
</div>
<!-- IP actuellement bloquées après 4 échecs : un visiteur légitime qui se trompe
plusieurs fois peut se retrouver bloqué, ce bouton permet de le débloquer
sans attendre les 24h de blocage automatique -->
<div class="project-container">
<div class="project-form-card">
<h3 class="admin-data-title"><i class="fa-solid fa-lock"></i> IP bloquées</h3>
<?php afficherTentativesVerrouilleesAdmin(); ?>
</div>
</div>
</section>
<!-- ========== SECTION LOGOS (bandeaux page d'accueil) ========== -->
<section id="admin-logos" class="admin-section">
<h2 class="admin-section-title"><i class="fa-solid fa-images"></i> Logos partenaires (page d'accueil)</h2>
@@ -350,9 +452,13 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
<form method="POST" action="<?php echo $logoAModifier ? '../scripts/updateLogo.php' : '../scripts/addLogo.php'; ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(csrfToken()); ?>">
<?php if ($logoAModifier): ?>
<input type="hidden" name="id" value="<?php echo (int) $logoAModifier['id']; ?>">
<?php endif; ?>
<?php
// En mode modification, on transmet l'id de la ligne à mettre à jour.
// En mode ajout la variable est vide : pas de champ caché, donc pas d'id envoyé.
if ($logoAModifier) {
echo '<input type="hidden" name="id" value="' . (int) $logoAModifier['id'] . '">';
}
?>
<!-- Seul le bandeau "Ils m'ont fait confiance" est géré ici -->
<input type="hidden" name="category" value="partner">
@@ -604,6 +710,36 @@ $contactAddressEnabled = recupererSetting('contact_address_enabled') ?? '1';
})();
</script>
<!-- Bouton "Insérer une image" du mode présentation : ajoute la syntaxe markdown d'une
image (![légende](url)) à l'endroit où était le curseur dans le champ, pour ne pas
avoir à se souvenir de la syntaxe -->
<script>
(function () {
document.querySelectorAll('.markdown-insert-image').forEach(function (bouton) {
bouton.addEventListener('click', function () {
var champ = document.getElementById(bouton.dataset.target);
if (!champ) return;
var url = prompt('Lien de l\'image (URL) :');
if (!url) return;
var legende = prompt('Légende de l\'image (optionnel) :') || '';
var markdown = '![' + legende + '](' + url + ')';
// On insère au niveau du curseur plutôt qu'à la fin, pour pouvoir placer
// l'image n'importe où dans le texte déjà écrit
var debut = champ.selectionStart;
var fin = champ.selectionEnd;
champ.value = champ.value.slice(0, debut) + markdown + champ.value.slice(fin);
champ.focus();
var curseur = debut + markdown.length;
champ.setSelectionRange(curseur, curseur);
});
});
})();
</script>
<?php
// On ajoute ici le footer
require_once('../elements/footer.php'); ?>