mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
formulaire: default interne, unpublished, contact toggle, settings section
This commit is contained in:
32
public/admin/actions/settings.php
Normal file
32
public/admin/actions/settings.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../../config/bootstrap.php';
|
||||
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
||||
AdminAuth::requireLogin();
|
||||
|
||||
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
||||
App::flash('error', "Erreur de sécurité : token invalide.");
|
||||
header('Location: /admin/parametres.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once APP_ROOT . '/src/Database.php';
|
||||
$db = new Database();
|
||||
|
||||
$section = $_POST['section'] ?? '';
|
||||
|
||||
if ($section === 'formulaire') {
|
||||
// Save access-type toggle settings
|
||||
$allowed = ['access_type_libre_enabled', 'access_type_interne_enabled', 'access_type_interdit_enabled'];
|
||||
foreach ($allowed as $key) {
|
||||
$value = isset($_POST[$key]) ? '1' : '0';
|
||||
$db->setSetting($key, $value);
|
||||
}
|
||||
App::flash('success', "Paramètres du formulaire mis à jour.");
|
||||
} else {
|
||||
App::flash('error', "Section inconnue.");
|
||||
}
|
||||
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
header('Location: /admin/parametres.php');
|
||||
exit;
|
||||
@@ -63,6 +63,16 @@ function wasSelected($key, $value) {
|
||||
<?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'; ?>
|
||||
<?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 -->
|
||||
<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>
|
||||
|
||||
<?php require APP_ROOT . '/templates/partials/form/jury-fieldset.php'; ?>
|
||||
|
||||
<?php
|
||||
@@ -105,6 +115,26 @@ function wasSelected($key, $value) {
|
||||
|
||||
<?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'; ?>
|
||||
|
||||
<?php
|
||||
// Visibility select — only show options enabled in settings
|
||||
$accessOptions = array_map(function($at) {
|
||||
return ['id' => $at['id'], 'name' => $at['name']];
|
||||
}, $enabledAccessTypes);
|
||||
// Default: Interne (id=2)
|
||||
$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';
|
||||
?>
|
||||
|
||||
<div class="admin-form-footer">
|
||||
<button type="submit" name="go" class="admin-btn">Soumettre</button>
|
||||
</div>
|
||||
|
||||
@@ -45,7 +45,17 @@ try {
|
||||
<input type="hidden" name="thesis_id" value="<?= $thesisId ?>">
|
||||
|
||||
<?php $name = 'auteurice'; $label = 'Auteur·ice(s) :'; $value = htmlspecialchars($thesis['authors']); $required = true; $attrs = array_merge(['autocomplete' => 'name'], $autofocusField === 'auteurice' ? ['autofocus' => true] : []); include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||
<?php $name = 'mail'; $label = 'Contact :'; $value = ''; $attrs = ['autocomplete' => 'email']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||
<?php $name = 'mail'; $label = 'Contact :'; $value = htmlspecialchars($currentAuthorEmail ?? ''); $attrs = ['autocomplete' => 'email']; include APP_ROOT . '/templates/partials/form/text-field.php'; ?>
|
||||
|
||||
<!-- Contact visibility -->
|
||||
<div class="admin-form-group">
|
||||
<label class="admin-checkbox-label">
|
||||
<input type="checkbox" name="contact_public" value="1"
|
||||
<?= !empty($currentAuthorShowContact) ? 'checked' : '' ?>>
|
||||
Je veux que mon contact soit accessible à toustes depuis la plateforme xamxam
|
||||
</label>
|
||||
<small>Si cette case est cochée, le contact apparaît sur la page publique du TFE.</small>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$name = 'année'; $label = 'Année :'; $value = htmlspecialchars((string)$thesis['year']); $required = true;
|
||||
|
||||
@@ -9,6 +9,10 @@ $credentialsFile = APP_ROOT . '/config/admin_credentials.php';
|
||||
$hasPassword = defined('ADMIN_PASSWORD_HASH');
|
||||
$maintenanceOn = file_exists(APP_ROOT . '/storage/maintenance.flag');
|
||||
|
||||
require_once APP_ROOT . '/src/Database.php';
|
||||
$db = new Database();
|
||||
$siteSettings = $db->getAllSettings();
|
||||
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
@@ -56,7 +60,58 @@ if (empty($_SESSION['csrf_token'])) {
|
||||
</section>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════════
|
||||
SECTION 2 — Compte administrateur
|
||||
SECTION 2 — Formulaire
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<section class="admin-settings-section" aria-labelledby="settings-formulaire-title">
|
||||
<h2 class="admin-settings-section__title" id="settings-formulaire-title">Formulaire</h2>
|
||||
|
||||
<p>Options de visibilité disponibles dans le formulaire d'ajout de TFE.</p>
|
||||
<p><small>L'option <strong>Libre</strong> ne sera activée qu'à partir de l'année académique prochaine.</small></p>
|
||||
|
||||
<form method="post" action="actions/settings.php" class="admin-form">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="section" value="formulaire">
|
||||
|
||||
<div class="admin-settings-toggles">
|
||||
<label class="admin-toggle-row">
|
||||
<span class="admin-toggle-label">
|
||||
<strong>Interdit</strong>
|
||||
<small>TFE non disponible en physique ni sur le site</small>
|
||||
</span>
|
||||
<input type="checkbox" name="access_type_interdit_enabled" value="1"
|
||||
class="admin-toggle"
|
||||
<?= ($siteSettings['access_type_interdit_enabled'] ?? '1') === '1' ? 'checked' : '' ?>>
|
||||
</label>
|
||||
|
||||
<label class="admin-toggle-row">
|
||||
<span class="admin-toggle-label">
|
||||
<strong>Interne</strong>
|
||||
<small>TFE accessible uniquement sur place en physique</small>
|
||||
</span>
|
||||
<input type="checkbox" name="access_type_interne_enabled" value="1"
|
||||
class="admin-toggle"
|
||||
<?= ($siteSettings['access_type_interne_enabled'] ?? '1') === '1' ? 'checked' : '' ?>>
|
||||
</label>
|
||||
|
||||
<label class="admin-toggle-row admin-toggle-row--disabled">
|
||||
<span class="admin-toggle-label">
|
||||
<strong>Libre</strong>
|
||||
<small>Libre accès — disponible à partir de l'année académique prochaine</small>
|
||||
</span>
|
||||
<input type="checkbox" name="access_type_libre_enabled" value="1"
|
||||
class="admin-toggle"
|
||||
<?= ($siteSettings['access_type_libre_enabled'] ?? '0') === '1' ? 'checked' : '' ?>>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="admin-form-footer">
|
||||
<button type="submit" class="admin-btn">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- ══════════════════════════════════════════════════════════════
|
||||
SECTION 3 — Compte administrateur
|
||||
══════════════════════════════════════════════════════════════ -->
|
||||
<section class="admin-settings-section" aria-labelledby="settings-account-title">
|
||||
<h2 class="admin-settings-section__title" id="settings-account-title">Compte administrateur</h2>
|
||||
|
||||
@@ -1164,3 +1164,83 @@
|
||||
height: 50vh;
|
||||
border: 1px solid var(--border-primary);
|
||||
}
|
||||
|
||||
/* ── Settings: formulaire toggles ──────────────────────────────────────────── */
|
||||
.admin-settings-toggles {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
margin-bottom: var(--space-m);
|
||||
}
|
||||
|
||||
.admin-toggle-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-m);
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 4px;
|
||||
padding: var(--space-xs) var(--space-m);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.admin-toggle-row--disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.admin-toggle-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.admin-toggle-label strong {
|
||||
font-size: var(--step-0);
|
||||
}
|
||||
|
||||
.admin-toggle-label small {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--step--2);
|
||||
}
|
||||
|
||||
/* Native checkbox styled as toggle pill */
|
||||
.admin-toggle {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
width: 40px;
|
||||
height: 22px;
|
||||
background: var(--border-primary);
|
||||
border-radius: 11px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.admin-toggle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.admin-toggle:checked {
|
||||
background: var(--accent-primary);
|
||||
}
|
||||
|
||||
.admin-toggle:checked::after {
|
||||
transform: translateX(18px);
|
||||
}
|
||||
|
||||
/* ── Form group (for checkbox inside .admin-form) ──────────────────────────── */
|
||||
.admin-form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3xs);
|
||||
}
|
||||
|
||||
@@ -149,18 +149,42 @@ extract($ctrl->handle());
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($data['baiu_link'])): ?>
|
||||
<?php
|
||||
$_contactHref = htmlspecialchars($data['baiu_link']);
|
||||
$_contactLabel = preg_replace('#^https?://#i', '', rtrim($data['baiu_link'], '/'));
|
||||
?>
|
||||
<?php if (!empty($data['author_email']) && !empty($data['author_show_contact'])): ?>
|
||||
<div>
|
||||
<dt>Contact :</dt>
|
||||
<dd>
|
||||
<a href="<?= $_contactHref ?>" target="_blank" rel="noopener">
|
||||
<?= htmlspecialchars($_contactLabel) ?>
|
||||
<?php
|
||||
$_contact = $data['author_email'];
|
||||
$_isUrl = filter_var($_contact, FILTER_VALIDATE_URL) !== false;
|
||||
$_isEmail = !$_isUrl && str_contains($_contact, '@');
|
||||
if ($_isUrl):
|
||||
?>
|
||||
<a href="<?= htmlspecialchars($_contact) ?>" target="_blank" rel="noopener">
|
||||
<?= htmlspecialchars(preg_replace('#^https?://#i', '', rtrim($_contact, '/'))) ?>
|
||||
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
||||
</a>
|
||||
<?php elseif ($_isEmail): ?>
|
||||
<a href="mailto:<?= htmlspecialchars($_contact) ?>"><?= htmlspecialchars($_contact) ?></a>
|
||||
<?php else: ?>
|
||||
<?= htmlspecialchars($_contact) ?>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($data['baiu_link'])): ?>
|
||||
<?php
|
||||
$_baiuHref = htmlspecialchars($data['baiu_link']);
|
||||
$_baiuLabel = preg_replace('#^https?://#i', '', rtrim($data['baiu_link'], '/'));
|
||||
?>
|
||||
<div>
|
||||
<dt>Lien :</dt>
|
||||
<dd>
|
||||
<a href="<?= $_baiuHref ?>" target="_blank" rel="noopener">
|
||||
<?= htmlspecialchars($_baiuLabel) ?>
|
||||
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
||||
</a>
|
||||
|
||||
</dd>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
Reference in New Issue
Block a user