import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../blocs/user/user_bloc.dart'; import '../../blocs/user/user_state.dart' as user_state; import '../../blocs/group/group_bloc.dart'; import '../../blocs/group/group_state.dart'; import '../../blocs/group/group_event.dart'; import '../../data/models/group.dart'; class GroupContent extends StatefulWidget { const GroupContent({super.key}); @override State createState() => _GroupContentState(); } class _GroupContentState extends State { @override void initState() { super.initState(); _loadInitialData(); } void _loadInitialData() { final userState = context.read().state; if (userState is user_state.UserLoaded) { // Charger les groupes de l'utilisateur connecté context.read().add(LoadGroupsByUserId(userState.user.id)); } } @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, userState) { if (userState is user_state.UserLoading) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } if (userState is user_state.UserError) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error, size: 64, color: Colors.red), const SizedBox(height: 16), Text('Erreur: ${userState.message}'), ], ), ), ); } if (userState is! user_state.UserLoaded) { return const Scaffold( body: Center(child: Text('Utilisateur non connecté')), ); } final user = userState.user; return BlocConsumer( listener: (context, groupState) { if (groupState is GroupOperationSuccess) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(groupState.message), backgroundColor: Colors.green, ), ); // Recharger les groupes après une opération réussie context.read().add(LoadGroupsByUserId(user.id)); } else if (groupState is GroupError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(groupState.message), backgroundColor: Colors.red, ), ); } }, builder: (context, groupState) { return Scaffold( body: RefreshIndicator( onRefresh: () async { context.read().add(LoadGroupsByUserId(user.id)); }, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // En-tête Text( 'Mes groupes', style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black, ), ), const SizedBox(height: 8), Text( 'Discutez avec les participants de vos voyages', style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ), const SizedBox(height: 24), // Contenu principal if (groupState is GroupLoading) _buildLoadingState() else if (groupState is GroupError) _buildErrorState(groupState.message, user.id) else if (groupState is GroupsLoaded) groupState.groups.isEmpty ? _buildEmptyState() : _buildGroupGrid(groupState.groups) else _buildEmptyState(), const SizedBox(height: 80), ], ), ), ), ); }, ); }, ); } Widget _buildLoadingState() { return const Center( child: Padding( padding: EdgeInsets.all(32), child: CircularProgressIndicator(), ), ); } Widget _buildErrorState(String error, String userId) { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error, size: 64, color: Colors.red), const SizedBox(height: 16), const Text( 'Erreur lors du chargement des groupes', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Text( error, textAlign: TextAlign.center, style: const TextStyle(fontSize: 12, color: Colors.grey), ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () { context.read().add(LoadGroupsByUserId(userId)); }, icon: const Icon(Icons.refresh), label: const Text('Réessayer'), ), ], ), ), ); } Widget _buildEmptyState() { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( children: [ Icon( Icons.forum_outlined, size: 80, color: Colors.grey[400], ), const SizedBox(height: 16), const Text( 'Aucun groupe', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( 'Les groupes sont créés automatiquement lorsque vous créez ou rejoignez un voyage', textAlign: TextAlign.center, style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ), ], ), ), ); } Widget _buildGroupGrid(List groups) { return GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 12, mainAxisSpacing: 12, childAspectRatio: 0.85, ), itemCount: groups.length, itemBuilder: (context, index) => _buildGroupCard(groups[index]), ); } Widget _buildGroupCard(Group group) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; final colors = [ Colors.blue, Colors.purple, Colors.green, Colors.orange, Colors.teal, Colors.pink, ]; final color = colors[group.name.hashCode.abs() % colors.length]; return Card( elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: InkWell( onTap: () => _openGroupChat(group), borderRadius: BorderRadius.circular(16), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ color.withOpacity(0.1), color.withOpacity(0.05), ], ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Avatar du groupe Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withOpacity(0.2), borderRadius: BorderRadius.circular(12), ), child: Icon( Icons.group, color: color, size: 32, ), ), const Spacer(), // Nom du groupe Text( group.name, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black87, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 8), // Nombre de membres Row( children: [ Icon( Icons.people, size: 16, color: Colors.grey[600], ), const SizedBox(width: 4), Text( '${group.members.length} membre${group.members.length > 1 ? 's' : ''}', style: TextStyle( fontSize: 13, color: Colors.grey[600], ), ), ], ), const SizedBox(height: 4), // Afficher les premiers membres if (group.members.isNotEmpty) Text( group.members.take(3).map((m) => m.pseudo).join(', ') + (group.members.length > 3 ? '...' : ''), style: TextStyle( fontSize: 11, color: Colors.grey[500], ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ), ); } void _openGroupChat(Group group) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Ouverture du chat: ${group.name}'), duration: const Duration(seconds: 1), ), ); // TODO: Navigation vers la page de chat // Navigator.push( // context, // MaterialPageRoute( // builder: (context) => GroupChatPage(group: group), // ), // ); } }