import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:em2rp/models/event_model.dart'; import 'package:em2rp/controllers/event_form_controller.dart'; import 'package:em2rp/views/widgets/event_form/event_basic_info_section.dart'; import 'package:em2rp/views/widgets/event_form/event_details_section.dart'; import 'package:em2rp/views/widgets/event_form/event_staff_and_documents_section.dart'; import 'package:em2rp/views/widgets/event_form/event_form_actions.dart'; import 'package:em2rp/views/widgets/inputs/option_selector_widget.dart'; import 'package:flutter/foundation.dart'; class EventAddEditPage extends StatefulWidget { final EventModel? event; const EventAddEditPage({super.key, this.event}); @override State createState() => _EventAddEditPageState(); } class _EventAddEditPageState extends State { final _formKey = GlobalKey(); late EventFormController _controller; bool get isEditMode => widget.event != null; @override void initState() { super.initState(); _controller = EventFormController(); _controller.initialize(widget.event); } @override void dispose() { _controller.dispose(); super.dispose(); } Future _onWillPop() async { if (!_controller.formChanged) return true; if (!mounted) return true; final shouldLeave = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Quitter la page ?'), content: const Text( 'Les modifications non enregistrées seront perdues. Voulez-vous vraiment quitter ?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Annuler'), ), ElevatedButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('Quitter'), ), ], ), ); return shouldLeave ?? false; } Future _submit() async { if (!_formKey.currentState!.validate()) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Veuillez remplir tous les champs obligatoires.'), backgroundColor: Colors.red, ), ); return; } final success = await _controller.submitForm(context, existingEvent: widget.event); if (success && mounted) { Navigator.of(context).pop(); } } Future _deleteEvent() async { if (widget.event == null) return; final shouldDelete = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Supprimer l\'événement'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Êtes-vous sûr de vouloir supprimer cet événement ?'), const SizedBox(height: 8), Text( 'Nom : ${widget.event!.name}', style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 16), const Text( 'Cette action est irréversible.', style: TextStyle( color: Colors.red, fontWeight: FontWeight.bold, ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Annuler'), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), onPressed: () => Navigator.of(context).pop(true), child: const Text('Supprimer'), ), ], ), ); if (shouldDelete == true) { final success = await _controller.deleteEvent(context, widget.event!.id); if (success && mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Événement supprimé avec succès'), backgroundColor: Colors.green, ), ); Navigator.of(context).pop(); } } } @override Widget build(BuildContext context) { final isMobile = MediaQuery.of(context).size.width < 600; return ChangeNotifierProvider.value( value: _controller, child: PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) async { if (didPop) return; final shouldPop = await _onWillPop(); if (shouldPop && mounted) { Navigator.of(context).pop(); } }, child: Scaffold( appBar: AppBar( title: Text(isEditMode ? 'Modifier un événement' : 'Créer un événement'), ), body: Center( child: SingleChildScrollView( child: (isMobile ? Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: _buildFormContent(isMobile), ) : Card( elevation: 6, margin: const EdgeInsets.all(24), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 32), child: _buildFormContent(isMobile), ), )), ), ), ), ), ); } Widget _buildFormContent(bool isMobile) { return Consumer( builder: (context, controller, child) { // Trouver le nom du type d'événement pour le passer au sélecteur d'options final selectedEventTypeIndex = controller.selectedEventTypeId != null ? controller.eventTypes.indexWhere((et) => et.id == controller.selectedEventTypeId) : -1; final selectedEventType = selectedEventTypeIndex != -1 ? controller.eventTypes[selectedEventTypeIndex] : null; final selectedEventTypeName = selectedEventType?.name; return Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ EventBasicInfoSection( nameController: controller.nameController, basePriceController: controller.basePriceController, eventTypes: controller.eventTypes, isLoadingEventTypes: controller.isLoadingEventTypes, selectedEventTypeId: controller.selectedEventTypeId, startDateTime: controller.startDateTime, endDateTime: controller.endDateTime, onEventTypeChanged: (typeId) => controller.onEventTypeChanged(typeId, context), onStartDateTimeChanged: controller.setStartDateTime, onEndDateTimeChanged: controller.setEndDateTime, onAnyFieldChanged: () {}, // Géré automatiquement par le contrôleur ), const SizedBox(height: 16), OptionSelectorWidget( eventType: controller.selectedEventTypeId, // Utilise l'ID au lieu du nom selectedOptions: controller.selectedOptions, onChanged: controller.setSelectedOptions, onRemove: (optionId) { final newOptions = List>.from(controller.selectedOptions); newOptions.removeWhere((o) => o['id'] == optionId); controller.setSelectedOptions(newOptions); }, eventTypeRequired: controller.selectedEventTypeId == null, isMobile: isMobile, ), EventDetailsSection( descriptionController: controller.descriptionController, installationController: controller.installationController, disassemblyController: controller.disassemblyController, addressController: controller.addressController, isMobile: isMobile, onAnyFieldChanged: () {}, // Géré automatiquement par le contrôleur ), EventStaffAndDocumentsSection( allUsers: controller.allUsers, selectedUserIds: controller.selectedUserIds, onUserSelectionChanged: controller.setSelectedUserIds, isLoadingUsers: controller.isLoadingUsers, uploadedFiles: controller.uploadedFiles, onFilesChanged: controller.setUploadedFiles, isLoading: controller.isLoading, error: controller.error, success: controller.success, isMobile: isMobile, onPickAndUploadFiles: controller.pickAndUploadFiles, ), if (controller.error != null) Padding( padding: const EdgeInsets.only(top: 16.0), child: Text( controller.error!, style: const TextStyle(color: Colors.red), textAlign: TextAlign.center, ), ), if (controller.success != null) Padding( padding: const EdgeInsets.only(top: 16.0), child: Text( controller.success!, style: const TextStyle(color: Colors.green), textAlign: TextAlign.center, ), ), EventFormActions( isLoading: controller.isLoading, isEditMode: isEditMode, onCancel: () async { final shouldLeave = await _onWillPop(); if (shouldLeave && mounted) { Navigator.of(context).pop(); } }, onSubmit: _submit, onSetConfirmed: !isEditMode ? () { } : null, onDelete: isEditMode ? _deleteEvent : null, // Ajout du callback de suppression ), ], ), ); }, ); } }