import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../bloc/dashboard_bloc.dart'; import '../widgets/connected/connected_stats_card.dart'; import '../widgets/connected/connected_recent_activities.dart'; import '../widgets/connected/connected_upcoming_events.dart'; import '../widgets/charts/dashboard_chart_widget.dart'; import '../widgets/metrics/real_time_metrics_widget.dart'; import '../widgets/notifications/dashboard_notifications_widget.dart'; import '../../../../shared/design_system/dashboard_theme.dart'; import '../../../../core/di/injection_container.dart'; /// Page dashboard avancée avec graphiques et analytics class AdvancedDashboardPage extends StatefulWidget { final String organizationId; final String userId; const AdvancedDashboardPage({ super.key, required this.organizationId, required this.userId, }); @override State createState() => _AdvancedDashboardPageState(); } class _AdvancedDashboardPageState extends State with TickerProviderStateMixin { late DashboardBloc _dashboardBloc; late TabController _tabController; @override void initState() { super.initState(); _dashboardBloc = sl(); _tabController = TabController(length: 3, vsync: this); _loadDashboardData(); } void _loadDashboardData() { _dashboardBloc.add(LoadDashboardData( organizationId: widget.organizationId, userId: widget.userId, )); } void _refreshDashboardData() { _dashboardBloc.add(RefreshDashboardData( organizationId: widget.organizationId, userId: widget.userId, )); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => _dashboardBloc, child: Scaffold( body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ _buildSliverAppBar(), ], body: Column( children: [ _buildTabBar(), Expanded( child: TabBarView( controller: _tabController, children: [ _buildOverviewTab(), _buildAnalyticsTab(), _buildReportsTab(), ], ), ), ], ), ), floatingActionButton: _buildFloatingActionButton(), ), ); } Widget _buildSliverAppBar() { return SliverAppBar( expandedHeight: 200, floating: false, pinned: true, flexibleSpace: FlexibleSpaceBar( background: Container( decoration: DashboardTheme.headerDecoration, child: SafeArea( child: Padding( padding: const EdgeInsets.all(DashboardTheme.spacing20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.end, children: [ Row( children: [ Container( padding: const EdgeInsets.all(DashboardTheme.spacing12), decoration: BoxDecoration( color: DashboardTheme.white.withOpacity(0.2), borderRadius: BorderRadius.circular(DashboardTheme.borderRadius), ), child: const Icon( Icons.dashboard, color: DashboardTheme.white, size: 32, ), ), const SizedBox(width: DashboardTheme.spacing16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Dashboard Avancé', style: DashboardTheme.titleLarge.copyWith( color: DashboardTheme.white, fontSize: 28, ), ), const SizedBox(height: DashboardTheme.spacing4), Text( 'Analytics & Insights', style: DashboardTheme.bodyMedium.copyWith( color: DashboardTheme.white.withOpacity(0.9), ), ), ], ), ), ], ), const SizedBox(height: DashboardTheme.spacing16), BlocBuilder( builder: (context, state) { if (state is DashboardLoaded || state is DashboardRefreshing) { final data = state is DashboardLoaded ? state.dashboardData : (state as DashboardRefreshing).dashboardData; return Row( children: [ _buildQuickStat( 'Membres', '${data.stats.activeMembers}/${data.stats.totalMembers}', Icons.people, ), const SizedBox(width: DashboardTheme.spacing16), _buildQuickStat( 'Événements', '${data.stats.upcomingEvents}', Icons.event, ), const SizedBox(width: DashboardTheme.spacing16), _buildQuickStat( 'Croissance', '${data.stats.monthlyGrowth.toStringAsFixed(1)}%', Icons.trending_up, ), ], ); } return const SizedBox.shrink(); }, ), ], ), ), ), ), ), actions: [ IconButton( onPressed: _refreshDashboardData, icon: const Icon( Icons.refresh, color: DashboardTheme.white, ), ), IconButton( onPressed: () { // TODO: Ouvrir les paramètres }, icon: const Icon( Icons.settings, color: DashboardTheme.white, ), ), ], ); } Widget _buildQuickStat(String label, String value, IconData icon) { return Container( padding: const EdgeInsets.symmetric( horizontal: DashboardTheme.spacing12, vertical: DashboardTheme.spacing8, ), decoration: BoxDecoration( color: DashboardTheme.white.withOpacity(0.15), borderRadius: BorderRadius.circular(DashboardTheme.borderRadius), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, color: DashboardTheme.white, size: 16, ), const SizedBox(width: DashboardTheme.spacing8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( value, style: DashboardTheme.bodyMedium.copyWith( color: DashboardTheme.white, fontWeight: FontWeight.bold, ), ), Text( label, style: DashboardTheme.bodySmall.copyWith( color: DashboardTheme.white.withOpacity(0.8), ), ), ], ), ], ), ); } Widget _buildTabBar() { return Container( color: DashboardTheme.white, child: TabBar( controller: _tabController, labelColor: DashboardTheme.royalBlue, unselectedLabelColor: DashboardTheme.grey500, indicatorColor: DashboardTheme.royalBlue, tabs: const [ Tab(text: 'Vue d\'ensemble', icon: Icon(Icons.dashboard)), Tab(text: 'Analytics', icon: Icon(Icons.analytics)), Tab(text: 'Rapports', icon: Icon(Icons.assessment)), ], ), ); } Widget _buildOverviewTab() { return RefreshIndicator( onRefresh: () async => _refreshDashboardData(), color: DashboardTheme.royalBlue, child: SingleChildScrollView( padding: const EdgeInsets.all(DashboardTheme.spacing16), child: Column( children: [ // Métriques temps réel RealTimeMetricsWidget( organizationId: widget.organizationId, userId: widget.userId, ), const SizedBox(height: DashboardTheme.spacing24), // Grille de statistiques _buildStatsGrid(), const SizedBox(height: DashboardTheme.spacing24), // Notifications const DashboardNotificationsWidget(maxNotifications: 3), const SizedBox(height: DashboardTheme.spacing24), // Activités et événements const Row( children: [ Expanded( child: ConnectedRecentActivities(maxItems: 3), ), SizedBox(width: DashboardTheme.spacing16), Expanded( child: ConnectedUpcomingEvents(maxItems: 2), ), ], ), ], ), ), ); } Widget _buildAnalyticsTab() { return const SingleChildScrollView( padding: EdgeInsets.all(DashboardTheme.spacing16), child: Column( children: [ Row( children: [ Expanded( child: DashboardChartWidget( title: 'Activité des Membres', chartType: DashboardChartType.memberActivity, height: 250, ), ), SizedBox(width: DashboardTheme.spacing16), Expanded( child: DashboardChartWidget( title: 'Croissance Mensuelle', chartType: DashboardChartType.monthlyGrowth, height: 250, ), ), ], ), SizedBox(height: DashboardTheme.spacing24), DashboardChartWidget( title: 'Tendance des Contributions', chartType: DashboardChartType.contributionTrend, height: 300, ), SizedBox(height: DashboardTheme.spacing24), DashboardChartWidget( title: 'Participation aux Événements', chartType: DashboardChartType.eventParticipation, height: 250, ), ], ), ); } Widget _buildReportsTab() { return SingleChildScrollView( padding: const EdgeInsets.all(DashboardTheme.spacing16), child: Column( children: [ _buildReportCard( 'Rapport Mensuel', 'Synthèse complète des activités du mois', Icons.calendar_month, DashboardTheme.royalBlue, ), const SizedBox(height: DashboardTheme.spacing16), _buildReportCard( 'Rapport Financier', 'État des contributions et finances', Icons.account_balance, DashboardTheme.tealBlue, ), const SizedBox(height: DashboardTheme.spacing16), _buildReportCard( 'Rapport d\'Activité', 'Analyse de l\'engagement des membres', Icons.trending_up, DashboardTheme.success, ), const SizedBox(height: DashboardTheme.spacing16), _buildReportCard( 'Rapport Événements', 'Statistiques des événements organisés', Icons.event_note, DashboardTheme.warning, ), ], ), ); } Widget _buildStatsGrid() { return GridView.count( crossAxisCount: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisSpacing: DashboardTheme.spacing16, mainAxisSpacing: DashboardTheme.spacing16, childAspectRatio: 1.2, children: [ ConnectedStatsCard( title: 'Membres totaux', icon: Icons.people, valueExtractor: (stats) => stats.totalMembers.toString(), subtitleExtractor: (stats) => '${stats.activeMembers} actifs', customColor: DashboardTheme.royalBlue, ), ConnectedStatsCard( title: 'Contributions', icon: Icons.payment, valueExtractor: (stats) => stats.formattedContributionAmount, subtitleExtractor: (stats) => '${stats.totalContributions} versements', customColor: DashboardTheme.tealBlue, ), ConnectedStatsCard( title: 'Événements', icon: Icons.event, valueExtractor: (stats) => stats.totalEvents.toString(), subtitleExtractor: (stats) => '${stats.upcomingEvents} à venir', customColor: DashboardTheme.success, ), ConnectedStatsCard( title: 'Engagement', icon: Icons.favorite, valueExtractor: (stats) => '${(stats.engagementRate * 100).toStringAsFixed(0)}%', subtitleExtractor: (stats) => stats.isHighEngagement ? 'Excellent' : 'Moyen', customColor: DashboardTheme.warning, ), ], ); } Widget _buildReportCard(String title, String description, IconData icon, Color color) { return Container( decoration: DashboardTheme.cardDecoration, padding: const EdgeInsets.all(DashboardTheme.spacing16), child: Row( children: [ Container( padding: const EdgeInsets.all(DashboardTheme.spacing12), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(DashboardTheme.borderRadius), ), child: Icon( icon, color: color, size: 24, ), ), const SizedBox(width: DashboardTheme.spacing16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: DashboardTheme.titleSmall, ), const SizedBox(height: DashboardTheme.spacing4), Text( description, style: DashboardTheme.bodySmall, ), ], ), ), IconButton( onPressed: () { // TODO: Générer le rapport }, icon: Icon( Icons.download, color: color, ), ), ], ), ); } Widget _buildFloatingActionButton() { return FloatingActionButton.extended( onPressed: () { // TODO: Actions rapides }, backgroundColor: DashboardTheme.royalBlue, foregroundColor: DashboardTheme.white, icon: const Icon(Icons.add), label: const Text('Action'), ); } @override void dispose() { _tabController.dispose(); _dashboardBloc.close(); super.dispose(); } }