import 'package:flutter/material.dart'; import 'package:geosector_app/core/data/models/membre_model.dart'; import 'package:geosector_app/core/repositories/membre_repository.dart'; import 'package:geosector_app/presentation/widgets/membre_row_widget.dart'; class MembreTableWidget extends StatelessWidget { final List membres; final Function(MembreModel)? onEdit; final Function(MembreModel)? onDelete; final Function(MembreModel)? onResetPassword; final MembreRepository membreRepository; final bool showHeader; final double? height; final EdgeInsetsGeometry? padding; final bool isLoading; final String? emptyMessage; const MembreTableWidget({ super.key, required this.membres, required this.membreRepository, this.onEdit, this.onDelete, this.onResetPassword, this.showHeader = true, this.height, this.padding, this.isLoading = false, this.emptyMessage, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final screenWidth = MediaQuery.of(context).size.width; final isMobile = screenWidth < 768; return Container( height: height, padding: padding ?? const EdgeInsets.all(16.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8.0), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // En-tête du tableau avec fond grisé if (showHeader) Container( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), margin: const EdgeInsets.only(bottom: 16.0), decoration: BoxDecoration( color: theme.colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(4.0), ), child: Row( children: [ // ID - masqué en mobile if (!isMobile) Expanded( flex: 1, child: Text( 'ID', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Identifiant (username) - masqué en mobile if (!isMobile) Expanded( flex: 2, child: Text( 'Identifiant', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Prénom (firstName) Expanded( flex: isMobile ? 2 : 2, child: Text( 'Prénom', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Nom (name) Expanded( flex: isMobile ? 2 : 2, child: Text( 'Nom', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Email - masqué en mobile if (!isMobile) Expanded( flex: 3, child: Text( 'Email', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Rôle (fkRole) - masqué en mobile if (!isMobile) Expanded( flex: 1, child: Text( 'Rôle', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Statut Expanded( flex: 1, child: Text( 'Statut', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Actions (si onEdit, onDelete ou onResetPassword sont fournis) if (onEdit != null || onDelete != null || onResetPassword != null) Expanded( flex: isMobile ? 2 : 2, child: Text( 'Actions', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), textAlign: TextAlign.end, ), ), ], ), ), // Corps du tableau Expanded( child: _buildTableContent(context, isMobile), ), ], ), ); } Widget _buildTableContent(BuildContext context, bool isMobile) { // Afficher un indicateur de chargement si isLoading est true if (isLoading) { return const Center(child: CircularProgressIndicator()); } // Afficher un message si la liste est vide if (membres.isEmpty) { return Center( child: Text( emptyMessage ?? 'Aucun membre trouvé', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), ), ), ); } // Afficher la liste des membres return ListView.separated( itemCount: membres.length, separatorBuilder: (context, index) => Divider( color: Theme.of(context).dividerColor.withOpacity(0.3), height: 1, ), itemBuilder: (context, index) { final membre = membres[index]; return MembreRowWidget( membre: membre, onEdit: onEdit, onDelete: onDelete, onResetPassword: onResetPassword, isAlternate: index % 2 == 1, onTap: onEdit != null ? () => onEdit!(membre) : null, isMobile: isMobile, ); }, ); } }