import 'package:flutter/material.dart'; import '../../../../shared/theme/app_theme.dart'; import '../widgets/kpi_card.dart'; import '../widgets/clickable_kpi_card.dart'; import '../widgets/chart_card.dart'; import '../widgets/activity_feed.dart'; import '../widgets/quick_actions_grid.dart'; import '../widgets/navigation_cards.dart'; class EnhancedDashboard extends StatefulWidget { final Function(int)? onNavigateToTab; const EnhancedDashboard({ super.key, this.onNavigateToTab, }); @override State createState() => _EnhancedDashboardState(); } class _EnhancedDashboardState extends State { final PageController _pageController = PageController(); int _currentPage = 0; @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppTheme.backgroundLight, body: CustomScrollView( slivers: [ _buildAppBar(), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildWelcomeCard(), const SizedBox(height: 24), _buildKPISection(), const SizedBox(height: 24), _buildChartsSection(), const SizedBox(height: 24), NavigationCards( onNavigateToTab: widget.onNavigateToTab, ), const SizedBox(height: 24), const QuickActionsGrid(), const SizedBox(height: 24), const ActivityFeed(), const SizedBox(height: 24), ], ), ), ), ], ), ); } Widget _buildAppBar() { return SliverAppBar( expandedHeight: 120, floating: false, pinned: true, backgroundColor: AppTheme.primaryColor, flexibleSpace: FlexibleSpaceBar( title: const Text( 'Tableau de bord', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), background: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [AppTheme.primaryColor, AppTheme.primaryDark], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), ), ), actions: [ IconButton( icon: const Icon(Icons.notifications_outlined), onPressed: () => _showNotifications(), ), IconButton( icon: const Icon(Icons.refresh), onPressed: () => _refreshData(), ), PopupMenuButton( icon: const Icon(Icons.more_vert), onSelected: _handleMenuSelection, itemBuilder: (context) => [ const PopupMenuItem( value: 'settings', child: Row( children: [ Icon(Icons.settings), SizedBox(width: 8), Text('Paramètres'), ], ), ), const PopupMenuItem( value: 'export', child: Row( children: [ Icon(Icons.download), SizedBox(width: 8), Text('Exporter'), ], ), ), const PopupMenuItem( value: 'help', child: Row( children: [ Icon(Icons.help), SizedBox(width: 8), Text('Aide'), ], ), ), ], ), ], ); } Widget _buildWelcomeCard() { return Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( gradient: LinearGradient( colors: [AppTheme.primaryColor, AppTheme.primaryLight], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: AppTheme.primaryColor.withOpacity(0.3), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Bonjour !', style: TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( 'Découvrez les dernières statistiques de votre association', style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 16, ), ), const SizedBox(height: 16), Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.trending_up, color: Colors.white, size: 16, ), const SizedBox(width: 4), Text( '+12% ce mois', style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.w600, ), ), ], ), ), ], ), ], ), ), Container( width: 80, height: 80, decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(40), ), child: const Icon( Icons.dashboard_rounded, color: Colors.white, size: 40, ), ), ], ), ); } Widget _buildKPISection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Indicateurs clés', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: AppTheme.textPrimary, ), ), TextButton.icon( onPressed: () {}, icon: const Icon(Icons.analytics, size: 16), label: const Text('Analyse détaillée'), ), ], ), const SizedBox(height: 16), SizedBox( height: 180, child: PageView( controller: _pageController, onPageChanged: (index) { setState(() { _currentPage = index; }); }, children: [ _buildKPIPage1(), _buildKPIPage2(), ], ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildPageIndicator(0), const SizedBox(width: 8), _buildPageIndicator(1), ], ), ], ); } Widget _buildKPIPage1() { return Row( children: [ Expanded( child: ClickableKPICard( title: 'Membres actifs', value: '1,247', change: '+5.2%', icon: Icons.people, color: AppTheme.secondaryColor, actionText: 'Gérer', onTap: () => widget.onNavigateToTab?.call(1), ), ), const SizedBox(width: 12), Expanded( child: ClickableKPICard( title: 'Revenus mensuel', value: '€45,890', change: '+12.8%', icon: Icons.euro, color: AppTheme.successColor, actionText: 'Finances', onTap: () => _showFinancesMessage(), ), ), ], ); } Widget _buildKPIPage2() { return Row( children: [ Expanded( child: ClickableKPICard( title: 'Événements', value: '23', change: '+3', icon: Icons.event, color: AppTheme.warningColor, actionText: 'Planifier', onTap: () => widget.onNavigateToTab?.call(3), ), ), const SizedBox(width: 12), Expanded( child: ClickableKPICard( title: 'Taux cotisation', value: '89.5%', change: '+2.1%', icon: Icons.payments, color: AppTheme.accentColor, actionText: 'Gérer', onTap: () => widget.onNavigateToTab?.call(2), ), ), ], ); } Widget _buildPageIndicator(int index) { return AnimatedContainer( duration: const Duration(milliseconds: 300), width: _currentPage == index ? 20 : 8, height: 8, decoration: BoxDecoration( color: _currentPage == index ? AppTheme.primaryColor : AppTheme.primaryColor.withOpacity(0.3), borderRadius: BorderRadius.circular(4), ), ); } Widget _buildChartsSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Analyses et tendances', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: AppTheme.textPrimary, ), ), const SizedBox(height: 16), ChartCard( title: 'Évolution des membres', subtitle: 'Croissance sur 6 mois', chart: const MembershipChart(), onTap: () => widget.onNavigateToTab?.call(1), ), const SizedBox(height: 16), Row( children: [ Expanded( child: ChartCard( title: 'Répartition', subtitle: 'Par catégorie', chart: const CategoryChart(), onTap: () => widget.onNavigateToTab?.call(1), ), ), const SizedBox(width: 12), Expanded( child: ChartCard( title: 'Revenus', subtitle: 'Évolution mensuelle', chart: const RevenueChart(), onTap: () => _showFinancesMessage(), ), ), ], ), ], ); } void _showNotifications() { showModalBottomSheet( context: context, builder: (context) => Container( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text( 'Notifications', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), ListTile( leading: const Icon(Icons.warning, color: AppTheme.warningColor), title: const Text('3 cotisations en retard'), subtitle: const Text('Nécessite votre attention'), onTap: () {}, ), ListTile( leading: const Icon(Icons.event, color: AppTheme.accentColor), title: const Text('Assemblée générale'), subtitle: const Text('Dans 5 jours'), onTap: () {}, ), ListTile( leading: const Icon(Icons.check_circle, color: AppTheme.successColor), title: const Text('Rapport mensuel'), subtitle: const Text('Prêt à être envoyé'), onTap: () {}, ), ], ), ), ); } void _refreshData() { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Données actualisées'), backgroundColor: AppTheme.successColor, behavior: SnackBarBehavior.floating, ), ); } void _handleMenuSelection(String value) { switch (value) { case 'settings': ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Paramètres - En développement')), ); break; case 'export': ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Export - En développement')), ); break; case 'help': ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Aide - En développement')), ); break; } } void _showFinancesMessage() { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Module Finances - Prochainement disponible'), backgroundColor: AppTheme.successColor, behavior: SnackBarBehavior.floating, ), ); } }