import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales import 'package:flutter/material.dart'; import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales import 'package:geosector_app/core/repositories/user_repository.dart'; /// Widget de profil commun pour toute l'application /// Affiche une boîte de dialogue modale avec un formulaire de mise à jour /// des données utilisateur class ProfileDialog extends StatefulWidget { /// ID de l'utilisateur dont on veut afficher/modifier le profil final String userId; const ProfileDialog({ Key? key, required this.userId, }) : super(key: key); /// Affiche la boîte de dialogue de profil static void show(BuildContext context, String userId) { showDialog( context: context, builder: (context) => ProfileDialog(userId: userId), ); } @override State createState() => _ProfileDialogState(); } class _ProfileDialogState extends State { /// Contrôleurs pour les champs du formulaire final TextEditingController _firstNameController = TextEditingController(); final TextEditingController _lastNameController = TextEditingController(); final TextEditingController _emailController = TextEditingController(); final TextEditingController _phoneController = TextEditingController(); /// État de chargement bool _isLoading = true; /// État d'erreur String? _errorMessage; @override void initState() { super.initState(); _loadUserData(); } @override void dispose() { _firstNameController.dispose(); _lastNameController.dispose(); _emailController.dispose(); _phoneController.dispose(); super.dispose(); } /// Charge les données de l'utilisateur depuis l'API Future _loadUserData() async { try { setState(() { _isLoading = true; _errorMessage = null; }); // Utiliser l'instance globale définie dans app.dart final user = userRepository.currentUser; // Si l'utilisateur est trouvé, remplir les champs du formulaire if (user != null) { _firstNameController.text = user.firstName ?? ''; _lastNameController.text = user.name ?? ''; _emailController.text = user.email ?? ''; // Note: Utiliser la propriété appropriée pour le téléphone si elle existe // ou laisser vide si elle n'existe pas _phoneController.text = ''; // Champ laissé vide par défaut } else { _errorMessage = 'Utilisateur non trouvé'; } } catch (e) { _errorMessage = 'Erreur lors du chargement des données: $e'; } finally { setState(() { _isLoading = false; }); } } /// Enregistre les modifications du profil Future _saveProfile() async { try { setState(() { _isLoading = true; _errorMessage = null; }); // Utiliser l'instance globale définie dans app.dart // Mettre à jour les données de l'utilisateur // Note: Cette partie dépend de l'implémentation réelle du UserRepository // et devrait être adaptée en fonction de l'API disponible // Récupérer l'utilisateur actuel final user = userRepository.currentUser; if (user != null) { // Mettre à jour les propriétés de l'utilisateur user.firstName = _firstNameController.text; user.name = _lastNameController.text; // Sauvegarder les modifications // Note: Utiliser la méthode appropriée du repository // Exemple: userRepo.saveUser(user) ou userRepo.updateUser(user) // Pour l'instant, nous simulons une mise à jour réussie // Cette partie devra être adaptée à l'API réelle await Future.delayed(const Duration(milliseconds: 500)); // Fermer la boîte de dialogue if (mounted) { Navigator.of(context) .pop(true); // Retourne true pour indiquer le succès // Afficher un message de succès ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('Profil mis à jour avec succès'), backgroundColor: Theme.of(context).colorScheme.primary, ), ); } } else { throw Exception('Utilisateur non trouvé'); } } catch (e) { setState(() { _errorMessage = 'Erreur lors de la mise à jour du profil: $e'; _isLoading = false; }); } } @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; final theme = Theme.of(context); // Déterminer si nous sommes sur un appareil mobile ou un ordinateur de bureau final isDesktop = size.width > 900; // Calculer la largeur de la boîte de dialogue // 90% de la largeur de l'écran pour les mobiles // 50% de la largeur de l'écran pour les ordinateurs de bureau (max 600px) final dialogWidth = isDesktop ? size.width * 0.5 > 600 ? 600.0 : size.width * 0.5 : size.width * 0.9; return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), // Définir la largeur de la boîte de dialogue child: Container( width: dialogWidth, padding: const EdgeInsets.all(24), child: _isLoading ? const Center( child: CircularProgressIndicator(), ) : _errorMessage != null ? _buildErrorView() : _buildProfileForm(), ), ); } /// Construit la vue d'erreur Widget _buildErrorView() { final theme = Theme.of(context); return Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.error_outline, color: theme.colorScheme.error, size: 48, ), const SizedBox(height: 16), Text( 'Erreur', style: theme.textTheme.titleLarge?.copyWith( color: theme.colorScheme.error, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( _errorMessage ?? 'Une erreur inconnue est survenue', textAlign: TextAlign.center, style: theme.textTheme.bodyMedium, ), const SizedBox(height: 24), ElevatedButton( onPressed: () => Navigator.of(context).pop(), style: ElevatedButton.styleFrom( backgroundColor: theme.colorScheme.primary, foregroundColor: theme.colorScheme.onPrimary, ), child: const Text('Fermer'), ), ], ); } /// Construit le formulaire de profil Widget _buildProfileForm() { final theme = Theme.of(context); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Titre du formulaire Row( children: [ Icon( Icons.person, color: theme.colorScheme.primary, size: 28, ), const SizedBox(width: 12), Expanded( child: Text( 'Mon compte', style: theme.textTheme.titleLarge?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), ), IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.of(context).pop(), tooltip: 'Fermer', ), ], ), const Divider(height: 32), // Formulaire Form( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Prénom TextFormField( controller: _firstNameController, decoration: const InputDecoration( labelText: 'Prénom', prefixIcon: Icon(Icons.person_outline), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre prénom'; } return null; }, ), const SizedBox(height: 16), // Nom TextFormField( controller: _lastNameController, decoration: const InputDecoration( labelText: 'Nom', prefixIcon: Icon(Icons.person_outline), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre nom'; } return null; }, ), const SizedBox(height: 16), // Email TextFormField( controller: _emailController, decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.email_outlined), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre email'; } if (!value.contains('@')) { return 'Veuillez entrer un email valide'; } return null; }, ), const SizedBox(height: 16), // Téléphone TextFormField( controller: _phoneController, decoration: const InputDecoration( labelText: 'Téléphone', prefixIcon: Icon(Icons.phone_outlined), border: OutlineInputBorder(), ), ), ], ), ), const SizedBox(height: 24), // Boutons d'action Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text( 'Annuler', style: TextStyle( color: theme.colorScheme.error, ), ), ), const SizedBox(width: 16), ElevatedButton( onPressed: _saveProfile, style: ElevatedButton.styleFrom( backgroundColor: theme.colorScheme.primary, foregroundColor: theme.colorScheme.onPrimary, padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 12, ), ), child: const Text('Enregistrer'), ), ], ), ], ); } }