mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
feat: student mode support for thanks page (admin-auth only)
- add hidden student_mode field in add.php form - pass mode=student through redirect to thanks.php in formulaire.php - thanks.php renders clean student thank-you page (no header, centered button) - add CSS for .thanks-student-page, .btn-new-form, .thanks-success, .thanks-error - admin auth always required; student mode is purely UI variant on the physical machine
This commit is contained in:
22
TODO.md
22
TODO.md
@@ -1,16 +1,10 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
## Paramètres page cleanup
|
- [x] Make thanks.php respect student mode (no header, centered "add new form" button)
|
||||||
- [x] Remove card syntax (`.admin-settings-section` border/radius containers)
|
- [x] Add hidden input `student_mode` in add.php form when in student mode
|
||||||
- [x] Replace pill toggles with native semantic checkboxes inside `<fieldset>`
|
- [x] Append `mode=student` to thanks redirect in formulaire.php
|
||||||
- [x] Move "delete all TFE" danger zone into Maintenance section
|
- [x] Update thanks.php to detect student mode, hide header, show centered button
|
||||||
- [x] Use `<fieldset>` for danger zones (semantic, with `<legend>` instead of `<div>`)
|
- [x] Cleanup public/admin/add.php — standardise fieldsets and add licence explanation sections from docs PDF
|
||||||
- [x] Update CSS: new `.param-*` classes for flat semantic layout
|
- [x] Organise all fields into `<fieldset>/<legend>` blocks: Informations du TFE, Composition du jury, Cadre académique, Fichiers, Métadonnées complémentaires
|
||||||
- [x] Exclude parametres sections from generic `.admin-body main > section` card styling via `aria-labelledby` prefix
|
- [x] Remove double-wrapping of jury-fieldset (it has its own `<fieldset>`)
|
||||||
|
- [x] Add "Degrés d'ouverture et licences" section (Libre / Interne / Interdit + Généralités) wrapped in `if ($studentMode)` — hidden in admin
|
||||||
## Add TFE: admin/student mode toggle
|
|
||||||
- [x] Add `?mode=student` query param to same add.php page
|
|
||||||
- [x] Student mode: no admin header/nav, just the form with a back-link
|
|
||||||
- [x] Admin mode: full admin header/nav, with "Mode étudiant ↗" toggle link (opens in new tab)
|
|
||||||
- [x] Auth guard stays the same — still requires admin login
|
|
||||||
- [x] Add `.student-body`, `.thesis-add-header`, `.mode-toggle`, `.form-footer` CSS
|
|
||||||
|
|||||||
BIN
docs/Proposition procédure licences_V2.pdf
Normal file
BIN
docs/Proposition procédure licences_V2.pdf
Normal file
Binary file not shown.
@@ -9,6 +9,8 @@ ini_set('error_log', 'error.log');
|
|||||||
|
|
||||||
AdminAuth::requireLogin();
|
AdminAuth::requireLogin();
|
||||||
|
|
||||||
|
$studentMode = isset($_POST['student_mode']) && $_POST['student_mode'] === '1';
|
||||||
|
|
||||||
// Verify CSRF token
|
// Verify CSRF token
|
||||||
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||||
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
||||||
@@ -26,7 +28,11 @@ try {
|
|||||||
|
|
||||||
unset($_SESSION['csrf_token']);
|
unset($_SESSION['csrf_token']);
|
||||||
|
|
||||||
header('Location: ../thanks.php?id=' . urlencode($thesisId));
|
$redirect = '../thanks.php?id=' . urlencode($thesisId);
|
||||||
|
if ($studentMode) {
|
||||||
|
$redirect .= '&mode=student';
|
||||||
|
}
|
||||||
|
header('Location: ' . $redirect);
|
||||||
exit();
|
exit();
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -35,11 +41,16 @@ try {
|
|||||||
App::flash('error', $e->getMessage());
|
App::flash('error', $e->getMessage());
|
||||||
$_SESSION['form_data'] = $_POST;
|
$_SESSION['form_data'] = $_POST;
|
||||||
|
|
||||||
|
$redirect = '../add.php';
|
||||||
|
if ($studentMode) {
|
||||||
|
$redirect .= '?mode=student';
|
||||||
|
}
|
||||||
|
|
||||||
$autofocusField = ThesisCreateController::autofocusFieldForError($e->getMessage());
|
$autofocusField = ThesisCreateController::autofocusFieldForError($e->getMessage());
|
||||||
if ($autofocusField !== null) {
|
if ($autofocusField !== null) {
|
||||||
App::flashAutofocus($autofocusField);
|
App::flashAutofocus($autofocusField);
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Location: ../add.php');
|
header('Location: ' . $redirect);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,9 @@ try {
|
|||||||
$formData = $_SESSION['form_data'] ?? [];
|
$formData = $_SESSION['form_data'] ?? [];
|
||||||
unset($_SESSION['form_data']);
|
unset($_SESSION['form_data']);
|
||||||
$autofocusField = App::consumeAutofocus();
|
$autofocusField = App::consumeAutofocus();
|
||||||
// Flash error consumed by the flash-messages partial below.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge autofocus into the $attrs array for a given field.
|
* Merge autofocus into the $attrs array for a given field.
|
||||||
* Only adds the attribute when $autofocusField matches $fieldName.
|
|
||||||
*/
|
*/
|
||||||
function withAutofocus(string $fieldName, array $attrs = []): array {
|
function withAutofocus(string $fieldName, array $attrs = []): array {
|
||||||
global $autofocusField;
|
global $autofocusField;
|
||||||
@@ -74,83 +72,147 @@ if ($studentMode) {
|
|||||||
|
|
||||||
<form action="actions/formulaire.php" method="post" enctype="multipart/form-data" class="admin-form">
|
<form action="actions/formulaire.php" method="post" enctype="multipart/form-data" class="admin-form">
|
||||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION["csrf_token"]) ?>">
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION["csrf_token"]) ?>">
|
||||||
|
<?php if ($studentMode): ?>
|
||||||
|
<input type="hidden" name="student_mode" value="1">
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php $name = 'titre'; $label = 'Titre :'; $value = old('titre'); $required = true; $attrs = withAutofocus('titre'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<!-- ═══════════════════ Informations du TFE ═══════════════════ -->
|
||||||
<?php $name = 'subtitle'; $label = 'Sous-titre (si applicable) :'; $value = old('subtitle'); $required = false; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<fieldset>
|
||||||
<?php $name = 'auteurice'; $label = 'Auteur·ice(s) :'; $value = old('auteurice'); $required = true; $attrs = withAutofocus('auteurice', ['autocomplete' => 'name']); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<legend>Informations du TFE</legend>
|
||||||
<?php $name = 'mail'; $label = 'Contact(s) (optionnel) [mail/site/insta/etc.] :'; $value = old('mail'); $attrs = ['autocomplete' => 'email']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
|
||||||
|
|
||||||
<!-- Contact visibility -->
|
<?php $name = 'titre'; $label = 'Titre :'; $value = old('titre'); $required = true; $attrs = withAutofocus('titre'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
<div class="admin-form-group">
|
<?php $name = 'subtitle'; $label = 'Sous-titre (si applicable) :'; $value = old('subtitle'); $required = false; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
<label class="admin-checkbox-label">
|
<?php $name = 'auteurice'; $label = 'Auteur·ice(s) :'; $value = old('auteurice'); $required = true; $attrs = withAutofocus('auteurice', ['autocomplete' => 'name']); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
<input type="checkbox" name="contact_public" value="1"
|
<?php $name = 'mail'; $label = 'Contact(s) (optionnel) [mail/site/insta/etc.] :'; $value = old('mail'); $attrs = ['autocomplete' => 'email']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
<?= isset($formData['contact_public']) ? 'checked' : '' ?>>
|
|
||||||
Je veux que mon contact soit accessible à toustes depuis la plateforme xamxam
|
|
||||||
</label>
|
|
||||||
<small>Si cette case est cochée, votre contact apparaîtra sur la page publique de votre TFE.</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="admin-form-group">
|
||||||
|
<label class="admin-checkbox-label">
|
||||||
|
<input type="checkbox" name="contact_public" value="1"
|
||||||
|
<?= isset($formData['contact_public']) ? 'checked' : '' ?>>
|
||||||
|
Je veux que mon contact soit accessible à toustes depuis la plateforme xamxam
|
||||||
|
</label>
|
||||||
|
<small>Si cette case est cochée, votre contact apparaîtra sur la page publique de votre TFE.</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="synopsis">Synopsis :</label>
|
||||||
|
<textarea id="synopsis" name="synopsis"
|
||||||
|
rows="7" required
|
||||||
|
<?= $autofocusField === 'synopsis' ? 'autofocus' : '' ?>><?= old('synopsis') ?></textarea>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<!-- ═══════════════════ Composition du jury ═══════════════════ -->
|
||||||
<?php require APP_ROOT . '/templates/partials/form/jury-fieldset.php'; ?>
|
<?php require APP_ROOT . '/templates/partials/form/jury-fieldset.php'; ?>
|
||||||
|
|
||||||
<?php
|
<!-- ═══════════════════ Cadre académique ═══════════════════ -->
|
||||||
$name = 'année'; $label = 'Année :'; $value = old('année'); $required = true;
|
<fieldset>
|
||||||
$type = 'number';
|
<legend>Cadre académique</legend>
|
||||||
$placeholder = date('Y');
|
|
||||||
$attrs = withAutofocus('année', ['min' => 2000, 'max' => date('Y') + 1]);
|
|
||||||
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
||||||
?>
|
|
||||||
|
|
||||||
<?php $name = 'orientation'; $label = 'Orientation :'; $options = $orientations; $selected = $formData['orientation'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('orientation'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
<?php
|
||||||
|
$name = 'année'; $label = 'Année :'; $value = old('année'); $required = true;
|
||||||
|
$type = 'number';
|
||||||
|
$placeholder = date('Y');
|
||||||
|
$attrs = withAutofocus('année', ['min' => 2000, 'max' => date('Y') + 1]);
|
||||||
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
||||||
|
?>
|
||||||
|
|
||||||
<?php $name = 'ap'; $label = 'Atelier pluridisciplinaire :'; $options = $apPrograms; $selected = $formData['ap'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('ap'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
<?php $name = 'orientation'; $label = 'Orientation :'; $options = $orientations; $selected = $formData['orientation'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('orientation'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
||||||
|
<?php $name = 'ap'; $label = 'Atelier pluridisciplinaire :'; $options = $apPrograms; $selected = $formData['ap'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('ap'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
||||||
|
<?php $name = 'finality'; $label = 'Finalité du master :'; $options = $finalityTypes; $selected = $formData['finality'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('finality'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
||||||
|
|
||||||
<?php $name = 'finality'; $label = 'Finalité du master :'; $options = $finalityTypes; $selected = $formData['finality'] ?? ''; $required = true; $placeholder = ''; $attrs = withAutofocus('finality'); include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
<?php $name = 'languages'; $label = 'Langue(s) :'; $options = $languages; $checked = $formData['languages'] ?? []; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
||||||
|
<?php $name = 'formats'; $label = 'Format(s) :'; $options = $formatTypes; $checked = $formData['formats'] ?? []; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
||||||
|
|
||||||
<?php $name = 'languages'; $label = 'Langue(s) :'; $options = $languages; $checked = $formData['languages'] ?? []; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
<?php $name = 'tag'; $label = 'Mots-clés :'; $value = old('tag'); $placeholder = 'sociologie, anthropologie, ...'; $hint = 'Séparez par des virgules. Max 10 mots-clés.'; $attrs = withAutofocus('tag'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<?php $name = 'formats'; $label = 'Format(s) :'; $options = $formatTypes; $checked = $formData['formats'] ?? []; include APP_ROOT . '/templates/partials/form/checkbox-list.php'; ?>
|
<!-- ═══════════════════ Fichiers ═══════════════════ -->
|
||||||
|
<fieldset>
|
||||||
|
<legend>Fichiers</legend>
|
||||||
|
|
||||||
<?php $name = 'tag'; $label = 'Mots-clés :'; $value = old('tag'); $placeholder = 'sociologie, anthropologie, ...'; $hint = 'Séparez par des virgules. Max 10 mots-clés.'; $attrs = withAutofocus('tag'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<?php $name = 'couverture'; $label = 'Image de couverture :'; $accept = 'image/jpeg,image/png'; $hint = 'JPG, PNG. Taille max : 10 MB.'; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
||||||
|
<?php $name = 'banner'; $label = 'Image bannière (accueil) :'; $accept = 'image/jpeg,image/png,image/webp'; $hint = 'JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 5 MB.'; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
||||||
|
<?php $name = 'files'; $label = 'Fichiers du TFE :'; $accept = '.pdf,.jpg,.jpeg,.png,.mp4,.zip,.vtt'; $hint = 'PDF, JPG, PNG, MP4, ZIP. Max 50 MB par fichier. Pour les vidéos, un fichier .vtt de sous-titres peut être joint (il sera associé automatiquement à la vidéo correspondante).'; $multiple = true; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<!-- Synopsis -->
|
<!-- ═══════════════════ Métadonnées complémentaires ═══════════════════ -->
|
||||||
<div>
|
<fieldset>
|
||||||
<label for="synopsis">Synopsis :</label>
|
<legend>Métadonnées complémentaires</legend>
|
||||||
<textarea id="synopsis" name="synopsis"
|
|
||||||
rows="7" required
|
|
||||||
<?= $autofocusField === 'synopsis' ? 'autofocus' : '' ?>><?= old('synopsis') ?></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php $name = 'license_id'; $label = 'Licence :'; $options = $licenseTypes; $selected = $formData['license_id'] ?? ''; $placeholder = '— Inconnue —'; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
<?php $name = 'license_id'; $label = 'Licence :'; $options = $licenseTypes; $selected = $formData['license_id'] ?? ''; $placeholder = '— Inconnue —'; include APP_ROOT . '/templates/partials/form/select-field.php'; ?>
|
||||||
|
|
||||||
<?php $name = 'duration_info'; $label = 'Durée / Taille :'; $value = old('duration_info'); $placeholder = 'Ex : 84 pages'; $hint = 'Durée (minutes) ou nombre de pages.'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<?php $name = 'duration_info'; $label = 'Durée / Taille :'; $value = old('duration_info'); $placeholder = 'Ex : 84 pages'; $hint = 'Durée (minutes) ou nombre de pages.'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
|
|
||||||
<?php $name = 'lien'; $label = 'Lien (site / ressource) :'; $value = old('lien'); $type = 'url'; $placeholder = 'https://...'; $attrs = withAutofocus('lien'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
<?php $name = 'lien'; $label = 'Lien (site / ressource) :'; $value = old('lien'); $type = 'url'; $placeholder = 'https://...'; $attrs = withAutofocus('lien'); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||||
|
|
||||||
<?php $name = 'couverture'; $label = 'Image de couverture :'; $accept = 'image/jpeg,image/png'; $hint = 'JPG, PNG. Taille max : 10 MB.'; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
<?php
|
||||||
|
$accessOptions = array_map(function($at) {
|
||||||
|
return ['id' => $at['id'], 'name' => $at['name']];
|
||||||
|
}, $enabledAccessTypes);
|
||||||
|
$defaultAccessType = 2;
|
||||||
|
$selectedAccessType = isset($formData['access_type_id'])
|
||||||
|
? (int)$formData['access_type_id']
|
||||||
|
: $defaultAccessType;
|
||||||
|
$name = 'access_type_id';
|
||||||
|
$label = 'Visibilité / Accès :';
|
||||||
|
$options = $accessOptions;
|
||||||
|
$selected = $selectedAccessType;
|
||||||
|
$placeholder = null;
|
||||||
|
$required = true;
|
||||||
|
$attrs = [];
|
||||||
|
include APP_ROOT . '/templates/partials/form/select-field.php';
|
||||||
|
?>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<?php $name = 'banner'; $label = 'Image bannière (accueil) :'; $accept = 'image/jpeg,image/png,image/webp'; $hint = 'JPG, PNG ou WEBP. Format paysage recommandé (4:1). Max 5 MB.'; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
<?php if ($studentMode): ?>
|
||||||
|
<!-- ═══════════════════ Degrés d'ouverture ═══════════════════ -->
|
||||||
|
<fieldset class="licence-explanation">
|
||||||
|
<legend>Degrés d'ouverture et licences</legend>
|
||||||
|
|
||||||
<?php $name = 'files'; $label = 'Fichiers du TFE :'; $accept = '.pdf,.jpg,.jpeg,.png,.mp4,.zip,.vtt'; $hint = 'PDF, JPG, PNG, MP4, ZIP. Max 50 MB par fichier. Pour les vidéos, un fichier .vtt de sous-titres peut être joint (il sera associé automatiquement à la vidéo correspondante).'; $multiple = true; include APP_ROOT . '/templates/partials/form/file-field.php'; ?>
|
<div class="licence-info">
|
||||||
|
<h3>Je veux que mon TFE soit disponible sous les conditions suivantes :</h3>
|
||||||
|
|
||||||
<?php
|
<div class="licence-degree">
|
||||||
// Visibility select — only show options enabled in settings
|
<h4>🔓 Libre</h4>
|
||||||
$accessOptions = array_map(function($at) {
|
<p>Mon TFE est en libre accès à tout le monde sur la plateforme des TFE ainsi que dans la bibliothèque de l'erg. Je suis conscient·e des responsabilités et obligations légales qui viennent avec une diffusion externe – et acquiesce avoir lu la documentation prévue à cet effet par l'erg, ainsi qu'avoir discuté des enjeux d'une publication avec l'équipe pédagogique. J'accepte de partager mes droits de diffusion avec l'erg, ce uniquement dans le cadre d'une diffusion sur la plateforme xamxam.</p>
|
||||||
return ['id' => $at['id'], 'name' => $at['name']];
|
<ul>
|
||||||
}, $enabledAccessTypes);
|
<li><label><input type="checkbox" name="cc4r" value="1"> J'accepte les conditions collectives de réutilisation (CC4r) <em class="hint">(pas obligatoire)</em></label></li>
|
||||||
// Default: Interne (id=2)
|
<li><label><input type="checkbox" name="specific_license" value="1"> Je souhaite appliquer une licence spécifique à mon travail <em class="hint">(pas obligatoire)</em></label></li>
|
||||||
$defaultAccessType = 2;
|
</ul>
|
||||||
$selectedAccessType = isset($formData['access_type_id'])
|
<p class="licence-note"><em>Au moins une des deux cases doit être cochée pour le degré Libre.</em></p>
|
||||||
? (int)$formData['access_type_id']
|
</div>
|
||||||
: $defaultAccessType;
|
|
||||||
$name = 'access_type_id';
|
<div class="licence-degree">
|
||||||
$label = 'Visibilité / Accès :';
|
<h4>🔒 Interne</h4>
|
||||||
$options = $accessOptions;
|
<p>Mon TFE et ma note d'intention ne sont accessibles que sur place en physique ainsi que sur la plateforme xamxam par la communauté erg. Une note descriptive est disponible sur le site à toustes. J'autorise une (ré-)utilisation et diffusion dans un contexte académique et didactique au sein de l'erg.</p>
|
||||||
$selected = $selectedAccessType;
|
<p class="licence-note"><em>La diffusion limitée est protégée par le cadre académique/didactique, le travail pourrait donc être diffusé en interne et être cité par d'autres étudiant·es sans implications légales pour l'auteur·ice ni pour l'école.</em></p>
|
||||||
$placeholder = null;
|
<ul>
|
||||||
$required = true;
|
<li><label><input type="checkbox" name="cc4r" value="1"> J'accepte les conditions collectives de réutilisation (CC4r) <em class="hint">(pas obligatoire)</em></label></li>
|
||||||
$attrs = [];
|
<li><label><input type="checkbox" name="specific_license" value="1"> Je souhaite appliquer une licence spécifique à mon travail <em class="hint">(pas obligatoire)</em></label></li>
|
||||||
include APP_ROOT . '/templates/partials/form/select-field.php';
|
</ul>
|
||||||
?>
|
<p class="licence-note"><em>Au moins une des deux cases doit être cochée.</em></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="licence-degree">
|
||||||
|
<h4>🚫 Interdit</h4>
|
||||||
|
<p>Mon TFE n'est pas disponible en physique ni sur le site. Une note descriptive est disponible sur le site.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="licence-generalites">
|
||||||
|
<h3>Généralités</h3>
|
||||||
|
<ul>
|
||||||
|
<li>L'auteur·ice peut décider entre trois degrés de partage de son travail : <strong>libre</strong>, <strong>interne</strong>, <strong>interdit</strong>.</li>
|
||||||
|
<li>L'auteur·ice peut, à tout moment, décider de <strong>restreindre</strong> le degré d'accès à son travail. Il ne peut néanmoins pas l'ouvrir davantage.</li>
|
||||||
|
<li>Le choix effectué dans ce formulaire sera d'application <strong>une semaine après la soutenance orale</strong> de l'auteur·ice. Celui-ci peut donc décider de restreindre ce choix avant sa publication (mais pas l'ouvrir).</li>
|
||||||
|
<li>L'erg se réserve le droit de restreindre le degré d'ouverture du TFE – ce en accord avec le règlement.</li>
|
||||||
|
<li>Dans tous les cas, l'auteur·ice garde les droits d'auteurs, de diffusion, d'utilisation, etc. de son travail – sauf si la licence choisie restreindrait ses droits.</li>
|
||||||
|
<li>La diffusion « xamxam » est indépendante de la diffusion à la BAIU.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="form-footer">
|
<div class="form-footer">
|
||||||
<button type="submit" name="go">Soumettre</button>
|
<button type="submit" name="go">Soumettre</button>
|
||||||
|
|||||||
@@ -3,14 +3,16 @@
|
|||||||
require_once __DIR__ . "/../../config/bootstrap.php";
|
require_once __DIR__ . "/../../config/bootstrap.php";
|
||||||
require_once __DIR__ . '/../../src/AdminAuth.php';
|
require_once __DIR__ . '/../../src/AdminAuth.php';
|
||||||
|
|
||||||
// PHP-level auth guard (defence-in-depth behind nginx Basic Auth)
|
|
||||||
AdminAuth::requireLogin();
|
|
||||||
|
|
||||||
// Configure error reporting
|
// Configure error reporting
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
ini_set('error_log', 'error.log');
|
ini_set('error_log', 'error.log');
|
||||||
|
|
||||||
|
$studentMode = isset($_GET['mode']) && $_GET['mode'] === 'student';
|
||||||
|
if (!$studentMode) {
|
||||||
|
AdminAuth::requireLogin();
|
||||||
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/../../src/Database.php';
|
require_once __DIR__ . '/../../src/Database.php';
|
||||||
|
|
||||||
// Security: Validate thesis ID parameter
|
// Security: Validate thesis ID parameter
|
||||||
@@ -62,10 +64,48 @@ function formatFileSize($bytes) {
|
|||||||
// Set page title for header
|
// Set page title for header
|
||||||
$pageTitle = "Récapitulatif TFE";
|
$pageTitle = "Récapitulatif TFE";
|
||||||
?>
|
?>
|
||||||
<?php $isAdmin = true; $bodyClass = 'admin-body'; require_once APP_ROOT . '/templates/head.php'; ?>
|
<?php
|
||||||
<?php include APP_ROOT . '/templates/header.php'; ?>
|
$isAdmin = true;
|
||||||
|
if ($studentMode) {
|
||||||
|
$bodyClass = 'admin-body student-body';
|
||||||
|
require_once APP_ROOT . '/templates/head.php';
|
||||||
|
} else {
|
||||||
|
$bodyClass = 'admin-body';
|
||||||
|
require_once APP_ROOT . '/templates/head.php';
|
||||||
|
include APP_ROOT . '/templates/header.php';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<main id="main-content">
|
<main id="main-content">
|
||||||
|
<?php if ($studentMode): ?>
|
||||||
|
<!-- ═══════════════════ STUDENT MODE: Thank you page ═══════════════════ -->
|
||||||
|
<div class="thanks-student-page">
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="thanks-error">
|
||||||
|
<h1>⚠ Oups…</h1>
|
||||||
|
<p><?= htmlspecialchars($error) ?></p>
|
||||||
|
<a href="/admin/add.php?mode=student" class="btn-new-form">← Retour au formulaire</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php elseif ($thesis): ?>
|
||||||
|
<div class="thanks-success">
|
||||||
|
<h1>Merci 🎉</h1>
|
||||||
|
<p class="thanks-message">
|
||||||
|
Ton TFE <strong><?= htmlspecialchars($thesis['title']) ?></strong> a bien été soumis.
|
||||||
|
</p>
|
||||||
|
<a href="/admin/add.php?mode=student" class="btn-new-form">+ Ajouter un nouveau TFE</a>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="thanks-error">
|
||||||
|
<h1>Erreur</h1>
|
||||||
|
<p>Aucune donnée à afficher.</p>
|
||||||
|
<a href="/admin/add.php?mode=student" class="btn-new-form">← Retour au formulaire</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
<!-- ═══════════════════ ADMIN MODE: Recap page ═══════════════════ -->
|
||||||
<h1>Récapitulatif TFE</h1>
|
<h1>Récapitulatif TFE</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
@@ -148,6 +188,8 @@ $pageTitle = "Récapitulatif TFE";
|
|||||||
<p class="admin-muted">Aucune donnée à afficher.</p>
|
<p class="admin-muted">Aucune donnée à afficher.</p>
|
||||||
<p><a href="/admin/add.php" class="admin-btn-secondary">Retour au formulaire</a></p>
|
<p><a href="/admin/add.php" class="admin-btn-secondary">Retour au formulaire</a></p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php endif; ?>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>
|
||||||
|
|||||||
@@ -1748,3 +1748,66 @@
|
|||||||
.form-footer button:hover {
|
.form-footer button:hover {
|
||||||
background: var(--accent-secondary);
|
background: var(--accent-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Student thanks page ────────────────────────────────────────────────── */
|
||||||
|
.thanks-student-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 60vh;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thanks-success,
|
||||||
|
.thanks-error {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-m);
|
||||||
|
max-width: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thanks-success h1,
|
||||||
|
.thanks-error h1 {
|
||||||
|
font-size: var(--step-3);
|
||||||
|
margin: 0;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thanks-message {
|
||||||
|
font-size: var(--step-0);
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thanks-error p {
|
||||||
|
font-size: var(--step-0);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new-form {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2xs);
|
||||||
|
padding: var(--space-m) var(--space-2xl);
|
||||||
|
background: var(--accent-primary);
|
||||||
|
color: var(--accent-foreground);
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: var(--step-0);
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
transition: background 0.15s, transform 0.15s;
|
||||||
|
margin-top: var(--space-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new-form:hover {
|
||||||
|
background: var(--accent-secondary);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|||||||
1
storage/maintenance.flag
Normal file
1
storage/maintenance.flag
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2026-04-15T11:53:16+00:00
|
||||||
Reference in New Issue
Block a user