import 'package:flutter/material.dart'; import 'package:afterwork/data/models/event_model.dart'; import 'package:afterwork/data/models/user_model.dart'; import 'package:afterwork/core/constants/urls.dart'; import 'package:afterwork/data/services/category_service.dart'; import '../location/location_picker_screen.dart'; import 'dart:convert'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:http/http.dart' as http; /// Classe représentant la boîte de dialogue pour ajouter un nouvel événement. class AddEventDialog extends StatefulWidget { final String userId; final String userName; final String userLastName; const AddEventDialog({ super.key, required this.userId, required this.userName, required this.userLastName, }); @override _AddEventDialogState createState() => _AddEventDialogState(); } class _AddEventDialogState extends State { final _formKey = GlobalKey(); // Variables pour stocker les données de l'événement String _title = ''; String _description = ''; DateTime? _selectedDate; String? _imagePath; String _location = 'Abidjan'; String _category = ''; String _link = ''; LatLng? _selectedLatLng = const LatLng(5.348722, -3.985038); Map> _categories = {}; List _currentCategories = []; String? _selectedCategoryType; @override void initState() { super.initState(); _loadCategories(); } void _loadCategories() async { final CategoryService categoryService = CategoryService(); final categories = await categoryService.loadCategories(); setState(() { _categories = categories; _selectedCategoryType = categories.keys.first; _currentCategories = categories[_selectedCategoryType] ?? []; }); } @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), ), backgroundColor: const Color(0xFF2C2C3E), child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildTitleField(), const SizedBox(height: 10), _buildDescriptionField(), const SizedBox(height: 10), _buildDatePicker(), const SizedBox(height: 10), _buildLocationField(context), const SizedBox(height: 10), _buildCategoryField(), const SizedBox(height: 10), _buildImagePicker(), const SizedBox(height: 10), _buildLinkField(), const SizedBox(height: 20), _buildSubmitButton(), ], ), ), ), ), ); } Widget _buildTitleField() { return TextFormField( decoration: InputDecoration( labelText: 'Titre', labelStyle: const TextStyle(color: Colors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide.none, ), prefixIcon: const Icon(Icons.title, color: Colors.white70), ), style: const TextStyle(color: Colors.white), validator: (value) { if (value == null || value.isEmpty) { print('Erreur: Titre est vide'); return 'Veuillez entrer un titre'; } return null; }, onSaved: (value) { _title = value ?? ''; print('Titre sauvegardé: $_title'); }, ); } Widget _buildDescriptionField() { return TextFormField( decoration: InputDecoration( labelText: 'Description', labelStyle: const TextStyle(color: Colors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide.none, ), prefixIcon: const Icon(Icons.description, color: Colors.white70), ), style: const TextStyle(color: Colors.white), maxLines: 3, validator: (value) { if (value == null || value.isEmpty) { print('Erreur: Description est vide'); return 'Veuillez entrer une description'; } return null; }, onSaved: (value) { _description = value ?? ''; print('Description sauvegardée: $_description'); }, ); } Widget _buildDatePicker() { return GestureDetector( onTap: () async { final DateTime? picked = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime(2101), ); if (picked != null && picked != _selectedDate) { setState(() { _selectedDate = picked; print('Date sélectionnée: $_selectedDate'); }); } else { print('Date non sélectionnée ou égale à la précédente'); } }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(10.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( _selectedDate == null ? 'Sélectionnez une date' : '${_selectedDate!.day}/${_selectedDate!.month}/${_selectedDate!.year}', style: const TextStyle(color: Colors.white70), ), const Icon(Icons.calendar_today, color: Colors.white70), ], ), ), ); } Widget _buildLocationField(BuildContext context) { return GestureDetector( onTap: () async { final LatLng? pickedLocation = await Navigator.push( context, MaterialPageRoute( builder: (context) => const LocationPickerScreen(), ), ); if (pickedLocation != null) { setState(() { _selectedLatLng = pickedLocation; _location = '${pickedLocation.latitude}, ${pickedLocation.longitude}'; print('Localisation sélectionnée: $_location'); }); } else { print('Localisation non sélectionnée'); } }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(10.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( _selectedLatLng == null ? 'Sélectionnez une localisation' : 'Localisation: $_location', style: const TextStyle(color: Colors.white70), ), const Icon(Icons.location_on, color: Colors.white70), ], ), ), ); } /// Construction du champ de catégorie avec sélection du type et de la catégorie. Widget _buildCategoryField() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DropdownButtonFormField( decoration: InputDecoration( labelText: 'Type de catégorie', labelStyle: const TextStyle(color: Colors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide.none, ), ), value: _selectedCategoryType, items: _categories.keys.map((String type) { return DropdownMenuItem( value: type, child: Text(type, style: const TextStyle(color: Colors.black)), ); }).toList(), onChanged: (String? newValue) { setState(() { _selectedCategoryType = newValue; _currentCategories = _categories[newValue] ?? []; _category = ''; // Réinitialiser la catégorie sélectionnée print('Type de catégorie sélectionné : $_selectedCategoryType'); print('Catégories disponibles pour ce type : $_currentCategories'); }); }, ), const SizedBox(height: 10), DropdownButtonFormField( decoration: InputDecoration( labelText: 'Catégorie', labelStyle: const TextStyle(color: Colors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide.none, ), ), value: _category.isNotEmpty ? _category : null, items: _currentCategories.map((String category) { return DropdownMenuItem( value: category, child: Text(category, style: const TextStyle(color: Colors.black)), ); }).toList(), onChanged: (String? newValue) { setState(() { _category = newValue ?? ''; print('Catégorie sélectionnée : $_category'); }); }, validator: (value) { if (value == null || value.isEmpty) { print('Erreur: Catégorie non sélectionnée'); return 'Veuillez sélectionner une catégorie'; } return null; }, ), ], ); } Widget _buildImagePicker() { return GestureDetector( onTap: () { // Logique pour sélectionner une image print('Image Picker activé'); }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(10.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( _imagePath == null ? 'Sélectionnez une image' : 'Image sélectionnée: $_imagePath', style: const TextStyle(color: Colors.white70), ), const Icon(Icons.image, color: Colors.white70), ], ), ), ); } Widget _buildLinkField() { return TextFormField( decoration: InputDecoration( labelText: 'Lien (optionnel)', labelStyle: const TextStyle(color: Colors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide.none, ), prefixIcon: const Icon(Icons.link, color: Colors.white70), ), style: const TextStyle(color: Colors.white), onSaved: (value) { _link = value ?? ''; print('Lien sauvegardé: $_link'); }, ); } Widget _buildSubmitButton() { return ElevatedButton( onPressed: () async { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); print('Formulaire validé'); EventModel newEvent = EventModel( id: '', title: _title, description: _description, date: _selectedDate?.toIso8601String() ?? '', location: _location, category: _category, link: _link, imageUrl: _imagePath ?? '', status: 'OPEN', creator: UserModel( userId: widget.userId, nom: widget.userName, prenoms: widget.userLastName, email: '', motDePasse: '', ), participants: [ UserModel( userId: widget.userId, nom: widget.userName, prenoms: widget.userLastName, email: '', motDePasse: '', ) ], ); Map eventData = newEvent.toJson(); print('Données JSON de l\'événement: $eventData'); final response = await http.post( Uri.parse('${Urls.baseUrl}/events'), headers: {'Content-Type': 'application/json'}, body: jsonEncode(eventData), ); print('Statut de la réponse: ${response.statusCode}'); print('Réponse brute: ${response.body}'); if (response.statusCode == 201) { print('Événement créé avec succès'); Fluttertoast.showToast( msg: "Événement créé avec succès!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 16.0, ); Navigator.of(context).pop(); // Fermer la boîte de dialogue } else { print('Erreur lors de la création de l\'événement: ${response.reasonPhrase}'); Fluttertoast.showToast( msg: "Erreur lors de la création de l'événement", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 16.0, ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Erreur: ${response.reasonPhrase}')), ); } } else { print('Le formulaire n\'est pas valide'); } }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF1DBF73), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), ), padding: const EdgeInsets.symmetric(vertical: 12.0), minimumSize: const Size(double.infinity, 40), ), child: const Text('Ajouter l\'événement', style: TextStyle(color: Colors.white)), ); } }