first commit

This commit is contained in:
DahoudG
2025-08-20 21:00:35 +00:00
commit b2a23bdf89
583 changed files with 243074 additions and 0 deletions

View File

@@ -0,0 +1,400 @@
import 'package:flutter/material.dart';
import '../../../../shared/theme/app_theme.dart';
import 'login_screen.dart';
import 'register_screen.dart';
class WelcomeScreen extends StatefulWidget {
const WelcomeScreen({super.key});
@override
State<WelcomeScreen> createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen>
with TickerProviderStateMixin {
late AnimationController _fadeController;
late AnimationController _slideController;
late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_initializeAnimations();
_startAnimations();
}
void _initializeAnimations() {
_fadeController = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_fadeAnimation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(CurvedAnimation(
parent: _fadeController,
curve: Curves.easeInOut,
));
_slideAnimation = Tween<Offset>(
begin: const Offset(0, 0.5),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _slideController,
curve: Curves.easeOutCubic,
));
}
void _startAnimations() async {
await Future.delayed(const Duration(milliseconds: 200));
_fadeController.forward();
await Future.delayed(const Duration(milliseconds: 300));
_slideController.forward();
}
@override
void dispose() {
_fadeController.dispose();
_slideController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppTheme.primaryColor,
AppTheme.primaryDark,
const Color(0xFF0D47A1),
],
),
),
child: SafeArea(
child: AnimatedBuilder(
animation: _fadeAnimation,
builder: (context, child) {
return Opacity(
opacity: _fadeAnimation.value,
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
children: [
// Header avec logo
Expanded(
flex: 3,
child: SlideTransition(
position: _slideAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Logo principal
Container(
width: 140,
height: 140,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(35),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 25,
offset: const Offset(0, 12),
),
],
),
child: const Icon(
Icons.groups_rounded,
size: 70,
color: AppTheme.primaryColor,
),
),
const SizedBox(height: 32),
// Titre principal
const Text(
'UnionFlow',
style: TextStyle(
fontSize: 42,
fontWeight: FontWeight.bold,
color: Colors.white,
letterSpacing: 1.5,
),
),
const SizedBox(height: 16),
// Sous-titre
Text(
'Gestion moderne d\'associations\net de mutuelles',
style: TextStyle(
fontSize: 18,
color: Colors.white.withOpacity(0.9),
fontWeight: FontWeight.w300,
height: 1.4,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
// Points forts
_buildFeatureHighlights(),
],
),
),
),
// Boutons d'action
Expanded(
flex: 2,
child: SlideTransition(
position: _slideAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Bouton Connexion
SizedBox(
width: double.infinity,
height: 56,
child: ElevatedButton(
onPressed: () => _navigateToLogin(),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: AppTheme.primaryColor,
elevation: 8,
shadowColor: Colors.black.withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.login, size: 20),
SizedBox(width: 8),
Text(
'Se connecter',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
const SizedBox(height: 16),
// Bouton Inscription
SizedBox(
width: double.infinity,
height: 56,
child: OutlinedButton(
onPressed: () => _navigateToRegister(),
style: OutlinedButton.styleFrom(
foregroundColor: Colors.white,
side: const BorderSide(
color: Colors.white,
width: 2,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.person_add, size: 20),
SizedBox(width: 8),
Text(
'Créer un compte',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
const SizedBox(height: 24),
// Lien mode démo
TextButton(
onPressed: () => _navigateToDemo(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.visibility,
size: 16,
color: Colors.white.withOpacity(0.8),
),
const SizedBox(width: 6),
Text(
'Découvrir en mode démo',
style: TextStyle(
color: Colors.white.withOpacity(0.8),
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
],
),
),
],
),
),
),
// Footer
Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
children: [
Text(
'Version 1.0.0 • Sécurisé et confidentiel',
style: TextStyle(
color: Colors.white.withOpacity(0.6),
fontSize: 12,
),
),
const SizedBox(height: 8),
Text(
'© 2024 Lions Club International',
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 10,
),
),
],
),
),
],
),
),
);
},
),
),
),
);
}
Widget _buildFeatureHighlights() {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 1,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildFeatureItem(Icons.security, 'Sécurisé'),
_buildFeatureItem(Icons.analytics, 'Analytique'),
_buildFeatureItem(Icons.cloud_sync, 'Synchronisé'),
],
),
);
}
Widget _buildFeatureItem(IconData icon, String label) {
return Column(
children: [
Icon(
icon,
color: Colors.white,
size: 20,
),
const SizedBox(height: 4),
Text(
label,
style: TextStyle(
color: Colors.white.withOpacity(0.9),
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
],
);
}
void _navigateToLogin() {
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
const LoginScreen(),
transitionDuration: const Duration(milliseconds: 400),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeInOut,
)),
child: child,
);
},
),
);
}
void _navigateToRegister() {
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) =>
const RegisterScreen(),
transitionDuration: const Duration(milliseconds: 400),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeInOut,
)),
child: child,
);
},
),
);
}
void _navigateToDemo() {
// TODO: Implémenter la navigation vers le mode démo
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Mode démo - En cours de développement'),
backgroundColor: AppTheme.primaryColor,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
);
}
}