Refactoring - Version OK

This commit is contained in:
dahoud
2025-11-17 16:02:04 +00:00
parent 3f00a26308
commit 3b9ffac8cd
198 changed files with 18010 additions and 11383 deletions

View File

@@ -0,0 +1,483 @@
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<AdvancedDashboardPage> createState() => _AdvancedDashboardPageState();
}
class _AdvancedDashboardPageState extends State<AdvancedDashboardPage>
with TickerProviderStateMixin {
late DashboardBloc _dashboardBloc;
late TabController _tabController;
@override
void initState() {
super.initState();
_dashboardBloc = sl<DashboardBloc>();
_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<DashboardBloc, DashboardState>(
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();
}
}