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:
Dayron
2025-10-14 10:53:28 +02:00
parent a467b92979
commit c4588a65c0
31 changed files with 1500 additions and 689 deletions

View File

@@ -1,26 +0,0 @@
class Group {
final String? id;
final String name;
final List<String> members;
Group({
this.id,
required this.name,
required this.members,
});
factory Group.fromMap(Map<String, dynamic> data, String documentId) {
return Group(
id: documentId,
name: data['name'] ?? '',
members: List<String>.from(data['members'] ?? []),
);
}
Map<String, dynamic> toMap() {
return {
'name': name,
'members': members,
};
}
}

View File

@@ -1,15 +0,0 @@
class Message {
final String text;
final DateTime timestamp;
final String senderId;
final String senderName;
final String groupId;
Message({
required this.text,
required this.timestamp,
required this.senderId,
required this.senderName,
required this.groupId,
});
}

View File

@@ -1,215 +0,0 @@
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;
}

View File

@@ -1,79 +0,0 @@
import 'dart:convert';
class User {
final String? id;
final String nom;
final String prenom;
final String email;
User({
this.id,
required this.nom,
required this.prenom,
required this.email,
});
// Constructeur pour créer un User depuis un Map (utile pour Firebase)
factory User.fromMap(Map<String, dynamic> map) {
return User(
id: map['id'],
nom: map['nom'] ?? '',
prenom: map['prenom'] ?? '',
email: map['email'] ?? '',
);
}
// Constructeur pour créer un User depuis JSON
factory User.fromJson(String jsonStr) {
Map<String, dynamic> map = json.decode(jsonStr);
return User.fromMap(map);
}
// Méthode pour convertir un User en Map (utile pour Firebase)
Map<String, dynamic> toMap() {
return {
'id': id,
'nom': nom,
'prenom': prenom,
'email': email,
};
}
// Méthode pour convertir un User en JSON
String toJson() {
return json.encode(toMap());
}
// Méthode pour obtenir le nom complet
String get fullName => '$prenom $nom';
// Méthode pour créer une copie avec des modifications
User copyWith({
String? id,
String? nom,
String? prenom,
String? email,
}) {
return User(
id: id ?? this.id,
nom: nom ?? this.nom,
prenom: prenom ?? this.prenom,
email: email ?? this.email,
);
}
@override
String toString() {
return 'User(id: $id, nom: $nom, prenom: $prenom, email: $email)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is User && other.email == email;
}
@override
int get hashCode => email.hashCode;
}