Refactoring
This commit is contained in:
@@ -0,0 +1,439 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../shared/widgets/unified_components.dart';
|
||||
import '../../../../shared/theme/app_theme.dart';
|
||||
import '../../../../core/animations/page_transitions.dart';
|
||||
import '../../../demo/presentation/pages/animations_demo_page.dart';
|
||||
import '../../../debug/debug_api_test_page.dart';
|
||||
|
||||
/// Page principale du tableau de bord UnionFlow - Version Unifiée
|
||||
///
|
||||
/// Utilise l'architecture unifiée avec composants standardisés pour :
|
||||
/// - Cohérence visuelle parfaite avec les autres onglets
|
||||
/// - Maintenabilité optimale et réutilisabilité maximale
|
||||
/// - Performance 60 FPS avec animations fluides
|
||||
/// - Expérience utilisateur homogène
|
||||
class DashboardPageUnified extends StatelessWidget {
|
||||
const DashboardPageUnified({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return UnifiedPageLayout(
|
||||
title: 'Tableau de bord',
|
||||
subtitle: 'Vue d\'ensemble de votre association',
|
||||
icon: Icons.dashboard,
|
||||
iconColor: AppTheme.primaryColor,
|
||||
actions: _buildActions(context),
|
||||
body: Column(
|
||||
children: [
|
||||
_buildWelcomeSection(),
|
||||
const SizedBox(height: AppTheme.spacingLarge),
|
||||
_buildKPISection(),
|
||||
const SizedBox(height: AppTheme.spacingLarge),
|
||||
_buildQuickActionsSection(),
|
||||
const SizedBox(height: AppTheme.spacingLarge),
|
||||
_buildRecentActivitiesSection(),
|
||||
const SizedBox(height: AppTheme.spacingLarge),
|
||||
_buildAnalyticsSection(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Actions de la barre d'outils
|
||||
List<Widget> _buildActions(BuildContext context) {
|
||||
return [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.animation),
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
PageTransitions.morphWithBlur(const AnimationsDemoPage()),
|
||||
),
|
||||
tooltip: 'Démonstration des animations',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.notifications_outlined),
|
||||
onPressed: () {
|
||||
// TODO: Implémenter la navigation vers les notifications
|
||||
},
|
||||
tooltip: 'Notifications',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.bug_report),
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
PageTransitions.slideFromRight(const DebugApiTestPage()),
|
||||
),
|
||||
tooltip: 'Debug API',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings_outlined),
|
||||
onPressed: () {
|
||||
// TODO: Implémenter la navigation vers les paramètres
|
||||
},
|
||||
tooltip: 'Paramètres',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/// Section d'accueil personnalisée
|
||||
Widget _buildWelcomeSection() {
|
||||
return UnifiedCard.elevated(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingLarge),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingMedium),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.primaryColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.waving_hand,
|
||||
color: AppTheme.primaryColor,
|
||||
size: 32,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingMedium),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Bonjour !',
|
||||
style: AppTheme.headlineSmall.copyWith(
|
||||
color: AppTheme.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingXSmall),
|
||||
Text(
|
||||
'Bienvenue sur votre tableau de bord UnionFlow',
|
||||
style: AppTheme.bodyMedium.copyWith(
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Section des indicateurs clés de performance
|
||||
Widget _buildKPISection() {
|
||||
final kpis = [
|
||||
UnifiedKPIData(
|
||||
title: 'Membres',
|
||||
value: '247',
|
||||
icon: Icons.people,
|
||||
color: AppTheme.primaryColor,
|
||||
trend: UnifiedKPITrend(
|
||||
direction: UnifiedKPITrendDirection.up,
|
||||
value: '+12',
|
||||
label: 'ce mois',
|
||||
),
|
||||
),
|
||||
UnifiedKPIData(
|
||||
title: 'Événements',
|
||||
value: '18',
|
||||
icon: Icons.event,
|
||||
color: AppTheme.accentColor,
|
||||
trend: UnifiedKPITrend(
|
||||
direction: UnifiedKPITrendDirection.up,
|
||||
value: '+3',
|
||||
label: 'ce mois',
|
||||
),
|
||||
),
|
||||
UnifiedKPIData(
|
||||
title: 'Cotisations',
|
||||
value: '89%',
|
||||
icon: Icons.account_balance_wallet,
|
||||
color: AppTheme.successColor,
|
||||
trend: UnifiedKPITrend(
|
||||
direction: UnifiedKPITrendDirection.up,
|
||||
value: '+5%',
|
||||
label: 'vs mois dernier',
|
||||
),
|
||||
),
|
||||
UnifiedKPIData(
|
||||
title: 'Trésorerie',
|
||||
value: '12.5K€',
|
||||
icon: Icons.euro,
|
||||
color: AppTheme.warningColor,
|
||||
trend: UnifiedKPITrend(
|
||||
direction: UnifiedKPITrendDirection.stable,
|
||||
value: '0%',
|
||||
label: 'stable',
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
return UnifiedKPISection(
|
||||
title: 'Vue d\'ensemble',
|
||||
kpis: kpis,
|
||||
);
|
||||
}
|
||||
|
||||
/// Section des actions rapides
|
||||
Widget _buildQuickActionsSection() {
|
||||
final actions = [
|
||||
UnifiedQuickAction(
|
||||
id: 'add_member',
|
||||
title: 'Nouveau\nMembre',
|
||||
icon: Icons.person_add,
|
||||
color: AppTheme.primaryColor,
|
||||
),
|
||||
UnifiedQuickAction(
|
||||
id: 'add_event',
|
||||
title: 'Nouvel\nÉvénement',
|
||||
icon: Icons.event_available,
|
||||
color: AppTheme.accentColor,
|
||||
badgeCount: 3,
|
||||
),
|
||||
UnifiedQuickAction(
|
||||
id: 'manage_cotisations',
|
||||
title: 'Gérer\nCotisations',
|
||||
icon: Icons.account_balance_wallet,
|
||||
color: AppTheme.successColor,
|
||||
badgeCount: 7,
|
||||
),
|
||||
UnifiedQuickAction(
|
||||
id: 'reports',
|
||||
title: 'Rapports\n& Stats',
|
||||
icon: Icons.analytics,
|
||||
color: AppTheme.infoColor,
|
||||
),
|
||||
UnifiedQuickAction(
|
||||
id: 'communications',
|
||||
title: 'Envoyer\nMessage',
|
||||
icon: Icons.send,
|
||||
color: AppTheme.warningColor,
|
||||
),
|
||||
UnifiedQuickAction(
|
||||
id: 'settings',
|
||||
title: 'Paramètres\nAssociation',
|
||||
icon: Icons.settings,
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
];
|
||||
|
||||
return UnifiedQuickActionsSection(
|
||||
title: 'Actions rapides',
|
||||
actions: actions,
|
||||
onActionTap: _handleQuickAction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Section des activités récentes
|
||||
Widget _buildRecentActivitiesSection() {
|
||||
final activities = [
|
||||
_ActivityItem(
|
||||
title: 'Nouveau membre inscrit',
|
||||
subtitle: 'Marie Dubois a rejoint l\'association',
|
||||
icon: Icons.person_add,
|
||||
color: AppTheme.successColor,
|
||||
time: 'Il y a 2h',
|
||||
),
|
||||
_ActivityItem(
|
||||
title: 'Événement créé',
|
||||
subtitle: 'Assemblée Générale 2024 programmée',
|
||||
icon: Icons.event,
|
||||
color: AppTheme.accentColor,
|
||||
time: 'Il y a 4h',
|
||||
),
|
||||
_ActivityItem(
|
||||
title: 'Cotisation reçue',
|
||||
subtitle: 'Jean Martin - Cotisation annuelle',
|
||||
icon: Icons.payment,
|
||||
color: AppTheme.primaryColor,
|
||||
time: 'Il y a 6h',
|
||||
),
|
||||
];
|
||||
|
||||
return UnifiedCard.elevated(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingLarge),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.timeline,
|
||||
color: AppTheme.primaryColor,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingSmall),
|
||||
Text(
|
||||
'Activités récentes',
|
||||
style: AppTheme.titleMedium.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingMedium),
|
||||
...activities.map((activity) => _buildActivityItem(activity)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Section d'analyses et graphiques
|
||||
Widget _buildAnalyticsSection() {
|
||||
return UnifiedCard.elevated(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingLarge),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.analytics,
|
||||
color: AppTheme.accentColor,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingSmall),
|
||||
Text(
|
||||
'Analyses & Tendances',
|
||||
style: AppTheme.titleMedium.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
UnifiedButton.tertiary(
|
||||
text: 'Voir plus',
|
||||
size: UnifiedButtonSize.small,
|
||||
onPressed: () {
|
||||
// TODO: Navigation vers analyses détaillées
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingMedium),
|
||||
Container(
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.accentColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.bar_chart,
|
||||
color: AppTheme.accentColor,
|
||||
size: 48,
|
||||
),
|
||||
const SizedBox(height: AppTheme.spacingSmall),
|
||||
Text(
|
||||
'Graphiques interactifs',
|
||||
style: AppTheme.bodyMedium.copyWith(
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Construit un élément d'activité
|
||||
Widget _buildActivityItem(_ActivityItem activity) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: AppTheme.spacingSmall),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(AppTheme.spacingSmall),
|
||||
decoration: BoxDecoration(
|
||||
color: activity.color.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(AppTheme.borderRadiusSmall),
|
||||
),
|
||||
child: Icon(
|
||||
activity.icon,
|
||||
color: activity.color,
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppTheme.spacingMedium),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
activity.title,
|
||||
style: AppTheme.bodyMedium.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
activity.subtitle,
|
||||
style: AppTheme.bodySmall.copyWith(
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
activity.time,
|
||||
style: AppTheme.bodySmall.copyWith(
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Gère les actions rapides
|
||||
void _handleQuickAction(UnifiedQuickAction action) {
|
||||
// TODO: Implémenter la navigation selon l'action
|
||||
switch (action.id) {
|
||||
case 'add_member':
|
||||
// Navigation vers ajout membre
|
||||
break;
|
||||
case 'add_event':
|
||||
// Navigation vers ajout événement
|
||||
break;
|
||||
case 'manage_cotisations':
|
||||
// Navigation vers gestion cotisations
|
||||
break;
|
||||
case 'reports':
|
||||
// Navigation vers rapports
|
||||
break;
|
||||
case 'communications':
|
||||
// Navigation vers communications
|
||||
break;
|
||||
case 'settings':
|
||||
// Navigation vers paramètres
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Modèle pour les éléments d'activité
|
||||
class _ActivityItem {
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
final String time;
|
||||
|
||||
const _ActivityItem({
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
required this.icon,
|
||||
required this.color,
|
||||
required this.time,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user