Refactoring

This commit is contained in:
DahoudG
2025-09-17 17:54:06 +00:00
parent 12d514d866
commit 63fe107f98
165 changed files with 54220 additions and 276 deletions

View File

@@ -0,0 +1,393 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../shared/widgets/common/unified_page_layout.dart';
import '../../../../shared/widgets/common/unified_card.dart';
import '../../../../shared/theme/design_system.dart';
import '../../../../core/utils/constants.dart';
import '../bloc/analytics_bloc.dart';
import '../widgets/kpi_card_widget.dart';
import '../widgets/trend_chart_widget.dart';
import '../widgets/period_selector_widget.dart';
import '../widgets/metrics_grid_widget.dart';
import '../widgets/performance_gauge_widget.dart';
import '../widgets/alerts_panel_widget.dart';
import '../../domain/entities/analytics_data.dart';
/// Page principale du tableau de bord analytics
class AnalyticsDashboardPage extends StatefulWidget {
const AnalyticsDashboardPage({super.key});
@override
State<AnalyticsDashboardPage> createState() => _AnalyticsDashboardPageState();
}
class _AnalyticsDashboardPageState extends State<AnalyticsDashboardPage>
with TickerProviderStateMixin {
late TabController _tabController;
PeriodeAnalyse _periodeSelectionnee = PeriodeAnalyse.ceMois;
String? _organisationId;
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this);
_chargerDonneesInitiales();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
void _chargerDonneesInitiales() {
context.read<AnalyticsBloc>().add(
ChargerTableauBordEvent(
periodeAnalyse: _periodeSelectionnee,
organisationId: _organisationId,
),
);
}
void _onPeriodeChanged(PeriodeAnalyse nouvellePeriode) {
setState(() {
_periodeSelectionnee = nouvellePeriode;
});
_chargerDonneesInitiales();
}
@override
Widget build(BuildContext context) {
return UnifiedPageLayout(
title: 'Analytics',
subtitle: 'Tableau de bord et métriques',
showBackButton: false,
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _chargerDonneesInitiales,
tooltip: 'Actualiser',
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () => _ouvrirParametres(context),
tooltip: 'Paramètres',
),
],
body: Column(
children: [
// Sélecteur de période
Padding(
padding: const EdgeInsets.all(DesignSystem.spacing16),
child: PeriodSelectorWidget(
periodeSelectionnee: _periodeSelectionnee,
onPeriodeChanged: _onPeriodeChanged,
),
),
// Onglets
TabBar(
controller: _tabController,
labelColor: DesignSystem.primaryColor,
unselectedLabelColor: DesignSystem.textSecondaryColor,
indicatorColor: DesignSystem.primaryColor,
tabs: const [
Tab(
icon: Icon(Icons.dashboard),
text: 'Vue d\'ensemble',
),
Tab(
icon: Icon(Icons.trending_up),
text: 'Tendances',
),
Tab(
icon: Icon(Icons.analytics),
text: 'Détails',
),
Tab(
icon: Icon(Icons.warning),
text: 'Alertes',
),
],
),
// Contenu des onglets
Expanded(
child: TabBarView(
controller: _tabController,
children: [
_buildVueEnsemble(),
_buildTendances(),
_buildDetails(),
_buildAlertes(),
],
),
),
],
),
);
}
/// Vue d'ensemble avec KPI principaux
Widget _buildVueEnsemble() {
return BlocBuilder<AnalyticsBloc, AnalyticsState>(
builder: (context, state) {
if (state is AnalyticsLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (state is AnalyticsError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.error_outline,
size: 64,
color: DesignSystem.errorColor,
),
const SizedBox(height: DesignSystem.spacing16),
Text(
'Erreur lors du chargement',
style: DesignSystem.textTheme.headlineSmall,
),
const SizedBox(height: DesignSystem.spacing8),
Text(
state.message,
style: DesignSystem.textTheme.bodyMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: DesignSystem.spacing16),
ElevatedButton(
onPressed: _chargerDonneesInitiales,
child: const Text('Réessayer'),
),
],
),
);
}
if (state is AnalyticsLoaded) {
return SingleChildScrollView(
padding: const EdgeInsets.all(DesignSystem.spacing16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Performance globale
if (state.performanceGlobale != null)
UnifiedCard(
variant: UnifiedCardVariant.elevated,
child: PerformanceGaugeWidget(
score: state.performanceGlobale!,
periode: _periodeSelectionnee,
),
),
const SizedBox(height: DesignSystem.spacing16),
// KPI principaux
Text(
'Indicateurs clés',
style: DesignSystem.textTheme.headlineSmall,
),
const SizedBox(height: DesignSystem.spacing12),
MetricsGridWidget(
metriques: state.metriques,
onMetriquePressed: (metrique) => _ouvrirDetailMetrique(
context,
metrique,
),
),
const SizedBox(height: DesignSystem.spacing24),
// Graphiques de tendance rapide
Text(
'Évolutions récentes',
style: DesignSystem.textTheme.headlineSmall,
),
const SizedBox(height: DesignSystem.spacing12),
if (state.tendances.isNotEmpty)
SizedBox(
height: 200,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: state.tendances.length,
itemBuilder: (context, index) {
final tendance = state.tendances[index];
return Container(
width: 300,
margin: const EdgeInsets.only(
right: DesignSystem.spacing12,
),
child: UnifiedCard(
variant: UnifiedCardVariant.outlined,
child: TrendChartWidget(
trend: tendance,
compact: true,
),
),
);
},
),
),
],
),
);
}
return const SizedBox.shrink();
},
);
}
/// Onglet des tendances détaillées
Widget _buildTendances() {
return BlocBuilder<AnalyticsBloc, AnalyticsState>(
builder: (context, state) {
if (state is AnalyticsLoaded && state.tendances.isNotEmpty) {
return ListView.builder(
padding: const EdgeInsets.all(DesignSystem.spacing16),
itemCount: state.tendances.length,
itemBuilder: (context, index) {
final tendance = state.tendances[index];
return Padding(
padding: const EdgeInsets.only(
bottom: DesignSystem.spacing16,
),
child: UnifiedCard(
variant: UnifiedCardVariant.elevated,
child: TrendChartWidget(
trend: tendance,
compact: false,
showPredictions: true,
showAnomalies: true,
),
),
);
},
);
}
return const Center(
child: Text('Aucune tendance disponible'),
);
},
);
}
/// Onglet des détails par métrique
Widget _buildDetails() {
return BlocBuilder<AnalyticsBloc, AnalyticsState>(
builder: (context, state) {
if (state is AnalyticsLoaded) {
return ListView.builder(
padding: const EdgeInsets.all(DesignSystem.spacing16),
itemCount: TypeMetrique.values.length,
itemBuilder: (context, index) {
final typeMetrique = TypeMetrique.values[index];
final metrique = state.metriques.firstWhere(
(m) => m.typeMetrique == typeMetrique,
orElse: () => AnalyticsData(
id: 'placeholder_$index',
typeMetrique: typeMetrique,
periodeAnalyse: _periodeSelectionnee,
valeur: 0,
dateDebut: DateTime.now().subtract(const Duration(days: 30)),
dateFin: DateTime.now(),
dateCalcul: DateTime.now(),
),
);
return Padding(
padding: const EdgeInsets.only(
bottom: DesignSystem.spacing12,
),
child: KPICardWidget(
analyticsData: metrique,
onTap: () => _ouvrirDetailMetrique(context, metrique),
showTrend: true,
showDetails: true,
),
);
},
);
}
return const Center(
child: Text('Aucun détail disponible'),
);
},
);
}
/// Onglet des alertes
Widget _buildAlertes() {
return BlocBuilder<AnalyticsBloc, AnalyticsState>(
builder: (context, state) {
if (state is AnalyticsLoaded) {
final alertes = state.metriques
.where((m) => m.isCritique || !m.isDonneesFiables)
.toList();
if (alertes.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.check_circle_outline,
size: 64,
color: DesignSystem.successColor,
),
const SizedBox(height: DesignSystem.spacing16),
Text(
'Aucune alerte active',
style: DesignSystem.textTheme.headlineSmall,
),
const SizedBox(height: DesignSystem.spacing8),
Text(
'Toutes les métriques sont dans les normes',
style: DesignSystem.textTheme.bodyMedium,
textAlign: TextAlign.center,
),
],
),
);
}
return AlertsPanelWidget(
alertes: alertes,
onAlertePressed: (alerte) => _ouvrirDetailMetrique(
context,
alerte,
),
);
}
return const Center(
child: Text('Aucune alerte disponible'),
);
},
);
}
void _ouvrirDetailMetrique(BuildContext context, AnalyticsData metrique) {
Navigator.of(context).pushNamed(
AppRoutes.analyticsDetail,
arguments: {
'metrique': metrique,
'periode': _periodeSelectionnee,
'organisationId': _organisationId,
},
);
}
void _ouvrirParametres(BuildContext context) {
Navigator.of(context).pushNamed(AppRoutes.analyticsSettings);
}
}

View File

@@ -0,0 +1,357 @@
import 'package:flutter/material.dart';
import '../../../../shared/widgets/common/unified_card.dart';
import '../../../../shared/theme/design_system.dart';
import '../../../../core/utils/formatters.dart';
import '../../domain/entities/analytics_data.dart';
/// Widget de carte KPI utilisant le design system unifié
class KPICardWidget extends StatelessWidget {
const KPICardWidget({
super.key,
required this.analyticsData,
this.onTap,
this.showTrend = true,
this.showDetails = false,
this.compact = false,
});
final AnalyticsData analyticsData;
final VoidCallback? onTap;
final bool showTrend;
final bool showDetails;
final bool compact;
@override
Widget build(BuildContext context) {
return UnifiedCard(
variant: UnifiedCardVariant.elevated,
onTap: onTap,
child: Padding(
padding: EdgeInsets.all(
compact ? DesignSystem.spacing12 : DesignSystem.spacing16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
// En-tête avec icône et titre
Row(
children: [
Container(
padding: const EdgeInsets.all(DesignSystem.spacing8),
decoration: BoxDecoration(
color: _getCouleurMetrique().withOpacity(0.1),
borderRadius: BorderRadius.circular(DesignSystem.radius8),
),
child: Icon(
_getIconeMetrique(),
color: _getCouleurMetrique(),
size: compact ? 20 : 24,
),
),
const SizedBox(width: DesignSystem.spacing12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
analyticsData.libelleAffichage,
style: compact
? DesignSystem.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600,
)
: DesignSystem.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
if (!compact && analyticsData.description != null)
Padding(
padding: const EdgeInsets.only(
top: DesignSystem.spacing4,
),
child: Text(
analyticsData.description!,
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
// Indicateur de fiabilité
if (showDetails)
_buildIndicateurFiabilite(),
],
),
SizedBox(height: compact ? DesignSystem.spacing8 : DesignSystem.spacing16),
// Valeur principale
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
analyticsData.valeurFormatee,
style: compact
? DesignSystem.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
color: _getCouleurMetrique(),
)
: DesignSystem.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
color: _getCouleurMetrique(),
),
),
),
// Évolution
if (showTrend && analyticsData.pourcentageEvolution != null)
_buildEvolution(),
],
),
// Détails supplémentaires
if (showDetails) ...[
const SizedBox(height: DesignSystem.spacing12),
_buildDetails(),
],
// Période et dernière mise à jour
if (!compact) ...[
const SizedBox(height: DesignSystem.spacing12),
_buildInfosPeriode(),
],
],
),
),
);
}
/// Widget d'évolution avec icône et pourcentage
Widget _buildEvolution() {
final evolution = analyticsData.pourcentageEvolution!;
final isPositive = evolution > 0;
final isNegative = evolution < 0;
Color couleur;
IconData icone;
if (isPositive) {
couleur = DesignSystem.successColor;
icone = Icons.trending_up;
} else if (isNegative) {
couleur = DesignSystem.errorColor;
icone = Icons.trending_down;
} else {
couleur = DesignSystem.warningColor;
icone = Icons.trending_flat;
}
return Container(
padding: const EdgeInsets.symmetric(
horizontal: DesignSystem.spacing8,
vertical: DesignSystem.spacing4,
),
decoration: BoxDecoration(
color: couleur.withOpacity(0.1),
borderRadius: BorderRadius.circular(DesignSystem.radius12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icone,
size: 16,
color: couleur,
),
const SizedBox(width: DesignSystem.spacing4),
Text(
analyticsData.evolutionFormatee,
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: couleur,
fontWeight: FontWeight.w600,
),
),
],
),
);
}
/// Widget d'indicateur de fiabilité
Widget _buildIndicateurFiabilite() {
final fiabilite = analyticsData.indicateurFiabilite;
Color couleur;
if (fiabilite >= 90) {
couleur = DesignSystem.successColor;
} else if (fiabilite >= 70) {
couleur = DesignSystem.warningColor;
} else {
couleur = DesignSystem.errorColor;
}
return Container(
padding: const EdgeInsets.symmetric(
horizontal: DesignSystem.spacing6,
vertical: DesignSystem.spacing2,
),
decoration: BoxDecoration(
color: couleur.withOpacity(0.1),
borderRadius: BorderRadius.circular(DesignSystem.radius8),
border: Border.all(
color: couleur.withOpacity(0.3),
width: 1,
),
),
child: Text(
'${fiabilite.toStringAsFixed(0)}%',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: couleur,
fontWeight: FontWeight.w600,
),
),
);
}
/// Widget des détails supplémentaires
Widget _buildDetails() {
return Column(
children: [
// Valeur précédente
if (analyticsData.valeurPrecedente != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Période précédente',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
Text(
_formaterValeur(analyticsData.valeurPrecedente!),
style: DesignSystem.textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
],
),
const SizedBox(height: DesignSystem.spacing4),
// Éléments analysés
if (analyticsData.nombreElementsAnalyses != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Éléments analysés',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
Text(
analyticsData.nombreElementsAnalyses.toString(),
style: DesignSystem.textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
],
),
const SizedBox(height: DesignSystem.spacing4),
// Temps de calcul
if (analyticsData.tempsCalculMs != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Temps de calcul',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
Text(
'${analyticsData.tempsCalculMs}ms',
style: DesignSystem.textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
],
),
],
);
}
/// Widget des informations de période
Widget _buildInfosPeriode() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
analyticsData.periodeAnalyse.libelle,
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
),
Text(
'Mis à jour ${AppFormatters.formatDateRelative(analyticsData.dateCalcul)}',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
],
);
}
/// Obtient la couleur de la métrique
Color _getCouleurMetrique() {
return Color(int.parse(
analyticsData.couleur.replaceFirst('#', '0xFF'),
));
}
/// Obtient l'icône de la métrique
IconData _getIconeMetrique() {
switch (analyticsData.icone) {
case 'people':
return Icons.people;
case 'attach_money':
return Icons.attach_money;
case 'event':
return Icons.event;
case 'favorite':
return Icons.favorite;
case 'trending_up':
return Icons.trending_up;
case 'business':
return Icons.business;
case 'settings':
return Icons.settings;
default:
return Icons.analytics;
}
}
/// Formate une valeur selon le type de métrique
String _formaterValeur(double valeur) {
switch (analyticsData.typeMetrique.typeValeur) {
case 'amount':
return '${valeur.toStringAsFixed(0)} ${analyticsData.unite}';
case 'percentage':
return '${valeur.toStringAsFixed(1)}${analyticsData.unite}';
case 'average':
return valeur.toStringAsFixed(1);
default:
return valeur.toStringAsFixed(0);
}
}
}

View File

@@ -0,0 +1,271 @@
import 'package:flutter/material.dart';
import '../../../../shared/widgets/common/unified_card.dart';
import '../../../../shared/theme/design_system.dart';
import '../../domain/entities/analytics_data.dart';
/// Widget de sélection de période pour les analytics
class PeriodSelectorWidget extends StatelessWidget {
const PeriodSelectorWidget({
super.key,
required this.periodeSelectionnee,
required this.onPeriodeChanged,
this.compact = false,
});
final PeriodeAnalyse periodeSelectionnee;
final ValueChanged<PeriodeAnalyse> onPeriodeChanged;
final bool compact;
@override
Widget build(BuildContext context) {
if (compact) {
return _buildCompactSelector(context);
} else {
return _buildFullSelector(context);
}
}
/// Sélecteur compact avec dropdown
Widget _buildCompactSelector(BuildContext context) {
return UnifiedCard(
variant: UnifiedCardVariant.outlined,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: DesignSystem.spacing16,
vertical: DesignSystem.spacing8,
),
child: DropdownButtonHideUnderline(
child: DropdownButton<PeriodeAnalyse>(
value: periodeSelectionnee,
onChanged: (periode) {
if (periode != null) {
onPeriodeChanged(periode);
}
},
icon: const Icon(Icons.expand_more),
isExpanded: true,
items: PeriodeAnalyse.values.map((periode) {
return DropdownMenuItem<PeriodeAnalyse>(
value: periode,
child: Text(
periode.libelle,
style: DesignSystem.textTheme.bodyMedium,
),
);
}).toList(),
),
),
),
);
}
/// Sélecteur complet avec chips
Widget _buildFullSelector(BuildContext context) {
final periodesRapides = [
PeriodeAnalyse.aujourdHui,
PeriodeAnalyse.hier,
PeriodeAnalyse.cetteSemaine,
PeriodeAnalyse.ceMois,
PeriodeAnalyse.troisDerniersMois,
PeriodeAnalyse.cetteAnnee,
];
final periodesPersonnalisees = [
PeriodeAnalyse.septDerniersJours,
PeriodeAnalyse.trenteDerniersJours,
PeriodeAnalyse.sixDerniersMois,
PeriodeAnalyse.anneeDerniere,
PeriodeAnalyse.periodePersonnalisee,
];
return UnifiedCard(
variant: UnifiedCardVariant.outlined,
child: Padding(
padding: const EdgeInsets.all(DesignSystem.spacing16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Titre
Row(
children: [
Icon(
Icons.date_range,
size: 20,
color: DesignSystem.primaryColor,
),
const SizedBox(width: DesignSystem.spacing8),
Text(
'Période d\'analyse',
style: DesignSystem.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: DesignSystem.spacing12),
// Périodes rapides
Text(
'Accès rapide',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: DesignSystem.spacing8),
Wrap(
spacing: DesignSystem.spacing8,
runSpacing: DesignSystem.spacing8,
children: periodesRapides.map((periode) {
return _buildPeriodeChip(periode, isRapide: true);
}).toList(),
),
const SizedBox(height: DesignSystem.spacing16),
// Périodes personnalisées
Text(
'Autres périodes',
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: DesignSystem.spacing8),
Wrap(
spacing: DesignSystem.spacing8,
runSpacing: DesignSystem.spacing8,
children: periodesPersonnalisees.map((periode) {
return _buildPeriodeChip(periode, isRapide: false);
}).toList(),
),
// Informations sur la période sélectionnée
if (periodeSelectionnee != PeriodeAnalyse.periodePersonnalisee) ...[
const SizedBox(height: DesignSystem.spacing16),
_buildInfosPeriode(),
],
],
),
),
);
}
/// Chip de sélection de période
Widget _buildPeriodeChip(PeriodeAnalyse periode, {required bool isRapide}) {
final isSelected = periode == periodeSelectionnee;
return FilterChip(
label: Text(
periode.libelle,
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: isSelected
? Colors.white
: isRapide
? DesignSystem.primaryColor
: DesignSystem.textSecondaryColor,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
),
),
selected: isSelected,
onSelected: (_) => onPeriodeChanged(periode),
backgroundColor: isRapide
? DesignSystem.primaryColor.withOpacity(0.1)
: DesignSystem.surfaceColor,
selectedColor: isRapide
? DesignSystem.primaryColor
: DesignSystem.secondaryColor,
checkmarkColor: Colors.white,
side: BorderSide(
color: isSelected
? Colors.transparent
: isRapide
? DesignSystem.primaryColor.withOpacity(0.3)
: DesignSystem.borderColor,
width: 1,
),
elevation: isSelected ? 2 : 0,
pressElevation: 4,
);
}
/// Informations sur la période sélectionnée
Widget _buildInfosPeriode() {
return Container(
padding: const EdgeInsets.all(DesignSystem.spacing12),
decoration: BoxDecoration(
color: DesignSystem.primaryColor.withOpacity(0.05),
borderRadius: BorderRadius.circular(DesignSystem.radius8),
border: Border.all(
color: DesignSystem.primaryColor.withOpacity(0.2),
width: 1,
),
),
child: Row(
children: [
Icon(
Icons.info_outline,
size: 16,
color: DesignSystem.primaryColor,
),
const SizedBox(width: DesignSystem.spacing8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Période sélectionnée : ${periodeSelectionnee.libelle}',
style: DesignSystem.textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: DesignSystem.spacing2),
Text(
_getDescriptionPeriode(),
style: DesignSystem.textTheme.bodySmall?.copyWith(
color: DesignSystem.textSecondaryColor,
),
),
],
),
),
],
),
);
}
/// Description de la période sélectionnée
String _getDescriptionPeriode() {
switch (periodeSelectionnee) {
case PeriodeAnalyse.aujourdHui:
return 'Données du jour en cours';
case PeriodeAnalyse.hier:
return 'Données de la journée précédente';
case PeriodeAnalyse.cetteSemaine:
return 'Du lundi au dimanche de cette semaine';
case PeriodeAnalyse.semaineDerniere:
return 'Du lundi au dimanche de la semaine passée';
case PeriodeAnalyse.ceMois:
return 'Du 1er au dernier jour de ce mois';
case PeriodeAnalyse.moisDernier:
return 'Du 1er au dernier jour du mois passé';
case PeriodeAnalyse.troisDerniersMois:
return 'Les 3 derniers mois complets';
case PeriodeAnalyse.sixDerniersMois:
return 'Les 6 derniers mois complets';
case PeriodeAnalyse.cetteAnnee:
return 'Du 1er janvier à aujourd\'hui';
case PeriodeAnalyse.anneeDerniere:
return 'Du 1er janvier au 31 décembre de l\'année passée';
case PeriodeAnalyse.septDerniersJours:
return 'Les 7 derniers jours glissants';
case PeriodeAnalyse.trenteDerniersJours:
return 'Les 30 derniers jours glissants';
case PeriodeAnalyse.periodePersonnalisee:
return 'Définissez vos propres dates de début et fin';
}
}
}