import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../custom_text_field.dart'; class PassageForm extends StatefulWidget { final Function(Map)? onSubmit; final Map? initialData; const PassageForm({ super.key, this.onSubmit, this.initialData, }); @override State createState() => _PassageFormState(); } class _PassageFormState extends State { final _formKey = GlobalKey(); // Controllers late final TextEditingController _villeController; late final TextEditingController _adresseController; late final TextEditingController _nomHabitantController; late final TextEditingController _emailController; late final TextEditingController _montantController; late final TextEditingController _commentairesController; // Form values String _typeHabitat = 'Individuel'; String _typeReglement = 'Espèces'; @override void initState() { super.initState(); // Initialize controllers with initial data if available final data = widget.initialData ?? {}; _villeController = TextEditingController(text: data['ville'] ?? ''); _adresseController = TextEditingController(text: data['adresse'] ?? ''); _nomHabitantController = TextEditingController(text: data['nomHabitant'] ?? ''); _emailController = TextEditingController(text: data['email'] ?? ''); _montantController = TextEditingController(text: data['montant'] ?? ''); _commentairesController = TextEditingController(text: data['commentaires'] ?? ''); _typeHabitat = data['typeHabitat'] ?? 'Individuel'; _typeReglement = data['typeReglement'] ?? 'Espèces'; } @override void dispose() { _villeController.dispose(); _adresseController.dispose(); _nomHabitantController.dispose(); _emailController.dispose(); _montantController.dispose(); _commentairesController.dispose(); super.dispose(); } void _submitForm() { if (_formKey.currentState!.validate()) { final formData = { 'ville': _villeController.text, 'adresse': _adresseController.text, 'typeHabitat': _typeHabitat, 'nomHabitant': _nomHabitantController.text, 'email': _emailController.text, 'montant': _montantController.text, 'typeReglement': _typeReglement, 'commentaires': _commentairesController.text, }; if (widget.onSubmit != null) { widget.onSubmit!(formData); } } } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Ville CustomTextField( controller: _villeController, label: 'Ville', validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer une ville'; } return null; }, ), const SizedBox(height: 16), // Adresse CustomTextField( controller: _adresseController, label: 'Adresse', validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer une adresse'; } return null; }, ), const SizedBox(height: 16), // Type d'habitat Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Type d'habitat", style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), Row( children: [ _buildRadioOption( value: 'Individuel', groupValue: _typeHabitat, onChanged: (value) { setState(() { _typeHabitat = value!; }); }, ), const SizedBox(width: 40), _buildRadioOption( value: 'Collectif', groupValue: _typeHabitat, onChanged: (value) { setState(() { _typeHabitat = value!; }); }, ), ], ), ], ), const SizedBox(height: 16), // Nom de l'habitant CustomTextField( controller: _nomHabitantController, label: "Nom de l'habitant", validator: (value) { if (value == null || value.isEmpty) { return "Veuillez entrer le nom de l'habitant"; } return null; }, ), const SizedBox(height: 16), // Email de l'habitant CustomTextField( controller: _emailController, label: "Adresse email de l'habitant", keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || value.isEmpty) { return null; // Email optionnel } // Simple email validation if (!value.contains('@') || !value.contains('.')) { return "Veuillez entrer une adresse email valide"; } return null; }, ), const SizedBox(height: 16), // Montant et Type de règlement Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Montant reçu Expanded( flex: 1, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Montant reçu", style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), TextFormField( controller: _montantController, keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: [ FilteringTextInputFormatter.allow( RegExp(r'^\d+\.?\d{0,2}')), ], style: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSurface, ), decoration: InputDecoration( hintText: '0.00 €', hintStyle: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSurface.withOpacity(0.5), ), fillColor: const Color(0xFFF4F5F6), filled: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: theme.colorScheme.onSurface.withOpacity(0.1), width: 1, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: theme.colorScheme.onSurface.withOpacity(0.1), width: 1, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: theme.colorScheme.primary, width: 2, ), ), contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 16, ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Requis'; } return null; }, ), ], ), ), const SizedBox(width: 20), // Type de règlement Expanded( flex: 2, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Type de règlement", style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), _buildDropdown(), ], ), ), ], ), const SizedBox(height: 16), // Commentaires CustomTextField( controller: _commentairesController, label: "Commentaires", hintText: "Placeholder", maxLines: 3, ), const SizedBox(height: 25), // Titre de section Text( "Mise à jour du passage effectué", style: theme.textTheme.bodyLarge?.copyWith( color: const Color(0xFF20335E), ), ), const SizedBox(height: 16), // Bouton Enregistrer Center( child: ElevatedButton( onPressed: _submitForm, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF20335E), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(50), ), minimumSize: const Size(200, 50), ), child: const Text( 'Enregistrer', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500, ), ), ), ), ], ), ); } Widget _buildRadioOption({ required String value, required String groupValue, required Function(String?) 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( value, style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurface, fontWeight: FontWeight.w500, ), ), ], ); } Widget _buildDropdown() { final theme = Theme.of(context); return Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), decoration: BoxDecoration( color: const Color(0xFFF4F5F6).withOpacity(0.85), borderRadius: BorderRadius.circular(8), border: Border.all( color: const Color(0xFF20335E).withOpacity(0.1), width: 1, ), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: _typeReglement, isExpanded: true, icon: const Icon( Icons.keyboard_arrow_down, color: Color(0xFF20335E), ), style: theme.textTheme.bodyMedium?.copyWith( color: const Color(0xFF20335E), ), dropdownColor: Colors.white, items: ['Espèces', 'CB', 'Chèque'] .map>((String value) { return DropdownMenuItem( value: value, child: Row( children: [ _getPaymentIcon(value), const SizedBox(width: 8), Text(value), ], ), ); }).toList(), onChanged: (String? newValue) { setState(() { _typeReglement = newValue!; }); }, ), ), ); } Widget _getPaymentIcon(String type) { switch (type) { case 'Espèces': return const Icon(Icons.payments_outlined, color: Color(0xFF20335E), size: 20); case 'CB': return const Icon(Icons.credit_card, color: Color(0xFF20335E), size: 20); case 'Chèque': return const Icon(Icons.account_balance_wallet_outlined, color: Color(0xFF20335E), size: 20); default: return const SizedBox.shrink(); } } }