Files
TravelMate/lib/components/error/error_content.dart
Dayron 2faf37f145 Enhance model and service documentation with detailed comments and descriptions
- Updated Group, Trip, User, and other model classes to include comprehensive documentation for better understanding and maintainability.
- Improved error handling and logging in services, including AuthService, ErrorService, and StorageService.
- Added validation and business logic explanations in ExpenseService and TripService.
- Refactored method comments to follow a consistent format across the codebase.
- Translated error messages and comments from French to English for consistency.
2025-10-30 15:56:17 +01:00

256 lines
7.0 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(),
),
);
},
);
}
// Fonction helper pour afficher l'erreur en bottom sheet
void showErrorBottomSheet(
BuildContext context, {
String title = 'Une erreur est survenue',
required String message,
VoidCallback? onRetry,
IconData icon = Icons.error_outline,
Color? iconColor,
bool isDismissible = true,
}) {
showModalBottomSheet(
context: context,
isDismissible: isDismissible,
enableDrag: isDismissible,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (BuildContext sheetContext) {
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(16),
child: ErrorContent(
title: title,
message: message,
icon: icon,
iconColor: iconColor,
onRetry: onRetry != null
? () {
Navigator.of(sheetContext).pop();
onRetry();
}
: null,
onClose: () => Navigator.of(sheetContext).pop(),
),
),
);
},
);
}
// Fonction helper pour afficher en SnackBar (pour erreurs mineures)
void showErrorSnackBar(
BuildContext context, {
required String message,
VoidCallback? onRetry,
Duration duration = const Duration(seconds: 4),
}) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red[400],
duration: duration,
action: onRetry != null
? SnackBarAction(
label: 'Réessayer',
textColor: Colors.white,
onPressed: onRetry,
)
: null,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
}