Files
TravelMate/lib/components/error/error_content.dart

184 lines
5.1 KiB
Dart

import 'package:flutter/material.dart';
/// A reusable error display component.
///
/// This widget provides a consistent way to display error messages throughout
/// the application. It supports customizable titles, messages, icons, and
/// action buttons for retry and close operations.
class ErrorContent extends StatelessWidget {
/// The error title to display
final String title;
/// The error message to display
final String message;
/// Optional callback for retry action
final VoidCallback? onRetry;
/// Optional callback for close action
final VoidCallback? onClose;
/// Icon to display with the error
final IconData icon;
/// Color of the error icon
final Color? iconColor;
/// Creates a new [ErrorContent] widget.
///
/// [message] is required, other parameters are optional with sensible defaults.
const ErrorContent({
super.key,
this.title = 'An error occurred',
required this.message,
this.onRetry,
this.onClose,
this.icon = Icons.error_outline,
this.iconColor,
});
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final defaultIconColor = iconColor ?? Colors.red[400];
return Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 10,
spreadRadius: 2,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Bouton fermer en haut à droite
if (onClose != null)
Align(
alignment: Alignment.topRight,
child: IconButton(
icon: const Icon(Icons.close),
onPressed: onClose,
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
),
),
const SizedBox(height: 8),
// Icône d'erreur
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: defaultIconColor?.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: Icon(icon, size: 48, color: defaultIconColor),
),
const SizedBox(height: 24),
// Titre
Text(
title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.white : Colors.black87,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 12),
// Message d'erreur
Text(
message,
style: TextStyle(
fontSize: 14,
color: Colors.grey[600],
height: 1.5,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
// Boutons d'action
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (onRetry != null) ...[
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,
),
),
),
if (onClose != null) const SizedBox(width: 12),
],
if (onClose != null)
OutlinedButton.icon(
onPressed: onClose,
icon: const Icon(Icons.close),
label: const Text('Fermer'),
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
),
],
),
],
),
);
}
}
// Fonction helper pour afficher l'erreur en dialog
void showErrorDialog(
BuildContext context, {
String title = 'Une erreur est survenue',
required String message,
VoidCallback? onRetry,
IconData icon = Icons.error_outline,
Color? iconColor,
bool barrierDismissible = true,
}) {
showDialog(
context: context,
barrierDismissible: barrierDismissible,
builder: (BuildContext dialogContext) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: ErrorContent(
title: title,
message: message,
icon: icon,
iconColor: iconColor,
onRetry: onRetry != null
? () {
Navigator.of(dialogContext).pop();
onRetry();
}
: null,
onClose: () => Navigator.of(dialogContext).pop(),
),
);
},
);
}