/// Widget de section d'insights du dashboard /// Affiche les métriques de performance dans une carte library dashboard_insights_section; 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_metric_row.dart'; /// Widget de section d'insights /// /// Affiche les métriques de performance : /// - Taux de cotisation /// - Participation aux événements /// - Demandes traitées /// /// Chaque métrique peut être tapée pour plus de détails class DashboardInsightsSection extends StatelessWidget { /// Callback pour les actions sur les métriques final Function(String metricType)? onMetricTap; /// Liste des métriques à afficher final List? metrics; /// Constructeur de la section d'insights const DashboardInsightsSection({ super.key, this.onMetricTap, this.metrics, }); /// Génère la liste des métriques par défaut List _getDefaultMetrics() { return [ DashboardMetric( label: 'Taux de cotisation', value: '85%', progress: 0.85, color: ColorTokens.success, onTap: () => onMetricTap?.call('cotisation_rate'), ), DashboardMetric( label: 'Participation événements', value: '72%', progress: 0.72, color: ColorTokens.primary, onTap: () => onMetricTap?.call('event_participation'), ), DashboardMetric( label: 'Demandes traitées', value: '95%', progress: 0.95, color: ColorTokens.tertiary, onTap: () => onMetricTap?.call('requests_processed'), ), ]; } @override Widget build(BuildContext context) { final metricsToShow = metrics ?? _getDefaultMetrics(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Insights', style: TypographyTokens.headlineSmall.copyWith( fontWeight: FontWeight.w700, ), ), const SizedBox(height: SpacingTokens.md), Card( elevation: 1, child: Padding( padding: const EdgeInsets.all(SpacingTokens.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Performance ce mois-ci', style: TypographyTokens.titleSmall.copyWith( fontWeight: FontWeight.w600, ), ), const SizedBox(height: SpacingTokens.md), ...metricsToShow.map((metric) { final isLast = metric == metricsToShow.last; return Column( children: [ DashboardMetricRow(metric: metric), if (!isLast) const SizedBox(height: SpacingTokens.sm), ], ); }), ], ), ), ), ], ); } }