import 'package:flutter/material.dart'; import 'common/activity_item.dart'; /// Section des activités récentes du dashboard /// /// Widget réutilisable pour afficher les dernières activités, /// notifications, logs ou événements selon le contexte. class RecentActivitiesSection extends StatelessWidget { /// Titre de la section final String title; /// Sous-titre optionnel final String? subtitle; /// Liste des activités à afficher final List activities; /// Nombre maximum d'activités à afficher final int maxItems; /// Style des éléments d'activité final ActivityItemStyle itemStyle; /// Callback lors du tap sur une activité final Function(RecentActivity)? onActivityTap; /// Callback pour voir toutes les activités final VoidCallback? onViewAll; /// Afficher ou non l'en-tête de section final bool showHeader; /// Afficher ou non le bouton "Voir tout" final bool showViewAll; /// Message à afficher si aucune activité final String? emptyMessage; const RecentActivitiesSection({ super.key, required this.title, this.subtitle, required this.activities, this.maxItems = 5, this.itemStyle = ActivityItemStyle.normal, this.onActivityTap, this.onViewAll, this.showHeader = true, this.showViewAll = true, this.emptyMessage, }); /// Constructeur pour les activités système (Super Admin) const RecentActivitiesSection.system({ super.key, this.onActivityTap, this.onViewAll, }) : title = 'Activité Système', subtitle = 'Événements récents', activities = const [ RecentActivity( title: 'Sauvegarde automatique terminée', description: 'Sauvegarde complète réussie (2.3 GB)', timestamp: 'il y a 1h', type: ActivityType.system, ), RecentActivity( title: 'Nouvelle organisation créée', description: 'TechCorp a rejoint la plateforme', timestamp: 'il y a 2h', type: ActivityType.organization, ), RecentActivity( title: 'Mise à jour système', description: 'Version 2.1.0 déployée avec succès', timestamp: 'il y a 4h', type: ActivityType.system, ), RecentActivity( title: 'Alerte CPU résolue', description: 'Charge CPU revenue à la normale', timestamp: 'il y a 6h', type: ActivityType.success, ), ], maxItems = 4, itemStyle = ActivityItemStyle.normal, showHeader = true, showViewAll = true, emptyMessage = null; /// Constructeur pour les activités d'organisation const RecentActivitiesSection.organization({ super.key, this.onActivityTap, this.onViewAll, }) : title = 'Activité Récente', subtitle = null, activities = const [ RecentActivity( title: 'Nouveau membre inscrit', description: 'Marie Dubois a rejoint l\'organisation', timestamp: 'il y a 30min', type: ActivityType.user, ), RecentActivity( title: 'Événement créé', description: 'Réunion mensuelle programmée', timestamp: 'il y a 2h', type: ActivityType.event, ), RecentActivity( title: 'Document partagé', description: 'Rapport Q4 2024 publié', timestamp: 'il y a 1j', type: ActivityType.organization, ), ], maxItems = 3, itemStyle = ActivityItemStyle.normal, showHeader = true, showViewAll = true, emptyMessage = null; /// Constructeur pour les alertes système const RecentActivitiesSection.alerts({ super.key, this.onActivityTap, this.onViewAll, }) : title = 'Alertes Récentes', subtitle = 'Notifications importantes', activities = const [ RecentActivity( title: 'Charge CPU élevée', description: 'Serveur principal à 85%', timestamp: 'il y a 15min', type: ActivityType.alert, ), RecentActivity( title: 'Espace disque faible', description: 'Base de données à 90%', timestamp: 'il y a 1h', type: ActivityType.error, ), RecentActivity( title: 'Connexions élevées', description: 'Load balancer surchargé', timestamp: 'il y a 2h', type: ActivityType.alert, ), ], maxItems = 3, itemStyle = ActivityItemStyle.alert, showHeader = true, showViewAll = true, emptyMessage = null; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (showHeader) _buildHeader(), const SizedBox(height: 12), _buildActivitiesList(), ], ), ); } /// En-tête de la section Widget _buildHeader() { return Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF6C5CE7), ), ), if (subtitle != null) ...[ const SizedBox(height: 2), Text( subtitle!, style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ], ), ), if (showViewAll && onViewAll != null) TextButton( onPressed: onViewAll, child: const Text( 'Voir tout', style: TextStyle( fontSize: 12, color: Color(0xFF6C5CE7), fontWeight: FontWeight.w600, ), ), ), ], ); } /// Liste des activités Widget _buildActivitiesList() { if (activities.isEmpty) { return _buildEmptyState(); } final displayedActivities = activities.take(maxItems).toList(); return Column( children: displayedActivities.map((activity) => ActivityItem( title: activity.title, description: activity.description, timestamp: activity.timestamp, icon: activity.icon, color: activity.color, type: activity.type, style: itemStyle, onTap: onActivityTap != null ? () => onActivityTap!(activity) : null, )).toList(), ); } /// État vide Widget _buildEmptyState() { return Container( padding: const EdgeInsets.all(24), child: Column( children: [ Icon( Icons.inbox_outlined, size: 48, color: Colors.grey[400], ), const SizedBox(height: 12), Text( emptyMessage ?? 'Aucune activité récente', style: TextStyle( fontSize: 14, color: Colors.grey[600], ), textAlign: TextAlign.center, ), ], ), ); } } /// Modèle de données pour une activité récente class RecentActivity { final String title; final String? description; final String timestamp; final IconData? icon; final Color? color; final ActivityType? type; final Map? metadata; const RecentActivity({ required this.title, this.description, required this.timestamp, this.icon, this.color, this.type, this.metadata, }); /// Constructeur pour une activité système const RecentActivity.system({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.settings, color = const Color(0xFF6C5CE7), type = ActivityType.system; /// Constructeur pour une activité utilisateur const RecentActivity.user({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.person, color = const Color(0xFF00B894), type = ActivityType.user; /// Constructeur pour une activité d'organisation const RecentActivity.organization({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.business, color = const Color(0xFF0984E3), type = ActivityType.organization; /// Constructeur pour une activité d'événement const RecentActivity.event({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.event, color = const Color(0xFFE17055), type = ActivityType.event; /// Constructeur pour une alerte const RecentActivity.alert({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.warning, color = Colors.orange, type = ActivityType.alert; /// Constructeur pour une erreur const RecentActivity.error({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.error, color = Colors.red, type = ActivityType.error; /// Constructeur pour un succès const RecentActivity.success({ required this.title, this.description, required this.timestamp, this.metadata, }) : icon = Icons.check_circle, color = const Color(0xFF00B894), type = ActivityType.success; }