diff --git a/lib/components/home/show_trip_details_content.dart b/lib/components/home/show_trip_details_content.dart index c746d9f..00e64fc 100644 --- a/lib/components/home/show_trip_details_content.dart +++ b/lib/components/home/show_trip_details_content.dart @@ -21,9 +21,8 @@ class _ShowTripDetailsContentState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => MapContent( - initialSearchQuery: widget.trip.location, - ), + builder: (context) => + MapContent(initialSearchQuery: widget.trip.location), ), ); } @@ -32,7 +31,7 @@ class _ShowTripDetailsContentState extends State { Future _openGoogleMaps() async { final location = Uri.encodeComponent(widget.trip.location); final url = 'https://www.google.com/maps/search/?api=1&query=$location'; - + try { final uri = Uri.parse(url); if (await canLaunchUrl(uri)) { @@ -48,7 +47,9 @@ class _ShowTripDetailsContentState extends State { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text('Impossible d\'ouvrir Google Maps. Vérifiez que l\'application est installée.'), + content: Text( + 'Impossible d\'ouvrir Google Maps. Vérifiez que l\'application est installée.', + ), backgroundColor: Colors.red, ), ); @@ -69,15 +70,12 @@ class _ShowTripDetailsContentState extends State { @override Widget build(BuildContext context) { - final isDarkMode = Theme.of(context).brightness == Brightness.dark; final textColor = isDarkMode ? Colors.white : Colors.black; final secondaryTextColor = isDarkMode ? Colors.white70 : Colors.grey[600]; - + return Scaffold( - appBar: AppBar( - title: Text(widget.trip.title), - ), + appBar: AppBar(title: Text(widget.trip.title)), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( @@ -92,10 +90,7 @@ class _ShowTripDetailsContentState extends State { ), ), SizedBox(height: 8), - Text( - widget.trip.description, - style: TextStyle(color: textColor), - ), + Text(widget.trip.description, style: TextStyle(color: textColor)), SizedBox(height: 16), Row( children: [ @@ -125,10 +120,7 @@ class _ShowTripDetailsContentState extends State { SizedBox(width: 8), Text( '${widget.trip.participants.length} participant${widget.trip.participants.length > 1 ? 's' : ''}', - style: TextStyle( - fontSize: 14, - color: secondaryTextColor, - ), + style: TextStyle(fontSize: 14, color: secondaryTextColor), ), ], ), @@ -166,7 +158,7 @@ class _ShowTripDetailsContentState extends State { ), ), style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, + backgroundColor: const Color.fromARGB(255, 102, 102, 102), padding: EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), @@ -175,7 +167,7 @@ class _ShowTripDetailsContentState extends State { ), ), SizedBox(width: 12), - + // Bouton Google Maps Expanded( child: ElevatedButton.icon( @@ -189,7 +181,7 @@ class _ShowTripDetailsContentState extends State { ), ), style: ElevatedButton.styleFrom( - backgroundColor: Colors.green[700], + backgroundColor: const Color.fromARGB(255, 102, 102, 102), padding: EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), @@ -211,13 +203,11 @@ class _ShowTripDetailsContentState extends State { final result = await Navigator.push( context, MaterialPageRoute( - builder: (context) => CreateTripContent( - tripToEdit: widget.trip, - ), + builder: (context) => + CreateTripContent(tripToEdit: widget.trip), ), ); - - + if (result == true && mounted) { Navigator.pop(context, true); // Retour avec flag } @@ -249,7 +239,8 @@ class _ShowTripDetailsContentState extends State { builder: (context) => AlertDialog( title: Text('Confirmer la suppression'), content: Text( - 'Êtes-vous sûr de vouloir supprimer ce voyage ? Cette action est irréversible.'), + 'Êtes-vous sûr de vouloir supprimer ce voyage ? Cette action est irréversible.', + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), @@ -257,9 +248,14 @@ class _ShowTripDetailsContentState extends State { ), TextButton( onPressed: () { - context.read().add(TripDeleteRequested(tripId: widget.trip.id!)); + context.read().add( + TripDeleteRequested(tripId: widget.trip.id!), + ); Navigator.pop(context); // Fermer le dialogue - Navigator.pop(context, true); // Retourner à l'écran précédent + Navigator.pop( + context, + true, + ); // Retourner à l'écran précédent }, child: Text( 'Supprimer', @@ -285,10 +281,10 @@ class _ShowTripDetailsContentState extends State { ), ), ), - ) + ), ], ), ), ); } -} \ No newline at end of file +} diff --git a/lib/models/user.dart b/lib/models/user.dart index 95a80d8..ef6024c 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -1,36 +1,49 @@ import 'dart:convert'; /// Model representing a user in the travel mate application. -/// +/// /// This class encapsulates user information including personal details /// and provides methods for serialization/deserialization with Firebase /// and JSON operations. class User { /// Unique identifier for the user (usually Firebase UID). final String? id; - + /// User's last name. final String nom; - + /// User's first name. final String prenom; - + /// User's email address. final String email; + /// User's profile picture URL (optional). + final String? profilePictureUrl; + + /// User's phone number (optional). + final String? phoneNumber; + + /// Platform used for authentication (e.g., 'google', 'apple', 'email'). + final String platform; + /// Creates a new [User] instance. - /// - /// [nom], [prenom], and [email] are required fields. + /// + /// [nom], [prenom], [email] and [platform] are required fields. + /// [profilePictureUrl] and [phoneNumber] are optional. /// [id] is optional and typically assigned by Firebase. User({ this.id, required this.nom, required this.prenom, required this.email, + this.profilePictureUrl, + this.phoneNumber, + required this.platform, }); /// Creates a [User] instance from a Map (useful for Firebase operations). - /// + /// /// Handles null values gracefully by providing empty string defaults. factory User.fromMap(Map map) { return User( @@ -38,11 +51,14 @@ class User { nom: map['nom'] ?? '', prenom: map['prenom'] ?? '', email: map['email'] ?? '', + profilePictureUrl: map['profilePictureUrl'], + phoneNumber: map['phoneNumber'], + platform: map['platform'] ?? '', ); } /// Creates a [User] instance from a JSON string. - /// + /// /// Parses the JSON and delegates to [fromMap] for object creation. factory User.fromJson(String jsonStr) { Map map = json.decode(jsonStr); @@ -50,7 +66,7 @@ class User { } /// Converts the [User] instance to a Map (useful for Firebase operations). - /// + /// /// Returns a map with all user properties for database storage. Map toMap() { return { @@ -58,11 +74,14 @@ class User { 'nom': nom, 'prenom': prenom, 'email': email, + 'profilePictureUrl': profilePictureUrl, + 'phoneNumber': phoneNumber, + 'platform': platform, }; } /// Converts the [User] instance to a JSON string. - /// + /// /// Useful for API communications and data serialization. String toJson() { return json.encode(toMap()); @@ -72,7 +91,7 @@ class User { String get fullName => '$prenom $nom'; /// Creates a copy of this user with optionally modified properties. - /// + /// /// Allows updating specific fields while preserving others. /// Useful for state management and partial updates. User copyWith({ @@ -80,12 +99,18 @@ class User { String? nom, String? prenom, String? email, + String? profilePictureUrl, + String? phoneNumber, + String? platform, }) { return User( id: id ?? this.id, nom: nom ?? this.nom, prenom: prenom ?? this.prenom, email: email ?? this.email, + profilePictureUrl: profilePictureUrl ?? this.profilePictureUrl, + phoneNumber: phoneNumber ?? this.phoneNumber, + platform: platform ?? this.platform, ); } @@ -96,7 +121,7 @@ class User { } /// Compares users based on email address. - /// + /// /// Two users are considered equal if they have the same email. @override bool operator ==(Object other) { @@ -108,4 +133,3 @@ class User { @override int get hashCode => email.hashCode; } - diff --git a/lib/repositories/auth_repository.dart b/lib/repositories/auth_repository.dart index 2c334c5..6afb966 100644 --- a/lib/repositories/auth_repository.dart +++ b/lib/repositories/auth_repository.dart @@ -61,6 +61,7 @@ class AuthRepository { } catch (e) { _errorService.showError(message: 'Utilisateur ou mot de passe incorrect'); } + return null; } /// Creates a new user account with email and password. @@ -93,6 +94,9 @@ class AuthRepository { email: email, nom: nom, prenom: prenom, + phoneNumber: 'Uknown', + platform: 'email', + profilePictureUrl: '', ); await _firestore.collection('users').doc(user.id).set(user.toMap()); @@ -100,6 +104,7 @@ class AuthRepository { } catch (e) { _errorService.showError(message: 'Erreur lors de la création du compte'); } + return null; } /// Signs in a user using Google authentication. @@ -127,6 +132,9 @@ class AuthRepository { email: firebaseUser.user!.email ?? '', nom: '', prenom: firebaseUser.user!.displayName ?? 'User', + phoneNumber: firebaseUser.user!.phoneNumber ?? 'Uknown', + profilePictureUrl: firebaseUser.user!.photoURL, + platform: 'google', ); await _firestore.collection('users').doc(user.id).set(user.toMap()); @@ -162,6 +170,9 @@ class AuthRepository { email: firebaseUser.user!.email ?? '', nom: '', prenom: firebaseUser.user!.displayName ?? 'User', + phoneNumber: firebaseUser.user!.phoneNumber ?? 'Uknown', + profilePictureUrl: firebaseUser.user!.photoURL, + platform: 'apple', ); await _firestore.collection('users').doc(user.id).set(user.toMap());