Files
TravelMate/lib/services/trip_service.dart
Dayron c4588a65c0 Refactor signup page to use BLoC pattern and implement authentication repository
- Updated signup.dart to replace Provider with BLoC for state management.
- Created AuthRepository to handle authentication logic and Firestore user management.
- Added TripRepository and UserRepository for trip and user data management.
- Implemented methods for user sign-in, sign-up, and data retrieval in repositories.
- Enhanced trip management with create, update, delete, and participant management functionalities.
- Updated AuthService to include new methods for sign-in and sign-up.
- Removed unnecessary print statements from TripService for cleaner code.
- Added dependencies for flutter_bloc and equatable in pubspec.yaml.

Not tested yet
2025-10-14 10:53:28 +02:00

269 lines
8.4 KiB
Dart

import 'package:cloud_firestore/cloud_firestore.dart';
import '../data/models/trip.dart';
class TripService {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
static const String _tripsCollection = 'trips';
// Charger tous les voyages
Future<List<Trip>> loadTrips() async {
try {
final QuerySnapshot querySnapshot = await _firestore
.collection(_tripsCollection)
.orderBy('createdAt', descending: true)
.get();
return querySnapshot.docs.map((doc) {
final data = doc.data() as Map<String, dynamic>;
return Trip.fromMap({...data, 'id': doc.id});
}).toList();
} catch (e) {
print('Erreur lors du chargement des voyages: $e');
return [];
}
}
// Ajouter un nouveau voyage
Future<bool> addTrip(Trip trip) async {
try {
final tripData = trip.toMap();
// Retirer l'ID vide du map
tripData.remove('id');
// Convertir les dates en Timestamp pour Firestore
tripData['startDate'] = Timestamp.fromDate(trip.startDate);
tripData['endDate'] = Timestamp.fromDate(trip.endDate);
tripData['createdAt'] = FieldValue.serverTimestamp();
tripData['updatedAt'] = FieldValue.serverTimestamp();
await _firestore.collection(_tripsCollection).add(tripData);
return true;
} catch (e) {
print('Erreur lors de l\'ajout du voyage: $e');
return false;
}
}
// Stream pour écouter les voyages d'un utilisateur en temps réel
Stream<List<Trip>> getTripsStreamByUser(String userId, String userEmail) {
print('=== STREAM CRÉÉ ===');
print('UserId: $userId');
return _firestore
.collection(_tripsCollection)
.snapshots()
.map((snapshot) {
final List<Trip> trips = [];
for (int i = 0; i < snapshot.docs.length; i++) {
var doc = snapshot.docs[i];
try {
final data = doc.data();
// Vérifier si l'utilisateur est impliqué dans ce voyage
final String createdBy = data['createdBy']?.toString() ?? '';
final List<dynamic> participants = data['participants'] ?? [];
bool userIsInvolved = false;
String reason = '';
// L'utilisateur est le créateur
if (createdBy == userId) {
userIsInvolved = true;
reason = 'Créateur du voyage';
}
// L'utilisateur est dans la liste des participants (par ID uniquement)
if (participants.contains(userId)) {
userIsInvolved = true;
reason = reason.isEmpty ? 'Participant par ID' : '$reason + Participant par ID';
}
if (userIsInvolved) {
final trip = _convertDocumentToTrip(doc.id, data);
if (trip != null) {
trips.add(trip);
}
}
} catch (e, stackTrace) {
print('Erreur lors du traitement du document ${doc.id}: $e');
print('StackTrace: $stackTrace');
}
}
// Trier par date de création (les plus récents en premier)
trips.sort((a, b) {
try {
return b.createdAt.compareTo(a.createdAt);
} catch (e) {
print('Erreur lors du tri: $e');
return 0;
}
});
return trips;
}).handleError((error, stackTrace) {
print('Erreur dans le stream: $error');
print('StackTrace: $stackTrace');
return <Trip>[];
});
}
// Obtenir les voyages d'un utilisateur (version simplifiée)
Future<List<Trip>> getTripsByUser(String userId) async {
try {
// Récupérer d'abord les voyages créés par l'utilisateur
final QuerySnapshot createdTrips = await _firestore
.collection(_tripsCollection)
.where('createdBy', isEqualTo: userId)
.get();
final List<Trip> trips = [];
for (var doc in createdTrips.docs) {
try {
final data = doc.data() as Map<String, dynamic>;
final trip = _convertDocumentToTrip(doc.id, data);
if (trip != null) {
trips.add(trip);
}
} catch (e) {
print('Erreur lors de la conversion du voyage créé ${doc.id}: $e');
}
}
// Trier par date de création
trips.sort((a, b) {
try {
return b.createdAt.compareTo(a.createdAt);
} catch (e) {
return 0;
}
});
return trips;
} catch (e) {
print('Erreur lors de la récupération des voyages: $e');
return [];
}
}
// Méthode helper pour convertir un document Firestore en Trip
Trip? _convertDocumentToTrip(String docId, Map<String, dynamic> data) {
try {
// Créer une copie des données pour ne pas modifier l'original
Map<String, dynamic> processedData = Map<String, dynamic>.from(data);
// Convertir les Timestamps Firestore en String ISO
if (processedData['createdAt'] is Timestamp) {
processedData['createdAt'] = (processedData['createdAt'] as Timestamp).toDate().toIso8601String();
}
if (processedData['updatedAt'] is Timestamp) {
processedData['updatedAt'] = (processedData['updatedAt'] as Timestamp).toDate().toIso8601String();
}
if (processedData['startDate'] is Timestamp) {
processedData['startDate'] = (processedData['startDate'] as Timestamp).toDate().toIso8601String();
}
if (processedData['endDate'] is Timestamp) {
processedData['endDate'] = (processedData['endDate'] as Timestamp).toDate().toIso8601String();
}
// Assurer que tous les champs requis sont présents
processedData['id'] = docId;
processedData['participants'] = processedData['participants'] ?? [];
processedData['budget'] = (processedData['budget'] is num) ? (processedData['budget'] as num).toDouble() : 0.0;
processedData['description'] = processedData['description'] ?? '';
processedData['status'] = processedData['status'] ?? 'draft';
final trip = Trip.fromMap(processedData);
return trip;
} catch (e, stackTrace) {
print('Erreur lors de la conversion du document $docId: $e');
print('StackTrace: $stackTrace');
return null;
}
}
// Mettre à jour un voyage
Future<bool> updateTrip(Trip updatedTrip) async {
try {
final tripData = updatedTrip.toMap();
tripData['updatedAt'] = FieldValue.serverTimestamp();
tripData.remove('id'); // Retirer l'ID des données à mettre à jour
await _firestore
.collection(_tripsCollection)
.doc(updatedTrip.id)
.update(tripData);
return true;
} catch (e) {
print('Erreur lors de la mise à jour du voyage: $e');
return false;
}
}
// Supprimer un voyage
Future<bool> deleteTrip(String tripId) async {
try {
await _firestore.collection(_tripsCollection).doc(tripId).delete();
return true;
} catch (e) {
print('Erreur lors de la suppression du voyage: $e');
return false;
}
}
// Obtenir un voyage par son ID
Future<Trip?> getTripById(String tripId) async {
try {
final DocumentSnapshot doc = await _firestore
.collection(_tripsCollection)
.doc(tripId)
.get();
if (doc.exists) {
final data = doc.data() as Map<String, dynamic>;
return Trip.fromMap({...data, 'id': doc.id});
}
return null;
} catch (e) {
print('Erreur lors de la récupération du voyage: $e');
return null;
}
}
// Ajouter un participant à un voyage
Future<bool> addParticipant(String tripId, String userId) async {
try {
await _firestore.collection(_tripsCollection).doc(tripId).update({
'participants': FieldValue.arrayUnion([userId]),
'updatedAt': FieldValue.serverTimestamp(),
});
return true;
} catch (e) {
print('Erreur lors de l\'ajout du participant: $e');
return false;
}
}
// Retirer un participant d'un voyage
Future<bool> removeParticipant(String tripId, String userId) async {
try {
await _firestore.collection(_tripsCollection).doc(tripId).update({
'participants': FieldValue.arrayRemove([userId]),
'updatedAt': FieldValue.serverTimestamp(),
});
return true;
} catch (e) {
print('Erreur lors du retrait du participant: $e');
return false;
}
}
}