import 'package:flutter/material.dart'; import '../constants/app_colors.dart'; import '../constants/app_typography.dart'; /// 커스텀 에러 위젯 /// /// Flutter의 기본 ErrorWidget과 이름 충돌을 피하기 위해 CustomErrorWidget으로 명명 class CustomErrorWidget extends StatelessWidget { /// 에러 메시지 final String message; /// 에러 아이콘 (선택사항) final IconData? icon; /// 재시도 버튼 콜백 (선택사항) final VoidCallback? onRetry; /// 상세 에러 메시지 (선택사항) final String? details; const CustomErrorWidget({ super.key, required this.message, this.icon, this.onRetry, this.details, }); @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; 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: isDark ? AppColors.darkError : AppColors.lightError, ), const SizedBox(height: 16), // 에러 메시지 Text( message, style: AppTypography.heading2(isDark), textAlign: TextAlign.center, ), // 상세 메시지 (있을 경우) if (details != null) ...[ const SizedBox(height: 8), Text( details!, style: AppTypography.body2(isDark), textAlign: TextAlign.center, ), ], // 재시도 버튼 (있을 경우) if (onRetry != null) ...[ const SizedBox(height: 24), ElevatedButton.icon( onPressed: onRetry, icon: const Icon(Icons.refresh), label: const Text('다시 시도'), style: ElevatedButton.styleFrom( backgroundColor: isDark ? AppColors.darkPrimary : AppColors.lightPrimary, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 12, ), ), ), ], ], ), ), ); } } /// 간단한 에러 스낵바를 표시하는 유틸리티 함수 void showErrorSnackBar({ required BuildContext context, required String message, Duration duration = const Duration(seconds: 3), SnackBarAction? action, }) { final isDark = Theme.of(context).brightness == Brightness.dark; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( message, style: const TextStyle(color: Colors.white), ), backgroundColor: isDark ? AppColors.darkError : AppColors.lightError, duration: duration, action: action, behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), margin: const EdgeInsets.all(8), ), ); }