Files
unionflow-server-api/unionflow-mobile-apps/lib/features/dashboard/presentation/pages/dashboard_page_unified.dart
2025-09-17 17:54:06 +00:00

440 lines
13 KiB
Dart

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,
});
}