import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../../shared/design_system/unionflow_design_system.dart'; import '../../../../../shared/widgets/core_card.dart'; import '../../bloc/dashboard_bloc.dart'; import '../../../domain/entities/dashboard_entity.dart'; /// Widget de carte de statistiques connecté au backend class ConnectedStatsCard extends StatelessWidget { final String title; final IconData icon; final String Function(DashboardStatsEntity) valueExtractor; final String? Function(DashboardStatsEntity)? subtitleExtractor; final Color? customColor; final VoidCallback? onTap; const ConnectedStatsCard({ super.key, required this.title, required this.icon, required this.valueExtractor, this.subtitleExtractor, this.customColor, this.onTap, }); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state is DashboardLoading) { return _buildLoadingCard(); } else if (state is DashboardLoaded || state is DashboardRefreshing) { final data = state is DashboardLoaded ? state.dashboardData : (state as DashboardRefreshing).dashboardData; return _buildDataCard(data.stats); } else if (state is DashboardError) { return _buildErrorCard(state.message); } return _buildLoadingCard(); }, ); } Widget _buildDataCard(DashboardStatsEntity stats) { final value = valueExtractor(stats); final subtitle = subtitleExtractor?.call(stats); final color = customColor ?? AppColors.primary; return CoreCard( onTap: onTap, padding: const EdgeInsets.all(8), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.all(5), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), child: Icon( icon, color: color, size: 14, ), ), const SizedBox(width: 6), Expanded( child: Text( title.toUpperCase(), style: AppTypography.subtitleSmall.copyWith( fontWeight: FontWeight.bold, fontSize: 9, letterSpacing: 1.0, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), const SizedBox(height: 4), Flexible( child: Text( value, style: AppTypography.headerSmall.copyWith( color: color, fontWeight: FontWeight.bold, fontSize: 16, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), if (subtitle != null) Flexible( child: Text( subtitle, style: AppTypography.subtitleSmall.copyWith(fontSize: 9), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ); } Widget _buildLoadingCard() { return const CoreCard( padding: EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // On peut utiliser un Shimmer ici si disponible CircularProgressIndicator(strokeWidth: 2), ], ), ); } Widget _buildErrorCard(String message) { return CoreCard( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.error_outline, color: AppColors.error, size: 20), const SizedBox(height: 8), Text(message, style: AppTypography.subtitleSmall.copyWith(color: AppColors.error)), ], ), ); } }