Authentification stable - WIP

This commit is contained in:
DahoudG
2025-09-19 12:35:46 +00:00
parent 63fe107f98
commit 098894bdc1
383 changed files with 13072 additions and 93334 deletions

View File

@@ -0,0 +1,322 @@
/// Dashboard Membre Actif - Activity Center Personnalisé
/// Interface personnalisée pour participation active
library active_member_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Activity Center pour Membre Actif
class ActiveMemberDashboard extends StatelessWidget {
const ActiveMemberDashboard({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar Membre Actif
SliverAppBar(
expandedHeight: 160,
floating: false,
pinned: true,
backgroundColor: const Color(0xFF00B894), // Vert communauté
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Activity Center',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF00B894), Color(0xFF00A085)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: const Center(
child: Icon(Icons.groups, color: Colors.white, size: 60),
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Bienvenue personnalisé
_buildPersonalizedWelcome(),
const SizedBox(height: SpacingTokens.xl),
// Mes statistiques
_buildMyStats(),
const SizedBox(height: SpacingTokens.xl),
// Actions membres
_buildMemberActions(),
const SizedBox(height: SpacingTokens.xl),
// Événements à venir
_buildUpcomingEvents(),
const SizedBox(height: SpacingTokens.xl),
// Mon activité
_buildMyActivity(),
],
),
),
),
],
),
);
}
Widget _buildPersonalizedWelcome() {
return Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF00B894), Color(0xFF00CEC9)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(RadiusTokens.lg),
),
child: Row(
children: [
const CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: Icon(Icons.person, color: Color(0xFF00B894), size: 30),
),
const SizedBox(width: SpacingTokens.md),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Bonjour, Marie !',
style: TypographyTokens.headlineMedium.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Membre depuis 2 ans • Niveau Actif',
style: TypographyTokens.bodyMedium.copyWith(
color: Colors.white.withOpacity(0.9),
),
),
],
),
),
],
),
);
}
Widget _buildMyStats() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Mes Statistiques',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardStatsGrid(
stats: [
DashboardStat(
icon: Icons.event_available,
value: '12',
title: 'Événements',
color: const Color(0xFF00B894),
onTap: () {},
),
DashboardStat(
icon: Icons.volunteer_activism,
value: '3',
title: 'Solidarité',
color: const Color(0xFF00CEC9),
onTap: () {},
),
DashboardStat(
icon: Icons.payment,
value: 'À jour',
title: 'Cotisations',
color: const Color(0xFF0984E3),
onTap: () {},
),
DashboardStat(
icon: Icons.star,
value: '4.8',
title: 'Engagement',
color: const Color(0xFFE17055),
onTap: () {},
),
],
onStatTap: (type) {},
),
],
);
}
Widget _buildMemberActions() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Actions Rapides',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardQuickActionsGrid(
actions: [
DashboardQuickAction(
icon: Icons.event,
title: 'Créer Événement',
subtitle: 'Organiser activité',
color: const Color(0xFF00B894),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.volunteer_activism,
title: 'Demande Aide',
subtitle: 'Solidarité',
color: const Color(0xFF00CEC9),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.account_circle,
title: 'Mon Profil',
subtitle: 'Modifier infos',
color: const Color(0xFF0984E3),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.message,
title: 'Contacter',
subtitle: 'Support',
color: const Color(0xFFE17055),
onTap: () {},
),
],
onActionTap: (type) {},
),
],
);
}
Widget _buildUpcomingEvents() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'Événements à Venir',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const Spacer(),
TextButton(
onPressed: () {},
child: const Text('Voir tout'),
),
],
),
const SizedBox(height: SpacingTokens.md),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF00B894).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('15', style: TextStyle(fontWeight: FontWeight.bold)),
Text('DÉC', style: TextStyle(fontSize: 10)),
],
),
),
title: const Text('Assemblée Générale'),
subtitle: const Text('Salle communale • 19h00'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
),
const Divider(height: 1),
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF00CEC9).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('22', style: TextStyle(fontWeight: FontWeight.bold)),
Text('DÉC', style: TextStyle(fontSize: 10)),
],
),
),
title: const Text('Soirée de Noël'),
subtitle: const Text('Restaurant Le Gourmet • 20h00'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
),
],
),
),
],
);
}
Widget _buildMyActivity() {
return DashboardRecentActivitySection(
activities: [
DashboardActivity(
title: 'Participation confirmée',
subtitle: 'Assemblée Générale',
icon: Icons.check_circle,
color: const Color(0xFF00B894),
time: 'Il y a 2h',
),
DashboardActivity(
title: 'Cotisation payée',
subtitle: 'Décembre 2024',
icon: Icons.payment,
color: const Color(0xFF0984E3),
time: 'Il y a 1j',
),
DashboardActivity(
title: 'Événement créé',
subtitle: 'Sortie ski de fond',
icon: Icons.event,
color: const Color(0xFF00CEC9),
time: 'Il y a 3j',
),
],
onActivityTap: (id) {},
);
}
}

View File

@@ -0,0 +1,236 @@
/// Dashboard Modérateur - Management Hub Focalisé
/// Outils de modération et gestion partielle
library moderator_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Management Hub pour Modérateur
class ModeratorDashboard extends StatelessWidget {
const ModeratorDashboard({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar Modérateur
SliverAppBar(
expandedHeight: 160,
floating: false,
pinned: true,
backgroundColor: const Color(0xFFE17055), // Orange focus
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Management Hub',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFFE17055), Color(0xFFD63031)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: const Center(
child: Icon(Icons.manage_accounts, color: Colors.white, size: 60),
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Métriques modération
_buildModerationMetrics(),
const SizedBox(height: SpacingTokens.xl),
// Actions modération
_buildModerationActions(),
const SizedBox(height: SpacingTokens.xl),
// Tâches en attente
_buildPendingTasks(),
const SizedBox(height: SpacingTokens.xl),
// Activité récente
_buildRecentActivity(),
],
),
),
),
],
),
);
}
Widget _buildModerationMetrics() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Métriques de Modération',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardStatsGrid(
stats: [
DashboardStat(
icon: Icons.flag,
value: '12',
title: 'Signalements',
color: const Color(0xFFE17055),
onTap: () {},
),
DashboardStat(
icon: Icons.pending_actions,
value: '8',
title: 'En Attente',
color: const Color(0xFFD63031),
onTap: () {},
),
DashboardStat(
icon: Icons.check_circle,
value: '45',
title: 'Résolus',
color: const Color(0xFF00B894),
onTap: () {},
),
DashboardStat(
icon: Icons.people,
value: '156',
title: 'Membres',
color: const Color(0xFF0984E3),
onTap: () {},
),
],
onStatTap: (type) {},
),
],
);
}
Widget _buildModerationActions() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Actions de Modération',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardQuickActionsGrid(
actions: [
DashboardQuickAction(
icon: Icons.gavel,
title: 'Modérer',
subtitle: 'Contenu signalé',
color: const Color(0xFFE17055),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.person_remove,
title: 'Suspendre',
subtitle: 'Membre problématique',
color: const Color(0xFFD63031),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.message,
title: 'Communiquer',
subtitle: 'Envoyer message',
color: const Color(0xFF0984E3),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.report,
title: 'Rapport',
subtitle: 'Activité modération',
color: const Color(0xFF6C5CE7),
onTap: () {},
),
],
onActionTap: (type) {},
),
],
);
}
Widget _buildPendingTasks() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tâches en Attente',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
ListTile(
leading: const CircleAvatar(
backgroundColor: Color(0xFFFFE0E0),
child: Icon(Icons.flag, color: Color(0xFFD63031)),
),
title: const Text('Contenu inapproprié signalé'),
subtitle: const Text('Commentaire sur événement'),
trailing: const Text('Urgent'),
),
const Divider(height: 1),
ListTile(
leading: const CircleAvatar(
backgroundColor: Color(0xFFFFF3E0),
child: Icon(Icons.person_add, color: Color(0xFFE17055)),
),
title: const Text('Demande d\'adhésion'),
subtitle: const Text('Marie Dubois'),
trailing: const Text('2j'),
),
],
),
),
],
);
}
Widget _buildRecentActivity() {
return DashboardRecentActivitySection(
activities: [
DashboardActivity(
title: 'Signalement traité',
subtitle: 'Contenu supprimé',
icon: Icons.check_circle,
color: const Color(0xFF00B894),
time: 'Il y a 1h',
),
DashboardActivity(
title: 'Membre suspendu',
subtitle: 'Violation des règles',
icon: Icons.person_remove,
color: const Color(0xFFD63031),
time: 'Il y a 3h',
),
],
onActivityTap: (id) {},
);
}
}

View File

@@ -0,0 +1,558 @@
/// Dashboard Administrateur d'Organisation - Control Panel Sophistiqué
/// Gestion complète de l'organisation avec outils avancés
library org_admin_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Control Panel pour Administrateur d'Organisation
///
/// Fonctionnalités exclusives :
/// - Gestion complète des membres
/// - Contrôle financier avancé
/// - Configuration organisation
/// - Rapports et analytics
/// - Outils de communication
class OrgAdminDashboard extends StatefulWidget {
const OrgAdminDashboard({super.key});
@override
State<OrgAdminDashboard> createState() => _OrgAdminDashboardState();
}
class _OrgAdminDashboardState extends State<OrgAdminDashboard> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar avec gradient Org Admin
SliverAppBar(
expandedHeight: 180,
floating: false,
pinned: true,
backgroundColor: const Color(0xFF0984E3), // Bleu corporate
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Control Panel',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0984E3), // Bleu principal
Color(0xFF0770C4), // Bleu plus foncé
Color(0xFF055A9F), // Bleu profond
],
),
),
child: Stack(
children: [
// Motif corporate
Positioned.fill(
child: CustomPaint(
painter: _CorporatePatternPainter(),
),
),
// Contenu de l'en-tête
Positioned(
bottom: 60,
left: 20,
right: 20,
child: Row(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(30),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 2,
),
),
child: const Icon(
Icons.business_center,
color: Colors.white,
size: 30,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Administrateur',
style: TypographyTokens.headlineSmall.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Association des Développeurs',
style: TypographyTokens.bodyMedium.copyWith(
color: Colors.white.withOpacity(0.9),
),
),
],
),
),
],
),
),
],
),
),
),
),
// Contenu principal
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Métriques organisation
_buildOrganizationMetricsSection(),
const SizedBox(height: SpacingTokens.xl),
// Actions rapides admin
_buildAdminQuickActionsSection(),
const SizedBox(height: SpacingTokens.xl),
// Gestion des membres
_buildMemberManagementSection(),
const SizedBox(height: SpacingTokens.xl),
// Finances et budget
_buildFinancialOverviewSection(),
const SizedBox(height: SpacingTokens.xl),
// Activité récente
_buildRecentActivitySection(),
],
),
),
),
],
),
);
}
/// Section métriques organisation
Widget _buildOrganizationMetricsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Vue d\'ensemble Organisation',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
DashboardStatsGrid(
stats: [
DashboardStat(
icon: Icons.people,
value: '156',
title: 'Membres Actifs',
color: const Color(0xFF00B894),
onTap: () => _onStatTap('members'),
),
DashboardStat(
icon: Icons.euro,
value: '12,450€',
title: 'Budget Mensuel',
color: const Color(0xFF0984E3),
onTap: () => _onStatTap('budget'),
),
DashboardStat(
icon: Icons.event,
value: '8',
title: 'Événements',
color: const Color(0xFFE17055),
onTap: () => _onStatTap('events'),
),
DashboardStat(
icon: Icons.trending_up,
value: '94%',
title: 'Satisfaction',
color: const Color(0xFF00CEC9),
onTap: () => _onStatTap('satisfaction'),
),
],
onStatTap: _onStatTap,
),
],
);
}
/// Section actions rapides admin
Widget _buildAdminQuickActionsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Actions Administrateur',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: SpacingTokens.md,
mainAxisSpacing: SpacingTokens.md,
childAspectRatio: 2.5,
children: [
_buildAdminActionCard(
'Approuver Membres',
'5 en attente',
Icons.person_add,
const Color(0xFF00B894),
() => _onAdminAction('approve_members'),
),
_buildAdminActionCard(
'Gérer Budget',
'Révision mensuelle',
Icons.account_balance_wallet,
const Color(0xFF0984E3),
() => _onAdminAction('manage_budget'),
),
_buildAdminActionCard(
'Configurer Org',
'Paramètres avancés',
Icons.settings,
const Color(0xFFE17055),
() => _onAdminAction('configure_org'),
),
_buildAdminActionCard(
'Rapports',
'Générer rapport',
Icons.assessment,
const Color(0xFF6C5CE7),
() => _onAdminAction('generate_reports'),
),
],
),
],
);
}
/// Carte d'action admin
Widget _buildAdminActionCard(
String title,
String subtitle,
IconData icon,
Color color,
VoidCallback onTap,
) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(RadiusTokens.md),
child: Container(
padding: const EdgeInsets.all(SpacingTokens.md),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
border: Border.all(
color: color.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
),
child: Icon(icon, color: color, size: 20),
),
const SizedBox(width: SpacingTokens.sm),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
title,
style: TypographyTokens.bodyMedium.copyWith(
fontWeight: FontWeight.w600,
),
),
Text(
subtitle,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
],
),
),
],
),
),
);
}
/// Section gestion des membres
Widget _buildMemberManagementSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'Gestion des Membres',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
TextButton.icon(
onPressed: () => _onViewAllMembers(),
icon: const Icon(Icons.arrow_forward),
label: const Text('Voir tout'),
),
],
),
const SizedBox(height: SpacingTokens.md),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
_buildMemberItem(
'Marie Dubois',
'Demande d\'adhésion',
Icons.person_add,
Colors.orange,
'En attente',
),
const Divider(height: 1),
_buildMemberItem(
'Jean Martin',
'Cotisation en retard',
Icons.warning,
Colors.red,
'15 jours',
),
const Divider(height: 1),
_buildMemberItem(
'Sophie Laurent',
'Nouveau membre actif',
Icons.check_circle,
Colors.green,
'Aujourd\'hui',
),
],
),
),
],
);
}
/// Item de membre
Widget _buildMemberItem(
String name,
String status,
IconData icon,
Color color,
String time,
) {
return ListTile(
leading: CircleAvatar(
backgroundColor: color.withOpacity(0.1),
child: Icon(icon, color: color, size: 20),
),
title: Text(
name,
style: TypographyTokens.bodyMedium.copyWith(
fontWeight: FontWeight.w600,
),
),
subtitle: Text(status),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
time,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
const SizedBox(height: 2),
Icon(
Icons.arrow_forward_ios,
size: 12,
color: ColorTokens.textSecondary,
),
],
),
onTap: () => _onMemberTap(name),
);
}
/// Section aperçu financier
Widget _buildFinancialOverviewSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Aperçu Financier',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
DashboardInsightsSection(
metrics: [
DashboardMetric(
label: 'Cotisations collectées',
value: '89%',
progress: 0.89,
color: const Color(0xFF00B894),
),
DashboardMetric(
label: 'Budget utilisé',
value: '67%',
progress: 0.67,
color: const Color(0xFF0984E3),
),
DashboardMetric(
label: 'Objectif annuel',
value: '78%',
progress: 0.78,
color: const Color(0xFFE17055),
),
],
),
],
);
}
/// Section activité récente
Widget _buildRecentActivitySection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Activité Récente',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
DashboardRecentActivitySection(
activities: [
DashboardActivity(
title: 'Nouveau membre approuvé',
subtitle: 'Sophie Laurent rejoint l\'organisation',
icon: Icons.person_add,
color: const Color(0xFF00B894),
time: 'Il y a 2h',
),
DashboardActivity(
title: 'Budget mis à jour',
subtitle: 'Allocation événements modifiée',
icon: Icons.account_balance_wallet,
color: const Color(0xFF0984E3),
time: 'Il y a 4h',
),
DashboardActivity(
title: 'Rapport généré',
subtitle: 'Rapport mensuel d\'activité',
icon: Icons.assessment,
color: const Color(0xFF6C5CE7),
time: 'Il y a 1j',
),
],
onActivityTap: (activityId) => _onActivityTap(activityId),
),
],
);
}
// === CALLBACKS ===
void _onStatTap(String statType) {
// Navigation vers les détails de la statistique
}
void _onAdminAction(String action) {
// Exécuter l'action admin
}
void _onViewAllMembers() {
// Navigation vers la liste complète des membres
}
void _onMemberTap(String memberName) {
// Navigation vers le profil du membre
}
void _onActivityTap(String activityId) {
// Navigation vers les détails de l'activité
}
}
/// Painter pour le motif corporate de l'en-tête
class _CorporatePatternPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.08)
..strokeWidth = 2
..style = PaintingStyle.stroke;
// Dessiner un motif corporate sophistiqué
for (int i = 0; i < 8; i++) {
final path = Path();
path.moveTo(i * size.width / 8, 0);
path.lineTo(i * size.width / 8 + size.width / 16, size.height);
canvas.drawPath(path, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,11 @@
/// Export de tous les dashboards spécifiques par rôle
/// Facilite l'importation des dashboards dans l'application
library role_dashboards;
// Dashboards spécifiques par rôle
export 'super_admin_dashboard.dart';
export 'org_admin_dashboard.dart';
export 'moderator_dashboard.dart';
export 'active_member_dashboard.dart';
export 'simple_member_dashboard.dart';
export 'visitor_dashboard.dart';

View File

@@ -0,0 +1,371 @@
/// Dashboard Membre Simple - Personal Space Minimaliste
/// Interface simplifiée pour accès basique
library simple_member_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Personal Space pour Membre Simple
class SimpleMemberDashboard extends StatelessWidget {
const SimpleMemberDashboard({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar Membre Simple
SliverAppBar(
expandedHeight: 140,
floating: false,
pinned: true,
backgroundColor: const Color(0xFF00CEC9), // Teal simple
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Mon Espace',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF00CEC9), Color(0xFF00B3B3)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: const Center(
child: Icon(Icons.person, color: Colors.white, size: 50),
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Profil personnel
_buildPersonalProfile(),
const SizedBox(height: SpacingTokens.xl),
// Mes informations
_buildMyInfo(),
const SizedBox(height: SpacingTokens.xl),
// Actions simples
_buildSimpleActions(),
const SizedBox(height: SpacingTokens.xl),
// Événements publics
_buildPublicEvents(),
const SizedBox(height: SpacingTokens.xl),
// Mon historique
_buildMyHistory(),
],
),
),
),
],
),
);
}
Widget _buildPersonalProfile() {
return Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.lg),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
const CircleAvatar(
radius: 35,
backgroundColor: Color(0xFF00CEC9),
child: Icon(Icons.person, color: Colors.white, size: 35),
),
const SizedBox(width: SpacingTokens.md),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pierre Dupont',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
'Membre depuis 6 mois',
style: TypographyTokens.bodyMedium.copyWith(
color: ColorTokens.textSecondary,
),
),
const SizedBox(height: SpacingTokens.sm),
Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: const Color(0xFF00CEC9).withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: Text(
'Membre Simple',
style: TypographyTokens.bodySmall.copyWith(
color: const Color(0xFF00CEC9),
fontWeight: FontWeight.w600,
),
),
),
],
),
),
],
),
);
}
Widget _buildMyInfo() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Mes Informations',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardStatsGrid(
stats: [
DashboardStat(
icon: Icons.payment,
value: 'À jour',
title: 'Cotisations',
color: const Color(0xFF00B894),
onTap: () {},
),
DashboardStat(
icon: Icons.event,
value: '2',
title: 'Événements',
color: const Color(0xFF00CEC9),
onTap: () {},
),
DashboardStat(
icon: Icons.account_circle,
value: '100%',
title: 'Profil',
color: const Color(0xFF0984E3),
onTap: () {},
),
DashboardStat(
icon: Icons.notifications,
value: '3',
title: 'Notifications',
color: const Color(0xFFE17055),
onTap: () {},
),
],
onStatTap: (type) {},
),
],
);
}
Widget _buildSimpleActions() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Actions Disponibles',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardQuickActionsGrid(
actions: [
DashboardQuickAction(
icon: Icons.edit,
title: 'Modifier Profil',
subtitle: 'Mes informations',
color: const Color(0xFF00CEC9),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.payment,
title: 'Mes Cotisations',
subtitle: 'Historique paiements',
color: const Color(0xFF0984E3),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.event,
title: 'Événements',
subtitle: 'Voir les événements',
color: const Color(0xFF00B894),
onTap: () {},
),
DashboardQuickAction(
icon: Icons.help,
title: 'Aide',
subtitle: 'Support & FAQ',
color: const Color(0xFFE17055),
onTap: () {},
),
],
onActionTap: (type) {},
),
],
);
}
Widget _buildPublicEvents() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Événements Disponibles',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF00B894).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Icon(
Icons.event,
color: Color(0xFF00B894),
),
),
title: const Text('Assemblée Générale'),
subtitle: const Text('15 décembre • 19h00'),
trailing: Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: const Color(0xFF00B894).withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: const Text(
'Public',
style: TextStyle(
color: Color(0xFF00B894),
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
),
const Divider(height: 1),
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF00CEC9).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Icon(
Icons.celebration,
color: Color(0xFF00CEC9),
),
),
title: const Text('Soirée de Noël'),
subtitle: const Text('22 décembre • 20h00'),
trailing: Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: const Color(0xFF00CEC9).withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: const Text(
'Public',
style: TextStyle(
color: Color(0xFF00CEC9),
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
),
],
),
),
],
);
}
Widget _buildMyHistory() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Mon Historique',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
DashboardRecentActivitySection(
activities: [
DashboardActivity(
title: 'Cotisation payée',
subtitle: 'Décembre 2024',
icon: Icons.payment,
color: const Color(0xFF00B894),
time: 'Il y a 1j',
),
DashboardActivity(
title: 'Profil mis à jour',
subtitle: 'Informations personnelles',
icon: Icons.edit,
color: const Color(0xFF00CEC9),
time: 'Il y a 1 sem',
),
DashboardActivity(
title: 'Inscription événement',
subtitle: 'Assemblée Générale',
icon: Icons.event,
color: const Color(0xFF0984E3),
time: 'Il y a 2 sem',
),
],
onActivityTap: (id) {},
),
],
);
}
}

View File

@@ -0,0 +1,514 @@
/// Dashboard Super Administrateur - Command Center Ultra-Sophistiqué
/// Vue globale multi-organisations avec métriques système avancées
library super_admin_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Command Center pour Super Administrateur
///
/// Fonctionnalités exclusives :
/// - Vue globale multi-organisations
/// - Métriques système en temps réel
/// - Outils d'administration avancés
/// - Monitoring et analytics
/// - Gestion des utilisateurs globale
class SuperAdminDashboard extends StatefulWidget {
const SuperAdminDashboard({super.key});
@override
State<SuperAdminDashboard> createState() => _SuperAdminDashboardState();
}
class _SuperAdminDashboardState extends State<SuperAdminDashboard>
with TickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar avec gradient Super Admin
SliverAppBar(
expandedHeight: 200,
floating: false,
pinned: true,
backgroundColor: const Color(0xFF6C5CE7), // Violet Super Admin
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Command Center',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF6C5CE7), // Violet principal
Color(0xFF5A4FCF), // Violet plus foncé
Color(0xFF4834D4), // Violet profond
],
),
),
child: Stack(
children: [
// Motif géométrique sophistiqué
Positioned.fill(
child: CustomPaint(
painter: _GeometricPatternPainter(),
),
),
// Contenu de l'en-tête
Positioned(
bottom: 60,
left: 20,
right: 20,
child: Row(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(30),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 2,
),
),
child: const Icon(
Icons.admin_panel_settings,
color: Colors.white,
size: 30,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Super Administrateur',
style: TypographyTokens.headlineSmall.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Contrôle total du système',
style: TypographyTokens.bodyMedium.copyWith(
color: Colors.white.withOpacity(0.9),
),
),
],
),
),
],
),
),
],
),
),
),
bottom: TabBar(
controller: _tabController,
indicatorColor: Colors.white,
labelColor: Colors.white,
unselectedLabelColor: Colors.white.withOpacity(0.7),
tabs: const [
Tab(text: 'Vue Globale'),
Tab(text: 'Organisations'),
Tab(text: 'Système'),
Tab(text: 'Analytics'),
],
),
),
// Contenu des onglets
SliverFillRemaining(
child: TabBarView(
controller: _tabController,
children: [
_buildGlobalOverviewTab(),
_buildOrganizationsTab(),
_buildSystemTab(),
_buildAnalyticsTab(),
],
),
),
],
),
);
}
/// Onglet Vue Globale
Widget _buildGlobalOverviewTab() {
return SingleChildScrollView(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Métriques globales
_buildGlobalMetricsSection(),
const SizedBox(height: SpacingTokens.xl),
// Alertes système
_buildSystemAlertsSection(),
const SizedBox(height: SpacingTokens.xl),
// Activité récente globale
_buildGlobalActivitySection(),
],
),
);
}
/// Section métriques globales
Widget _buildGlobalMetricsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Métriques Globales',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
// Grille de métriques système
GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: SpacingTokens.md,
mainAxisSpacing: SpacingTokens.md,
childAspectRatio: 1.4,
children: [
_buildSystemMetricCard(
'Organisations',
'247',
'+12 ce mois',
Icons.business,
const Color(0xFF0984E3),
),
_buildSystemMetricCard(
'Utilisateurs',
'15,847',
'+1,234 ce mois',
Icons.people,
const Color(0xFF00B894),
),
_buildSystemMetricCard(
'Uptime',
'99.97%',
'30 derniers jours',
Icons.trending_up,
const Color(0xFF00CEC9),
),
_buildSystemMetricCard(
'Performance',
'1.2s',
'Temps de réponse',
Icons.speed,
const Color(0xFFE17055),
),
],
),
],
);
}
/// Carte de métrique système
Widget _buildSystemMetricCard(
String title,
String value,
String subtitle,
IconData icon,
Color color,
) {
return Container(
padding: const EdgeInsets.all(SpacingTokens.md),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
),
child: Icon(icon, color: color, size: 20),
),
const Spacer(),
Icon(
Icons.trending_up,
color: Colors.green,
size: 16,
),
],
),
const SizedBox(height: SpacingTokens.sm),
Text(
value,
style: TypographyTokens.headlineLarge.copyWith(
fontWeight: FontWeight.bold,
color: color,
),
),
Text(
title,
style: TypographyTokens.bodyMedium.copyWith(
fontWeight: FontWeight.w600,
),
),
Text(
subtitle,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
],
),
);
}
/// Section alertes système
Widget _buildSystemAlertsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'Alertes Système',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: Text(
'3 critiques',
style: TypographyTokens.bodySmall.copyWith(
color: Colors.red,
fontWeight: FontWeight.w600,
),
),
),
],
),
const SizedBox(height: SpacingTokens.md),
// Liste des alertes
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
_buildAlertItem(
'Charge CPU élevée',
'Serveur principal à 89%',
Icons.warning,
Colors.orange,
'2 min',
),
const Divider(height: 1),
_buildAlertItem(
'Espace disque faible',
'Base de données à 92%',
Icons.error,
Colors.red,
'5 min',
),
const Divider(height: 1),
_buildAlertItem(
'Connexions simultanées',
'Pic de trafic détecté',
Icons.info,
Colors.blue,
'12 min',
),
],
),
),
],
);
}
/// Item d'alerte
Widget _buildAlertItem(
String title,
String description,
IconData icon,
Color color,
String time,
) {
return ListTile(
leading: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
),
child: Icon(icon, color: color, size: 20),
),
title: Text(
title,
style: TypographyTokens.bodyMedium.copyWith(
fontWeight: FontWeight.w600,
),
),
subtitle: Text(description),
trailing: Text(
time,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
);
}
/// Section activité globale
Widget _buildGlobalActivitySection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Activité Récente Globale',
style: TypographyTokens.headlineMedium.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: SpacingTokens.md),
DashboardRecentActivitySection(
activities: [
DashboardActivity(
title: 'Nouvelle organisation créée',
subtitle: 'Association des Développeurs',
icon: Icons.business,
color: const Color(0xFF0984E3),
time: 'Il y a 5 min',
),
DashboardActivity(
title: 'Mise à jour système',
subtitle: 'Version 2.1.4 déployée',
icon: Icons.system_update,
color: const Color(0xFF00B894),
time: 'Il y a 15 min',
),
DashboardActivity(
title: 'Alerte sécurité résolue',
subtitle: 'Tentative d\'intrusion bloquée',
icon: Icons.security,
color: const Color(0xFFE17055),
time: 'Il y a 32 min',
),
],
onActivityTap: (activityId) {
// Navigation vers les détails
},
),
],
);
}
/// Onglet Organisations (placeholder)
Widget _buildOrganizationsTab() {
return const Center(
child: Text('Gestion des Organisations'),
);
}
/// Onglet Système (placeholder)
Widget _buildSystemTab() {
return const Center(
child: Text('Administration Système'),
);
}
/// Onglet Analytics (placeholder)
Widget _buildAnalyticsTab() {
return const Center(
child: Text('Analytics Avancées'),
);
}
}
/// Painter pour le motif géométrique de l'en-tête
class _GeometricPatternPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.1)
..strokeWidth = 1
..style = PaintingStyle.stroke;
// Dessiner un motif géométrique sophistiqué
for (int i = 0; i < 10; i++) {
final rect = Rect.fromLTWH(
i * size.width / 10,
i * size.height / 10,
size.width / 5,
size.height / 5,
);
canvas.drawRect(rect, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,550 @@
/// Dashboard Visiteur - Landing Experience Accueillante
/// Interface publique pour découvrir l'organisation
library visitor_dashboard;
import 'package:flutter/material.dart';
import '../../../../../core/design_system/tokens/tokens.dart';
import '../../widgets/widgets.dart';
/// Dashboard Landing Experience pour Visiteur
class VisitorDashboard extends StatelessWidget {
const VisitorDashboard({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorTokens.surface,
body: CustomScrollView(
slivers: [
// App Bar Visiteur
SliverAppBar(
expandedHeight: 200,
floating: false,
pinned: true,
backgroundColor: const Color(0xFF6C5CE7), // Indigo accueillant
flexibleSpace: FlexibleSpaceBar(
title: const Text(
'Découvrir UnionFlow',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF6C5CE7), Color(0xFF5A4FCF)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Stack(
children: [
// Motif d'accueil
Positioned.fill(
child: CustomPaint(
painter: _WelcomePatternPainter(),
),
),
const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.waving_hand, color: Colors.white, size: 60),
SizedBox(height: 8),
Text(
'Bienvenue !',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(SpacingTokens.md),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Message d'accueil
_buildWelcomeMessage(),
const SizedBox(height: SpacingTokens.xl),
// À propos de l'organisation
_buildAboutOrganization(),
const SizedBox(height: SpacingTokens.xl),
// Événements publics
_buildPublicEvents(),
const SizedBox(height: SpacingTokens.xl),
// Comment rejoindre
_buildHowToJoin(),
const SizedBox(height: SpacingTokens.xl),
// Contact
_buildContactInfo(),
],
),
),
),
],
),
);
}
Widget _buildWelcomeMessage() {
return Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF6C5CE7), Color(0xFF5A4FCF)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(RadiusTokens.lg),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.info_outline, color: Colors.white, size: 30),
const SizedBox(width: SpacingTokens.sm),
Text(
'Découvrez notre communauté',
style: TypographyTokens.headlineMedium.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: SpacingTokens.md),
Text(
'Bienvenue sur UnionFlow ! Explorez notre organisation, découvrez nos événements publics et apprenez comment nous rejoindre.',
style: TypographyTokens.bodyLarge.copyWith(
color: Colors.white.withOpacity(0.9),
),
),
const SizedBox(height: SpacingTokens.md),
ElevatedButton(
onPressed: () => _onJoinNow(),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF6C5CE7),
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.lg,
vertical: SpacingTokens.md,
),
),
child: const Text(
'Nous Rejoindre',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
],
),
);
}
Widget _buildAboutOrganization() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'À Propos de Nous',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
Row(
children: [
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: const Color(0xFF6C5CE7).withOpacity(0.1),
borderRadius: BorderRadius.circular(30),
),
child: const Icon(
Icons.business,
color: Color(0xFF6C5CE7),
size: 30,
),
),
const SizedBox(width: SpacingTokens.md),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Association des Développeurs',
style: TypographyTokens.headlineSmall.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
'Communauté tech passionnée',
style: TypographyTokens.bodyMedium.copyWith(
color: ColorTokens.textSecondary,
),
),
],
),
),
],
),
const SizedBox(height: SpacingTokens.md),
Text(
'Nous sommes une association dynamique qui rassemble les passionnés de technologie. Notre mission est de favoriser l\'apprentissage, le partage de connaissances et l\'entraide dans le domaine du développement.',
style: TypographyTokens.bodyMedium,
),
const SizedBox(height: SpacingTokens.md),
// Statistiques publiques
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildPublicStat('156', 'Membres'),
_buildPublicStat('24', 'Événements/an'),
_buildPublicStat('5', 'Ans d\'existence'),
],
),
],
),
),
],
);
}
Widget _buildPublicStat(String value, String label) {
return Column(
children: [
Text(
value,
style: TypographyTokens.headlineMedium.copyWith(
color: const Color(0xFF6C5CE7),
fontWeight: FontWeight.bold,
),
),
Text(
label,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
],
);
}
Widget _buildPublicEvents() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Événements Publics',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF00B894).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('15', style: TextStyle(fontWeight: FontWeight.bold)),
Text('DÉC', style: TextStyle(fontSize: 10)),
],
),
),
title: const Text('Assemblée Générale Publique'),
subtitle: const Text('Salle communale • 19h00 • Gratuit'),
trailing: Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: const Color(0xFF00B894).withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: const Text(
'OUVERT',
style: TextStyle(
color: Color(0xFF00B894),
fontSize: 10,
fontWeight: FontWeight.bold,
),
),
),
),
const Divider(height: 1),
ListTile(
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF6C5CE7).withOpacity(0.1),
borderRadius: BorderRadius.circular(25),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('20', style: TextStyle(fontWeight: FontWeight.bold)),
Text('DÉC', style: TextStyle(fontSize: 10)),
],
),
),
title: const Text('Conférence Tech Trends 2025'),
subtitle: const Text('Amphithéâtre Université • 14h00 • Gratuit'),
trailing: Container(
padding: const EdgeInsets.symmetric(
horizontal: SpacingTokens.sm,
vertical: SpacingTokens.xs,
),
decoration: BoxDecoration(
color: const Color(0xFF6C5CE7).withOpacity(0.1),
borderRadius: BorderRadius.circular(RadiusTokens.sm),
),
child: const Text(
'OUVERT',
style: TextStyle(
color: Color(0xFF6C5CE7),
fontSize: 10,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
],
);
}
Widget _buildHowToJoin() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Comment Nous Rejoindre',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
_buildJoinStep('1', 'Créer un compte', 'Inscription gratuite en 2 minutes'),
const SizedBox(height: SpacingTokens.md),
_buildJoinStep('2', 'Compléter le profil', 'Partagez vos centres d\'intérêt'),
const SizedBox(height: SpacingTokens.md),
_buildJoinStep('3', 'Validation', 'Approbation par nos modérateurs'),
const SizedBox(height: SpacingTokens.lg),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => _onStartRegistration(),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF6C5CE7),
padding: const EdgeInsets.symmetric(vertical: SpacingTokens.md),
),
child: const Text(
'Commencer l\'inscription',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
],
);
}
Widget _buildJoinStep(String number, String title, String description) {
return Row(
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: const Color(0xFF6C5CE7),
borderRadius: BorderRadius.circular(15),
),
child: Center(
child: Text(
number,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(width: SpacingTokens.md),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TypographyTokens.bodyMedium.copyWith(
fontWeight: FontWeight.w600,
),
),
Text(
description,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.textSecondary,
),
),
],
),
),
],
);
}
Widget _buildContactInfo() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Nous Contacter',
style: TypographyTokens.headlineMedium.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: SpacingTokens.md),
Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(RadiusTokens.md),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
ListTile(
leading: const Icon(Icons.email, color: Color(0xFF6C5CE7)),
title: const Text('Email'),
subtitle: const Text('contact@association-dev.fr'),
contentPadding: EdgeInsets.zero,
),
ListTile(
leading: const Icon(Icons.phone, color: Color(0xFF6C5CE7)),
title: const Text('Téléphone'),
subtitle: const Text('+33 1 23 45 67 89'),
contentPadding: EdgeInsets.zero,
),
ListTile(
leading: const Icon(Icons.location_on, color: Color(0xFF6C5CE7)),
title: const Text('Adresse'),
subtitle: const Text('123 Rue de la Tech, 75001 Paris'),
contentPadding: EdgeInsets.zero,
),
],
),
),
],
);
}
// === CALLBACKS ===
void _onJoinNow() {
// Navigation vers l'inscription
}
void _onStartRegistration() {
// Démarrer le processus d'inscription
}
}
/// Painter pour le motif d'accueil
class _WelcomePatternPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.1)
..strokeWidth = 1
..style = PaintingStyle.stroke;
// Dessiner des cercles concentriques
for (int i = 1; i <= 5; i++) {
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
i * size.width / 10,
paint,
);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}