/// Dialogue d'inscription à un événement library inscription_event_dialog; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../bloc/evenements_bloc.dart'; import '../../bloc/evenements_event.dart'; import '../../data/models/evenement_model.dart'; class InscriptionEventDialog extends StatefulWidget { final EvenementModel evenement; final bool isInscrit; const InscriptionEventDialog({ super.key, required this.evenement, this.isInscrit = false, }); @override State createState() => _InscriptionEventDialogState(); } class _InscriptionEventDialogState extends State { final _formKey = GlobalKey(); final _commentaireController = TextEditingController(); @override void dispose() { _commentaireController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Dialog( child: Container( width: MediaQuery.of(context).size.width * 0.9, constraints: const BoxConstraints(maxHeight: 500), child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildHeader(), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildEventInfo(), const SizedBox(height: 16), if (!widget.isInscrit) ...[ _buildPlacesInfo(), const SizedBox(height: 16), _buildCommentaireField(), ] else ...[ _buildDesinscriptionWarning(), ], ], ), ), ), ), _buildActionButtons(), ], ), ), ); } Widget _buildHeader() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: widget.isInscrit ? Colors.red : const Color(0xFF3B82F6), borderRadius: const BorderRadius.only( topLeft: Radius.circular(4), topRight: Radius.circular(4), ), ), child: Row( children: [ Icon( widget.isInscrit ? Icons.cancel : Icons.event_available, color: Colors.white, ), const SizedBox(width: 12), Expanded( child: Text( widget.isInscrit ? 'Se désinscrire' : 'S\'inscrire à l\'événement', style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ), IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.pop(context), ), ], ), ); } Widget _buildEventInfo() { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.blue[50], border: Border.all(color: Colors.blue[200]!), borderRadius: BorderRadius.circular(4), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.event, color: Color(0xFF3B82F6)), const SizedBox(width: 8), Expanded( child: Text( widget.evenement.titre, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 8), Row( children: [ const Icon(Icons.calendar_today, size: 16, color: Colors.grey), const SizedBox(width: 8), Text( _formatDate(widget.evenement.dateDebut), style: const TextStyle(fontSize: 14), ), ], ), if (widget.evenement.lieu != null) ...[ const SizedBox(height: 4), Row( children: [ const Icon(Icons.location_on, size: 16, color: Colors.grey), const SizedBox(width: 8), Expanded( child: Text( widget.evenement.lieu!, style: const TextStyle(fontSize: 14), ), ), ], ), ], ], ), ); } Widget _buildPlacesInfo() { final placesRestantes = (widget.evenement.maxParticipants ?? 0) - widget.evenement.participantsActuels; final isComplet = placesRestantes <= 0 && widget.evenement.maxParticipants != null; return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isComplet ? Colors.red[50] : Colors.green[50], border: Border.all( color: isComplet ? Colors.red[200]! : Colors.green[200]!, ), borderRadius: BorderRadius.circular(4), ), child: Row( children: [ Icon( isComplet ? Icons.warning : Icons.check_circle, color: isComplet ? Colors.red : Colors.green, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( isComplet ? 'Événement complet' : 'Places disponibles', style: TextStyle( fontWeight: FontWeight.bold, color: isComplet ? Colors.red[900] : Colors.green[900], ), ), if (widget.evenement.maxParticipants != null) Text( '$placesRestantes places restantes sur ${widget.evenement.maxParticipants}', style: const TextStyle(fontSize: 12), ) else const Text( 'Nombre de places illimité', style: TextStyle(fontSize: 12), ), ], ), ), ], ), ); } Widget _buildCommentaireField() { return TextFormField( controller: _commentaireController, decoration: const InputDecoration( labelText: 'Commentaire (optionnel)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.comment), hintText: 'Ajoutez un commentaire...', ), maxLines: 3, ); } Widget _buildDesinscriptionWarning() { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.orange[50], border: Border.all(color: Colors.orange[200]!), borderRadius: BorderRadius.circular(4), ), child: Row( children: [ const Icon(Icons.warning, color: Colors.orange), const SizedBox(width: 12), const Expanded( child: Text( 'Êtes-vous sûr de vouloir vous désinscrire de cet événement ?', style: TextStyle(fontSize: 14), ), ), ], ), ); } Widget _buildActionButtons() { final placesRestantes = (widget.evenement.maxParticipants ?? 0) - widget.evenement.participantsActuels; final isComplet = placesRestantes <= 0 && widget.evenement.maxParticipants != null; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[100], border: Border(top: BorderSide(color: Colors.grey[300]!)), ), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Annuler'), ), const SizedBox(width: 12), ElevatedButton( onPressed: (widget.isInscrit || !isComplet) ? _submitForm : null, style: ElevatedButton.styleFrom( backgroundColor: widget.isInscrit ? Colors.red : const Color(0xFF3B82F6), foregroundColor: Colors.white, ), child: Text(widget.isInscrit ? 'Se désinscrire' : 'S\'inscrire'), ), ], ), ); } String _formatDate(DateTime date) { final months = [ 'janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre' ]; return '${date.day} ${months[date.month - 1]} ${date.year} à ${date.hour}:${date.minute.toString().padLeft(2, '0')}'; } void _submitForm() { if (widget.isInscrit) { // Désinscription context.read().add(DesinscrireEvenement(widget.evenement.id!)); Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Désinscription réussie'), backgroundColor: Colors.orange, ), ); } else { // Inscription context.read().add( InscrireEvenement(widget.evenement.id!), ); Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Inscription réussie'), backgroundColor: Colors.green, ), ); } } }