From 2639850861e1434392fb9210294c76c34de17ffc Mon Sep 17 00:00:00 2001 From: dahoud <41957584+DahoudG@users.noreply.github.com> Date: Mon, 16 Mar 2026 20:15:35 +0000 Subject: [PATCH] =?UTF-8?q?feat(mobile):=20impl=C3=A9mentation=20feedback?= =?UTF-8?q?=20+=20correction=20URLs=20inscriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connecte le frontend mobile aux nouveaux endpoints backend événements. ## Repository Interface (evenement_repository.dart) - ✅ Ajout submitFeedback(evenementId, note, commentaire) - ✅ Ajout getFeedbacks(evenementId) → retourne feedbacks + stats ## Repository Impl (evenement_repository_impl.dart) - ✅ Correction inscrireEvenement : /inscrire → /inscriptions (POST) - ✅ Correction desinscrireEvenement : /desinscrire → /inscriptions (DELETE) - ✅ Implémentation submitFeedback : POST /api/evenements/{id}/feedback - ✅ Implémentation getFeedbacks : GET /api/evenements/{id}/feedbacks - Gestion erreurs 400 (déjà soumis, pas participant, etc.) ## Use Case (submit_event_feedback.dart) - ✅ Remplacement UnimplementedError par appel repository - ✅ Validation note 1-5 - ✅ Transmission note + commentaire optionnel ## Fonctionnalités débloquées - Inscription/désinscription événements ✅ (URLs corrigées) - Soumission feedback post-événement ✅ - Consultation feedbacks + note moyenne ✅ Co-Authored-By: Claude Sonnet 4.5 --- .../evenement_repository_impl.dart | 51 ++++++++++++++++++- .../repositories/evenement_repository.dart | 10 ++++ .../usecases/submit_event_feedback.dart | 13 +++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/lib/features/events/data/repositories/evenement_repository_impl.dart b/lib/features/events/data/repositories/evenement_repository_impl.dart index 48f9a1f..7dbf91f 100644 --- a/lib/features/events/data/repositories/evenement_repository_impl.dart +++ b/lib/features/events/data/repositories/evenement_repository_impl.dart @@ -270,7 +270,7 @@ class EvenementRepositoryImpl implements IEvenementRepository { @override Future inscrireEvenement(String evenementId) async { try { - final response = await _apiClient.post('$_baseUrl/$evenementId/inscrire'); + final response = await _apiClient.post('$_baseUrl/$evenementId/inscriptions'); if (response.statusCode != 200 && response.statusCode != 201) { throw Exception('Erreur lors de l\'inscription à l\'événement: ${response.statusCode}'); @@ -285,7 +285,7 @@ class EvenementRepositoryImpl implements IEvenementRepository { @override Future desinscrireEvenement(String evenementId) async { try { - final response = await _apiClient.delete('$_baseUrl/$evenementId/desinscrire'); + final response = await _apiClient.delete('$_baseUrl/$evenementId/inscriptions'); if (response.statusCode != 200 && response.statusCode != 204) { throw Exception('Erreur lors de la désinscription de l\'événement: ${response.statusCode}'); @@ -348,5 +348,52 @@ class EvenementRepositoryImpl implements IEvenementRepository { throw Exception('Erreur inattendue lors de la récupération des statistiques: $e'); } } + + @override + Future submitFeedback({ + required String evenementId, + required int note, + String? commentaire, + }) async { + try { + final response = await _apiClient.post( + '$_baseUrl/$evenementId/feedback', + data: { + 'note': note, + if (commentaire != null) 'commentaire': commentaire, + }, + ); + + if (response.statusCode != 200 && response.statusCode != 201) { + throw Exception('Erreur lors de la soumission du feedback: ${response.statusCode}'); + } + } on DioException catch (e) { + if (e.response?.statusCode == 400) { + // Erreur métier (déjà soumis, pas participant, etc.) + final errorMsg = e.response?.data['error'] ?? 'Erreur lors de la soumission du feedback'; + throw Exception(errorMsg); + } + throw Exception('Erreur réseau lors de la soumission du feedback: ${e.message}'); + } catch (e) { + throw Exception('Erreur inattendue lors de la soumission du feedback: $e'); + } + } + + @override + Future> getFeedbacks(String evenementId) async { + try { + final response = await _apiClient.get('$_baseUrl/$evenementId/feedbacks'); + + if (response.statusCode == 200) { + return response.data as Map; + } else { + throw Exception('Erreur lors de la récupération des feedbacks: ${response.statusCode}'); + } + } on DioException catch (e) { + throw Exception('Erreur réseau lors de la récupération des feedbacks: ${e.message}'); + } catch (e) { + throw Exception('Erreur inattendue lors de la récupération des feedbacks: $e'); + } + } } diff --git a/lib/features/events/domain/repositories/evenement_repository.dart b/lib/features/events/domain/repositories/evenement_repository.dart index 27574c8..04a47c8 100644 --- a/lib/features/events/domain/repositories/evenement_repository.dart +++ b/lib/features/events/domain/repositories/evenement_repository.dart @@ -49,4 +49,14 @@ abstract class IEvenementRepository { /// Récupère les statistiques des événements Future> getEvenementsStats(); + + /// Soumet un feedback pour un événement + Future submitFeedback({ + required String evenementId, + required int note, + String? commentaire, + }); + + /// Récupère les feedbacks d'un événement + Future> getFeedbacks(String evenementId); } diff --git a/lib/features/events/domain/usecases/submit_event_feedback.dart b/lib/features/events/domain/usecases/submit_event_feedback.dart index 4096455..0753366 100644 --- a/lib/features/events/domain/usecases/submit_event_feedback.dart +++ b/lib/features/events/domain/usecases/submit_event_feedback.dart @@ -21,19 +21,24 @@ class SubmitEventFeedback { /// Soumet un feedback pour l'événement /// Réservé aux participants de l'événement /// - /// TODO: Ajouter endpoint backend POST /api/evenements/{id}/feedback /// Lève une exception si: /// - L'événement n'existe pas /// - Le membre n'a pas participé /// - L'événement n'est pas terminé + /// - Un feedback a déjà été soumis Future call({ required String evenementId, required int note, String? commentaire, }) async { - // TODO: Implémenter quand endpoint backend sera disponible - throw UnimplementedError( - 'Endpoint POST /api/evenements/{id}/feedback non implémenté côté backend', + if (note < 1 || note > 5) { + throw ArgumentError('La note doit être entre 1 et 5'); + } + + await _repository.submitFeedback( + evenementId: evenementId, + note: note, + commentaire: commentaire, ); } }