import 'package:flutter/material.dart'; import '../../core/auth/services/permission_service.dart'; /// Widget qui affiche son contenu seulement si l'utilisateur a les permissions requises class PermissionWidget extends StatelessWidget { const PermissionWidget({ super.key, required this.child, this.permission, this.roles, this.fallback, this.showFallbackMessage = false, this.fallbackMessage, }) : assert(permission != null || roles != null, 'Either permission or roles must be provided'); /// Widget à afficher si les permissions sont accordées final Widget child; /// Fonction de vérification de permission personnalisée final bool Function()? permission; /// Liste des rôles autorisés final List? roles; /// Widget à afficher si les permissions ne sont pas accordées final Widget? fallback; /// Afficher un message par défaut si pas de permissions final bool showFallbackMessage; /// Message personnalisé à afficher si pas de permissions final String? fallbackMessage; @override Widget build(BuildContext context) { final permissionService = PermissionService(); bool hasPermission = false; if (permission != null) { hasPermission = permission!(); } else if (roles != null) { hasPermission = permissionService.hasAnyRole(roles!); } if (hasPermission) { return child; } // Si pas de permissions, afficher le fallback ou rien if (fallback != null) { return fallback!; } if (showFallbackMessage) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.lock_outline, size: 48, color: Colors.grey[400], ), const SizedBox(height: 8), Text( fallbackMessage ?? 'Accès restreint', style: TextStyle( color: Colors.grey[600], fontSize: 14, ), textAlign: TextAlign.center, ), ], ), ); } return const SizedBox.shrink(); } } /// Widget pour les boutons avec contrôle de permissions class PermissionButton extends StatelessWidget { const PermissionButton({ super.key, required this.onPressed, required this.child, this.permission, this.roles, this.tooltip, this.style, this.showDisabled = true, this.disabledMessage, }) : assert(permission != null || roles != null, 'Either permission or roles must be provided'); /// Callback quand le bouton est pressé final VoidCallback onPressed; /// Contenu du bouton final Widget child; /// Fonction de vérification de permission personnalisée final bool Function()? permission; /// Liste des rôles autorisés final List? roles; /// Tooltip du bouton final String? tooltip; /// Style du bouton final ButtonStyle? style; /// Afficher le bouton désactivé si pas de permissions final bool showDisabled; /// Message à afficher quand le bouton est désactivé final String? disabledMessage; @override Widget build(BuildContext context) { final permissionService = PermissionService(); bool hasPermission = false; if (permission != null) { hasPermission = permission!(); } else if (roles != null) { hasPermission = permissionService.hasAnyRole(roles!); } if (!hasPermission && !showDisabled) { return const SizedBox.shrink(); } Widget button = ElevatedButton( onPressed: hasPermission ? onPressed : null, style: style, child: child, ); if (tooltip != null || (!hasPermission && disabledMessage != null)) { button = Tooltip( message: hasPermission ? (tooltip ?? '') : (disabledMessage ?? 'Permissions insuffisantes'), child: button, ); } return button; } } /// Widget pour les IconButton avec contrôle de permissions class PermissionIconButton extends StatelessWidget { const PermissionIconButton({ super.key, required this.onPressed, required this.icon, this.permission, this.roles, this.tooltip, this.color, this.showDisabled = true, this.disabledMessage, }) : assert(permission != null || roles != null, 'Either permission or roles must be provided'); /// Callback quand le bouton est pressé final VoidCallback onPressed; /// Icône du bouton final Widget icon; /// Fonction de vérification de permission personnalisée final bool Function()? permission; /// Liste des rôles autorisés final List? roles; /// Tooltip du bouton final String? tooltip; /// Couleur de l'icône final Color? color; /// Afficher le bouton désactivé si pas de permissions final bool showDisabled; /// Message à afficher quand le bouton est désactivé final String? disabledMessage; @override Widget build(BuildContext context) { final permissionService = PermissionService(); bool hasPermission = false; if (permission != null) { hasPermission = permission!(); } else if (roles != null) { hasPermission = permissionService.hasAnyRole(roles!); } if (!hasPermission && !showDisabled) { return const SizedBox.shrink(); } return IconButton( onPressed: hasPermission ? onPressed : null, icon: icon, color: hasPermission ? color : Colors.grey, tooltip: hasPermission ? tooltip : (disabledMessage ?? 'Permissions insuffisantes'), ); } } /// Widget pour les FloatingActionButton avec contrôle de permissions class PermissionFAB extends StatelessWidget { const PermissionFAB({ super.key, required this.onPressed, required this.child, this.permission, this.roles, this.tooltip, this.backgroundColor, this.foregroundColor, this.showDisabled = false, }) : assert(permission != null || roles != null, 'Either permission or roles must be provided'); /// Callback quand le bouton est pressé final VoidCallback onPressed; /// Contenu du bouton final Widget child; /// Fonction de vérification de permission personnalisée final bool Function()? permission; /// Liste des rôles autorisés final List? roles; /// Tooltip du bouton final String? tooltip; /// Couleur de fond final Color? backgroundColor; /// Couleur de premier plan final Color? foregroundColor; /// Afficher le bouton désactivé si pas de permissions final bool showDisabled; @override Widget build(BuildContext context) { final permissionService = PermissionService(); bool hasPermission = false; if (permission != null) { hasPermission = permission!(); } else if (roles != null) { hasPermission = permissionService.hasAnyRole(roles!); } if (!hasPermission && !showDisabled) { return const SizedBox.shrink(); } return FloatingActionButton( onPressed: hasPermission ? onPressed : null, backgroundColor: hasPermission ? backgroundColor : Colors.grey, foregroundColor: foregroundColor, tooltip: tooltip, child: child, ); } } /// Mixin pour faciliter l'utilisation des permissions dans les widgets mixin PermissionMixin { PermissionService get permissionService => PermissionService(); /// Vérifie si l'utilisateur a une permission spécifique bool hasPermission(bool Function() permission) { return permission(); } /// Vérifie si l'utilisateur a un des rôles spécifiés bool hasAnyRole(List roles) { return permissionService.hasAnyRole(roles); } /// Affiche un SnackBar d'erreur de permission void showPermissionError(BuildContext context, [String? message]) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( message ?? 'Vous n\'avez pas les permissions nécessaires pour cette action', ), backgroundColor: Colors.red, action: SnackBarAction( label: 'Fermer', textColor: Colors.white, onPressed: () => ScaffoldMessenger.of(context).hideCurrentSnackBar(), ), ), ); } /// Exécute une action seulement si l'utilisateur a les permissions void executeWithPermission( BuildContext context, bool Function() permission, VoidCallback action, { String? errorMessage, }) { if (permission()) { action(); } else { showPermissionError(context, errorMessage); } } }