diff --git a/lib/assets/images/logo.png b/lib/assets/images/logo.png new file mode 100644 index 0000000..847469e Binary files /dev/null and b/lib/assets/images/logo.png differ diff --git a/lib/config/router.dart b/lib/config/router.dart index e7eecde..8616d41 100644 --- a/lib/config/router.dart +++ b/lib/config/router.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:afterwork/presentation/screens/home/home_screen.dart'; +import 'package:afterwork/presentation/screens/login/login_screen.dart'; class AppRouter { static Route generateRoute(RouteSettings settings) { switch (settings.name) { case '/': - return MaterialPageRoute(builder: (_) => const HomeScreen()); + return MaterialPageRoute(builder: (_) => const LoginScreen()); // Ajoute d'autres routes ici default: return MaterialPageRoute( builder: (_) => const Scaffold( - body: Center(child: Text('Page not found')), + body: Center(child: Text('Page non trouvée')), ), ); } diff --git a/lib/presentation/screens/login/login_screen.dart b/lib/presentation/screens/login/login_screen.dart new file mode 100644 index 0000000..8ee1aa1 --- /dev/null +++ b/lib/presentation/screens/login/login_screen.dart @@ -0,0 +1,185 @@ +import 'package:flutter/material.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({Key? key}) : super(key: key); + + @override + _LoginScreenState createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State with SingleTickerProviderStateMixin { + final _formKey = GlobalKey(); + String _email = ''; + String _password = ''; + bool _isPasswordVisible = false; + + late AnimationController _animationController; + late Animation _slideAnimation; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + ); + + _slideAnimation = Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, + ).animate(CurvedAnimation( + parent: _animationController, + curve: Curves.easeOut, + )); + + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + void _togglePasswordVisibility() { + setState(() { + _isPasswordVisible = !_isPasswordVisible; + }); + } + + void _submit() { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + print('Email: $_email, Password: $_password'); // Utilisation des valeurs + // Implémente la logique de connexion ici + } + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: SlideTransition( + position: _slideAnimation, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Logo + Image.asset( + 'lib/assets/images/logo.png', + height: size.height * 0.2, + ), + const SizedBox(height: 20), + const Text( + 'Bienvenue sur AfterWork', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.blueAccent, + ), + ), + const SizedBox(height: 40), + + // Formulaire de connexion + Form( + key: _formKey, + child: Column( + children: [ + // Champ Email + TextFormField( + decoration: const InputDecoration( + labelText: 'Email', + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.email), + ), + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Veuillez entrer votre email'; + } + if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) { + return 'Veuillez entrer un email valide'; + } + return null; + }, + onSaved: (value) { + _email = value!; + }, + ), + const SizedBox(height: 20), + + // Champ Mot de passe + TextFormField( + decoration: InputDecoration( + labelText: 'Mot de passe', + border: const OutlineInputBorder(), + prefixIcon: const Icon(Icons.lock), + suffixIcon: IconButton( + icon: Icon( + _isPasswordVisible + ? Icons.visibility + : Icons.visibility_off, + ), + onPressed: _togglePasswordVisibility, + ), + ), + obscureText: !_isPasswordVisible, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Veuillez entrer votre mot de passe'; + } + if (value.length < 6) { + return 'Le mot de passe doit comporter au moins 6 caractères'; + } + return null; + }, + onSaved: (value) { + _password = value!; + }, + ), + const SizedBox(height: 20), + + // Bouton de connexion + SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.all(16.0), + textStyle: const TextStyle(fontSize: 18), + backgroundColor: Colors.blueAccent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + onPressed: _submit, + child: const Text('Connexion'), + ), + ), + const SizedBox(height: 20), + + // Lien pour s'inscrire + TextButton( + onPressed: () { + // Naviguer vers la page d'inscription + }, + child: const Text( + 'Pas encore de compte ? Inscrivez-vous', + style: TextStyle(color: Colors.blueAccent), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 6427867..5720137 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,9 @@ dev_dependencies: flutter: uses-material-design: true + assets: + - lib/assets/images/logo.png + # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg