Version propre - Dashboard enhanced

This commit is contained in:
DahoudG
2025-09-13 19:05:06 +00:00
parent 3df010add7
commit 73459b3092
70 changed files with 15317 additions and 1498 deletions

View File

@@ -0,0 +1,432 @@
import 'package:flutter/material.dart';
import '../../../../../shared/theme/app_theme.dart';
import '../common/section_header_widget.dart';
/// Widget de section des analyses et tendances avec graphiques
///
/// Affiche tous les graphiques d'analyse en une seule colonne:
/// - Évolution des membres actifs (ligne)
/// - Répartition des cotisations (camembert)
/// - Revenus par source (barres)
/// - Cotisations par mois (barres)
/// - Engagement des membres (radar)
/// - Tendances géographiques (carte)
/// - Analyse comparative (barres groupées)
///
/// Chaque graphique est optimisé pour l'affichage mobile
/// avec des détails enrichis et des légendes complètes.
class ChartsAnalyticsWidget extends StatelessWidget {
const ChartsAnalyticsWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SectionHeaderWidget(title: 'Analyses & Tendances'),
const SizedBox(height: 16),
// Graphiques d'analyse - Une seule colonne pour exploiter toute la largeur
_buildLineChart(context),
const SizedBox(height: 16),
_buildPieChart(context),
const SizedBox(height: 16),
_buildRevenueChart(context),
const SizedBox(height: 16),
_buildCotisationsChart(context),
const SizedBox(height: 16),
_buildEngagementChart(context),
const SizedBox(height: 16),
_buildTrendsChart(context),
const SizedBox(height: 16),
_buildGeographicChart(context),
],
);
}
/// Graphique d'évolution des membres actifs (ligne)
Widget _buildLineChart(BuildContext context) {
return Container(
height: 280,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// En-tête enrichi avec icône et métriques
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: AppTheme.primaryColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(6),
),
child: const Icon(
Icons.trending_up,
color: AppTheme.primaryColor,
size: 16,
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Évolution des membres actifs',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppTheme.textPrimary,
),
),
const SizedBox(height: 2),
const Text(
'Croissance sur 5 mois • +24.7% (+247 membres)',
style: TextStyle(
fontSize: 11,
color: AppTheme.textSecondary,
),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppTheme.successColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.trending_up,
color: AppTheme.successColor,
size: 12,
),
SizedBox(width: 4),
Text(
'+24.7%',
style: TextStyle(
color: AppTheme.successColor,
fontSize: 11,
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
const SizedBox(height: 16),
// Placeholder pour le graphique
Expanded(
child: Container(
decoration: BoxDecoration(
color: AppTheme.primaryColor.withOpacity(0.05),
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: AppTheme.primaryColor.withOpacity(0.1),
width: 1,
),
),
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.show_chart,
color: AppTheme.primaryColor,
size: 48,
),
SizedBox(height: 8),
Text(
'Graphique d\'évolution des membres',
style: TextStyle(
color: AppTheme.textSecondary,
fontSize: 12,
),
),
],
),
),
),
),
],
),
);
}
/// Graphique de répartition des cotisations (camembert)
Widget _buildPieChart(BuildContext context) {
return Container(
height: 280,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// En-tête enrichi
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: AppTheme.accentColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(6),
),
child: const Icon(
Icons.pie_chart,
color: AppTheme.accentColor,
size: 16,
),
),
const SizedBox(width: 8),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Répartition des cotisations',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppTheme.textPrimary,
),
),
SizedBox(height: 2),
Text(
'Par statut de paiement • 1,247 membres total',
style: TextStyle(
fontSize: 11,
color: AppTheme.textSecondary,
),
),
],
),
),
],
),
const SizedBox(height: 16),
// Placeholder pour le graphique camembert
Expanded(
child: Container(
decoration: BoxDecoration(
color: AppTheme.accentColor.withOpacity(0.05),
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: AppTheme.accentColor.withOpacity(0.1),
width: 1,
),
),
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.donut_small,
color: AppTheme.accentColor,
size: 48,
),
SizedBox(height: 8),
Text(
'Graphique camembert des cotisations',
style: TextStyle(
color: AppTheme.textSecondary,
fontSize: 12,
),
),
],
),
),
),
),
],
),
);
}
/// Placeholder pour les autres graphiques
Widget _buildRevenueChart(BuildContext context) {
return _buildPlaceholderChart(
'Revenus par source',
'Analyse mensuelle • 2,845,000 FCFA total',
Icons.bar_chart,
AppTheme.successColor,
'Graphique des revenus par source',
);
}
Widget _buildCotisationsChart(BuildContext context) {
return _buildPlaceholderChart(
'Cotisations par mois',
'Évolution sur 12 mois • Tendance positive',
Icons.assessment,
AppTheme.infoColor,
'Graphique des cotisations mensuelles',
);
}
Widget _buildEngagementChart(BuildContext context) {
return _buildPlaceholderChart(
'Engagement des membres',
'Analyse multi-critères • Score global 85/100',
Icons.radar,
const Color(0xFF9C27B0),
'Graphique radar d\'engagement',
);
}
Widget _buildTrendsChart(BuildContext context) {
return _buildPlaceholderChart(
'Tendances comparatives',
'Comparaison avec période précédente',
Icons.compare_arrows,
AppTheme.warningColor,
'Graphique de tendances comparatives',
);
}
Widget _buildGeographicChart(BuildContext context) {
return _buildPlaceholderChart(
'Répartition géographique',
'Membres par région • Côte d\'Ivoire',
Icons.map,
const Color(0xFF795548),
'Carte géographique des membres',
);
}
/// Widget placeholder générique pour les graphiques
Widget _buildPlaceholderChart(
String title,
String subtitle,
IconData icon,
Color color,
String description,
) {
return Container(
height: 280,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(6),
),
child: Icon(
icon,
color: color,
size: 16,
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppTheme.textPrimary,
),
),
const SizedBox(height: 2),
Text(
subtitle,
style: const TextStyle(
fontSize: 11,
color: AppTheme.textSecondary,
),
),
],
),
),
],
),
const SizedBox(height: 16),
Expanded(
child: Container(
decoration: BoxDecoration(
color: color.withOpacity(0.05),
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: color.withOpacity(0.1),
width: 1,
),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: color,
size: 48,
),
const SizedBox(height: 8),
Text(
description,
style: const TextStyle(
color: AppTheme.textSecondary,
fontSize: 12,
),
),
],
),
),
),
),
],
),
);
}
}