feat: Enhance trip management features and improve UI responsiveness
- Implemented AutomaticKeepAliveClientMixin in HomeContent to maintain state during navigation. - Modified trip loading logic to trigger after the first frame for better performance. - Updated trip loading events to use LoadTripsByUserId for consistency. - Added temporary success messages for trip creation and operations. - Improved UI elements for better user experience, including updated text styles and spacing. - Refactored trip model to support Firestore timestamps and improved error handling during parsing. - Streamlined trip repository methods for better clarity and performance. - Enhanced trip service methods to ensure correct mapping from Firestore documents. - Removed unnecessary trip reset logic on logout.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class Trip {
|
||||
final String? id;
|
||||
@@ -9,10 +10,10 @@ class Trip {
|
||||
final DateTime endDate;
|
||||
final double? budget;
|
||||
final List<String> participants;
|
||||
final String createdBy; // ID de l'utilisateur créateur
|
||||
final String createdBy;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final String status; // 'draft', 'active', 'completed', 'cancelled'
|
||||
final String status;
|
||||
|
||||
Trip({
|
||||
this.id,
|
||||
@@ -29,74 +30,71 @@ class Trip {
|
||||
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();
|
||||
// NOUVELLE MÉTHODE HELPER pour convertir n'importe quel format de date
|
||||
static DateTime _parseDateTime(dynamic value) {
|
||||
if (value == null) return DateTime.now();
|
||||
|
||||
// Si c'est déjà un Timestamp Firebase
|
||||
if (value is Timestamp) {
|
||||
return value.toDate();
|
||||
}
|
||||
|
||||
if (dateValue is DateTime) {
|
||||
return dateValue;
|
||||
|
||||
// Si c'est un int (millisecondes depuis epoch)
|
||||
if (value is int) {
|
||||
return DateTime.fromMillisecondsSinceEpoch(value);
|
||||
}
|
||||
|
||||
if (dateValue is String) {
|
||||
try {
|
||||
// Essayer de parser comme ISO 8601
|
||||
return DateTime.parse(dateValue);
|
||||
} catch (e) {
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
// Si c'est un String (ISO 8601)
|
||||
if (value is String) {
|
||||
return DateTime.parse(value);
|
||||
}
|
||||
|
||||
if (dateValue is int) {
|
||||
try {
|
||||
// Traiter comme millisecondes
|
||||
return DateTime.fromMillisecondsSinceEpoch(dateValue);
|
||||
} catch (e) {
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
// Si c'est déjà un DateTime
|
||||
if (value is DateTime) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Par défaut
|
||||
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);
|
||||
// Constructeur pour créer un Trip depuis un Map (utile pour Firebase)
|
||||
factory Trip.fromMap(Map<String, dynamic> map, String id) {
|
||||
try {
|
||||
return Trip(
|
||||
id: id,
|
||||
title: map['title'] as String? ?? '',
|
||||
description: map['description'] as String? ?? '',
|
||||
location: map['location'] as String? ?? '',
|
||||
startDate: _parseDateTime(map['startDate']),
|
||||
endDate: _parseDateTime(map['endDate']),
|
||||
budget: (map['budget'] as num?)?.toDouble(),
|
||||
createdBy: map['createdBy'] as String? ?? '',
|
||||
participants: List<String>.from(map['participants'] as List? ?? []),
|
||||
createdAt: _parseDateTime(map['createdAt']),
|
||||
updatedAt: _parseDateTime(map['updatedAt']),
|
||||
status: map['status'] as String? ?? 'draft',
|
||||
);
|
||||
} catch (e) {
|
||||
print('❌ Erreur parsing Trip: $e');
|
||||
print('Map reçue: $map');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour convertir un Trip en Map (utile pour Firebase)
|
||||
// MODIFIÉ : Convertir en Map avec Timestamp pour Firestore
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'location': location,
|
||||
'startDate': startDate.millisecondsSinceEpoch,
|
||||
'endDate': endDate.millisecondsSinceEpoch,
|
||||
'startDate': Timestamp.fromDate(startDate),
|
||||
'endDate': Timestamp.fromDate(endDate),
|
||||
'budget': budget,
|
||||
'participants': participants,
|
||||
'createdBy': createdBy,
|
||||
'createdAt': createdAt.millisecondsSinceEpoch,
|
||||
'updatedAt': updatedAt.millisecondsSinceEpoch,
|
||||
'createdAt': Timestamp.fromDate(createdAt),
|
||||
'updatedAt': Timestamp.fromDate(updatedAt),
|
||||
'status': status,
|
||||
};
|
||||
}
|
||||
@@ -166,12 +164,12 @@ class Trip {
|
||||
// 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
|
||||
return budget! / (participants.length + 1);
|
||||
}
|
||||
|
||||
// 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
|
||||
return participants.length + 1;
|
||||
}
|
||||
|
||||
// Méthode pour formater les dates
|
||||
@@ -197,7 +195,7 @@ class Trip {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Trip(id: $id, title: $title, location: $location, dates: $formattedDates, participants: ${participants.length})';
|
||||
return 'Trip(id: $id, title: $title, location: $location, status: $status)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -208,4 +206,4 @@ class Trip {
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user