Admin : gestion groupes, services par groupes, badge admin
- admin/groups.php : liste/création/suppression des groupes Keycloak avec comptage des membres et services associés par groupe - admin/services.php : remplace requires_adherent par sélection multi-groupes - inc/services.php : modèle groups[], migration auto depuis requires_adherent, helper service_accessible() pour l'accès contextuel - inc/keycloak.php : kc_list_groups, kc_create_group, kc_delete_group, kc_group_members - profile.php : badge Admin visible dans la tuile Mon compte - index.php : utilise service_accessible() avec les groupes de l'utilisateur Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f5f831dfb0
commit
4921a0691c
8 changed files with 228 additions and 37 deletions
127
web/admin/groups.php
Normal file
127
web/admin/groups.php
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../inc/config.php';
|
||||||
|
require_once __DIR__ . '/../inc/auth.php';
|
||||||
|
require_once __DIR__ . '/../inc/keycloak.php';
|
||||||
|
require_once __DIR__ . '/../inc/services.php';
|
||||||
|
|
||||||
|
session_start_safe();
|
||||||
|
require_admin();
|
||||||
|
|
||||||
|
$errors = [];
|
||||||
|
$success = '';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
|
if ($action === 'create') {
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
if (!$name) {
|
||||||
|
$errors[] = 'Le nom du groupe est obligatoire.';
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
kc_create_group($name);
|
||||||
|
set_flash('success', "Groupe « $name » créé.");
|
||||||
|
header('Location: /admin/groups.php'); exit;
|
||||||
|
} catch (Exception $e) { $errors[] = $e->getMessage(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'delete') {
|
||||||
|
$group_id = $_POST['group_id'] ?? '';
|
||||||
|
if ($group_id) {
|
||||||
|
try {
|
||||||
|
kc_delete_group($group_id);
|
||||||
|
set_flash('success', 'Groupe supprimé.');
|
||||||
|
header('Location: /admin/groups.php'); exit;
|
||||||
|
} catch (Exception $e) { $errors[] = $e->getMessage(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$groups = kc_list_groups();
|
||||||
|
$services = services_list();
|
||||||
|
|
||||||
|
// Indexe les services par groupe requis
|
||||||
|
$services_by_group = [];
|
||||||
|
foreach ($services as $s) {
|
||||||
|
foreach ($s['groups'] ?? [] as $g) {
|
||||||
|
$services_by_group[$g][] = $s['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = 'Gestion des groupes';
|
||||||
|
require __DIR__ . '/../views/layout.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="admin-page">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>Gestion des groupes</h1>
|
||||||
|
<div class="admin-nav">
|
||||||
|
<a href="/admin/members.php">Membres</a>
|
||||||
|
<a href="/admin/groups.php" class="active">Groupes</a>
|
||||||
|
<a href="/admin/services.php">Services</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($errors): ?>
|
||||||
|
<div class="alert alert-error"><ul><?php foreach ($errors as $e): ?><li><?= htmlspecialchars($e) ?></li><?php endforeach; ?></ul></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Liste des groupes -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>Groupes Keycloak (<?= count($groups) ?>)</h2>
|
||||||
|
<?php if (!$groups): ?>
|
||||||
|
<p class="text-muted">Aucun groupe trouvé.</p>
|
||||||
|
<?php else: ?>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Nom</th><th>Membres</th><th>Services associés</th><th>Actions</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($groups as $g):
|
||||||
|
$members = kc_group_members($g['id']);
|
||||||
|
$linked = $services_by_group[$g['name']] ?? [];
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><strong><?= htmlspecialchars($g['name']) ?></strong></td>
|
||||||
|
<td><?= count($members) ?></td>
|
||||||
|
<td>
|
||||||
|
<?php if ($linked): ?>
|
||||||
|
<?php foreach ($linked as $svc): ?>
|
||||||
|
<span class="badge"><?= htmlspecialchars($svc) ?></span>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<span class="text-muted small">—</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form method="post" style="display:inline"
|
||||||
|
onsubmit="return confirm('Supprimer le groupe « <?= htmlspecialchars(addslashes($g['name'])) ?> » ?')">
|
||||||
|
<input type="hidden" name="action" value="delete">
|
||||||
|
<input type="hidden" name="group_id" value="<?= htmlspecialchars($g['id']) ?>">
|
||||||
|
<button type="submit" class="btn-danger btn-sm">Supprimer</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Créer un groupe -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>Créer un groupe</h2>
|
||||||
|
<form method="post" style="display:flex; gap:.8rem; align-items:flex-end">
|
||||||
|
<input type="hidden" name="action" value="create">
|
||||||
|
<div class="form-group" style="margin:0; flex:1">
|
||||||
|
<label>Nom du groupe</label>
|
||||||
|
<input type="text" name="name" required placeholder="ex: bureau, moderateurs…"
|
||||||
|
value="<?= htmlspecialchars($_POST['name'] ?? '') ?>">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-primary">Créer</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php require __DIR__ . '/../views/layout_end.php'; ?>
|
||||||
|
|
@ -28,6 +28,7 @@ require __DIR__ . '/../views/layout.php';
|
||||||
<h1>Gestion des membres</h1>
|
<h1>Gestion des membres</h1>
|
||||||
<div class="admin-nav">
|
<div class="admin-nav">
|
||||||
<a href="/admin/members.php" class="active">Membres</a>
|
<a href="/admin/members.php" class="active">Membres</a>
|
||||||
|
<a href="/admin/groups.php">Groupes</a>
|
||||||
<a href="/admin/services.php">Services</a>
|
<a href="/admin/services.php">Services</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@
|
||||||
require_once __DIR__ . '/../inc/config.php';
|
require_once __DIR__ . '/../inc/config.php';
|
||||||
require_once __DIR__ . '/../inc/auth.php';
|
require_once __DIR__ . '/../inc/auth.php';
|
||||||
require_once __DIR__ . '/../inc/services.php';
|
require_once __DIR__ . '/../inc/services.php';
|
||||||
|
require_once __DIR__ . '/../inc/keycloak.php';
|
||||||
|
|
||||||
session_start_safe();
|
session_start_safe();
|
||||||
require_admin();
|
require_admin();
|
||||||
|
|
||||||
|
$kc_groups = kc_list_groups();
|
||||||
|
$group_names = array_column($kc_groups, 'name');
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$updated = [];
|
$updated = [];
|
||||||
foreach ($_POST as $key => $val) {
|
foreach ($_POST as $key => $val) {
|
||||||
|
|
@ -15,23 +19,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
'name' => trim($val),
|
'name' => trim($val),
|
||||||
'url' => trim($_POST["url_$idx"] ?? ''),
|
'url' => trim($_POST["url_$idx"] ?? ''),
|
||||||
'description' => trim($_POST["description_$idx"] ?? ''),
|
'description' => trim($_POST["description_$idx"] ?? ''),
|
||||||
'requires_adherent' => isset($_POST["requires_$idx"]),
|
'groups' => (array)($_POST["groups_$idx"] ?? []),
|
||||||
'visible' => isset($_POST["visible_$idx"]),
|
'visible' => isset($_POST["visible_$idx"]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
// Ajout d'un nouveau service si rempli
|
|
||||||
$new_name = trim($_POST['new_name'] ?? '');
|
$new_name = trim($_POST['new_name'] ?? '');
|
||||||
if ($new_name) {
|
if ($new_name) {
|
||||||
$updated[] = [
|
$updated[] = [
|
||||||
'name' => $new_name,
|
'name' => $new_name,
|
||||||
'url' => trim($_POST['new_url'] ?? ''),
|
'url' => trim($_POST['new_url'] ?? ''),
|
||||||
'description' => trim($_POST['new_description'] ?? ''),
|
'description' => trim($_POST['new_description'] ?? ''),
|
||||||
'requires_adherent' => isset($_POST['new_requires']),
|
'groups' => (array)($_POST['new_groups'] ?? []),
|
||||||
'visible' => isset($_POST['new_visible']),
|
'visible' => isset($_POST['new_visible']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
services_save($updated);
|
services_save($updated);
|
||||||
set_flash('success', 'Configuration des services sauvegardée.');
|
set_flash('success', 'Services sauvegardés.');
|
||||||
header('Location: /admin/services.php');
|
header('Location: /admin/services.php');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
@ -46,16 +49,12 @@ require __DIR__ . '/../views/layout.php';
|
||||||
<h1>Paramétrage des services</h1>
|
<h1>Paramétrage des services</h1>
|
||||||
<div class="admin-nav">
|
<div class="admin-nav">
|
||||||
<a href="/admin/members.php">Membres</a>
|
<a href="/admin/members.php">Membres</a>
|
||||||
|
<a href="/admin/groups.php">Groupes</a>
|
||||||
<a href="/admin/services.php" class="active">Services</a>
|
<a href="/admin/services.php" class="active">Services</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<p class="text-muted">
|
|
||||||
Définissez quels services sont accessibles aux simples inscrits
|
|
||||||
et lesquels nécessitent une adhésion validée.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<table class="services-table">
|
<table class="services-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -63,7 +62,7 @@ require __DIR__ . '/../views/layout.php';
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>URL</th>
|
<th>URL</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Adhérent requis</th>
|
<th>Groupes requis</th>
|
||||||
<th>Visible</th>
|
<th>Visible</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -73,26 +72,46 @@ require __DIR__ . '/../views/layout.php';
|
||||||
<td><input type="text" name="name_<?= $i ?>" value="<?= htmlspecialchars($s['name']) ?>" required></td>
|
<td><input type="text" name="name_<?= $i ?>" value="<?= htmlspecialchars($s['name']) ?>" required></td>
|
||||||
<td><input type="url" name="url_<?= $i ?>" value="<?= htmlspecialchars($s['url']) ?>"></td>
|
<td><input type="url" name="url_<?= $i ?>" value="<?= htmlspecialchars($s['url']) ?>"></td>
|
||||||
<td><input type="text" name="description_<?= $i ?>" value="<?= htmlspecialchars($s['description']) ?>"></td>
|
<td><input type="text" name="description_<?= $i ?>" value="<?= htmlspecialchars($s['description']) ?>"></td>
|
||||||
<td class="center">
|
<td>
|
||||||
<input type="checkbox" name="requires_<?= $i ?>" <?= $s['requires_adherent'] ? 'checked' : '' ?>>
|
<div class="group-checks">
|
||||||
|
<?php foreach ($group_names as $gn): ?>
|
||||||
|
<label class="group-check-label">
|
||||||
|
<input type="checkbox" name="groups_<?= $i ?>[]" value="<?= htmlspecialchars($gn) ?>"
|
||||||
|
<?= in_array($gn, $s['groups'], true) ? 'checked' : '' ?>>
|
||||||
|
<?= htmlspecialchars($gn) ?>
|
||||||
|
</label>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php if (!$group_names): ?>
|
||||||
|
<span class="text-muted small">Aucun groupe</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="center">
|
<td class="center">
|
||||||
<input type="checkbox" name="visible_<?= $i ?>" <?= $s['visible'] ? 'checked' : '' ?>>
|
<input type="checkbox" name="visible_<?= $i ?>" <?= $s['visible'] ? 'checked' : '' ?>>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<!-- Ligne ajout nouveau service -->
|
|
||||||
<tr class="new-row">
|
<tr class="new-row">
|
||||||
<td><input type="text" name="new_name" placeholder="Nouveau service"></td>
|
<td><input type="text" name="new_name" placeholder="Nouveau service"></td>
|
||||||
<td><input type="url" name="new_url" placeholder="https://..."></td>
|
<td><input type="url" name="new_url" placeholder="https://..."></td>
|
||||||
<td><input type="text" name="new_description" placeholder="Description"></td>
|
<td><input type="text" name="new_description" placeholder="Description"></td>
|
||||||
<td class="center"><input type="checkbox" name="new_requires"></td>
|
<td>
|
||||||
|
<div class="group-checks">
|
||||||
|
<?php foreach ($group_names as $gn): ?>
|
||||||
|
<label class="group-check-label">
|
||||||
|
<input type="checkbox" name="new_groups[]" value="<?= htmlspecialchars($gn) ?>">
|
||||||
|
<?= htmlspecialchars($gn) ?>
|
||||||
|
</label>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td class="center"><input type="checkbox" name="new_visible" checked></td>
|
<td class="center"><input type="checkbox" name="new_visible" checked></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div style="margin-top:1rem">
|
||||||
<button type="submit" class="btn-primary">Enregistrer</button>
|
<button type="submit" class="btn-primary">Enregistrer</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,8 @@ td.center { text-align: center; }
|
||||||
padding: .3rem .5rem; font-size: .85rem;
|
padding: .3rem .5rem; font-size: .85rem;
|
||||||
}
|
}
|
||||||
.new-row td { background: #eef1ff; }
|
.new-row td { background: #eef1ff; }
|
||||||
|
.group-checks { display: flex; flex-direction: column; gap: .2rem; }
|
||||||
|
.group-check-label { display: flex; align-items: center; gap: .4rem; font-size: .8rem; cursor: pointer; white-space: nowrap; }
|
||||||
|
|
||||||
/* ── Helpers ──────────────────────────────────────────────────────── */
|
/* ── Helpers ──────────────────────────────────────────────────────── */
|
||||||
.text-success { color: var(--success); }
|
.text-success { color: var(--success); }
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,29 @@ function kc_list_users(int $max = 200): array {
|
||||||
return $users;
|
return $users;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function kc_list_groups(): array {
|
||||||
|
$resp = _kc_request('GET', '/groups?max=200&briefRepresentation=false');
|
||||||
|
if ($resp['status'] !== 200) return [];
|
||||||
|
return json_decode($resp['body'], true) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function kc_create_group(string $name): void {
|
||||||
|
$resp = _kc_request('POST', '/groups', ['name' => $name]);
|
||||||
|
if ($resp['status'] === 409) throw new RuntimeException("Le groupe « $name » existe déjà.");
|
||||||
|
if ($resp['status'] !== 201) throw new RuntimeException("Erreur création groupe ({$resp['status']})");
|
||||||
|
}
|
||||||
|
|
||||||
|
function kc_delete_group(string $group_id): void {
|
||||||
|
$resp = _kc_request('DELETE', "/groups/$group_id");
|
||||||
|
if ($resp['status'] >= 300) throw new RuntimeException("Erreur suppression groupe ({$resp['status']})");
|
||||||
|
}
|
||||||
|
|
||||||
|
function kc_group_members(string $group_id, int $max = 200): array {
|
||||||
|
$resp = _kc_request('GET', "/groups/$group_id/members?max=$max");
|
||||||
|
if ($resp['status'] !== 200) return [];
|
||||||
|
return json_decode($resp['body'], true) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
function _kc_group_id(string $group_name): string {
|
function _kc_group_id(string $group_name): string {
|
||||||
$resp = _kc_request('GET', '/groups?search=' . urlencode($group_name));
|
$resp = _kc_request('GET', '/groups?search=' . urlencode($group_name));
|
||||||
$groups = json_decode($resp['body'], true) ?? [];
|
$groups = json_decode($resp['body'], true) ?? [];
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,38 @@
|
||||||
require_once __DIR__ . '/config.php';
|
require_once __DIR__ . '/config.php';
|
||||||
|
|
||||||
const DEFAULT_SERVICES = [
|
const DEFAULT_SERVICES = [
|
||||||
['name' => 'Wiki', 'url' => 'https://wiki.alpinux.org', 'description' => 'Documentation et guides', 'requires_adherent' => false, 'visible' => true],
|
['name' => 'Wiki', 'url' => 'https://wiki.alpinux.org', 'description' => 'Documentation et guides', 'groups' => [], 'visible' => true],
|
||||||
['name' => 'Gitea', 'url' => 'https://gitea.alpinux.org', 'description' => 'Forge de code', 'requires_adherent' => false, 'visible' => true],
|
['name' => 'Gitea', 'url' => 'https://gitea.alpinux.org', 'description' => 'Forge de code', 'groups' => [], 'visible' => true],
|
||||||
['name' => 'Quiz interactifs','url' => 'https://dynamic.alpinux.org', 'description' => 'Jeux et quiz', 'requires_adherent' => false, 'visible' => true],
|
['name' => 'Quiz interactifs','url' => 'https://dynamic.alpinux.org', 'description' => 'Jeux et quiz', 'groups' => [], 'visible' => true],
|
||||||
['name' => 'Install Party', 'url' => 'https://installparty.alpinux.org', 'description' => 'Événements et ateliers', 'requires_adherent' => false, 'visible' => true],
|
['name' => 'Install Party', 'url' => 'https://installparty.alpinux.org', 'description' => 'Événements et ateliers', 'groups' => [], 'visible' => true],
|
||||||
['name' => 'Nextcloud', 'url' => 'https://cloud.alpinux.org', 'description' => 'Stockage et collaboration', 'requires_adherent' => true, 'visible' => true],
|
['name' => 'Nextcloud', 'url' => 'https://cloud.alpinux.org', 'description' => 'Stockage et collaboration', 'groups' => ['adherents'], 'visible' => true],
|
||||||
['name' => 'Dolibarr', 'url' => 'https://dolibarr.alpinux.org', 'description' => 'Gestion de l\'association', 'requires_adherent' => true, 'visible' => true],
|
['name' => 'Dolibarr', 'url' => 'https://dolibarr.alpinux.org', 'description' => 'Gestion de l\'association', 'groups' => ['adherents'], 'visible' => true],
|
||||||
];
|
];
|
||||||
|
|
||||||
function services_list(): array {
|
function services_list(): array {
|
||||||
$file = SERVICES_FILE;
|
$file = SERVICES_FILE;
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
$data = json_decode(file_get_contents($file), true);
|
$data = json_decode(file_get_contents($file), true);
|
||||||
if (is_array($data)) return $data;
|
if (is_array($data)) return array_map('_service_normalize', $data);
|
||||||
}
|
}
|
||||||
return DEFAULT_SERVICES;
|
return DEFAULT_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _service_normalize(array $s): array {
|
||||||
|
// Migre l'ancien champ requires_adherent vers groups
|
||||||
|
if (!array_key_exists('groups', $s)) {
|
||||||
|
$s['groups'] = ($s['requires_adherent'] ?? false) ? [ADHERENT_GROUP] : [];
|
||||||
|
}
|
||||||
|
unset($s['requires_adherent']);
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function service_accessible(array $service, array $user_groups, bool $is_admin): bool {
|
||||||
|
if ($is_admin) return true;
|
||||||
|
$required = $service['groups'] ?? [];
|
||||||
|
return empty($required) || (bool) array_intersect($required, $user_groups);
|
||||||
|
}
|
||||||
|
|
||||||
function services_save(array $services): void {
|
function services_save(array $services): void {
|
||||||
$dir = dirname(SERVICES_FILE);
|
$dir = dirname(SERVICES_FILE);
|
||||||
if (!is_dir($dir)) mkdir($dir, 0755, true);
|
if (!is_dir($dir)) mkdir($dir, 0755, true);
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ $user = current_user();
|
||||||
$title = 'Portail Alpinux';
|
$title = 'Portail Alpinux';
|
||||||
$services = services_list();
|
$services = services_list();
|
||||||
|
|
||||||
$is_adherent = $user && (
|
$is_admin = $user && ($user['is_admin'] ?? false);
|
||||||
$user['is_adherent'] ||
|
$is_adherent = $user && ($user['is_adherent'] || $is_admin);
|
||||||
($user['is_admin'] ?? false)
|
$user_groups = $user['groups'] ?? [];
|
||||||
);
|
|
||||||
|
|
||||||
require __DIR__ . '/views/layout.php';
|
require __DIR__ . '/views/layout.php';
|
||||||
?>
|
?>
|
||||||
|
|
@ -69,7 +68,7 @@ require __DIR__ . '/views/layout.php';
|
||||||
<h2>Nos services</h2>
|
<h2>Nos services</h2>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<?php foreach ($services as $s): if (!$s['visible']) continue;
|
<?php foreach ($services as $s): if (!$s['visible']) continue;
|
||||||
$can_access = !$s['requires_adherent'] || $is_adherent; ?>
|
$can_access = service_accessible($s, $user_groups, $is_admin); ?>
|
||||||
<div class="service-card <?= $s['requires_adherent'] ? 'adherent-only' : '' ?> <?= (!$can_access) ? 'locked' : '' ?>">
|
<div class="service-card <?= $s['requires_adherent'] ? 'adherent-only' : '' ?> <?= (!$can_access) ? 'locked' : '' ?>">
|
||||||
<div class="service-header">
|
<div class="service-header">
|
||||||
<strong><?= htmlspecialchars($s['name']) ?></strong>
|
<strong><?= htmlspecialchars($s['name']) ?></strong>
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,12 @@ require __DIR__ . '/views/layout.php';
|
||||||
<div class="tile-header">
|
<div class="tile-header">
|
||||||
<div class="tile-label">
|
<div class="tile-label">
|
||||||
<div class="tile-title">Mon compte</div>
|
<div class="tile-title">Mon compte</div>
|
||||||
<div class="tile-sub"><?= htmlspecialchars($user['username']) ?></div>
|
<div class="tile-sub">
|
||||||
|
<?= htmlspecialchars($user['username']) ?>
|
||||||
|
<?php if ($user['is_admin']): ?>
|
||||||
|
<span class="badge badge-admin" style="margin-left:.4rem">Admin</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($edit !== 'email'): ?>
|
<?php if ($edit !== 'email'): ?>
|
||||||
<a href="?edit=email" class="btn-outline btn-sm tile-action">Modifier</a>
|
<a href="?edit=email" class="btn-outline btn-sm tile-action">Modifier</a>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue