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 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.showHeader = true, this.height, this.padding, this.isLoading = false, this.emptyMessage, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); 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 if (showHeader) Padding( padding: const EdgeInsets.only(bottom: 16.0, left: 16.0, right: 16.0), child: Row( children: [ // ID Expanded( flex: 1, child: Text( 'ID', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Prénom (firstName) Expanded( flex: 2, child: Text( 'Prénom', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Nom (name) Expanded( flex: 2, child: Text( 'Nom', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Email Expanded( flex: 3, child: Text( 'Email', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ), // Rôle (fkRole) 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 ou onDelete sont fournis) if (onEdit != null || onDelete != null) Expanded( flex: 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), ), ], ), ); } Widget _buildTableContent(BuildContext context) { // 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, isAlternate: index % 2 == 1, ); }, ); } }