/// Widget de ligne de métrique avec barre de progression /// Affiche une métrique avec label, valeur et indicateur visuel library dashboard_metric_row; import 'package:flutter/material.dart'; import '../../../../core/design_system/tokens/spacing_tokens.dart'; import '../../../../core/design_system/tokens/typography_tokens.dart'; /// Modèle de données pour une métrique class DashboardMetric { /// Label descriptif de la métrique final String label; /// Valeur formatée à afficher final String value; /// Progression entre 0.0 et 1.0 final double progress; /// Couleur thématique de la métrique final Color color; /// Callback optionnel lors du tap sur la métrique final VoidCallback? onTap; /// Constructeur du modèle de métrique const DashboardMetric({ required this.label, required this.value, required this.progress, required this.color, this.onTap, }); } /// Widget de ligne de métrique /// /// Affiche une métrique avec : /// - Label et valeur alignés horizontalement /// - Barre de progression colorée /// - Design compact et lisible /// - Support du tap pour détails class DashboardMetricRow extends StatelessWidget { /// Données de la métrique à afficher final DashboardMetric metric; /// Constructeur de la ligne de métrique const DashboardMetricRow({ super.key, required this.metric, }); @override Widget build(BuildContext context) { return InkWell( onTap: metric.onTap, borderRadius: BorderRadius.circular(SpacingTokens.radiusSm), child: Padding( padding: const EdgeInsets.symmetric(vertical: SpacingTokens.xs), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( metric.label, style: TypographyTokens.bodySmall.copyWith( fontWeight: FontWeight.w500, ), ), Text( metric.value, style: TypographyTokens.labelLarge.copyWith( fontWeight: FontWeight.w600, color: metric.color, ), ), ], ), const SizedBox(height: SpacingTokens.xs), LinearProgressIndicator( value: metric.progress, backgroundColor: metric.color.withOpacity(0.1), valueColor: AlwaysStoppedAnimation(metric.color), minHeight: 4, ), ], ), ), ); } }