import 'package:flutter/material.dart'; import 'package:mobile_monitoring/core/constants/colors.dart'; /// Error Widget - Widget untuk menampilkan error state class CustomErrorWidget extends StatelessWidget { final String title; final String? message; final IconData? icon; final String? actionText; final VoidCallback? onAction; final ErrorType type; const CustomErrorWidget({ super.key, required this.title, this.message, this.icon, this.actionText, this.onAction, this.type = ErrorType.general, }); @override Widget build(BuildContext context) { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( icon ?? _getIconForType(), size: 80, color: _getColorForType(), ), const SizedBox(height: 24), Text( title, style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: _getColorForType(), ), textAlign: TextAlign.center, ), if (message != null) ...[ const SizedBox(height: 8), Text( message!, style: const TextStyle( fontSize: 14, color: AppColors.textSecondary, ), textAlign: TextAlign.center, ), ], if (actionText != null && onAction != null) ...[ const SizedBox(height: 24), ElevatedButton( onPressed: onAction, style: ElevatedButton.styleFrom( backgroundColor: _getColorForType(), foregroundColor: AppColors.white, padding: const EdgeInsets.symmetric( horizontal: 32, vertical: 12, ), ), child: Text(actionText!), ), ], ], ), ), ); } IconData _getIconForType() { switch (type) { case ErrorType.general: return Icons.error_outline; case ErrorType.network: return Icons.wifi_off_outlined; case ErrorType.notFound: return Icons.search_off_outlined; case ErrorType.permission: return Icons.lock_outline; case ErrorType.timeout: return Icons.access_time_outlined; } } Color _getColorForType() { switch (type) { case ErrorType.general: case ErrorType.timeout: return AppColors.error; case ErrorType.network: return AppColors.warning; case ErrorType.notFound: return AppColors.info; case ErrorType.permission: return AppColors.darkGray; } } } enum ErrorType { general, network, notFound, permission, timeout, } /// Error Snackbar - Helper untuk menampilkan error di snackbar class ErrorSnackbar { static void show(BuildContext context, String message, {ErrorType? type}) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ Icon( _getIconForType(type ?? ErrorType.general), color: AppColors.white, ), const SizedBox(width: 12), Expanded( child: Text( message, style: const TextStyle(color: AppColors.white), ), ), ], ), backgroundColor: _getColorForType(type ?? ErrorType.general), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), duration: const Duration(seconds: 4), ), ); } static IconData _getIconForType(ErrorType type) { switch (type) { case ErrorType.general: return Icons.error_outline; case ErrorType.network: return Icons.wifi_off_outlined; case ErrorType.notFound: return Icons.search_off_outlined; case ErrorType.permission: return Icons.lock_outline; case ErrorType.timeout: return Icons.access_time_outlined; } } static Color _getColorForType(ErrorType type) { switch (type) { case ErrorType.general: case ErrorType.timeout: return AppColors.error; case ErrorType.network: return AppColors.warning; case ErrorType.notFound: return AppColors.info; case ErrorType.permission: return AppColors.darkGray; } } } /// Success Snackbar - Helper untuk menampilkan success message class SuccessSnackbar { static void show(BuildContext context, String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ const Icon( Icons.check_circle_outline, color: AppColors.white, ), const SizedBox(width: 12), Expanded( child: Text( message, style: const TextStyle(color: AppColors.white), ), ), ], ), backgroundColor: AppColors.success, behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), duration: const Duration(seconds: 3), ), ); } }