import 'package:flutter/material.dart'; import 'package:youmazgestion/Models/users.dart'; import 'package:youmazgestion/Models/role.dart'; import 'package:youmazgestion/accueil.dart'; import '../Services/app_database.dart'; // Changé de authDatabase.dart class RegistrationPage extends StatefulWidget { const RegistrationPage({super.key}); @override _RegistrationPageState createState() => _RegistrationPageState(); } class _RegistrationPageState extends State { late TextEditingController _nameController; late TextEditingController _lastNameController; late TextEditingController _emailController; late TextEditingController _usernameController; late TextEditingController _passwordController; List _availableRoles = []; Role? _selectedRole; bool _isLoading = false; bool _isLoadingRoles = true; @override void initState() { super.initState(); _nameController = TextEditingController(); _lastNameController = TextEditingController(); _emailController = TextEditingController(); _usernameController = TextEditingController(); _passwordController = TextEditingController(); _initializeDatabase(); } Future _initializeDatabase() async { try { await AppDatabase.instance.initDatabase(); await _loadRoles(); } catch (error) { print('Erreur lors de l\'initialisation: $error'); if (mounted) { _showErrorDialog('Erreur d\'initialisation', 'Impossible d\'initialiser l\'application. Veuillez redémarrer.'); } } } Future _loadRoles() async { try { final roles = await AppDatabase.instance.getRoles(); if (mounted) { setState(() { _availableRoles = roles; _selectedRole = roles.isNotEmpty ? roles.first : null; _isLoadingRoles = false; }); } // Si aucun rôle n'existe, créer des rôles par défaut if (roles.isEmpty) { await _createDefaultRoles(); await _loadRoles(); // Recharger après création } } catch (error) { print('Erreur lors du chargement des rôles: $error'); if (mounted) { setState(() { _isLoadingRoles = false; }); } } } Future _createDefaultRoles() async { try { await AppDatabase.instance.createRole(Role(designation: 'Admin')); await AppDatabase.instance.createRole(Role(designation: 'Utilisateur')); await AppDatabase.instance.createRole(Role(designation: 'Gestionnaire')); print('Rôles par défaut créés'); } catch (error) { print('Erreur lors de la création des rôles par défaut: $error'); } } @override void dispose() { _nameController.dispose(); _lastNameController.dispose(); _emailController.dispose(); _usernameController.dispose(); _passwordController.dispose(); super.dispose(); } bool _validateFields() { if (_nameController.text.trim().isEmpty || _lastNameController.text.trim().isEmpty || _emailController.text.trim().isEmpty || _usernameController.text.trim().isEmpty || _passwordController.text.trim().isEmpty || _selectedRole == null) { _showErrorDialog('Champs manquants', 'Veuillez remplir tous les champs.'); return false; } // Validation basique de l'email if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(_emailController.text.trim())) { _showErrorDialog('Email invalide', 'Veuillez entrer un email valide.'); return false; } // Validation basique du mot de passe if (_passwordController.text.length < 6) { _showErrorDialog('Mot de passe trop court', 'Le mot de passe doit contenir au moins 6 caractères.'); return false; } return true; } void _register() async { if (_isLoading) return; if (!_validateFields()) return; setState(() { _isLoading = true; }); try { // Créer l'objet utilisateur avec le nouveau modèle final Users user = Users( name: _nameController.text.trim(), lastName: _lastNameController.text.trim(), email: _emailController.text.trim(), password: _passwordController.text.trim(), username: _usernameController.text.trim(), roleId: _selectedRole!.id!, // Utiliser l'ID du rôle roleName: _selectedRole!.designation, // Pour l'affichage ); // Sauvegarder l'utilisateur dans la base de données final int userId = await AppDatabase.instance.createUser(user); print('Utilisateur créé avec l\'ID: $userId'); // Inscription réussie if (mounted) { _showSuccessDialog(); } } catch (error) { print('Erreur lors de l\'inscription: $error'); String errorMessage = 'Une erreur est survenue lors de l\'inscription.'; // Personnaliser le message d'erreur selon le type d'erreur if (error.toString().contains('UNIQUE constraint failed: users.email')) { errorMessage = 'Cet email est déjà utilisé.'; } else if (error.toString().contains('UNIQUE constraint failed: users.username')) { errorMessage = 'Ce nom d\'utilisateur est déjà pris.'; } if (mounted) { _showErrorDialog('Inscription échouée', errorMessage); } } finally { if (mounted) { setState(() { _isLoading = false; }); } } } void _showSuccessDialog() { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: const Text('Inscription réussie'), content: const Text('Vous vous êtes inscrit avec succès.'), actions: [ ElevatedButton( onPressed: () { Navigator.of(context).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const AccueilPage()), ); }, child: const Text('OK'), ), ], ); }, ); } void _showErrorDialog(String title, String message) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(title), content: Text(message), actions: [ ElevatedButton( onPressed: () { Navigator.of(context).pop(); }, child: const Text('OK'), ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text( 'Inscription', style: TextStyle(color: Colors.white), ), backgroundColor: const Color.fromARGB(255, 4, 54, 95), centerTitle: true, iconTheme: const IconThemeData(color: Colors.white), ), body: _isLoadingRoles ? const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Chargement des rôles...'), ], ), ) : Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Card( elevation: 4, child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ const Icon( Icons.person_add, size: 64, color: Color.fromARGB(255, 4, 54, 95), ), const SizedBox(height: 16), TextField( controller: _nameController, enabled: !_isLoading, decoration: InputDecoration( labelText: 'Prénom', prefixIcon: const Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), ), const SizedBox(height: 16.0), TextField( controller: _lastNameController, enabled: !_isLoading, decoration: InputDecoration( labelText: 'Nom', prefixIcon: const Icon(Icons.person_outline), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), ), const SizedBox(height: 16.0), TextField( controller: _emailController, enabled: !_isLoading, decoration: InputDecoration( labelText: 'Email', prefixIcon: const Icon(Icons.email), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), keyboardType: TextInputType.emailAddress, ), const SizedBox(height: 16.0), TextField( controller: _usernameController, enabled: !_isLoading, decoration: InputDecoration( labelText: 'Nom d\'utilisateur', prefixIcon: const Icon(Icons.account_circle), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), ), const SizedBox(height: 16.0), TextField( controller: _passwordController, enabled: !_isLoading, decoration: InputDecoration( labelText: 'Mot de passe', prefixIcon: const Icon(Icons.lock), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), helperText: 'Au moins 6 caractères', ), obscureText: true, ), const SizedBox(height: 16.0), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: _selectedRole, hint: const Text('Sélectionner un rôle'), isExpanded: true, onChanged: _isLoading ? null : (Role? newValue) { setState(() { _selectedRole = newValue; }); }, items: _availableRoles .map>((Role role) { return DropdownMenuItem( value: role, child: Row( children: [ const Icon(Icons.badge, size: 20), const SizedBox(width: 8), Text(role.designation), ], ), ); }).toList(), ), ), ), const SizedBox(height: 24.0), SizedBox( width: double.infinity, height: 48, child: ElevatedButton( onPressed: _isLoading ? null : _register, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF0015B7), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: _isLoading ? const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( height: 20, width: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ), SizedBox(width: 12), Text( 'Inscription en cours...', style: TextStyle(color: Colors.white), ), ], ) : const Text( 'S\'inscrire', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ), ], ), ), ), ); } }