import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../../shared/design_system/unionflow_design_system.dart'; import '../../../../../shared/widgets/core_card.dart'; import '../../../../../shared/widgets/mini_avatar.dart'; import '../../../../events/presentation/pages/events_page_wrapper.dart'; import '../../../../members/presentation/pages/members_page_wrapper.dart'; import '../../../../adhesions/presentation/pages/adhesions_page_wrapper.dart'; import '../../../../solidarity/presentation/pages/demandes_aide_page_wrapper.dart'; import '../../bloc/dashboard_bloc.dart'; import '../../../domain/entities/dashboard_entity.dart'; /// Widget des activités récentes connecté au backend class ConnectedRecentActivities extends StatelessWidget { final int maxItems; final VoidCallback? onSeeAll; const ConnectedRecentActivities({ super.key, this.maxItems = 5, this.onSeeAll, }); @override Widget build(BuildContext context) { return CoreCard( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(), const SizedBox(height: 8), BlocBuilder( builder: (context, state) { if (state is DashboardLoading) { return _buildLoadingList(); } else if (state is DashboardLoaded || state is DashboardRefreshing) { final data = state is DashboardLoaded ? state.dashboardData : (state as DashboardRefreshing).dashboardData; return _buildActivitiesList(context, data.recentActivities); } else if (state is DashboardError) { return _buildErrorState(state.message); } return _buildEmptyState(); }, ), ], ), ); } Widget _buildHeader() { return Row( children: [ const Icon( Icons.history, color: AppColors.primaryGreen, size: 18, ), const SizedBox(width: 8), Expanded( child: Text( 'ACTIVITÉS RÉCENTES', style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1), ), ), if (onSeeAll != null) GestureDetector( onTap: onSeeAll, child: Text( 'TOUT VOIR', style: AppTypography.badgeText.copyWith( color: AppColors.primaryGreen, fontWeight: FontWeight.bold, ), ), ), ], ); } Widget _buildActivitiesList(BuildContext context, List activities) { if (activities.isEmpty) { return _buildEmptyState(); } final displayActivities = activities.take(maxItems).toList(); return Column( children: displayActivities.asMap().entries.map((entry) { final index = entry.key; final activity = entry.value; final isLast = index == displayActivities.length - 1; return Column( children: [ _buildActivityItem(context, activity), if (!isLast) const SizedBox(height: 12), ], ); }).toList(), ); } Widget _buildActivityItem(BuildContext context, RecentActivityEntity activity) { return InkWell( onTap: () => _navigateForActivity(context, activity), borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ MiniAvatar( fallbackText: activity.userName.isNotEmpty ? activity.userName[0].toUpperCase() : '?', imageUrl: activity.userAvatar, size: 32, ), const SizedBox(width: 12), // Contenu Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( activity.title, style: AppTypography.actionText.copyWith(fontSize: 12), maxLines: 1, overflow: TextOverflow.ellipsis, ), Text( activity.description, style: AppTypography.subtitleSmall.copyWith(fontSize: 10), maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 2), Row( children: [ Text( activity.userName, style: AppTypography.subtitleSmall.copyWith( fontWeight: FontWeight.w600, color: AppColors.primaryGreen, fontSize: 9, ), ), Text( ' • ${activity.timeAgo}', style: AppTypography.subtitleSmall.copyWith(fontSize: 9), ), ], ), ], ), ), // Action button si disponible if (activity.hasAction) const Icon( Icons.chevron_right, size: 14, color: AppColors.textSecondaryLight, ), ], ), ), ); } void _navigateForActivity(BuildContext context, RecentActivityEntity activity) { final type = activity.type.toLowerCase(); Widget? page; if (type.contains('event') || type.contains('evenement')) { page = const EventsPageWrapper(); } else if (type.contains('member') || type.contains('membre')) { page = const MembersPageWrapper(); } else if (type.contains('adhesion') || type.contains('adhésion')) { page = const AdhesionsPageWrapper(); } else if (type.contains('demande') || type.contains('solidarite') || type.contains('aide')) { page = const DemandesAidePageWrapper(); } if (page != null) { Navigator.of(context).push(MaterialPageRoute(builder: (context) => page!)); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(activity.title)), ); } } Widget _buildLoadingList() { return Column( children: List.generate(3, (index) => Column( children: [ _buildLoadingItem(), if (index < 2) const SizedBox(height: 12), ], )), ); } Widget _buildLoadingItem() { return Row( children: [ Container( width: 28, height: 28, decoration: BoxDecoration( color: AppColors.lightBorder, borderRadius: BorderRadius.circular(14), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 16, width: double.infinity, decoration: BoxDecoration( color: AppColors.lightBorder, borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 4), Container( height: 12, width: 200, decoration: BoxDecoration( color: AppColors.lightBorder.withOpacity(0.5), borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 4), Container( height: 12, width: 120, decoration: BoxDecoration( color: AppColors.lightBorder.withOpacity(0.5), borderRadius: BorderRadius.circular(4), ), ), ], ), ), ], ); } Widget _buildErrorState(String message) { return Center( child: Column( children: [ const Icon(Icons.error_outline, color: AppColors.error, size: 32), const SizedBox(height: 8), Text(message, style: AppTypography.subtitleSmall.copyWith(color: AppColors.error)), ], ), ); } Widget _buildEmptyState() { return Center( child: Column( children: [ const Icon(Icons.history, color: AppColors.textSecondaryLight, size: 32), const SizedBox(height: 8), const Text('AUCUNE ACTIVITÉ', style: AppTypography.subtitleSmall), Text('Les activités apparaîtront ici', style: AppTypography.subtitleSmall.copyWith(fontSize: 10)), ], ), ); } IconData _getActivityIcon(String type) { switch (type.toLowerCase()) { case 'member': return Icons.person_add; case 'event': return Icons.event; case 'contribution': return Icons.payment; case 'organization': return Icons.business; case 'system': return Icons.settings; default: return Icons.notifications; } } Color _getActivityColor(String type) { switch (type.toLowerCase()) { case 'member': return AppColors.success; case 'event': return AppColors.info; case 'contribution': return AppColors.brandGreen; case 'organization': return AppColors.primaryGreen; case 'system': return AppColors.warning; default: return AppColors.textSecondaryLight; } } }