import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:go_router/go_router.dart'; import '../../services/auth_service.dart'; import '../../theme/app_theme.dart'; class ChildData { final TextEditingController firstNameController = TextEditingController(); final TextEditingController lastNameController = TextEditingController(); DateTime? birthDate; DateTime? expectedBirthDate; XFile? photo; bool hasPhotoConsent = false; bool isMultipleBirth = false; bool isUnborn = false; } class ParentRegisterScreen extends StatefulWidget { const ParentRegisterScreen({super.key}); @override State createState() => _ParentRegisterScreenState(); } class _ParentRegisterScreenState extends State { final _formKey = GlobalKey(); final _authService = AuthService(); int _currentStep = 0; bool _isLoading = false; bool _hasPartner = false; bool _hasAcceptedCGU = false; bool _partnerSameAddress = false; // Contrôleurs pour le parent 1 final _emailController = TextEditingController(); final _passwordController = TextEditingController(); final _firstNameController = TextEditingController(); final _lastNameController = TextEditingController(); final _phoneController = TextEditingController(); final _addressController = TextEditingController(); final _cityController = TextEditingController(); final _postalCodeController = TextEditingController(); final _presentationController = TextEditingController(); // Contrôleurs pour le parent 2 final _partnerFirstNameController = TextEditingController(); final _partnerLastNameController = TextEditingController(); final _partnerEmailController = TextEditingController(); final _partnerPhoneController = TextEditingController(); final _partnerAddressController = TextEditingController(); final _partnerCityController = TextEditingController(); final _partnerPostalCodeController = TextEditingController(); // Liste des enfants final List _children = [ChildData()]; final _motivationController = TextEditingController(); @override void dispose() { _emailController.dispose(); _passwordController.dispose(); _firstNameController.dispose(); _lastNameController.dispose(); _phoneController.dispose(); _addressController.dispose(); _cityController.dispose(); _postalCodeController.dispose(); _presentationController.dispose(); _partnerFirstNameController.dispose(); _partnerLastNameController.dispose(); _partnerEmailController.dispose(); _partnerPhoneController.dispose(); _partnerAddressController.dispose(); _partnerCityController.dispose(); _partnerPostalCodeController.dispose(); for (var child in _children) { child.firstNameController.dispose(); child.lastNameController.dispose(); } _motivationController.dispose(); super.dispose(); } Future _pickImage(ChildData child) async { final ImagePicker picker = ImagePicker(); final XFile? image = await picker.pickImage(source: ImageSource.gallery); if (image != null) { setState(() { child.photo = image; }); } } Future _uploadImage(XFile image, String userId) async { // En mode démonstration, on retourne juste un chemin local return image.path; } Future _register() async { if (!_formKey.currentState!.validate()) return; setState(() => _isLoading = true); try { final List> childrenData = []; for (var child in _children) { String? childPhotoUrl; if (child.photo != null) { childPhotoUrl = await _uploadImage(child.photo!, _emailController.text); } childrenData.add({ 'firstName': child.firstNameController.text, 'lastName': child.lastNameController.text, 'birthDate': child.isUnborn ? null : child.birthDate, 'expectedBirthDate': child.isUnborn ? child.expectedBirthDate : null, 'photoUrl': childPhotoUrl, 'hasPhotoConsent': child.hasPhotoConsent, 'isMultipleBirth': child.isMultipleBirth, }); } await _authService.registerParent( email: _emailController.text, password: _passwordController.text, firstName: _firstNameController.text, lastName: _lastNameController.text, phoneNumber: _phoneController.text, address: _addressController.text, city: _cityController.text, postalCode: _postalCodeController.text, presentation: _presentationController.text, hasAcceptedCGU: _hasAcceptedCGU, partnerFirstName: _hasPartner ? _partnerFirstNameController.text : null, partnerLastName: _hasPartner ? _partnerLastNameController.text : null, partnerEmail: _hasPartner ? _partnerEmailController.text : null, partnerPhoneNumber: _hasPartner ? _partnerPhoneController.text : null, partnerAddress: _hasPartner ? (_partnerSameAddress ? _addressController.text : _partnerAddressController.text) : null, partnerCity: _hasPartner ? (_partnerSameAddress ? _cityController.text : _partnerCityController.text) : null, partnerPostalCode: _hasPartner ? (_partnerSameAddress ? _postalCodeController.text : _partnerPostalCodeController.text) : null, children: childrenData, motivation: _motivationController.text, ); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Inscription réussie ! Votre compte est en attente de validation.'), backgroundColor: Colors.green, ), ); context.pop(); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erreur lors de l\'inscription: $e'), backgroundColor: Colors.red, ), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } Widget _buildChildForm(ChildData child, int index) { return Card( margin: const EdgeInsets.symmetric(vertical: 8.0), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Enfant ${index + 1}', style: Theme.of(context).textTheme.titleMedium, ), if (index > 0) IconButton( icon: const Icon(Icons.delete), onPressed: () { setState(() { _children.removeAt(index); }); }, ), ], ), if (child.photo != null) CircleAvatar( radius: 50, backgroundImage: NetworkImage(child.photo!.path), ), TextButton( onPressed: () => _pickImage(child), child: const Text('Ajouter une photo'), ), SwitchListTile( title: const Text('Enfant à naître'), value: child.isUnborn, onChanged: (value) => setState(() => child.isUnborn = value), ), TextFormField( controller: child.firstNameController, decoration: const InputDecoration(labelText: 'Prénom de l\'enfant'), ), TextFormField( controller: child.lastNameController, decoration: const InputDecoration(labelText: 'Nom de l\'enfant'), ), if (!child.isUnborn) ListTile( title: const Text('Date de naissance'), subtitle: Text(child.birthDate != null ? '${child.birthDate!.day}/${child.birthDate!.month}/${child.birthDate!.year}' : 'Non définie'), trailing: IconButton( icon: const Icon(Icons.calendar_today), onPressed: () async { final date = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime.now(), ); if (date != null) { setState(() => child.birthDate = date); } }, ), ), if (child.isUnborn) ListTile( title: const Text('Date prévue'), subtitle: Text(child.expectedBirthDate != null ? '${child.expectedBirthDate!.day}/${child.expectedBirthDate!.month}/${child.expectedBirthDate!.year}' : 'Non définie'), trailing: IconButton( icon: const Icon(Icons.calendar_today), onPressed: () async { final date = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365)), ); if (date != null) { setState(() => child.expectedBirthDate = date); } }, ), ), SwitchListTile( title: const Text('Naissance multiple'), subtitle: const Text('Jumeaux, triplés, etc.'), value: child.isMultipleBirth, onChanged: (value) => setState(() => child.isMultipleBirth = value), ), if (child.photo != null) SwitchListTile( title: const Text('Consentement photo'), subtitle: const Text('J\'autorise l\'utilisation de la photo de mon enfant'), value: child.hasPhotoConsent, onChanged: (value) => setState(() => child.hasPhotoConsent = value), ), ], ), ), ); } List _getSteps() { return [ // Étape 1 : Parent 1 Step( title: const Text('Informations parent 1'), content: Column( children: [ TextFormField( controller: _emailController, decoration: const InputDecoration(labelText: 'Email'), keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre email'; } return null; }, ), TextFormField( controller: _passwordController, decoration: const InputDecoration(labelText: 'Mot de passe'), obscureText: true, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer un mot de passe'; } if (value.length < 6) { return 'Le mot de passe doit contenir au moins 6 caractères'; } return null; }, ), TextFormField( controller: _firstNameController, decoration: const InputDecoration(labelText: 'Prénom'), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre prénom'; } return null; }, ), TextFormField( controller: _lastNameController, decoration: const InputDecoration(labelText: 'Nom'), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre nom'; } return null; }, ), TextFormField( controller: _phoneController, decoration: const InputDecoration(labelText: 'Téléphone'), keyboardType: TextInputType.phone, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre numéro de téléphone'; } return null; }, ), TextFormField( controller: _addressController, decoration: const InputDecoration(labelText: 'Adresse'), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre adresse'; } return null; }, ), TextFormField( controller: _cityController, decoration: const InputDecoration(labelText: 'Ville'), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre ville'; } return null; }, ), TextFormField( controller: _postalCodeController, decoration: const InputDecoration(labelText: 'Code postal'), keyboardType: TextInputType.number, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre code postal'; } return null; }, ), TextFormField( controller: _presentationController, decoration: const InputDecoration(labelText: 'Présentation'), maxLines: 3, ), ], ), isActive: _currentStep >= 0, ), // Étape 2 : Parent 2 Step( title: const Text('Parent 2'), content: Column( children: [ SwitchListTile( title: const Text('Ajouter un deuxième parent'), value: _hasPartner, onChanged: (value) => setState(() => _hasPartner = value), ), if (_hasPartner) ...[ SwitchListTile( title: const Text('Adresse identique au parent 1'), value: _partnerSameAddress, onChanged: (value) { setState(() { _partnerSameAddress = value; if (value) { _partnerAddressController.text = _addressController.text; _partnerCityController.text = _cityController.text; _partnerPostalCodeController.text = _postalCodeController.text; } else { _partnerAddressController.clear(); _partnerCityController.clear(); _partnerPostalCodeController.clear(); } }); }, ), TextFormField( controller: _partnerFirstNameController, decoration: const InputDecoration(labelText: 'Prénom du deuxième parent'), validator: (value) { if (_hasPartner && (value == null || value.isEmpty)) { return 'Veuillez entrer le prénom'; } return null; }, ), TextFormField( controller: _partnerLastNameController, decoration: const InputDecoration(labelText: 'Nom du deuxième parent'), validator: (value) { if (_hasPartner && (value == null || value.isEmpty)) { return 'Veuillez entrer le nom'; } return null; }, ), TextFormField( controller: _partnerEmailController, decoration: const InputDecoration(labelText: 'Email du deuxième parent'), keyboardType: TextInputType.emailAddress, validator: (value) { if (_hasPartner && (value == null || value.isEmpty)) { return 'Veuillez entrer l\'email'; } return null; }, ), TextFormField( controller: _partnerPhoneController, decoration: const InputDecoration(labelText: 'Téléphone du deuxième parent'), keyboardType: TextInputType.phone, ), if (!_partnerSameAddress) ...[ TextFormField( controller: _partnerAddressController, decoration: const InputDecoration(labelText: 'Adresse du deuxième parent'), validator: (value) { if (_hasPartner && !_partnerSameAddress && (value == null || value.isEmpty)) { return 'Veuillez entrer l\'adresse'; } return null; }, ), TextFormField( controller: _partnerCityController, decoration: const InputDecoration(labelText: 'Ville du deuxième parent'), validator: (value) { if (_hasPartner && !_partnerSameAddress && (value == null || value.isEmpty)) { return 'Veuillez entrer la ville'; } return null; }, ), TextFormField( controller: _partnerPostalCodeController, decoration: const InputDecoration(labelText: 'Code postal du deuxième parent'), keyboardType: TextInputType.number, validator: (value) { if (_hasPartner && !_partnerSameAddress && (value == null || value.isEmpty)) { return 'Veuillez entrer le code postal'; } return null; }, ), ], ], ], ), isActive: _currentStep >= 1, ), // Étape 3 : Enfants Step( title: const Text('Enfants'), content: Column( children: [ ..._children.asMap().entries.map((entry) => _buildChildForm(entry.value, entry.key)), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () { setState(() { _children.add(ChildData()); }); }, icon: const Icon(Icons.add), label: const Text('Ajouter un autre enfant'), ), ], ), isActive: _currentStep >= 2, ), // Étape 4 : Description de la situation Step( title: const Text('Description de votre situation'), content: Column( children: [ TextFormField( controller: _motivationController, decoration: const InputDecoration( labelText: 'Décrivez votre situation', hintText: 'Expliquez-nous votre situation familiale et vos besoins...', ), maxLines: 5, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez nous décrire votre situation'; } return null; }, ), ], ), isActive: _currentStep >= 3, ), // Étape 5 : CGU Step( title: const Text('Conditions générales'), content: Column( children: [ SwitchListTile( title: const Text('Conditions générales'), subtitle: const Text('J\'accepte les conditions générales d\'utilisation'), value: _hasAcceptedCGU, onChanged: (value) => setState(() => _hasAcceptedCGU = value), ), if (!_hasAcceptedCGU) const Text( 'Vous devez accepter les conditions générales pour continuer', style: TextStyle(color: Colors.red), ), ], ), isActive: _currentStep >= 4, ), // Étape 6 : Résumé Step( title: const Text('Résumé'), content: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Veuillez vérifier vos informations avant validation :', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), const SizedBox(height: 16), // Parent 1 const Text('Parent 1', style: TextStyle(fontWeight: FontWeight.bold)), ListTile( title: const Text('Email'), subtitle: Text(_emailController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 0), ), ), ListTile( title: const Text('Nom complet'), subtitle: Text('${_firstNameController.text} ${_lastNameController.text}'), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 0), ), ), ListTile( title: const Text('Adresse'), subtitle: Text('${_addressController.text}\n${_postalCodeController.text} ${_cityController.text}'), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 0), ), ), ListTile( title: const Text('Téléphone'), subtitle: Text(_phoneController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 0), ), ), if (_presentationController.text.isNotEmpty) ListTile( title: const Text('Présentation'), subtitle: Text(_presentationController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 0), ), ), // Parent 2 if (_hasPartner) ...[ const SizedBox(height: 16), const Text('Parent 2', style: TextStyle(fontWeight: FontWeight.bold)), ListTile( title: const Text('Email'), subtitle: Text(_partnerEmailController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 1), ), ), ListTile( title: const Text('Nom complet'), subtitle: Text('${_partnerFirstNameController.text} ${_partnerLastNameController.text}'), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 1), ), ), ListTile( title: const Text('Téléphone'), subtitle: Text(_partnerPhoneController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 1), ), ), ListTile( title: const Text('Adresse'), subtitle: _partnerSameAddress ? const Text('Identique au parent 1') : Text('${_partnerAddressController.text}\n${_partnerPostalCodeController.text} ${_partnerCityController.text}'), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 1), ), ), ], // Enfants const SizedBox(height: 16), const Text('Enfants', style: TextStyle(fontWeight: FontWeight.bold)), ..._children.asMap().entries.map((entry) { final child = entry.value; return ListTile( title: Text('Enfant ${entry.key + 1}'), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Prénom : ${child.firstNameController.text} ${child.lastNameController.text}'), if (child.isUnborn) Text('Date prévue : ${child.expectedBirthDate?.day}/${child.expectedBirthDate?.month}/${child.expectedBirthDate?.year}') else Text('Date de naissance : ${child.birthDate?.day}/${child.birthDate?.month}/${child.birthDate?.year}'), if (child.isMultipleBirth) const Text('Naissance multiple'), ], ), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 2), ), ); }), // Motivation const SizedBox(height: 16), const Text('Motivation', style: TextStyle(fontWeight: FontWeight.bold)), ListTile( title: const Text('Votre message'), subtitle: Text(_motivationController.text), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () => setState(() => _currentStep = 3), ), ), ], ), ), isActive: _currentStep >= 5, ), ]; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Inscription Parent'), ), body: Form( key: _formKey, child: Stepper( currentStep: _currentStep, onStepContinue: () { if (_currentStep < _getSteps().length - 1) { setState(() => _currentStep++); } else if (_hasAcceptedCGU) { _register(); } }, onStepCancel: () { if (_currentStep > 0) { setState(() => _currentStep--); } else { Navigator.pop(context); } }, controlsBuilder: (context, details) { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Row( children: [ if (_currentStep > 0) OutlinedButton( onPressed: details.onStepCancel, child: const Text('Retour'), ), const SizedBox(width: 16), if (_currentStep < _getSteps().length - 1) ElevatedButton( onPressed: details.onStepContinue, child: const Text('Suivant'), ) else ElevatedButton( onPressed: _hasAcceptedCGU ? details.onStepContinue : null, child: _isLoading ? const CircularProgressIndicator() : const Text('S\'inscrire'), ), ], ), ); }, steps: _getSteps(), ), ), ); } }