import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; import '../../domain/entities/friend.dart'; /// [FriendsCircle] est un widget qui affiche un ami sous forme d'avatar circulaire avec son nom. /// L'avatar est cliquable, permettant à l'utilisateur d'accéder aux détails de l'ami /// ou de déclencher d'autres actions liées. class FriendsCircle extends StatelessWidget { final Friend friend; // Représente l'entité Friend à afficher (nom et image). final VoidCallback onTap; // Fonction callback exécutée lorsque l'utilisateur clique sur l'avatar. // Logger pour tracer les actions dans le terminal final Logger _logger = Logger(); /// Constructeur pour [FriendsCircle], prenant en entrée un ami et une fonction de callback. FriendsCircle({ Key? key, required this.friend, // L'ami à afficher (doit inclure friendId, name, imageUrl). required this.onTap, // Action à exécuter lors du clic. }) : super(key: key); @override Widget build(BuildContext context) { // Combine firstName et lastName ou utilise "Ami inconnu" par défaut. String displayName = [friend.friendFirstName, friend.friendLastName] .where((namePart) => namePart != null && namePart.isNotEmpty) .join(" ") .trim(); if (displayName.isEmpty) { displayName = 'Ami inconnu'; } return GestureDetector( onTap: () { _logger.i('[LOG] Avatar de ${displayName.trim()} cliqué'); onTap(); // Exécute l'action de clic définie par l'utilisateur }, child: Column( mainAxisAlignment: MainAxisAlignment.center, // Centre verticalement les éléments de la colonne. children: [ Hero( tag: friend.friendId, // Tag unique pour l'animation Hero basé sur l'ID de l'ami. child: CircleAvatar( radius: 40, backgroundImage: friend.imageUrl != null && friend.imageUrl!.isNotEmpty ? (friend.imageUrl!.startsWith('http') // Vérifie si l'image est une URL réseau ? NetworkImage(friend.imageUrl!) : AssetImage(friend.imageUrl!) as ImageProvider) // Utilise AssetImage si c'est une ressource locale : const AssetImage('lib/assets/images/default_avatar.png'), // Utilise AssetImage pour l'avatar par défaut onBackgroundImageError: (error, stackTrace) { _logger.e('[ERROR] Erreur lors du chargement de l\'image pour ${displayName.trim()} : $error'); }, backgroundColor: Colors.grey.shade800, // Fond si l'image ne charge pas. child: friend.imageUrl == null || friend.imageUrl!.isEmpty ? const Icon(Icons.person, size: 40, color: Colors.white) // Icône de remplacement si aucune image n'est disponible : null, ), ), const SizedBox(height: 8), // Ajoute un espace entre l'image et le texte. Text( displayName, // Affiche le nom de l'ami sous l'avatar ou une valeur par défaut. style: const TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ); } }