Refactoring : Fonctionnalité de Création d'un évènement est OK.
This commit is contained in:
@@ -4,6 +4,7 @@ import 'package:afterwork/data/models/event_model.dart';
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import '../../core/errors/exceptions.dart';
|
import '../../core/errors/exceptions.dart';
|
||||||
|
|
||||||
|
/// Source de données pour les événements distants.
|
||||||
class EventRemoteDataSource {
|
class EventRemoteDataSource {
|
||||||
final http.Client client;
|
final http.Client client;
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class EventModel {
|
|||||||
required this.location,
|
required this.location,
|
||||||
required this.category,
|
required this.category,
|
||||||
required this.link,
|
required this.link,
|
||||||
required this.imageUrl,
|
this.imageUrl,
|
||||||
required this.creator,
|
required this.creator,
|
||||||
required this.participants,
|
required this.participants,
|
||||||
});
|
});
|
||||||
@@ -36,14 +36,14 @@ class EventModel {
|
|||||||
date: json['date'],
|
date: json['date'],
|
||||||
location: json['location'],
|
location: json['location'],
|
||||||
category: json['category'],
|
category: json['category'],
|
||||||
link: json['link'],
|
link: json['link'] ?? '', // Assure qu'il ne soit pas null
|
||||||
imageUrl: json['imageUrl'],
|
imageUrl: json['imageUrl'] ?? '', // Assure qu'il ne soit pas null
|
||||||
creator: UserModel.fromJson(json['creator']),
|
creator: UserModel.fromJson(json['creator']),
|
||||||
participants: json['participants'] != null
|
participants: json['participants'] != null
|
||||||
? (json['participants'] as List)
|
? (json['participants'] as List)
|
||||||
.map((user) => UserModel.fromJson(user))
|
.map((user) => UserModel.fromJson(user))
|
||||||
.toList()
|
.toList()
|
||||||
: [],
|
: [], // Si participants est null, retourne une liste vide
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:afterwork/data/models/creator_model.dart';
|
|
||||||
import 'package:afterwork/data/models/event_model.dart';
|
import 'package:afterwork/data/models/event_model.dart';
|
||||||
import 'package:afterwork/data/models/participant_model.dart';
|
import 'package:afterwork/data/models/user_model.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:afterwork/data/providers/user_provider.dart';
|
|
||||||
import 'package:afterwork/core/constants/urls.dart';
|
import 'package:afterwork/core/constants/urls.dart';
|
||||||
import '../location/location_picker_screen.dart';
|
import '../location/location_picker_screen.dart';
|
||||||
|
|
||||||
|
/// Classe représentant la boîte de dialogue pour ajouter un nouvel événement.
|
||||||
|
/// Cette boîte de dialogue permet à l'utilisateur de remplir les détails d'un nouvel événement.
|
||||||
class AddEventDialog extends StatefulWidget {
|
class AddEventDialog extends StatefulWidget {
|
||||||
final String userId;
|
final String userId;
|
||||||
final String userName;
|
final String userName;
|
||||||
@@ -27,15 +26,15 @@ class AddEventDialog extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AddEventDialogState extends State<AddEventDialog> {
|
class _AddEventDialogState extends State<AddEventDialog> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>(); // Clé globale pour valider le formulaire
|
||||||
String _title = '';
|
String _title = '';
|
||||||
String _description = '';
|
String _description = '';
|
||||||
DateTime? _selectedDate;
|
DateTime? _selectedDate;
|
||||||
String? _imagePath;
|
String? _imagePath;
|
||||||
String _location = 'Abidjan'; // Par défaut à Cocody, Abidjan
|
String _location = 'Abidjan'; // Par défaut à Cocody, Abidjan
|
||||||
String _category = '';
|
String _category = '';
|
||||||
String _link = '';
|
String _link = '';
|
||||||
LatLng? _selectedLatLng = const LatLng(5.348722, -3.985038); // Par défaut à Cocody, Abidjan
|
LatLng? _selectedLatLng = const LatLng(5.348722, -3.985038); // Par défaut à Cocody, Abidjan
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -48,7 +47,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Form(
|
child: Form(
|
||||||
key: _formKey,
|
key: _formKey, // Formulaire clé pour valider l'entrée des utilisateurs
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -75,6 +74,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de saisie du titre de l'événement.
|
||||||
Widget _buildTitleField() {
|
Widget _buildTitleField() {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@@ -103,6 +103,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de saisie de la description de l'événement.
|
||||||
Widget _buildDescriptionField() {
|
Widget _buildDescriptionField() {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@@ -132,6 +133,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Widget pour le sélecteur de date pour l'événement.
|
||||||
Widget _buildDatePicker() {
|
Widget _buildDatePicker() {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
@@ -172,6 +174,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de localisation pour l'événement.
|
||||||
Widget _buildLocationField(BuildContext context) {
|
Widget _buildLocationField(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
@@ -213,6 +216,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de saisie de la catégorie de l'événement.
|
||||||
Widget _buildCategoryField() {
|
Widget _buildCategoryField() {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@@ -234,6 +238,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de sélection d'image pour l'événement.
|
||||||
Widget _buildImagePicker() {
|
Widget _buildImagePicker() {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -262,6 +267,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du champ de saisie du lien associé à l'événement.
|
||||||
Widget _buildLinkField() {
|
Widget _buildLinkField() {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@@ -283,6 +289,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction du bouton de soumission pour ajouter l'événement.
|
||||||
Widget _buildSubmitButton() {
|
Widget _buildSubmitButton() {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@@ -292,6 +299,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
|
|
||||||
// Créer l'événement en utilisant l'ID réel de l'utilisateur pour le créateur et les participants
|
// Créer l'événement en utilisant l'ID réel de l'utilisateur pour le créateur et les participants
|
||||||
EventModel newEvent = EventModel(
|
EventModel newEvent = EventModel(
|
||||||
|
id: '',
|
||||||
title: _title,
|
title: _title,
|
||||||
description: _description,
|
description: _description,
|
||||||
date: _selectedDate?.toIso8601String() ?? '',
|
date: _selectedDate?.toIso8601String() ?? '',
|
||||||
@@ -299,19 +307,22 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
category: _category,
|
category: _category,
|
||||||
link: _link,
|
link: _link,
|
||||||
imageUrl: _imagePath ?? '',
|
imageUrl: _imagePath ?? '',
|
||||||
creator: CreatorModel(
|
creator: UserModel(
|
||||||
id: widget.userId,
|
userId: widget.userId,
|
||||||
nom: widget.userName,
|
nom: widget.userName,
|
||||||
prenoms: widget.userLastName,
|
prenoms: widget.userLastName,
|
||||||
|
email: '',
|
||||||
|
motDePasse: '',
|
||||||
),
|
),
|
||||||
participants: [
|
participants: [
|
||||||
ParticipantModel(
|
UserModel(
|
||||||
id: widget.userId,
|
userId: widget.userId,
|
||||||
nom: widget.userName,
|
nom: widget.userName,
|
||||||
prenoms: widget.userLastName,
|
prenoms: widget.userLastName,
|
||||||
|
email: '',
|
||||||
|
motDePasse: '',
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
id: '',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convertir l'événement en JSON
|
// Convertir l'événement en JSON
|
||||||
@@ -331,7 +342,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
if (response.statusCode == 201) {
|
if (response.statusCode == 201) {
|
||||||
// Création réussie
|
// Création réussie
|
||||||
print('Événement créé avec succès');
|
print('Événement créé avec succès');
|
||||||
Navigator.of(context).pop(true);
|
Navigator.of(context).pop(); // Ne passez pas de valeur ici
|
||||||
} else {
|
} else {
|
||||||
// Gérer l'erreur
|
// Gérer l'erreur
|
||||||
print('Erreur lors de la création de l\'événement: ${response.reasonPhrase}');
|
print('Erreur lors de la création de l\'événement: ${response.reasonPhrase}');
|
||||||
@@ -351,8 +362,8 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
|||||||
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
||||||
minimumSize: const Size(double.infinity, 40),
|
minimumSize: const Size(double.infinity, 40),
|
||||||
),
|
),
|
||||||
child: const Text('Ajouter l\'événement',
|
child: const Text('Ajouter l\'événement', style: TextStyle(color: Colors.white)),
|
||||||
style: TextStyle(color: Colors.white)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:afterwork/data/models/event_model.dart';
|
||||||
|
import 'package:afterwork/data/datasources/event_remote_data_source.dart';
|
||||||
|
|
||||||
|
// Déclaration des événements
|
||||||
|
@immutable
|
||||||
|
abstract class EventEvent {}
|
||||||
|
|
||||||
|
class LoadEvents extends EventEvent {}
|
||||||
|
|
||||||
|
class AddEvent extends EventEvent {
|
||||||
|
final EventModel event;
|
||||||
|
|
||||||
|
AddEvent(this.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Déclaration des états
|
||||||
|
@immutable
|
||||||
|
abstract class EventState {}
|
||||||
|
|
||||||
|
class EventInitial extends EventState {}
|
||||||
|
|
||||||
|
class EventLoading extends EventState {}
|
||||||
|
|
||||||
|
class EventLoaded extends EventState {
|
||||||
|
final List<EventModel> events;
|
||||||
|
|
||||||
|
EventLoaded(this.events);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventError extends EventState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
EventError(this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bloc principal pour gérer la logique des événements
|
||||||
|
class EventBloc extends Bloc<EventEvent, EventState> {
|
||||||
|
final EventRemoteDataSource remoteDataSource;
|
||||||
|
|
||||||
|
EventBloc({required this.remoteDataSource}) : super(EventInitial()) {
|
||||||
|
on<LoadEvents>(_onLoadEvents);
|
||||||
|
on<AddEvent>(_onAddEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gestion de l'événement LoadEvents
|
||||||
|
Future<void> _onLoadEvents(LoadEvents event, Emitter<EventState> emit) async {
|
||||||
|
emit(EventLoading());
|
||||||
|
try {
|
||||||
|
final events = await remoteDataSource.getAllEvents();
|
||||||
|
emit(EventLoaded(events));
|
||||||
|
print('Événements chargés avec succès.');
|
||||||
|
} catch (e) {
|
||||||
|
emit(EventError('Erreur lors du chargement des événements.'));
|
||||||
|
print('Erreur lors du chargement des événements: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gestion de l'événement AddEvent
|
||||||
|
Future<void> _onAddEvent(AddEvent event, Emitter<EventState> emit) async {
|
||||||
|
emit(EventLoading());
|
||||||
|
try {
|
||||||
|
await remoteDataSource.createEvent(event.event);
|
||||||
|
final events = await remoteDataSource.getAllEvents();
|
||||||
|
emit(EventLoaded(events));
|
||||||
|
print('Événement ajouté avec succès.');
|
||||||
|
} catch (e) {
|
||||||
|
emit(EventError('Erreur lors de l\'ajout de l\'événement.'));
|
||||||
|
print('Erreur lors de l\'ajout de l\'événement: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user