import 'package:flutter/material.dart'; import 'package:em2rp/utils/colors.dart'; /// Action du menu contextuel class CardAction { final String id; final String label; final IconData icon; final Color? color; const CardAction({ required this.id, required this.label, required this.icon, this.color, }); } /// Widget de card générique pour les pages de gestion class ManagementCard extends StatelessWidget { final T item; final String Function(T) getId; final String Function(T) getTitle; final String Function(T) getSubtitle; final Widget Function(T) getIcon; final List Function(T) getInfoChips; final Widget Function(T) getStatusBadge; final List actions; final void Function(String actionId, T item) onActionSelected; final VoidCallback onTap; final VoidCallback? onLongPress; final bool isSelectionMode; final bool isSelected; final ValueChanged? onSelectionChanged; const ManagementCard({ super.key, required this.item, required this.getId, required this.getTitle, required this.getSubtitle, required this.getIcon, required this.getInfoChips, required this.getStatusBadge, required this.actions, required this.onActionSelected, required this.onTap, this.onLongPress, this.isSelectionMode = false, this.isSelected = false, this.onSelectionChanged, }); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.only(bottom: 12), elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: isSelected ? const BorderSide(color: AppColors.rouge, width: 2) : BorderSide.none, ), child: InkWell( onTap: onTap, onLongPress: onLongPress, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ // Checkbox en mode sélection if (isSelectionMode) Padding( padding: const EdgeInsets.only(right: 16), child: Checkbox( value: isSelected, onChanged: onSelectionChanged, activeColor: AppColors.rouge, ), ), // Icône principale getIcon(item), const SizedBox(width: 16), // Contenu principal Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Titre (ID) Text( getTitle(item), style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16, ), ), const SizedBox(height: 4), // Sous-titre Text( getSubtitle(item), style: TextStyle( fontSize: 14, color: Colors.grey.shade700, ), ), const SizedBox(height: 4), // Chips d'information Wrap( spacing: 8, runSpacing: 4, children: getInfoChips(item), ), ], ), ), const SizedBox(width: 16), // Badge de statut getStatusBadge(item), // Menu contextuel (si pas en mode sélection) if (!isSelectionMode) ...[ const SizedBox(width: 8), PopupMenuButton( icon: const Icon(Icons.more_vert), onSelected: (actionId) => onActionSelected(actionId, item), itemBuilder: (context) => actions.map((action) { return PopupMenuItem( value: action.id, child: Row( children: [ Icon( action.icon, size: 20, color: action.color, ), const SizedBox(width: 8), Text( action.label, style: TextStyle(color: action.color), ), ], ), ); }).toList(), ), ], ], ), ), ), ); } } /// Widget helper pour créer un chip d'information class InfoChip extends StatelessWidget { final String label; final IconData icon; const InfoChip({ super.key, required this.label, required this.icon, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14, color: Colors.grey.shade700), const SizedBox(width: 4), Text( label, style: TextStyle( fontSize: 12, color: Colors.grey.shade700, ), ), ], ), ); } } /// Widget helper pour créer un badge de statut class StatusBadge extends StatelessWidget { final String label; final Color color; const StatusBadge({ super.key, required this.label, required this.color, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: color), ), child: Text( label, style: TextStyle( color: color, fontWeight: FontWeight.bold, fontSize: 12, ), ), ); } }