Galerie photos illimitée pour les rencontres passées + page publique dédiée + carrousel
Photos : - Nouvelle table rencontre_passee_photos (photos illimitées par rencontre passée, avec position). Migration idempotente au démarrage des anciennes colonnes image_path/_2/_3 vers cette table (puis colonnes nullées) - Le nombre de photos affiché est désormais celui réellement uploadé (calculé), le champ manuel nb_photos n'est plus utilisé - Gestion admin : ajout illimité, choix de la photo « principale » (mise en avant), suppression réservée aux admins (les modérateurs ajoutent et réordonnent mais ne suppriment pas) Participants auto : - rencontres_passees.rencontre_id (FK, ON DELETE SET NULL) ; quand une rencontre passée est liée à une rencontre, le nombre de participants est calculé depuis ses inscriptions ; sinon valeur manuelle de repli. Le formulaire admin propose la liaison et affiche le compte auto Public : - Nouvelle page /rencontres-passees (menu « Rencontres passées ») listant toutes les rencontres passées - Carrousel plein écran (composant Carousel) montrant TOUTES les photos (flèches, clavier ←/→/Échap, compteur, miniatures) ; ouvert au clic sur une carte. La grille d'accueil montre 3 aperçus avec badge « +N » et un lien « Voir toutes les rencontres → » - Composant PastEventCard partagé entre l'accueil et la page dédiée Vérifié : 34 + 21 + 26 tests existants au vert, 19 nouveaux tests (participants auto liés/déliés, upload illimité, nb_photos calculé, principale, restrictions modérateur sur suppression de photo, migration legacy des colonnes inline), parcours navigateur complet (galerie admin, page publique, carrousel). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
This commit is contained in:
13 files changed
+476
-139
No files matched your search
@@ -71,13 +71,14 @@ export const rencontrePasseeSchema = z.object({
|
||||
lieu: trimmed(200, 1),
|
||||
titre: trimmed(200, 1),
|
||||
texte: trimmed(2000, 1),
|
||||
participants: z.coerce.number().int().min(0).max(100000),
|
||||
nb_photos: z.coerce.number().int().min(0).max(100000),
|
||||
// Manual fallback participant count; ignored when rencontre_id is set.
|
||||
participants: z.coerce.number().int().min(0).max(100000).optional().default(0),
|
||||
rencontre_id: z.coerce.number().int().positive().nullable().optional(),
|
||||
});
|
||||
|
||||
export const pastEventImageParam = z.object({
|
||||
export const pastPhotoParam = z.object({
|
||||
id: z.coerce.number().int().positive(),
|
||||
slot: z.coerce.number().int().min(1).max(3),
|
||||
photoId: z.coerce.number().int().positive(),
|
||||
});
|
||||
|
||||
export const categorySchema = z.object({ name: trimmed(80, 1) });
|
||||
|
||||
Reference in new issue
Block a user