import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fl_chart/fl_chart.dart'; import '../../../../../shared/design_system/unionflow_design_v2.dart'; import '../../bloc/dashboard_bloc.dart'; import '../../widgets/dashboard_drawer.dart'; import '../../../../authentication/presentation/bloc/auth_bloc.dart'; import '../../../../reports/presentation/pages/reports_page_wrapper.dart'; import '../../../../members/presentation/pages/members_page_wrapper.dart'; import '../../../../events/presentation/pages/events_page_wrapper.dart'; import '../../../../help/presentation/pages/help_support_page.dart'; /// Dashboard Consultant - Design UnionFlow Expertise & Analyses class ConsultantDashboard extends StatelessWidget { const ConsultantDashboard({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: UnionFlowColors.background, appBar: _buildAppBar(context), drawer: DashboardDrawer( onLogout: () => context.read().add(const AuthLogoutRequested()), ), body: AfricanPatternBackground( child: BlocBuilder( builder: (context, dashboardState) { if (dashboardState is DashboardLoading) { return const Center( child: CircularProgressIndicator(color: UnionFlowColors.amber), ); } final dashboardData = (dashboardState is DashboardLoaded) ? dashboardState.dashboardData : null; final stats = dashboardData?.stats; return SingleChildScrollView( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // En-tête Consultant AnimatedFadeIn( delay: const Duration(milliseconds: 100), child: UserIdentityCard( initials: 'CON', name: 'Consultant Expert', subtitle: 'Expertise & Analyses Stratégiques', badgeLabel: 'EXPERT', gradient: LinearGradient( colors: [UnionFlowColors.amber, UnionFlowColors.gold], begin: Alignment.topLeft, end: Alignment.bottomRight, ), accentColor: UnionFlowColors.amber, ), ), const SizedBox(height: 12), // Stats missions AnimatedSlideIn( delay: const Duration(milliseconds: 200), child: GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, mainAxisSpacing: 6, crossAxisSpacing: 6, childAspectRatio: 2.0, children: [ UnionStatWidget( label: 'Événements', value: '${stats?.totalEvents ?? 0}', icon: Icons.work_outline, color: UnionFlowColors.amber, trend: stats?.upcomingEvents != null ? '${stats!.upcomingEvents} à venir' : null, isTrendUp: true, ), UnionStatWidget( label: 'Organisations', value: '${stats?.totalOrganizations ?? 0}', icon: Icons.business_outlined, color: UnionFlowColors.indigo, ), UnionStatWidget( label: 'Demandes', value: '${stats?.pendingRequests ?? 0}', icon: Icons.pending_actions, color: UnionFlowColors.warning, ), UnionStatWidget( label: 'Membres', value: '${stats?.totalMembers ?? 0}', icon: Icons.people_outline, color: UnionFlowColors.success, ), ], ), ), const SizedBox(height: 12), // Événements à venir if (dashboardData != null && dashboardData.hasUpcomingEvents) ...[ AnimatedFadeIn( delay: const Duration(milliseconds: 400), child: UFSectionHeader( 'Prochains Événements', trailing: '${dashboardData.upcomingEvents.length} programmés', ), ), const SizedBox(height: 8), AnimatedSlideIn( delay: const Duration(milliseconds: 500), child: Column( children: dashboardData.upcomingEvents.take(3).map((event) => DashboardEventRow( title: event.title, date: event.formattedDate, ), ).toList(), ), ), const SizedBox(height: 12), ], // Répartition organisations par type if (stats != null && stats.organizationTypeDistribution != null && stats.organizationTypeDistribution!.isNotEmpty) ...[ AnimatedFadeIn( delay: const Duration(milliseconds: 600), child: UnionPieChart( title: 'Répartition Organisations', subtitle: 'Par type', sections: _buildOrgTypeSections(stats.organizationTypeDistribution!), ), ), const SizedBox(height: 12), ], // Mes Outils AnimatedFadeIn( delay: const Duration(milliseconds: 700), child: const UFSectionHeader('Mes Outils'), ), const SizedBox(height: 8), AnimatedSlideIn( delay: const Duration(milliseconds: 700), child: GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 3, mainAxisSpacing: 6, crossAxisSpacing: 6, childAspectRatio: 2.8, children: [ UnionActionButton( label: 'Audits', icon: Icons.assessment, iconColor: UnionFlowColors.unionGreen, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const ReportsPageWrapper())), ), UnionActionButton( label: 'Analyses', icon: Icons.analytics, iconColor: UnionFlowColors.indigo, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const ReportsPageWrapper())), ), UnionActionButton( label: 'Rapports', icon: Icons.description, iconColor: UnionFlowColors.gold, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const ReportsPageWrapper())), ), UnionActionButton( label: 'Clients', icon: Icons.people_outline, iconColor: UnionFlowColors.amber, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const MembersPageWrapper())), ), UnionActionButton( label: 'Calendrier', icon: Icons.calendar_today, iconColor: UnionFlowColors.terracotta, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const EventsPageWrapper())), ), UnionActionButton( label: 'Documents', icon: Icons.folder_outlined, iconColor: UnionFlowColors.info, onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const HelpSupportPage())), ), ], ), ), ], ), ); }, ), ), ); } PreferredSizeWidget _buildAppBar(BuildContext context) { return AppBar( backgroundColor: UnionFlowColors.surface, elevation: 0, title: Row( children: [ Container( width: 32, height: 32, decoration: BoxDecoration( gradient: LinearGradient( colors: [UnionFlowColors.amber, UnionFlowColors.gold], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(8), ), alignment: Alignment.center, child: const Text('C', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w900, fontSize: 18)), ), const SizedBox(width: 12), const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('UnionFlow', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: UnionFlowColors.textPrimary)), Text('Consultant', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w400, color: UnionFlowColors.textSecondary)), ], ), ], ), iconTheme: const IconThemeData(color: UnionFlowColors.textPrimary), actions: [ UnionExportButton( onExport: (_) => Navigator.of(context).push( MaterialPageRoute(builder: (_) => const ReportsPageWrapper()), ), ), const SizedBox(width: 8), ], ); } List _buildOrgTypeSections(Map distribution) { const colors = [ UnionFlowColors.unionGreen, UnionFlowColors.gold, UnionFlowColors.indigo, UnionFlowColors.amber, UnionFlowColors.terracotta, ]; final total = distribution.values.fold(0, (sum, value) => sum + value); final entries = distribution.entries.toList(); return List.generate(entries.length.clamp(0, 5), (index) { final entry = entries[index]; final percentage = total > 0 ? (entry.value / total * 100).toStringAsFixed(0) : '0'; return UnionPieChartSection.create( value: entry.value.toDouble(), color: colors[index % colors.length], title: '$percentage%\n${entry.key}', ); }); } }