diff --git a/lib/blocs/user/user_state.dart b/lib/blocs/user/user_state.dart index 5594361..c32f062 100644 --- a/lib/blocs/user/user_state.dart +++ b/lib/blocs/user/user_state.dart @@ -75,16 +75,20 @@ class UserModel { /// Platform used for authentication (e.g., 'google', 'apple', 'email'). final String? authMethod; + /// User's phone number (optional). + final String? phoneNumber; + /// Creates a new [UserModel] instance. /// /// [id], [email], and [prenom] are required fields. - /// [nom] and [authMethod] are optional and can be null. + /// [nom], [authMethod], and [phoneNumber] are optional and can be null. UserModel({ required this.id, required this.email, required this.prenom, this.nom, this.authMethod, + this.phoneNumber, }); /// Creates a [UserModel] instance from a JSON map. @@ -98,6 +102,7 @@ class UserModel { prenom: json['prenom'] ?? 'Voyageur', nom: json['nom'], authMethod: json['authMethod'] ?? json['platform'], + phoneNumber: json['phoneNumber'], ); } @@ -111,6 +116,7 @@ class UserModel { 'prenom': prenom, 'nom': nom, 'authMethod': authMethod, + 'phoneNumber': phoneNumber, }; } } diff --git a/lib/components/settings/profile/profile_content.dart b/lib/components/settings/profile/profile_content.dart index d9ac3d2..ab19a7b 100644 --- a/lib/components/settings/profile/profile_content.dart +++ b/lib/components/settings/profile/profile_content.dart @@ -18,44 +18,40 @@ class ProfileContent extends StatelessWidget { builder: (context, user) { final isEmailAuth = user.authMethod == 'email' || user.authMethod == null; - return Column( - children: [ - // Section titre - Padding( - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Row( - children: [ - Text( - 'Profil utilisateur', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Colors.grey[600], - ), - ), - ], - ), - ), - - // Card du profil - Card( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Padding( - padding: EdgeInsets.all(16), + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // En-tête avec photo de profil + Container( + padding: EdgeInsets.symmetric(vertical: 24, horizontal: 16), child: Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ // Photo de profil - CircleAvatar( - radius: 40, - backgroundColor: Theme.of(context).colorScheme.primary, - child: Text( - user.prenom.isNotEmpty - ? user.prenom[0].toUpperCase() - : 'U', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white, + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.1), + blurRadius: 8, + offset: Offset(0, 2), + ) + ], + ), + child: CircleAvatar( + radius: 50, + backgroundColor: Theme.of(context).colorScheme.primary, + child: Text( + user.prenom.isNotEmpty + ? user.prenom[0].toUpperCase() + : 'U', + style: TextStyle( + fontSize: 32, + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), ), ), @@ -66,17 +62,22 @@ class ProfileContent extends StatelessWidget { Text( '${user.prenom} ${user.nom ?? ''}', style: TextStyle( - fontSize: 20, + fontSize: 22, fontWeight: FontWeight.bold, ), + textAlign: TextAlign.center, ), - SizedBox(height: 8), + SizedBox(height: 4), // Email Text( user.email, - style: TextStyle(fontSize: 14, color: Colors.grey[600]), + style: TextStyle( + fontSize: 14, + color: Colors.grey[600], + ), + textAlign: TextAlign.center, ), SizedBox(height: 12), @@ -91,12 +92,14 @@ class ProfileContent extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Image.asset( - _getAuthMethodIcon(user.authMethod), - height: 16, - width: 16, - ), - SizedBox(width: 8), + if (_getAuthMethodIcon(user.authMethod).isNotEmpty) + Image.asset( + _getAuthMethodIcon(user.authMethod), + height: 16, + width: 16, + ), + if (_getAuthMethodIcon(user.authMethod).isNotEmpty) + SizedBox(width: 8), Text( _getAuthMethodLabel(user.authMethod), style: TextStyle( @@ -111,45 +114,208 @@ class ProfileContent extends StatelessWidget { ], ), ), - ), - // Actions du profil - ListTile( - leading: Icon(Icons.edit), - title: Text('Modifier le profil'), - trailing: Icon(Icons.arrow_forward_ios), - onTap: () { - _showEditProfileDialog(context, user); - }, - ), + // Section Informations personnelles + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + children: [ + Text( + 'Informations personnelles', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + ), + ], + ), + ), - // Afficher l'option de changement de mot de passe seulement pour email - if (isEmailAuth) - ListTile( - leading: Icon(Icons.lock), - title: Text('Changer le mot de passe'), - trailing: Icon(Icons.arrow_forward_ios), + // Tuiles d'information + _buildInfoTile( + icon: Icons.person_outline, + label: 'Nom complet', + value: '${user.prenom} ${user.nom ?? ''}', + context: context, + ), + + _buildInfoTile( + icon: Icons.email_outlined, + label: 'Adresse e-mail', + value: user.email, + context: context, + ), + + _buildInfoTile( + icon: Icons.phone_outlined, + label: 'Téléphone', + value: user.phoneNumber ?? 'Non défini', + context: context, + ), + + // Option de changement de mot de passe seulement pour email + if (isEmailAuth) + _buildActionTile( + icon: Icons.lock_outlined, + label: 'Changer de mot de passe', + context: context, + onTap: () { + _showChangePasswordDialog(context, user); + }, + ), + + SizedBox(height: 8), + + // Option pour modifier le profil + _buildActionTile( + icon: Icons.edit_outlined, + label: 'Modifier le profil', + context: context, onTap: () { - _showChangePasswordDialog(context, user); + _showEditProfileDialog(context, user); }, ), - Divider(), + SizedBox(height: 8), - ListTile( - leading: Icon(Icons.delete, color: Colors.red), - title: Text('Supprimer le compte'), - trailing: Icon(Icons.arrow_forward_ios), - onTap: () { - _showDeleteAccountDialog(context, user); - }, - ), - ], + // Option pour supprimer le compte + _buildActionTile( + icon: Icons.delete_outline, + label: 'Supprimer le compte', + context: context, + isDestructive: true, + onTap: () { + _showDeleteAccountDialog(context, user); + }, + ), + + SizedBox(height: 24), + ], + ), ); }, ); } + Widget _buildInfoTile({ + required IconData icon, + required String label, + required String value, + required BuildContext context, + }) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + return Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[850] : Colors.grey[100], + borderRadius: BorderRadius.circular(8), + ), + child: Row( + children: [ + Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[800] : Colors.grey[200], + borderRadius: BorderRadius.circular(6), + ), + child: Icon( + icon, + size: 20, + color: Theme.of(context).colorScheme.primary, + ), + ), + SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: TextStyle( + fontSize: 12, + color: Colors.grey[600], + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 2), + Text( + value, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black87, + ), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildActionTile({ + required IconData icon, + required String label, + required BuildContext context, + required VoidCallback onTap, + bool isDestructive = false, + }) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + return GestureDetector( + onTap: onTap, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[850] : Colors.grey[100], + borderRadius: BorderRadius.circular(8), + ), + child: Row( + children: [ + Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[800] : Colors.grey[200], + borderRadius: BorderRadius.circular(6), + ), + child: Icon( + icon, + size: 20, + color: isDestructive + ? Colors.red + : Theme.of(context).colorScheme.primary, + ), + ), + SizedBox(width: 16), + Expanded( + child: Text( + label, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: isDestructive + ? Colors.red + : (isDarkMode ? Colors.white : Colors.black87), + ), + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 16, + color: Colors.grey[400], + ), + ], + ), + ), + ); + } + String _getAuthMethodLabel(String? authMethod) { switch (authMethod) { case 'apple':