import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../../../core/models/membre_model.dart'; import '../../../../shared/theme/app_theme.dart'; /// Carte membre améliorée avec différents modes d'affichage class MembreEnhancedCard extends StatelessWidget { final MembreModel membre; final String viewMode; final VoidCallback? onTap; final VoidCallback? onEdit; final VoidCallback? onDelete; final VoidCallback? onCall; final VoidCallback? onMessage; const MembreEnhancedCard({ super.key, required this.membre, this.viewMode = 'card', this.onTap, this.onEdit, this.onDelete, this.onCall, this.onMessage, }); @override Widget build(BuildContext context) { switch (viewMode) { case 'list': return _buildListView(); case 'grid': return _buildGridView(); case 'card': default: return _buildCardView(); } } Widget _buildCardView() { return Card( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // En-tête avec avatar et actions Row( children: [ _buildAvatar(size: 50), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( membre.nomComplet, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), const SizedBox(height: 4), Text( membre.numeroMembre, style: const TextStyle( fontSize: 14, color: AppTheme.textSecondary, ), ), ], ), ), _buildStatusBadge(), ], ), const SizedBox(height: 12), // Informations de contact _buildContactInfo(), const SizedBox(height: 12), // Actions _buildActionButtons(), ], ), ), ), ); } Widget _buildListView() { return Card( elevation: 1, margin: const EdgeInsets.symmetric(vertical: 4), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), child: ListTile( onTap: onTap, leading: _buildAvatar(size: 40), title: Text( membre.nomComplet, style: const TextStyle( fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( membre.numeroMembre, style: const TextStyle( fontSize: 12, color: AppTheme.textSecondary, ), ), const SizedBox(height: 2), Text( membre.telephone, style: const TextStyle( fontSize: 12, color: AppTheme.textHint, ), ), ], ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ _buildStatusBadge(), const SizedBox(width: 8), PopupMenuButton( onSelected: _handleMenuAction, itemBuilder: (context) => [ const PopupMenuItem( value: 'call', child: Row( children: [ Icon(Icons.phone, size: 16), SizedBox(width: 8), Text('Appeler'), ], ), ), const PopupMenuItem( value: 'message', child: Row( children: [ Icon(Icons.message, size: 16), SizedBox(width: 8), Text('Message'), ], ), ), const PopupMenuItem( value: 'edit', child: Row( children: [ Icon(Icons.edit, size: 16), SizedBox(width: 8), Text('Modifier'), ], ), ), ], ), ], ), ), ); } Widget _buildGridView() { return Card( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(12), child: Column( children: [ _buildAvatar(size: 60), const SizedBox(height: 8), Text( membre.prenom, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, ), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ), Text( membre.nom, style: const TextStyle( fontSize: 12, color: AppTheme.textSecondary, ), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 8), _buildStatusBadge(), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildGridAction(Icons.phone, onCall), _buildGridAction(Icons.message, onMessage), _buildGridAction(Icons.edit, onEdit), ], ), ], ), ), ), ); } Widget _buildAvatar({required double size}) { return CircleAvatar( radius: size / 2, backgroundColor: AppTheme.primaryColor.withOpacity(0.1), child: Text( membre.initiales, style: TextStyle( fontSize: size * 0.4, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), ); } Widget _buildStatusBadge() { Color color; switch (membre.statut.toUpperCase()) { case 'ACTIF': color = AppTheme.successColor; break; case 'INACTIF': color = AppTheme.warningColor; break; case 'SUSPENDU': color = AppTheme.errorColor; break; default: color = AppTheme.textSecondary; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: color.withOpacity(0.3)), ), child: Text( membre.statutLibelle, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: color, ), ), ); } Widget _buildContactInfo() { return Column( children: [ Row( children: [ const Icon(Icons.phone, size: 16, color: AppTheme.textHint), const SizedBox(width: 8), Text( membre.telephone, style: const TextStyle( fontSize: 14, color: AppTheme.textSecondary, ), ), ], ), const SizedBox(height: 4), Row( children: [ const Icon(Icons.email, size: 16, color: AppTheme.textHint), const SizedBox(width: 8), Expanded( child: Text( membre.email, style: const TextStyle( fontSize: 14, color: AppTheme.textSecondary, ), overflow: TextOverflow.ellipsis, ), ), ], ), ], ); } Widget _buildActionButtons() { return Row( children: [ Expanded( child: OutlinedButton.icon( onPressed: onCall, icon: const Icon(Icons.phone, size: 16), label: const Text('Appeler'), style: OutlinedButton.styleFrom( foregroundColor: AppTheme.primaryColor, side: BorderSide(color: AppTheme.primaryColor.withOpacity(0.3)), ), ), ), const SizedBox(width: 8), Expanded( child: OutlinedButton.icon( onPressed: onMessage, icon: const Icon(Icons.message, size: 16), label: const Text('Message'), style: OutlinedButton.styleFrom( foregroundColor: AppTheme.secondaryColor, side: BorderSide(color: AppTheme.secondaryColor.withOpacity(0.3)), ), ), ), ], ); } Widget _buildGridAction(IconData icon, VoidCallback? onPressed) { return GestureDetector( onTap: () { HapticFeedback.lightImpact(); onPressed?.call(); }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Icon( icon, size: 16, color: AppTheme.primaryColor, ), ), ); } void _handleMenuAction(String action) { HapticFeedback.lightImpact(); switch (action) { case 'call': onCall?.call(); break; case 'message': onMessage?.call(); break; case 'edit': onEdit?.call(); break; } } }