Files
unionflow-server-api/unionflow-mobile-apps/lib/features/dashboard/presentation/widgets/dashboard_stats_card.dart
2025-09-19 12:35:46 +00:00

95 lines
2.6 KiB
Dart

/// Widget de carte de statistique individuelle
/// Affiche une métrique avec icône, valeur et titre
library dashboard_stats_card;
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';
/// Modèle de données pour une statistique
class DashboardStat {
/// Icône représentative de la statistique
final IconData icon;
/// Valeur numérique à afficher
final String value;
/// Titre descriptif de la statistique
final String title;
/// Couleur thématique de la carte
final Color color;
/// Callback optionnel lors du tap sur la carte
final VoidCallback? onTap;
/// Constructeur du modèle de statistique
const DashboardStat({
required this.icon,
required this.value,
required this.title,
required this.color,
this.onTap,
});
}
/// Widget de carte de statistique
///
/// Affiche une métrique individuelle avec :
/// - Icône colorée thématique
/// - Valeur numérique mise en évidence
/// - Titre descriptif
/// - Design Material avec élévation subtile
/// - Support du tap pour navigation
class DashboardStatsCard extends StatelessWidget {
/// Données de la statistique à afficher
final DashboardStat stat;
/// Constructeur de la carte de statistique
const DashboardStatsCard({
super.key,
required this.stat,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 1,
child: InkWell(
onTap: stat.onTap,
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
stat.icon,
size: 28,
color: stat.color,
),
const SizedBox(height: SpacingTokens.sm),
Text(
stat.value,
style: TypographyTokens.headlineSmall.copyWith(
fontWeight: FontWeight.w700,
color: stat.color,
),
),
const SizedBox(height: SpacingTokens.xs),
Text(
stat.title,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
],
),
),
),
);
}
}