Files
unionflow-mobile-apps/lib/features/dashboard/presentation/widgets/navigation/dashboard_navigation.dart
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

417 lines
14 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../../shared/design_system/unionflow_design_system.dart';
import '../../pages/connected_dashboard_page.dart';
import '../../pages/advanced_dashboard_page.dart';
import '../../../../settings/presentation/pages/language_settings_page.dart';
import '../../../../settings/presentation/pages/system_settings_page.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 '../../../../contributions/presentation/pages/contributions_page_wrapper.dart';
/// Widget de navigation pour les différents types de dashboard
class DashboardNavigation extends StatefulWidget {
final String organizationId;
final String userId;
const DashboardNavigation({
super.key,
required this.organizationId,
required this.userId,
});
@override
State<DashboardNavigation> createState() => _DashboardNavigationState();
}
class _DashboardNavigationState extends State<DashboardNavigation> {
int _currentIndex = 0;
final List<DashboardTab> _tabs = [
const DashboardTab(
title: 'Accueil',
icon: Icons.home,
activeIcon: Icons.home,
type: DashboardType.home,
),
const DashboardTab(
title: 'Analytics',
icon: Icons.analytics_outlined,
activeIcon: Icons.analytics,
type: DashboardType.analytics,
),
const DashboardTab(
title: 'Rapports',
icon: Icons.assessment_outlined,
activeIcon: Icons.assessment,
type: DashboardType.reports,
),
const DashboardTab(
title: 'Paramètres',
icon: Icons.settings_outlined,
activeIcon: Icons.settings,
type: DashboardType.settings,
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildCurrentPage(),
bottomNavigationBar: _buildBottomNavigationBar(),
floatingActionButton: _buildFloatingActionButton(),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
Widget _buildCurrentPage() {
switch (_tabs[_currentIndex].type) {
case DashboardType.home:
return ConnectedDashboardPage(
organizationId: widget.organizationId,
userId: widget.userId,
);
case DashboardType.analytics:
return AdvancedDashboardPage(
organizationId: widget.organizationId,
userId: widget.userId,
);
case DashboardType.reports:
return _buildReportsPage();
case DashboardType.settings:
return _buildSettingsPage();
}
}
Widget _buildBottomNavigationBar() {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, -2),
),
],
),
child: BottomAppBar(
shape: const CircularNotchedRectangle(),
notchMargin: 8,
color: Theme.of(context).cardColor,
elevation: 0,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: _tabs.asMap().entries.map((entry) {
final index = entry.key;
final tab = entry.value;
final isActive = index == _currentIndex;
// Skip the middle item for FAB space
if (index == 2) {
return const SizedBox(width: 40);
}
return _buildNavItem(tab, isActive, index);
}).toList(),
),
),
),
);
}
Widget _buildNavItem(DashboardTab tab, bool isActive, int index) {
return GestureDetector(
onTap: () => setState(() => _currentIndex = index),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
isActive ? tab.activeIcon : tab.icon,
color: isActive ? AppColors.primaryGreen : AppColors.textSecondaryLight,
size: 20,
),
const SizedBox(height: 4),
Text(
tab.title,
style: AppTypography.badgeText.copyWith(
color: isActive ? AppColors.primaryGreen : AppColors.textSecondaryLight,
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
fontSize: 9,
),
),
],
),
),
);
}
Widget _buildFloatingActionButton() {
return FloatingActionButton(
onPressed: _showQuickActions,
backgroundColor: AppColors.primaryGreen,
elevation: 4,
child: const Icon(
Icons.add_outlined,
color: Colors.white,
size: 28,
),
);
}
Widget _buildReportsPage() {
return Scaffold(
appBar: AppBar(
title: Text('Rapports'.toUpperCase(), style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 1.1)),
backgroundColor: AppColors.primaryGreen,
foregroundColor: Colors.white,
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.assessment_outlined,
size: 48,
color: AppColors.textSecondaryLight,
),
const SizedBox(height: 16),
Text(
'Page Rapports'.toUpperCase(),
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
'En cours de développement',
style: AppTypography.bodyTextSmall.copyWith(
color: AppColors.textSecondaryLight,
),
),
],
),
),
);
}
Widget _buildSettingsPage() {
return Scaffold(
appBar: AppBar(
title: Text('Paramètres'.toUpperCase(), style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 1.1)),
backgroundColor: AppColors.primaryGreen,
foregroundColor: Colors.white,
automaticallyImplyLeading: false,
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildSettingsSection(
'Apparence',
[
_buildSettingsTile(
'Thème',
'Design System UnionFlow',
Icons.palette_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage())),
),
_buildSettingsTile(
'Langue',
'Français',
Icons.language_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const LanguageSettingsPage())),
),
],
),
const SizedBox(height: 24),
_buildSettingsSection(
'Notifications',
[
_buildSettingsTile(
'Notifications push',
'Activées',
Icons.notifications_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage())),
),
_buildSettingsTile(
'Emails',
'Quotidien',
Icons.email_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage())),
),
],
),
const SizedBox(height: 24),
_buildSettingsSection(
'Données',
[
_buildSettingsTile(
'Synchronisation',
'Automatique',
Icons.sync_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage())),
),
_buildSettingsTile(
'Cache',
'Vider le cache',
Icons.storage_outlined,
() => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage())),
),
],
),
],
),
);
}
Widget _buildSettingsSection(String title, List<Widget> children) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title.toUpperCase(),
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, color: AppColors.primaryGreen, fontSize: 10),
),
const SizedBox(height: 12),
Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.lightBorder),
),
child: Column(children: children),
),
],
);
}
Widget _buildSettingsTile(
String title,
String subtitle,
IconData icon,
VoidCallback onTap,
) {
return ListTile(
leading: Icon(icon, color: AppColors.primaryGreen, size: 20),
title: Text(title, style: AppTypography.actionText.copyWith(fontSize: 13)),
subtitle: Text(subtitle, style: AppTypography.subtitleSmall.copyWith(fontSize: 10)),
trailing: const Icon(
Icons.chevron_right_outlined,
color: AppColors.textSecondaryLight,
size: 16,
),
onTap: onTap,
);
}
void _showQuickActions() {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (context) => Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: AppColors.lightBorder,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 20),
Text(
'ACTIONS RAPIDES',
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
),
const SizedBox(height: 20),
GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisSpacing: 12,
mainAxisSpacing: 12,
children: [
_buildQuickActionItem(context, 'Nouveau\nMembre', Icons.person_add_outlined, AppColors.success, () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const MembersPageWrapper()))),
_buildQuickActionItem(context, 'Créer\nÉvénement', Icons.event_available_outlined, AppColors.primaryGreen, () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const EventsPageWrapper()))),
_buildQuickActionItem(context, 'Ajouter\nContribution', Icons.account_balance_wallet_outlined, AppColors.brandGreen, () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const ContributionsPageWrapper()))),
_buildQuickActionItem(context, 'Générer\nRapport', Icons.assessment_outlined, AppColors.info, () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const ReportsPageWrapper()))),
_buildQuickActionItem(context, 'Paramètres', Icons.settings_outlined, AppColors.textSecondaryLight, () => Navigator.of(context).push(MaterialPageRoute<void>(builder: (_) => const SystemSettingsPage()))),
],
),
const SizedBox(height: 20),
],
),
),
);
}
Widget _buildQuickActionItem(BuildContext context, String title, IconData icon, Color color, VoidCallback onNavigate) {
return GestureDetector(
onTap: () {
Navigator.pop(context);
onNavigate();
},
child: Container(
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.all(12),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color, size: 20),
const SizedBox(height: 8),
Text(
title,
style: AppTypography.subtitleSmall.copyWith(
color: AppColors.textPrimaryLight,
fontSize: 9,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
],
),
),
);
}
}
class DashboardTab {
final String title;
final IconData icon;
final IconData activeIcon;
final DashboardType type;
const DashboardTab({
required this.title,
required this.icon,
required this.activeIcon,
required this.type,
});
}
enum DashboardType {
home,
analytics,
reports,
settings,
}