import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:geosector_app/core/data/models/user_model.dart'; import 'custom_text_field.dart'; class UserForm extends StatefulWidget { final UserModel? user; final Function(UserModel)? onSubmit; final bool readOnly; const UserForm({ Key? key, this.user, this.onSubmit, this.readOnly = false, }) : super(key: key); @override State createState() => _UserFormState(); } class _UserFormState extends State { final _formKey = GlobalKey(); // Controllers late final TextEditingController _usernameController; late final TextEditingController _firstNameController; late final TextEditingController _nameController; late final TextEditingController _phoneController; late final TextEditingController _mobileController; late final TextEditingController _emailController; late final TextEditingController _dateNaissanceController; late final TextEditingController _dateEmbaucheController; // Form values int _fkTitre = 1; // 1 = M., 2 = Mme DateTime? _dateNaissance; DateTime? _dateEmbauche; @override void initState() { super.initState(); // Initialize controllers with user data if available final user = widget.user; _usernameController = TextEditingController(text: user?.username ?? ''); _firstNameController = TextEditingController(text: user?.firstName ?? ''); _nameController = TextEditingController(text: user?.name ?? ''); _phoneController = TextEditingController(text: user?.phone ?? ''); _mobileController = TextEditingController(text: user?.mobile ?? ''); _emailController = TextEditingController(text: user?.email ?? ''); _dateNaissance = user?.dateNaissance; _dateEmbauche = user?.dateEmbauche; _dateNaissanceController = TextEditingController( text: _dateNaissance != null ? DateFormat('dd/MM/yyyy').format(_dateNaissance!) : ''); _dateEmbaucheController = TextEditingController( text: _dateEmbauche != null ? DateFormat('dd/MM/yyyy').format(_dateEmbauche!) : ''); _fkTitre = user?.fkTitre ?? 1; } @override void dispose() { _usernameController.dispose(); _firstNameController.dispose(); _nameController.dispose(); _phoneController.dispose(); _mobileController.dispose(); _emailController.dispose(); _dateNaissanceController.dispose(); _dateEmbaucheController.dispose(); super.dispose(); } // Méthode simplifiée pour sélectionner une date void _selectDate(BuildContext context, bool isDateNaissance) { // Utiliser un bloc try-catch pour capturer toutes les erreurs possibles try { // Afficher le sélecteur de date sans spécifier de locale showDatePicker( context: context, initialDate: DateTime.now(), // Toujours utiliser la date actuelle firstDate: DateTime(1900), lastDate: DateTime.now(), // Ne pas spécifier de locale pour éviter les problèmes ).then((DateTime? picked) { // Vérifier si une date a été sélectionnée if (picked != null) { setState(() { // Mettre à jour la date et le texte du contrôleur if (isDateNaissance) { _dateNaissance = picked; _dateNaissanceController.text = DateFormat('dd/MM/yyyy').format(picked); } else { _dateEmbauche = picked; _dateEmbaucheController.text = DateFormat('dd/MM/yyyy').format(picked); } }); } }).catchError((error) { // Gérer les erreurs spécifiques au sélecteur de date debugPrint('Erreur lors de la sélection de la date: $error'); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erreur lors de la sélection de la date'), backgroundColor: Colors.red, ), ); }); } catch (e) { // Gérer toutes les autres erreurs debugPrint('Exception lors de l\'affichage du sélecteur de date: $e'); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Impossible d\'afficher le sélecteur de date'), backgroundColor: Colors.red, ), ); } } void _submitForm() { if (_formKey.currentState!.validate()) { final user = widget.user?.copyWith( firstName: _firstNameController.text, name: _nameController.text, phone: _phoneController.text, mobile: _mobileController.text, email: _emailController.text, fkTitre: _fkTitre, dateNaissance: _dateNaissance, dateEmbauche: _dateEmbauche, ) ?? UserModel( id: 0, // Sera remplacé par l'API firstName: _firstNameController.text, name: _nameController.text, phone: _phoneController.text, mobile: _mobileController.text, email: _emailController.text, fkTitre: _fkTitre, dateNaissance: _dateNaissance, dateEmbauche: _dateEmbauche, role: 1, // Valeur par défaut createdAt: DateTime.now(), lastSyncedAt: DateTime.now(), ); if (widget.onSubmit != null) { widget.onSubmit!(user); } } } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Nom d'utilisateur (en lecture seule) CustomTextField( controller: _usernameController, label: "Nom d'utilisateur", readOnly: true, // Toujours en lecture seule prefixIcon: Icons.account_circle, ), const SizedBox(height: 16), // Titre (M. ou Mme) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Titre", style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onBackground, ), ), const SizedBox(height: 8), Row( children: [ _buildRadioOption( value: 1, label: 'M.', groupValue: _fkTitre, onChanged: widget.readOnly ? null : (value) { setState(() { _fkTitre = value!; }); }, ), const SizedBox(width: 40), _buildRadioOption( value: 2, label: 'Mme', groupValue: _fkTitre, onChanged: widget.readOnly ? null : (value) { setState(() { _fkTitre = value!; }); }, ), ], ), ], ), const SizedBox(height: 16), // Prénom CustomTextField( controller: _firstNameController, label: "Prénom", readOnly: widget.readOnly, validator: (value) { if (value == null || value.isEmpty) { return "Veuillez entrer le prénom"; } return null; }, ), const SizedBox(height: 16), // Nom CustomTextField( controller: _nameController, label: "Nom", readOnly: widget.readOnly, validator: (value) { if (value == null || value.isEmpty) { return "Veuillez entrer le nom"; } return null; }, ), const SizedBox(height: 16), // Téléphone fixe CustomTextField( controller: _phoneController, label: "Téléphone fixe", keyboardType: TextInputType.phone, readOnly: widget.readOnly, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(10), ], validator: (value) { if (value != null && value.isNotEmpty && value.length < 10) { return "Le numéro de téléphone doit contenir 10 chiffres"; } return null; }, ), const SizedBox(height: 16), // Téléphone mobile CustomTextField( controller: _mobileController, label: "Téléphone mobile", keyboardType: TextInputType.phone, readOnly: widget.readOnly, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(10), ], validator: (value) { if (value != null && value.isNotEmpty && value.length < 10) { return "Le numéro de mobile doit contenir 10 chiffres"; } return null; }, ), const SizedBox(height: 16), // Email CustomTextField( controller: _emailController, label: "Email", keyboardType: TextInputType.emailAddress, readOnly: widget.readOnly, validator: (value) { if (value == null || value.isEmpty) { return "Veuillez entrer l'adresse email"; } if (!value.contains('@') || !value.contains('.')) { return "Veuillez entrer une adresse email valide"; } return null; }, ), const SizedBox(height: 16), // Date de naissance CustomTextField( controller: _dateNaissanceController, label: "Date de naissance", readOnly: true, onTap: widget.readOnly ? null : () => _selectDate(context, true), suffixIcon: Icon( Icons.calendar_today, color: theme.colorScheme.primary, ), ), const SizedBox(height: 16), // Date d'embauche CustomTextField( controller: _dateEmbaucheController, label: "Date d'embauche", readOnly: true, onTap: widget.readOnly ? null : () => _selectDate(context, false), suffixIcon: Icon( Icons.calendar_today, color: theme.colorScheme.primary, ), ), // Espace en bas du formulaire const SizedBox(height: 16), ], ), ); } Widget _buildRadioOption({ required int value, required String label, required int groupValue, required Function(int?)? onChanged, }) { final theme = Theme.of(context); final isSelected = value == groupValue; return Row( children: [ Radio( value: value, groupValue: groupValue, onChanged: onChanged, activeColor: const Color(0xFF20335E), ), Text( label, style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onBackground, fontWeight: FontWeight.w500, ), ), ], ); } }