import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; import '../../domain/entities/friend.dart'; /// [FriendDetailScreen] affiche les détails d'un ami, incluant son nom, son image de profil, /// et une option pour envoyer un message. /// Utilisé lorsque l'utilisateur clique sur un ami pour voir plus de détails. class FriendDetailScreen extends StatelessWidget { /// Constructeur de la classe [FriendDetailScreen]. FriendDetailScreen({ required this.friendFirstName, required this.friendLastName, required this.imageUrl, required this.friendId, required this.status, required this.lastInteraction, required this.dateAdded, super.key, }); final String friendFirstName; // Nom de l'ami final String friendLastName; final String imageUrl; // URL de l'image de profil de l'ami final String friendId; // ID de l'ami pour des actions futures final Logger _logger = Logger(); // Logger pour suivre les actions dans le terminal final FriendStatus status; final String lastInteraction; final String dateAdded; /// Méthode statique pour lancer l'écran des détails d'un ami. static void open( BuildContext context, String friendId, String friendFirstName, String friendLastName, String imageUrl, FriendStatus status, String lastInteraction, String dateAdded,) { Navigator.push( context, MaterialPageRoute( builder: (_) => FriendDetailScreen( friendId: friendId, friendFirstName: friendFirstName, friendLastName: friendLastName, imageUrl: imageUrl, status: status, lastInteraction: lastInteraction, dateAdded: dateAdded, ), ), ); } /// Vérifie si une URL est valide pour le chargement d'image réseau. bool _isValidImageUrl(String? url) { if (url == null || url.isEmpty) { return false; } try { final uri = Uri.tryParse(url); if (uri == null) { return false; } // Vérifier que c'est une URL HTTP/HTTPS valide if (!uri.hasScheme || (!uri.scheme.startsWith('http'))) { return false; } // Vérifier qu'il y a un host if (uri.host.isEmpty) { return false; } return true; } catch (e) { return false; } } @override Widget build(BuildContext context) { _logger.i('[LOG] Affichage des détails de l\'ami : $friendFirstName (ID: $friendId)'); // Vérifier si l'URL est valide avant de créer le NetworkImage final bool hasValidImageUrl = _isValidImageUrl(imageUrl); final ImageProvider imageProvider = hasValidImageUrl ? NetworkImage(imageUrl) : const AssetImage('lib/assets/images/default_avatar.png') as ImageProvider; return Scaffold( appBar: AppBar( title: Text(friendFirstName), backgroundColor: Colors.teal.shade800, // Couleur de l'app bar elevation: 6, // Ombre sous l'app bar pour plus de profondeur ), body: Padding( padding: const EdgeInsets.all(16), // Espacement autour du contenu child: SingleChildScrollView( child: Column( children: [ // Animation Hero pour une transition fluide lors de la navigation Hero( tag: friendId, child: AnimatedContainer( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, child: CircleAvatar( radius: 80, backgroundImage: hasValidImageUrl ? imageProvider : null, backgroundColor: Colors.grey.shade800, onBackgroundImageError: (error, stackTrace) { _logger.e('[ERROR] Erreur lors du chargement de l\'image pour $friendFirstName (ID: $friendId): $error'); }, child: !hasValidImageUrl ? const Icon(Icons.person, size: 60, color: Colors.white) : null, ), ), ), const SizedBox(height: 16), // Affichage du nom de l'ami avec une meilleure hiérarchie visuelle Text( '$friendFirstName $friendLastName', style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), Text( status.name.toUpperCase(), style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: status == FriendStatus.accepted ? Colors.green.shade400 : status == FriendStatus.pending ? Colors.orange.shade400 : Colors.red.shade400, ), ), const SizedBox(height: 20), // Affichage des informations supplémentaires _buildInfoRow('Dernière interaction:', lastInteraction), _buildInfoRow('Date d\'ajout:', dateAdded), const SizedBox(height: 30), // Espacement avant le bouton // Bouton pour envoyer un message à l'ami avec animation ElevatedButton.icon( onPressed: () { _logger.i('[LOG] Envoi d\'un message à $friendFirstName (ID: $friendId)'); // Logique future pour envoyer un message à l'ami }, icon: const Icon(Icons.message), label: const Text('Envoyer un message'), style: ElevatedButton.styleFrom( backgroundColor: Colors.teal, // Couleur du bouton foregroundColor: Colors.white, // Couleur du texte et icône shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), // Coins arrondis ), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), elevation: 5, // Ombre pour effet de survol ), ), ], ), ), ), ); } /// Widget réutilisable pour afficher une ligne d'information avec un texte d'introduction et une valeur. Widget _buildInfoRow(String label, String value) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Row( children: [ Text( label, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(width: 8), Text( value, style: const TextStyle( fontSize: 16, color: Colors.white70, // Couleur plus claire pour les valeurs ), ), ], ), ); } }