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
This commit is contained in:
215
lib/data/models/trip.dart
Normal file
215
lib/data/models/trip.dart
Normal file
@@ -0,0 +1,215 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class Trip {
|
||||
final String? id;
|
||||
final String title;
|
||||
final String description;
|
||||
final String location;
|
||||
final DateTime startDate;
|
||||
final DateTime endDate;
|
||||
final double? budget;
|
||||
final List<String> participants;
|
||||
final String createdBy; // ID de l'utilisateur créateur
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final String status; // 'draft', 'active', 'completed', 'cancelled'
|
||||
|
||||
Trip({
|
||||
this.id,
|
||||
required this.title,
|
||||
required this.description,
|
||||
required this.location,
|
||||
required this.startDate,
|
||||
required this.endDate,
|
||||
this.budget,
|
||||
required this.participants,
|
||||
required this.createdBy,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.status = 'draft',
|
||||
});
|
||||
|
||||
// Constructeur pour créer un Trip depuis un Map (utile pour Firebase)
|
||||
factory Trip.fromMap(Map<String, dynamic> map) {
|
||||
return Trip(
|
||||
id: map['id'],
|
||||
title: map['title'] ?? '',
|
||||
description: map['description'] ?? '',
|
||||
location: map['location'] ?? '',
|
||||
startDate: _parseDateTime(map['startDate']),
|
||||
endDate: _parseDateTime(map['endDate']),
|
||||
budget: map['budget']?.toDouble(),
|
||||
participants: List<String>.from(map['participants'] ?? []),
|
||||
createdBy: map['createdBy'] ?? '',
|
||||
createdAt: _parseDateTime(map['createdAt']),
|
||||
updatedAt: _parseDateTime(map['updatedAt']),
|
||||
status: map['status'] ?? 'draft',
|
||||
);
|
||||
}
|
||||
|
||||
// Méthode helper pour parser les dates depuis différents formats
|
||||
static DateTime _parseDateTime(dynamic dateValue) {
|
||||
if (dateValue == null) {
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
if (dateValue is DateTime) {
|
||||
return dateValue;
|
||||
}
|
||||
|
||||
if (dateValue is String) {
|
||||
try {
|
||||
// Essayer de parser comme ISO 8601
|
||||
return DateTime.parse(dateValue);
|
||||
} catch (e) {
|
||||
print('Erreur parsing date string: $dateValue - $e');
|
||||
return DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
if (dateValue is int) {
|
||||
try {
|
||||
// Traiter comme millisecondes
|
||||
return DateTime.fromMillisecondsSinceEpoch(dateValue);
|
||||
} catch (e) {
|
||||
print('Erreur parsing date int: $dateValue - $e');
|
||||
return DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
print('Type de date non supporté: ${dateValue.runtimeType} - $dateValue');
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
// Constructeur pour créer un Trip depuis JSON
|
||||
factory Trip.fromJson(String jsonStr) {
|
||||
Map<String, dynamic> map = json.decode(jsonStr);
|
||||
return Trip.fromMap(map);
|
||||
}
|
||||
|
||||
// Méthode pour convertir un Trip en Map (utile pour Firebase)
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'location': location,
|
||||
'startDate': startDate.millisecondsSinceEpoch,
|
||||
'endDate': endDate.millisecondsSinceEpoch,
|
||||
'budget': budget,
|
||||
'participants': participants,
|
||||
'createdBy': createdBy,
|
||||
'createdAt': createdAt.millisecondsSinceEpoch,
|
||||
'updatedAt': updatedAt.millisecondsSinceEpoch,
|
||||
'status': status,
|
||||
};
|
||||
}
|
||||
|
||||
// Méthode pour convertir un Trip en JSON
|
||||
String toJson() {
|
||||
return json.encode(toMap());
|
||||
}
|
||||
|
||||
// Méthode pour créer une copie avec des modifications
|
||||
Trip copyWith({
|
||||
String? id,
|
||||
String? title,
|
||||
String? description,
|
||||
String? location,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
double? budget,
|
||||
List<String>? participants,
|
||||
String? createdBy,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
String? status,
|
||||
}) {
|
||||
return Trip(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
location: location ?? this.location,
|
||||
startDate: startDate ?? this.startDate,
|
||||
endDate: endDate ?? this.endDate,
|
||||
budget: budget ?? this.budget,
|
||||
participants: participants ?? this.participants,
|
||||
createdBy: createdBy ?? this.createdBy,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
status: status ?? this.status,
|
||||
);
|
||||
}
|
||||
|
||||
// Méthode pour obtenir la durée du voyage en jours
|
||||
int get durationInDays {
|
||||
return endDate.difference(startDate).inDays + 1;
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si le voyage est en cours
|
||||
bool get isActive {
|
||||
final now = DateTime.now();
|
||||
return status == 'active' &&
|
||||
now.isAfter(startDate) &&
|
||||
now.isBefore(endDate.add(Duration(days: 1)));
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si le voyage est à venir
|
||||
bool get isUpcoming {
|
||||
final now = DateTime.now();
|
||||
return status == 'active' && now.isBefore(startDate);
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si le voyage est terminé
|
||||
bool get isCompleted {
|
||||
final now = DateTime.now();
|
||||
return status == 'completed' ||
|
||||
(status == 'active' && now.isAfter(endDate));
|
||||
}
|
||||
|
||||
// Méthode pour obtenir le budget par participant
|
||||
double? get budgetPerParticipant {
|
||||
if (budget == null || participants.isEmpty) return null;
|
||||
return budget! / (participants.length + 1); // +1 pour le créateur
|
||||
}
|
||||
|
||||
// Méthode pour obtenir le nombre total de participants (incluant le créateur)
|
||||
int get totalParticipants {
|
||||
return participants.length + 1; // +1 pour le créateur
|
||||
}
|
||||
|
||||
// Méthode pour formater les dates
|
||||
String get formattedDates {
|
||||
return '${startDate.day}/${startDate.month}/${startDate.year} - ${endDate.day}/${endDate.month}/${endDate.year}';
|
||||
}
|
||||
|
||||
// Méthode pour obtenir le statut formaté
|
||||
String get formattedStatus {
|
||||
switch (status) {
|
||||
case 'draft':
|
||||
return 'Brouillon';
|
||||
case 'active':
|
||||
return 'Actif';
|
||||
case 'completed':
|
||||
return 'Terminé';
|
||||
case 'cancelled':
|
||||
return 'Annulé';
|
||||
default:
|
||||
return 'Inconnu';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Trip(id: $id, title: $title, location: $location, dates: $formattedDates, participants: ${participants.length})';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
return other is Trip && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
Reference in New Issue
Block a user