import 'package:flutter/material.dart'; import 'common/section_header.dart'; import 'common/stat_card.dart'; /// Section des statistiques rapides du dashboard /// /// Widget réutilisable pour afficher les KPIs et métriques principales /// avec différents layouts et styles selon le contexte. class QuickStatsSection extends StatelessWidget { /// Titre de la section final String title; /// Sous-titre optionnel final String? subtitle; /// Liste des statistiques à afficher final List stats; /// Layout des cartes (grid, row, column) final StatsLayout layout; /// Nombre de colonnes pour le layout grid final int gridColumns; /// Style des cartes de statistiques final StatCardStyle cardStyle; /// Taille des cartes final StatCardSize cardSize; /// Callback lors du tap sur une statistique final Function(QuickStat)? onStatTap; /// Afficher ou non l'en-tête de section final bool showHeader; const QuickStatsSection({ super.key, required this.title, this.subtitle, required this.stats, this.layout = StatsLayout.grid, this.gridColumns = 2, this.cardStyle = StatCardStyle.elevated, this.cardSize = StatCardSize.compact, this.onStatTap, this.showHeader = true, }); /// Constructeur pour les KPIs système (Super Admin) const QuickStatsSection.systemKPIs({ super.key, this.onStatTap, }) : title = 'Métriques Système', subtitle = null, stats = const [ QuickStat( title: 'Organisations', value: '247', subtitle: '+12 ce mois', icon: Icons.business, color: Color(0xFF0984E3), ), QuickStat( title: 'Utilisateurs', value: '15,847', subtitle: '+1,234 ce mois', icon: Icons.people, color: Color(0xFF00B894), ), QuickStat( title: 'Uptime', value: '99.97%', subtitle: '30 derniers jours', icon: Icons.trending_up, color: Color(0xFF00CEC9), ), QuickStat( title: 'Temps Réponse', value: '1.2s', subtitle: 'Moyenne 24h', icon: Icons.speed, color: Color(0xFFE17055), ), ], layout = StatsLayout.grid, gridColumns = 2, cardStyle = StatCardStyle.elevated, cardSize = StatCardSize.compact, showHeader = true; /// Constructeur pour les statistiques d'organisation const QuickStatsSection.organizationStats({ super.key, this.onStatTap, }) : title = 'Vue d\'ensemble', subtitle = null, stats = const [ QuickStat( title: 'Membres', value: '156', subtitle: '+12 ce mois', icon: Icons.people, color: Color(0xFF00B894), ), QuickStat( title: 'Événements', value: '23', subtitle: '8 à venir', icon: Icons.event, color: Color(0xFFE17055), ), QuickStat( title: 'Projets', value: '8', subtitle: '3 actifs', icon: Icons.work, color: Color(0xFF0984E3), ), QuickStat( title: 'Taux engagement', value: '78%', subtitle: '+5% ce mois', icon: Icons.trending_up, color: Color(0xFF6C5CE7), ), ], layout = StatsLayout.grid, gridColumns = 2, cardStyle = StatCardStyle.elevated, cardSize = StatCardSize.compact, showHeader = true; /// Constructeur pour les métriques de performance const QuickStatsSection.performanceMetrics({ super.key, this.onStatTap, }) : title = 'Performance', subtitle = 'Métriques temps réel', stats = const [ QuickStat( title: 'CPU', value: '23%', subtitle: 'Normal', icon: Icons.memory, color: Color(0xFF00B894), ), QuickStat( title: 'RAM', value: '67%', subtitle: 'Élevé', icon: Icons.storage, color: Color(0xFFE17055), ), QuickStat( title: 'Réseau', value: '12 MB/s', subtitle: 'Stable', icon: Icons.network_check, color: Color(0xFF0984E3), ), ], layout = StatsLayout.row, gridColumns = 3, cardStyle = StatCardStyle.outlined, cardSize = StatCardSize.normal, showHeader = true; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (showHeader) ...[ SectionHeader.section( title: title, subtitle: subtitle, ), ], _buildStatsLayout(), ], ); } /// Construction du layout des statistiques Widget _buildStatsLayout() { switch (layout) { case StatsLayout.grid: return _buildGridLayout(); case StatsLayout.row: return _buildRowLayout(); case StatsLayout.column: return _buildColumnLayout(); case StatsLayout.wrap: return _buildWrapLayout(); } } /// Layout en grille Widget _buildGridLayout() { return GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: gridColumns, crossAxisSpacing: 8, mainAxisSpacing: 8, childAspectRatio: _getChildAspectRatio(), ), itemCount: stats.length, itemBuilder: (context, index) => _buildStatCard(stats[index]), ); } /// Layout en ligne Widget _buildRowLayout() { return Row( children: stats.map((stat) => Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: _buildStatCard(stat), ), )).toList(), ); } /// Layout en colonne Widget _buildColumnLayout() { return Column( children: stats.map((stat) => Padding( padding: const EdgeInsets.only(bottom: 8), child: _buildStatCard(stat), )).toList(), ); } /// Layout wrap (adaptatif) Widget _buildWrapLayout() { return LayoutBuilder( builder: (context, constraints) { return Wrap( spacing: 8, runSpacing: 8, children: stats.map((stat) => SizedBox( width: (constraints.maxWidth - 8) / 2, // 2 colonnes avec espacement child: _buildStatCard(stat), )).toList(), ); }, ); } /// Construction d'une carte de statistique Widget _buildStatCard(QuickStat stat) { return StatCard( title: stat.title, value: stat.value, subtitle: stat.subtitle, icon: stat.icon, color: stat.color, size: cardSize, style: cardStyle, onTap: onStatTap != null ? () => onStatTap!(stat) : null, ); } /// Ratio d'aspect selon la taille des cartes double _getChildAspectRatio() { switch (cardSize) { case StatCardSize.compact: return 1.4; case StatCardSize.normal: return 1.2; case StatCardSize.large: return 1.0; } } } /// Modèle de données pour une statistique rapide class QuickStat { final String title; final String value; final String subtitle; final IconData icon; final Color color; final Map? metadata; const QuickStat({ required this.title, required this.value, required this.subtitle, required this.icon, required this.color, this.metadata, }); /// Constructeur pour une métrique système const QuickStat.system({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = const Color(0xFF6C5CE7), metadata = null; /// Constructeur pour une métrique utilisateur const QuickStat.user({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = const Color(0xFF00B894), metadata = null; /// Constructeur pour une métrique d'organisation const QuickStat.organization({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = const Color(0xFF0984E3), metadata = null; /// Constructeur pour une métrique d'événement const QuickStat.event({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = const Color(0xFFE17055), metadata = null; /// Constructeur pour une alerte const QuickStat.alert({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = Colors.orange, metadata = null; /// Constructeur pour une erreur const QuickStat.error({ required this.title, required this.value, required this.subtitle, required this.icon, }) : color = Colors.red, metadata = null; } /// Types de layout pour les statistiques enum StatsLayout { grid, row, column, wrap, }