import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; // Pour la gestion des logs. import '../../../data/models/event_model.dart'; import '../../widgets/event_header.dart'; import '../../widgets/event_image.dart'; import '../../widgets/event_interaction_row.dart'; import '../../widgets/event_status_badge.dart'; import '../../widgets/swipe_background.dart'; /// Widget représentant une carte d'événement affichant les informations /// principales de l'événement avec diverses options d'interaction. class EventCard extends StatefulWidget { final EventModel event; // Modèle de données pour l'événement. final String userId; // ID de l'utilisateur affichant l'événement. final String userFirstName; // Prénom de l'utilisateur. final String userLastName; // Nom de l'utilisateur. final String profileImageUrl; // Image de profile final String status; // Statut de l'événement (ouvert ou fermé). final VoidCallback onReact; // Callback pour réagir à l'événement. final VoidCallback onComment; // Callback pour commenter l'événement. final VoidCallback onShare; // Callback pour partager l'événement. final VoidCallback onParticipate; // Callback pour participer à l'événement. final VoidCallback onCloseEvent; // Callback pour fermer l'événement. final VoidCallback onReopenEvent; // Callback pour rouvrir l'événement. final Function onRemoveEvent; // Fonction pour supprimer l'événement. const EventCard({ Key? key, required this.event, required this.userId, required this.userFirstName, required this.userLastName, required this.profileImageUrl, required this.status, required this.onReact, required this.onComment, required this.onShare, required this.onParticipate, required this.onCloseEvent, required this.onReopenEvent, required this.onRemoveEvent, }) : super(key: key); @override _EventCardState createState() => _EventCardState(); } class _EventCardState extends State { bool _isExpanded = false; // Contrôle si la description est développée. static const int _descriptionThreshold = 100; // Limite de caractères. bool _isClosed = false; // Ajout d'une variable pour suivre l'état de l'événement. final Logger _logger = Logger(); @override void initState() { super.initState(); _isClosed = widget.event.status == 'fermé'; // Initialiser l'état selon le statut de l'événement. } @override Widget build(BuildContext context) { _logger.i("Construction de la carte d'événement"); // Log pour la construction du widget. final GlobalKey menuKey = GlobalKey(); // Clé pour le menu contextuel. final String descriptionText = widget.event.description; // Description de l'événement. final bool shouldTruncate = descriptionText.length > _descriptionThreshold; // Détermine si le texte doit être tronqué. return Dismissible( key: ValueKey(widget.event.id), // Clé unique pour chaque carte d'événement. direction: widget.event.status == 'fermé' // Direction du glissement basée sur le statut. ? DismissDirection.startToEnd : DismissDirection.endToStart, onDismissed: (direction) { // Action déclenchée lors d'un glissement. if (_isClosed) { _logger.i("Rouverte de l'événement ${widget.event.id}"); widget.onReopenEvent(); setState(() { _isClosed = false; // Mise à jour de l'état local. }); } else { _logger.i("Fermeture de l'événement ${widget.event.id}"); widget.onCloseEvent(); widget.onRemoveEvent(widget.event.id); // Suppression de l'événement. setState(() { _isClosed = true; // Mise à jour de l'état local. }); } }, background: SwipeBackground( // Arrière-plan pour les actions de glissement. color: _isClosed ? Colors.green : Colors.red, icon: _isClosed ? Icons.lock_open : Icons.lock, label: _isClosed ? 'Rouvrir' : 'Fermer', ), child: Card( color: const Color(0xFF2C2C3E), // Couleur de fond de la carte. margin: const EdgeInsets.symmetric(vertical: 10.0), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)), // Bordure arrondie. child: Padding( padding: const EdgeInsets.all(12.0), // Marge intérieure de la carte. child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Affichage de l'en-tête de l'événement. EventHeader( creatorFirstName: widget.event.creatorFirstName, creatorLastName: widget.event.creatorLastName, profileImageUrl: widget.event.profileImageUrl, eventDate: widget.event.startDate, imageUrl: widget.event.imageUrl, menuKey: menuKey, menuContext: context, location: widget.event.location, onClose: () { _logger.i("Menu de fermeture actionné pour l'événement ${widget.event.id}"); }, ), const Divider(color: Colors.white24), // Ligne de séparation visuelle. Row( children: [ const Spacer(), // Pousse le badge de statut à droite. EventStatusBadge(status: widget.status), // Badge de statut. ], ), Text( widget.event.title, // Titre de l'événement. style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 5), // Espacement entre le titre et la description. GestureDetector( onTap: () { setState(() { _isExpanded = !_isExpanded; // Change l'état d'expansion. }); _logger.i("Changement d'état d'expansion pour la description de l'événement ${widget.event.id}"); }, child: Text( _isExpanded || !shouldTruncate ? descriptionText : "${descriptionText.substring(0, _descriptionThreshold)}...", style: const TextStyle(color: Colors.white70, fontSize: 14), maxLines: _isExpanded ? null : 3, overflow: _isExpanded ? TextOverflow.visible : TextOverflow.ellipsis, ), ), if (shouldTruncate) // Bouton "Afficher plus" si la description est longue. GestureDetector( onTap: () { setState(() { _isExpanded = !_isExpanded; }); _logger.i("Affichage de la description complète de l'événement ${widget.event.id}"); }, child: Text( _isExpanded ? "Afficher moins" : "Afficher plus", style: const TextStyle( color: Colors.blue, fontSize: 10, fontWeight: FontWeight.bold, ), ), ), const SizedBox(height: 10), // Espacement avant l'image. EventImage(imageUrl: widget.event.imageUrl), // Affichage de l'image de l'événement. const Divider(color: Colors.white24), // Nouvelle ligne de séparation. // Rangée pour les interactions de l'événement (réagir, commenter, partager). EventInteractionRow( onReact: widget.onReact, onComment: widget.onComment, onShare: widget.onShare, reactionsCount: widget.event.reactionsCount, commentsCount: widget.event.commentsCount, sharesCount: widget.event.sharesCount, ), ], ), ), ), ); } }