/// Widget de grille de statistiques du dashboard /// Affiche les métriques principales dans une grille responsive library dashboard_stats_grid; import 'package:flutter/material.dart'; import '../../../../core/design_system/tokens/color_tokens.dart'; import '../../../../core/design_system/tokens/spacing_tokens.dart'; import '../../../../core/design_system/tokens/typography_tokens.dart'; import 'dashboard_stats_card.dart'; /// Widget de grille de statistiques /// /// Affiche les statistiques principales dans une grille 2x2 : /// - Membres actifs /// - Cotisations du mois /// - Événements programmés /// - Demandes de solidarité /// /// Chaque carte est interactive et peut déclencher une navigation class DashboardStatsGrid extends StatelessWidget { /// Callback pour les actions sur les statistiques final Function(String statType)? onStatTap; /// Liste des statistiques à afficher final List? stats; /// Constructeur de la grille de statistiques const DashboardStatsGrid({ super.key, this.onStatTap, this.stats, }); /// Génère la liste des statistiques par défaut List _getDefaultStats() { return [ DashboardStat( icon: Icons.people, value: '25', title: 'Membres', color: ColorTokens.primary, onTap: () => onStatTap?.call('members'), ), DashboardStat( icon: Icons.account_balance_wallet, value: '15', title: 'Cotisations', color: ColorTokens.success, onTap: () => onStatTap?.call('cotisations'), ), DashboardStat( icon: Icons.event, value: '8', title: 'Événements', color: ColorTokens.tertiary, onTap: () => onStatTap?.call('events'), ), DashboardStat( icon: Icons.favorite, value: '3', title: 'Solidarité', color: ColorTokens.error, onTap: () => onStatTap?.call('solidarity'), ), ]; } @override Widget build(BuildContext context) { final statsToShow = stats ?? _getDefaultStats(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Statistiques', style: TypographyTokens.headlineSmall.copyWith( fontWeight: FontWeight.w700, ), ), const SizedBox(height: SpacingTokens.md), GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: SpacingTokens.md, mainAxisSpacing: SpacingTokens.md, childAspectRatio: 1.4, ), itemCount: statsToShow.length, itemBuilder: (context, index) { return DashboardStatsCard(stat: statsToShow[index]); }, ), ], ); } }