Gestion des rencontres passées + interdiction des actions destructrices aux modérateurs
Rencontres passées (section « Ils y étaient » de l'accueil) : - Nouvel onglet « Rencontres passées » (admin + modérateur) : création, édition, jusqu'à 3 photos par rencontre (1 grande + 2 petites, upload après enregistrement — même schéma que la photo des rencontres à venir) - Nouvelles colonnes rencontres_passees.image_path/_2/_3 (migration ALTER TABLE IF NOT EXISTS) - Home.jsx affiche désormais les vraies photos uploadées (repli sur le motif placeholder si absentes) ; ordre passé de ORDER BY id à ORDER BY id DESC (les plus récentes en premier, seed réordonné en conséquence pour préserver l'affichage actuel) - Suppression réservée aux administrateurs Modérateurs : plus aucune action destructrice possible, imposé côté serveur (adminOnly) et masqué côté interface : - Validation/suspension d'un membre (toggle-valide) - Suppression d'une rencontre, d'une rencontre passée, d'une inscription Vérifié : 34 + 21 + 26 tests existants toujours au vert, 21 nouveaux tests (CRUD rencontres passées, upload des 3 emplacements photo, ordre d'affichage, restrictions modérateur sur chaque action désormais admin- only), parcours navigateur complet (upload des 3 photos, rendu réel sur la page d'accueil). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
This commit is contained in:
11 files changed
+426
-55
No files matched your search
@@ -4,15 +4,18 @@ import { useAuth } from '../lib/AuthContext.jsx';
|
||||
import { api, dateParts, statutLabel } from '../lib/api.js';
|
||||
import { MembersTab, RencontresTab, InscriptionsTab } from '../components/admin/AdminTabs.jsx';
|
||||
import { CategoriesTab, ContenuTab } from '../components/admin/AdminContent.jsx';
|
||||
import { PastEventsTab } from '../components/admin/AdminPast.jsx';
|
||||
import { UsersTab } from '../components/admin/AdminUsers.jsx';
|
||||
|
||||
// Moderators only get members/rencontres/inscriptions — everything else
|
||||
// (dashboard, taxonomy, site content, staff account management) is
|
||||
// admin-only, enforced both here (sidebar) and server-side (routes).
|
||||
// Moderators only get members/rencontres/inscriptions/rencontres passées
|
||||
// (create + edit, never delete) — everything else (dashboard, taxonomy,
|
||||
// site content, staff account management) is admin-only, enforced both
|
||||
// here (sidebar) and server-side (routes).
|
||||
const TABS = [
|
||||
{ key: 'dashboard', icon: '◧', label: 'Tableau de bord', title: 'Tableau de bord', roles: ['admin'] },
|
||||
{ key: 'membres', icon: '▤', label: 'Membres', title: 'Gestion des membres', roles: ['admin', 'moderator'] },
|
||||
{ key: 'rencontres', icon: '◈', label: 'Rencontres', title: 'Rencontres', roles: ['admin', 'moderator'] },
|
||||
{ key: 'passees', icon: '▦', label: 'Rencontres passées', title: 'Rencontres passées', roles: ['admin', 'moderator'] },
|
||||
{ key: 'inscriptions', icon: '✎', label: 'Inscriptions', title: 'Inscriptions', roles: ['admin', 'moderator'] },
|
||||
{ key: 'categories', icon: '☲', label: 'Catégories', title: 'Catégories', roles: ['admin'] },
|
||||
{ key: 'contenu', icon: '▧', label: 'Contenu du site', title: 'Contenu du site', roles: ['admin'] },
|
||||
@@ -143,6 +146,7 @@ export function AdminShell() {
|
||||
{tab === 'dashboard' && <Dashboard />}
|
||||
{tab === 'membres' && <MembersTab />}
|
||||
{tab === 'rencontres' && <RencontresTab />}
|
||||
{tab === 'passees' && <PastEventsTab />}
|
||||
{tab === 'inscriptions' && <InscriptionsTab />}
|
||||
{tab === 'categories' && <CategoriesTab />}
|
||||
{tab === 'contenu' && <ContenuTab />}
|
||||
|
||||
Reference in new issue
Block a user