import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:em2rp/providers/event_provider.dart'; import 'package:latlong2/latlong.dart'; import 'package:em2rp/models/event_model.dart'; import 'package:intl/intl.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:em2rp/views/widgets/inputs/int_stepper_field.dart'; class EventAddPage extends StatefulWidget { const EventAddPage({super.key}); @override State createState() => _EventAddPageState(); } class _EventAddPageState extends State { final _formKey = GlobalKey(); final TextEditingController _nameController = TextEditingController(); final TextEditingController _descriptionController = TextEditingController(); final TextEditingController _priceController = TextEditingController(); final TextEditingController _installationController = TextEditingController(); final TextEditingController _disassemblyController = TextEditingController(); final TextEditingController _latitudeController = TextEditingController(); final TextEditingController _longitudeController = TextEditingController(); DateTime? _startDateTime; DateTime? _endDateTime; bool _isLoading = false; String? _error; String? _success; String? _selectedEventType; final List _eventTypes = ['Bal', 'Mariage', 'Anniversaire']; int _descriptionMaxLines = 3; @override void initState() { super.initState(); _descriptionController.addListener(_handleDescriptionChange); } void _handleDescriptionChange() { final lines = '\n'.allMatches(_descriptionController.text).length + 1; setState(() { _descriptionMaxLines = lines.clamp(3, 6); }); } @override void dispose() { _nameController.dispose(); _descriptionController.dispose(); _priceController.dispose(); _installationController.dispose(); _disassemblyController.dispose(); _latitudeController.dispose(); _longitudeController.dispose(); super.dispose(); } Future _submit() async { if (!_formKey.currentState!.validate() || _startDateTime == null || _endDateTime == null || _selectedEventType == null) return; setState(() { _isLoading = true; _error = null; _success = null; }); try { final eventProvider = Provider.of(context, listen: false); final newEvent = EventModel( id: '', name: _nameController.text.trim(), description: _descriptionController.text.trim(), startDateTime: _startDateTime!, endDateTime: _endDateTime!, price: double.tryParse(_priceController.text) ?? 0.0, installationTime: int.tryParse(_installationController.text) ?? 0, disassemblyTime: int.tryParse(_disassemblyController.text) ?? 0, eventTypeId: _selectedEventType!, customerId: '', // à adapter si tu veux gérer les clients address: LatLng( double.tryParse(_latitudeController.text) ?? 0.0, double.tryParse(_longitudeController.text) ?? 0.0, ), workforce: [], ); await eventProvider.addEvent(newEvent); setState(() { _success = "Événement créé avec succès !"; }); if (context.mounted) Navigator.of(context).pop(); } catch (e) { setState(() { _error = "Erreur lors de la création : $e"; }); } finally { setState(() { _isLoading = false; }); } } Widget _buildSectionTitle(String title) { return Padding( padding: const EdgeInsets.only(top: 16.0, bottom: 8.0), child: Align( alignment: Alignment.centerLeft, child: Text( title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: const Text('Créer un événement'), ), body: Center( child: SingleChildScrollView( child: 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: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( padding: const EdgeInsets.only(top: 0.0, bottom: 4.0), child: Align( alignment: Alignment.centerLeft, child: Text( 'Informations principales', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), ), ), TextFormField( controller: _nameController, decoration: const InputDecoration( labelText: 'Nom de l\'événement', border: OutlineInputBorder(), prefixIcon: Icon(Icons.event), ), validator: (v) => v == null || v.isEmpty ? 'Champ requis' : null, ), const SizedBox(height: 16), DropdownButtonFormField( value: _selectedEventType, items: _eventTypes .map((type) => DropdownMenuItem( value: type, child: Text(type), )) .toList(), onChanged: (val) => setState(() => _selectedEventType = val), decoration: const InputDecoration( labelText: 'Type d\'événement', border: OutlineInputBorder(), prefixIcon: Icon(Icons.category), ), validator: (v) => v == null ? 'Sélectionnez un type' : null, ), const SizedBox(height: 16), Row( children: [ Expanded( child: GestureDetector( onTap: () async { final picked = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2099), ); if (picked != null) { final time = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (time != null) { setState(() { _startDateTime = DateTime( picked.year, picked.month, picked.day, time.hour, time.minute, ); }); } } }, child: AbsorbPointer( child: TextFormField( readOnly: true, decoration: InputDecoration( labelText: 'Début', border: const OutlineInputBorder(), prefixIcon: const Icon(Icons.calendar_today), suffixIcon: const Icon(Icons.edit_calendar), ), controller: TextEditingController( text: _startDateTime == null ? '' : DateFormat('dd/MM/yyyy HH:mm') .format(_startDateTime!), ), validator: (v) => _startDateTime == null ? 'Champ requis' : null, ), ), ), ), const SizedBox(width: 16), Expanded( child: GestureDetector( onTap: () async { final picked = await showDatePicker( context: context, initialDate: _startDateTime ?? DateTime.now(), firstDate: DateTime(2020), lastDate: DateTime(2099), ); if (picked != null) { final time = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (time != null) { setState(() { _endDateTime = DateTime( picked.year, picked.month, picked.day, time.hour, time.minute, ); }); } } }, child: AbsorbPointer( child: TextFormField( readOnly: true, decoration: InputDecoration( labelText: 'Fin', border: const OutlineInputBorder(), prefixIcon: const Icon(Icons.calendar_today), suffixIcon: const Icon(Icons.edit_calendar), ), controller: TextEditingController( text: _endDateTime == null ? '' : DateFormat('dd/MM/yyyy HH:mm') .format(_endDateTime!), ), validator: (v) => _endDateTime == null ? 'Champ requis' : null, ), ), ), ), ], ), const SizedBox(height: 16), TextFormField( controller: _priceController, decoration: const InputDecoration( labelText: 'Prix (€)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.euro), ), keyboardType: TextInputType.number, ), _buildSectionTitle('Détails'), AnimatedContainer( duration: const Duration(milliseconds: 200), constraints: BoxConstraints( minHeight: 48, maxHeight: 48.0 * 10, ), child: TextFormField( controller: _descriptionController, minLines: 1, maxLines: _descriptionMaxLines > 10 ? 10 : _descriptionMaxLines, decoration: const InputDecoration( labelText: 'Description', border: OutlineInputBorder(), prefixIcon: Icon(Icons.description), ), ), ), const SizedBox(height: 20), Row( children: [ Expanded( child: IntStepperField( label: 'Installation (h)', controller: _installationController, min: 0, max: 24, ), ), const SizedBox(width: 16), Expanded( child: IntStepperField( label: 'Démontage (h)', controller: _disassemblyController, min: 0, max: 24, ), ), ], ), _buildSectionTitle('Localisation'), Row( children: [ Expanded( child: TextFormField( controller: _latitudeController, decoration: const InputDecoration( labelText: 'Latitude', border: OutlineInputBorder(), prefixIcon: Icon(Icons.location_on), ), keyboardType: TextInputType.number, ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _longitudeController, decoration: const InputDecoration( labelText: 'Longitude', border: OutlineInputBorder(), prefixIcon: Icon(Icons.location_on), ), keyboardType: TextInputType.number, ), ), ], ), if (_error != null) Padding( padding: const EdgeInsets.only(top: 8.0), child: Text(_error!, style: const TextStyle(color: Colors.red)), ), if (_success != null) Padding( padding: const EdgeInsets.only(top: 8.0), child: Text(_success!, style: const TextStyle(color: Colors.green)), ), const SizedBox(height: 24), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: _isLoading ? null : () => Navigator.of(context).pop(), child: const Text('Annuler'), ), const SizedBox(width: 8), ElevatedButton.icon( icon: const Icon(Icons.check), onPressed: _isLoading ? null : _submit, label: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Créer'), ), ], ), ], ), ), ), ), ), ), ); } }