Files
unionflow-server-api/unionflow-mobile-apps/lib/shared/widgets/error_widget.dart
2025-11-17 16:02:04 +00:00

169 lines
4.4 KiB
Dart

/// Widget d'erreur réutilisable pour toute l'application
library error_widget;
import 'package:flutter/material.dart';
/// Widget d'erreur avec message et bouton de retry
class AppErrorWidget extends StatelessWidget {
/// Message d'erreur à afficher
final String message;
/// Callback appelé lors du clic sur le bouton retry
final VoidCallback? onRetry;
/// Icône personnalisée (optionnel)
final IconData? icon;
/// Titre personnalisé (optionnel)
final String? title;
const AppErrorWidget({
super.key,
required this.message,
this.onRetry,
this.icon,
this.title,
});
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon ?? Icons.error_outline,
size: 64,
color: Theme.of(context).colorScheme.error,
),
const SizedBox(height: 16),
Text(
title ?? 'Oups !',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
message,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
if (onRetry != null) ...[
const SizedBox(height: 24),
ElevatedButton.icon(
onPressed: onRetry,
icon: const Icon(Icons.refresh),
label: const Text('Réessayer'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
),
],
],
),
),
);
}
}
/// Widget d'erreur réseau spécifique
class NetworkErrorWidget extends StatelessWidget {
final VoidCallback? onRetry;
const NetworkErrorWidget({
super.key,
this.onRetry,
});
@override
Widget build(BuildContext context) {
return AppErrorWidget(
message: 'Impossible de se connecter au serveur.\nVérifiez votre connexion internet.',
onRetry: onRetry,
icon: Icons.wifi_off,
title: 'Pas de connexion',
);
}
}
/// Widget d'erreur de permissions
class PermissionErrorWidget extends StatelessWidget {
final String? message;
const PermissionErrorWidget({
super.key,
this.message,
});
@override
Widget build(BuildContext context) {
return AppErrorWidget(
message: message ?? 'Vous n\'avez pas les permissions nécessaires pour accéder à cette ressource.',
icon: Icons.lock_outline,
title: 'Accès refusé',
);
}
}
/// Widget d'erreur "Aucune donnée"
class EmptyDataWidget extends StatelessWidget {
final String message;
final IconData? icon;
final VoidCallback? onAction;
final String? actionLabel;
const EmptyDataWidget({
super.key,
required this.message,
this.icon,
this.onAction,
this.actionLabel,
});
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon ?? Icons.inbox_outlined,
size: 64,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const SizedBox(height: 16),
Text(
message,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
if (onAction != null && actionLabel != null) ...[
const SizedBox(height: 24),
ElevatedButton(
onPressed: onAction,
child: Text(actionLabel!),
),
],
],
),
),
);
}
}