mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
admin: replace header 'Ajouter un TFE' nav link with toolbar button
This commit is contained in:
@@ -9,8 +9,6 @@ ini_set('error_log', 'error.log');
|
||||
|
||||
AdminAuth::requireLogin();
|
||||
|
||||
$studentMode = isset($_POST['student_mode']) && $_POST['student_mode'] === '1';
|
||||
|
||||
// Verify CSRF token
|
||||
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
||||
@@ -28,10 +26,6 @@ try {
|
||||
|
||||
unset($_SESSION['csrf_token']);
|
||||
|
||||
$redirect = '../thanks.php?id=' . urlencode($thesisId);
|
||||
if ($studentMode) {
|
||||
$redirect .= '&mode=student';
|
||||
}
|
||||
header('Location: ' . $redirect);
|
||||
exit();
|
||||
|
||||
@@ -42,9 +36,6 @@ try {
|
||||
$_SESSION['form_data'] = $_POST;
|
||||
|
||||
$redirect = '../add.php';
|
||||
if ($studentMode) {
|
||||
$redirect .= '?mode=student';
|
||||
}
|
||||
|
||||
$autofocusField = ThesisCreateController::autofocusFieldForError($e->getMessage());
|
||||
if ($autofocusField !== null) {
|
||||
|
||||
69
public/admin/actions/student-access.php
Normal file
69
public/admin/actions/student-access.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Student-access link actions (create, toggle, set_password, delete).
|
||||
*/
|
||||
require_once __DIR__ . '/../../../config/bootstrap.php';
|
||||
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
||||
require_once __DIR__ . '/../../../src/ShareLink.php';
|
||||
|
||||
App::adminGuard();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST'
|
||||
|| !isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
||||
http_response_code(403);
|
||||
exit('CSRF token invalide.');
|
||||
}
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
$shareLink = ShareLink::make();
|
||||
|
||||
switch ($action) {
|
||||
case 'create':
|
||||
$password = !empty($_POST['password']) ? trim($_POST['password']) : null;
|
||||
$expiresRaw = !empty($_POST['expires_at']) ? trim($_POST['expires_at']) : null;
|
||||
$expiresAt = null;
|
||||
if ($expiresRaw) {
|
||||
// datetime-local gives "YYYY-MM-DDTHH:MM"
|
||||
$expiresAt = date('Y-m-d H:i:s', strtotime($expiresRaw));
|
||||
if ($expiresAt <= date('Y-m-d H:i:s')) {
|
||||
App::redirect('/admin/student-access.php', error: "La date d'expiration doit être dans le futur.");
|
||||
}
|
||||
}
|
||||
$shareLink->create(1, $password, $expiresAt);
|
||||
App::redirect('/admin/student-access.php', success: 'Lien d\'accès créé.');
|
||||
break;
|
||||
|
||||
case 'toggle':
|
||||
if ($id > 0) {
|
||||
$shareLink->toggleActive($id);
|
||||
App::redirect('/admin/student-access.php', success: 'Statut du lien modifié.');
|
||||
} else {
|
||||
App::redirect('/admin/student-access.php', error: 'Lien introuvable.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'set_password':
|
||||
if ($id > 0) {
|
||||
$password = isset($_POST['password']) && $_POST['password'] !== '' ? trim($_POST['password']) : null;
|
||||
$shareLink->setPassword($id, $password);
|
||||
App::redirect('/admin/student-access.php', success: 'Mot de passe mis à jour.');
|
||||
} else {
|
||||
App::redirect('/admin/student-access.php', error: 'Lien introuvable.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if ($id > 0) {
|
||||
$shareLink->delete($id);
|
||||
App::redirect('/admin/student-access.php', success: 'Lien supprimé.');
|
||||
} else {
|
||||
App::redirect('/admin/student-access.php', error: 'Lien introuvable.');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
App::redirect('/admin/student-access.php', error: 'Action inconnue.');
|
||||
break;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ if (empty($_SESSION["csrf_token"])) {
|
||||
}
|
||||
|
||||
$pageTitle = "Ajouter un TFE";
|
||||
$studentMode = isset($_GET['mode']) && $_GET['mode'] === 'student';
|
||||
|
||||
require_once __DIR__ . '/../../src/ThesisCreateController.php';
|
||||
|
||||
@@ -48,33 +47,20 @@ function wasSelected($key, $value) {
|
||||
?>
|
||||
<?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';
|
||||
}
|
||||
$bodyClass = 'admin-body';
|
||||
require_once APP_ROOT . '/templates/head.php';
|
||||
include APP_ROOT . '/templates/header.php';
|
||||
?>
|
||||
|
||||
<main id="main-content">
|
||||
<div class="thesis-add-header">
|
||||
<h1>Ajouter un TFE</h1>
|
||||
<?php if (!$studentMode): ?>
|
||||
<a href="?mode=student" class="mode-toggle" target="_blank" rel="noopener">Mode étudiant ↗</a>
|
||||
<?php else: ?>
|
||||
<a href="?mode=admin" class="mode-toggle mode-toggle--back">← Retour admin</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php include APP_ROOT . '/templates/partials/flash-messages.php'; ?>
|
||||
|
||||
<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"]) ?>">
|
||||
<?php if ($studentMode): ?>
|
||||
<input type="hidden" name="student_mode" value="1">
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ═══════════════════ Informations du TFE ═══════════════════ -->
|
||||
<fieldset>
|
||||
@@ -165,55 +151,6 @@ if ($studentMode) {
|
||||
?>
|
||||
</fieldset>
|
||||
|
||||
<?php if ($studentMode): ?>
|
||||
<!-- ═══════════════════ Degrés d'ouverture ═══════════════════ -->
|
||||
<fieldset class="licence-explanation">
|
||||
<legend>Degrés d'ouverture et licences</legend>
|
||||
|
||||
<div class="licence-info">
|
||||
<h3>Je veux que mon TFE soit disponible sous les conditions suivantes :</h3>
|
||||
|
||||
<div class="licence-degree">
|
||||
<h4>🔓 Libre</h4>
|
||||
<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>
|
||||
<ul>
|
||||
<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>
|
||||
<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>
|
||||
</ul>
|
||||
<p class="licence-note"><em>Au moins une des deux cases doit être cochée pour le degré Libre.</em></p>
|
||||
</div>
|
||||
|
||||
<div class="licence-degree">
|
||||
<h4>🔒 Interne</h4>
|
||||
<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>
|
||||
<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>
|
||||
<ul>
|
||||
<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>
|
||||
<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>
|
||||
</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">
|
||||
<button type="submit" name="go">Soumettre</button>
|
||||
</div>
|
||||
|
||||
244
public/admin/student-access.php
Normal file
244
public/admin/student-access.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../config/bootstrap.php';
|
||||
require_once __DIR__ . '/../../src/AdminAuth.php';
|
||||
require_once __DIR__ . '/../../src/ShareLink.php';
|
||||
|
||||
App::adminGuard();
|
||||
|
||||
require_once __DIR__ . '/../../src/ShareLink.php';
|
||||
|
||||
$shareLink = ShareLink::make();
|
||||
$links = $shareLink->listAll();
|
||||
$flash = App::consumeFlash();
|
||||
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$baseUrl = $protocol . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost');
|
||||
$pageTitle = 'Accès étudiant·e';
|
||||
$isAdmin = true;
|
||||
$bodyClass = 'admin-body';
|
||||
?>
|
||||
<?php require_once APP_ROOT . '/templates/head.php'; ?>
|
||||
<?php include APP_ROOT . '/templates/header.php'; ?>
|
||||
|
||||
<style>
|
||||
.access-main { padding: 2rem; max-width: 960px; }
|
||||
.access-toolbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; margin-bottom: 1.5rem; }
|
||||
.access-toolbar h1 { margin: 0; font-size: 1.5rem; }
|
||||
.access-btn { display: inline-flex; align-items: center; gap: .4rem; padding: .5rem 1rem; border: none; border-radius: 6px; cursor: pointer; font-size: .875rem; background: #2563eb; color: #fff; text-decoration: none; }
|
||||
.access-btn:hover { background: #1d4ed8; }
|
||||
.access-btn--secondary { background: #f1f5f9; color: #334155; border: 1px solid #cbd5e1; }
|
||||
.access-btn--secondary:hover { background: #e2e8f0; }
|
||||
.access-btn--danger { background: #fee2e2; color: #b91c1c; }
|
||||
.access-btn--danger:hover { background: #fca5a5; }
|
||||
.access-btn--sm { padding: .3rem .6rem; font-size: .8rem; }
|
||||
|
||||
.access-table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
|
||||
.access-table th, .access-table td { padding: .6rem .8rem; text-align: left; border-bottom: 1px solid #e2e8f0; vertical-align: middle; }
|
||||
.access-table th { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: #64748b; background: #f8fafc; }
|
||||
.access-table th:first-child { border-radius: 6px 0 0 0; }
|
||||
.access-table th:last-child { border-radius: 0 6px 0 0; }
|
||||
.access-table tbody tr:hover { background: #f8fafc; }
|
||||
.access-slug { font-family: ui-monospace, SFMono-Regular, monospace; font-size: .85rem; }
|
||||
.access-url-input { display: none; margin-top: .25rem; padding: .35rem .5rem; font-size: .8rem; border: 1px solid #cbd5e1; border-radius: 4px; width: 100%; max-width: 320px; font-family: ui-monospace, SFMono-Regular, monospace; }
|
||||
.access-url-input.visible { display: inline-block; }
|
||||
.access-badge { display: inline-block; padding: .15rem .5rem; border-radius: 9999px; font-size: .75rem; font-weight: 500; background: #dcfce7; color: #166534; }
|
||||
.access-badge--disabled { background: #fee2e2; color: #b91c1c; }
|
||||
.access-badge--expired { background: #fef3c7; color: #92400e; }
|
||||
.access-act { display: flex; gap: .35rem; flex-wrap: wrap; }
|
||||
|
||||
/* ── Create dialog ── */
|
||||
.access-dialog { border: none; border-radius: 12px; padding: 0; width: min(480px, 92vw); box-shadow: 0 20px 60px rgba(0,0,0,.18); max-height: 80vh; overflow: auto; }
|
||||
.access-dialog::backdrop { background: rgba(0,0,0,.35); }
|
||||
.access-dialog__header { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.5rem; border-bottom: 1px solid #e2e8f0; }
|
||||
.access-dialog__header h2 { margin: 0; font-size: 1.15rem; }
|
||||
.access-dialog__close { background: none; border: none; font-size: 1.4rem; cursor: pointer; color: #64748b; line-height: 1; }
|
||||
.access-dialog__body { padding: 1.5rem; }
|
||||
.access-dialog__body label { display: block; margin-bottom: 1rem; font-size: .9rem; }
|
||||
.access-dialog__body label input[type=text],
|
||||
.access-dialog__body label input[type=password],
|
||||
.access-dialog__body label input[type=datetime-local] { display: block; width: 100%; margin-top: .3rem; padding: .45rem .6rem; border: 1px solid #cbd5e1; border-radius: 6px; font-size: .9rem; box-sizing: border-box; }
|
||||
.access-dialog__body small { display: block; margin-top: .25rem; color: #64748b; }
|
||||
.access-dialog__footer { display: flex; justify-content: flex-end; gap: .5rem; padding: 1rem 1.5rem; border-top: 1px solid #e2e8f0; }
|
||||
|
||||
.access-empty { text-align: center; padding: 3rem 1rem; color: #94a3b8; }
|
||||
.access-empty svg { width: 48px; height: 48px; margin-bottom: .75rem; opacity: .5; }
|
||||
</style>
|
||||
|
||||
<main id="main-content" class="access-main">
|
||||
<?php if ($flash['success']): ?>
|
||||
<div class="flash flash--success"><?= htmlspecialchars($flash['success']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($flash['error']): ?>
|
||||
<div class="flash flash--error"><?= htmlspecialchars($flash['error']) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="access-toolbar">
|
||||
<h1>Accès étudiant·e</h1>
|
||||
<button type="button" class="access-btn" id="open-create-dialog">
|
||||
+ Créer un lien
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php if (empty($links)): ?>
|
||||
<div class="access-empty">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"/></svg>
|
||||
<p>Aucun lien d'accès créé.</p>
|
||||
<p>Cliquez sur « Créer un lien » pour générer un lien partageable.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<table class="access-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Lien</th>
|
||||
<th scope="col">Statut</th>
|
||||
<th scope="col">Mot de passe</th>
|
||||
<th scope="col">Utilisations</th>
|
||||
<th scope="col">Expiration</th>
|
||||
<th scope="col">Créé le</th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($links as $link): ?>
|
||||
<?php
|
||||
$isExpired = $link['expires_at'] !== null && strtotime($link['expires_at']) < time();
|
||||
$isActive = (bool)$link['is_active'] && !$isExpired;
|
||||
$statusLabel = $isExpired ? 'Expiré' : ($link['is_active'] ? 'Actif' : 'Désactivé');
|
||||
$statusClass = $isExpired ? 'access-badge--expired' : ($link['is_active'] ? '' : 'access-badge--disabled');
|
||||
$fullUrl = $baseUrl . '/partage/' . htmlspecialchars($link['slug']);
|
||||
$created = date('d/m/Y H:i', strtotime($link['created_at']));
|
||||
$expires = $link['expires_at'] ? date('d/m/Y', strtotime($link['expires_at'])) : '—';
|
||||
$hasPassword = !empty($link['password_hash']);
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="access-slug"><?= htmlspecialchars($link['slug']) ?></span>
|
||||
<input class="access-url-input" id="url-<?= $link['id'] ?>" value="<?= $fullUrl ?>" readonly>
|
||||
</td>
|
||||
<td><span class="access-badge <?= $statusClass ?>"><?= $statusLabel ?></span></td>
|
||||
<td><?= $hasPassword ? '🔒 Oui' : 'Non' ?></td>
|
||||
<td><?= intval($link['usage_count']) ?></td>
|
||||
<td><?= $expires ?></td>
|
||||
<td><?= $created ?></td>
|
||||
<td>
|
||||
<div class="access-act">
|
||||
<button type="button" class="access-btn access-btn--secondary access-btn--sm"
|
||||
onclick="copyUrl(<?= $link['id'] ?>)" title="Copier l'URL">
|
||||
Copier
|
||||
</button>
|
||||
<form method="post" action="actions/student-access.php" style="display:inline;">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="toggle">
|
||||
<input type="hidden" name="id" value="<?= $link['id'] ?>">
|
||||
<button type="submit" class="access-btn access-btn--secondary access-btn--sm"
|
||||
title="<?= $link['is_active'] ? 'Désactiver' : 'Activer' ?>">
|
||||
<?= $link['is_active'] ? '⏸' : '▶' ?>
|
||||
</button>
|
||||
</form>
|
||||
<button type="button" class="access-btn access-btn--secondary access-btn--sm"
|
||||
onclick="openPasswordDialog(<?= $link['id'] ?>, <?= $hasPassword ? 'true' : 'false' ?>)"
|
||||
title="Modifier le mot de passe">
|
||||
🔑
|
||||
</button>
|
||||
<form method="post" action="actions/student-access.php" style="display:inline;"
|
||||
onsubmit="return confirm('Supprimer ce lien ? Les soumissions via ce lien seront bloquées.')">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="id" value="<?= $link['id'] ?>">
|
||||
<button type="submit" class="access-btn access-btn--danger access-btn--sm" title="Supprimer">
|
||||
🗑
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<!-- ═══════════════════════ CREATE DIALOG ═══════════════════════ -->
|
||||
<dialog id="create-dialog" class="access-dialog">
|
||||
<div class="access-dialog__header">
|
||||
<h2>Créer un lien d'accès</h2>
|
||||
<button type="button" class="access-dialog__close" onclick="document.getElementById('create-dialog').close()">✕</button>
|
||||
</div>
|
||||
<form method="post" action="actions/student-access.php">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="create">
|
||||
<div class="access-dialog__body">
|
||||
<label>
|
||||
Mot de passe (optionnel)
|
||||
<input type="password" name="password" autocomplete="new-password">
|
||||
<small>Laissez vide pour un lien sans mot de passe.</small>
|
||||
</label>
|
||||
<label>
|
||||
Expiration (optionnel)
|
||||
<input type="datetime-local" name="expires_at">
|
||||
<small>Laissez vide pour qu'il n'expire jamais.</small>
|
||||
</label>
|
||||
</div>
|
||||
<div class="access-dialog__footer">
|
||||
<button type="button" class="access-btn access-btn--secondary"
|
||||
onclick="document.getElementById('create-dialog').close()">Annuler</button>
|
||||
<button type="submit" class="access-btn">Créer le lien</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<!-- ═══════════════════════ PASSWORD DIALOG ═══════════════════════ -->
|
||||
<dialog id="password-dialog" class="access-dialog">
|
||||
<div class="access-dialog__header">
|
||||
<h2>Mot de passe</h2>
|
||||
<button type="button" class="access-dialog__close" onclick="document.getElementById('password-dialog').close()">✕</button>
|
||||
</div>
|
||||
<form method="post" action="actions/student-access.php">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
<input type="hidden" name="action" value="set_password">
|
||||
<input type="hidden" name="id" id="password-link-id" value="">
|
||||
<div class="access-dialog__body">
|
||||
<label>
|
||||
Nouveau mot de passe
|
||||
<input type="password" name="password" autocomplete="new-password">
|
||||
<small>Laissez vide pour supprimer le mot de passe.</small>
|
||||
</label>
|
||||
<p id="password-current-info" style="font-size:.85rem;color:#64748b;margin-top:.5rem;"></p>
|
||||
</div>
|
||||
<div class="access-dialog__footer">
|
||||
<button type="button" class="access-btn access-btn--secondary"
|
||||
onclick="document.getElementById('password-dialog').close()">Annuler</button>
|
||||
<button type="submit" class="access-btn">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
document.getElementById('open-create-dialog').addEventListener('click', () => {
|
||||
document.getElementById('create-dialog').showModal();
|
||||
});
|
||||
|
||||
function copyUrl(id) {
|
||||
const input = document.getElementById('url-' + id);
|
||||
input.classList.toggle('visible');
|
||||
if (input.classList.contains('visible')) {
|
||||
input.select();
|
||||
navigator.clipboard.writeText(input.value).then(() => {
|
||||
// Brief visual feedback
|
||||
input.style.outline = '2px solid #22c55e';
|
||||
setTimeout(() => { input.style.outline = ''; }, 600);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function openPasswordDialog(id, hasPassword) {
|
||||
document.getElementById('password-link-id').value = id;
|
||||
const info = document.getElementById('password-current-info');
|
||||
info.textContent = hasPassword
|
||||
? 'Un mot de passe est actuellement configuré. Entrez-en un nouveau ou laissez vide pour le supprimer.'
|
||||
: 'Aucun mot de passe configuré.';
|
||||
document.getElementById('password-dialog').showModal();
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php require_once APP_ROOT . '/templates/admin/footer.php'; ?>
|
||||
Reference in New Issue
Block a user