1import 'package:flutter/material.dart'; 2 3import '../constants/app_colors.dart'; 4 5/// Full-screen loading indicator 6class FullScreenLoading extends StatelessWidget { 7 const FullScreenLoading({super.key}); 8 9 @override 10 Widget build(BuildContext context) { 11 return const Center( 12 child: CircularProgressIndicator(color: AppColors.primary), 13 ); 14 } 15} 16 17/// Full-screen error state with retry button 18class FullScreenError extends StatelessWidget { 19 const FullScreenError({ 20 required this.message, 21 required this.onRetry, 22 this.title = 'Failed to load', 23 super.key, 24 }); 25 26 final String title; 27 final String message; 28 final VoidCallback onRetry; 29 30 @override 31 Widget build(BuildContext context) { 32 return Center( 33 child: Padding( 34 padding: const EdgeInsets.all(24), 35 child: Column( 36 mainAxisAlignment: MainAxisAlignment.center, 37 children: [ 38 const Icon(Icons.error_outline, size: 64, color: AppColors.primary), 39 const SizedBox(height: 16), 40 Text( 41 title, 42 style: const TextStyle( 43 fontSize: 20, 44 color: AppColors.textPrimary, 45 fontWeight: FontWeight.bold, 46 ), 47 ), 48 const SizedBox(height: 8), 49 Text( 50 message, 51 style: const TextStyle( 52 fontSize: 14, 53 color: AppColors.textSecondary, 54 ), 55 textAlign: TextAlign.center, 56 ), 57 const SizedBox(height: 24), 58 ElevatedButton( 59 onPressed: onRetry, 60 style: ElevatedButton.styleFrom( 61 backgroundColor: AppColors.primary, 62 ), 63 child: const Text('Retry'), 64 ), 65 ], 66 ), 67 ), 68 ); 69 } 70} 71 72/// Inline loading indicator (for pagination) 73class InlineLoading extends StatelessWidget { 74 const InlineLoading({super.key}); 75 76 @override 77 Widget build(BuildContext context) { 78 return const Center( 79 child: Padding( 80 padding: EdgeInsets.all(16), 81 child: CircularProgressIndicator(color: AppColors.primary), 82 ), 83 ); 84 } 85} 86 87/// Inline error state with retry button (for pagination) 88class InlineError extends StatelessWidget { 89 const InlineError({required this.message, required this.onRetry, super.key}); 90 91 final String message; 92 final VoidCallback onRetry; 93 94 @override 95 Widget build(BuildContext context) { 96 return Container( 97 margin: const EdgeInsets.all(16), 98 padding: const EdgeInsets.all(16), 99 decoration: BoxDecoration( 100 color: AppColors.background, 101 borderRadius: BorderRadius.circular(8), 102 border: Border.all(color: AppColors.primary), 103 ), 104 child: Column( 105 children: [ 106 const Icon(Icons.error_outline, color: AppColors.primary, size: 32), 107 const SizedBox(height: 8), 108 Text( 109 message, 110 style: const TextStyle( 111 color: AppColors.textSecondary, 112 fontSize: 14, 113 ), 114 textAlign: TextAlign.center, 115 ), 116 const SizedBox(height: 12), 117 TextButton( 118 onPressed: onRetry, 119 style: TextButton.styleFrom(foregroundColor: AppColors.primary), 120 child: const Text('Retry'), 121 ), 122 ], 123 ), 124 ); 125 } 126} 127 128/// Full-screen not found error state with back button 129/// 130/// Used when a resource cannot be found (e.g., missing post in route extras). 131/// Provides a user-friendly message and navigation option. 132class NotFoundError extends StatelessWidget { 133 const NotFoundError({ 134 required this.title, 135 required this.message, 136 required this.onBackPressed, 137 super.key, 138 }); 139 140 final String title; 141 final String message; 142 final VoidCallback onBackPressed; 143 144 @override 145 Widget build(BuildContext context) { 146 return Scaffold( 147 backgroundColor: AppColors.background, 148 appBar: AppBar( 149 backgroundColor: AppColors.background, 150 foregroundColor: AppColors.textPrimary, 151 title: const Text('Not Found'), 152 elevation: 0, 153 ), 154 body: Center( 155 child: Padding( 156 padding: const EdgeInsets.all(24), 157 child: Column( 158 mainAxisAlignment: MainAxisAlignment.center, 159 children: [ 160 const Icon(Icons.search_off, size: 64, color: AppColors.primary), 161 const SizedBox(height: 16), 162 Text( 163 title, 164 style: const TextStyle( 165 fontSize: 20, 166 color: AppColors.textPrimary, 167 fontWeight: FontWeight.bold, 168 ), 169 ), 170 const SizedBox(height: 8), 171 Text( 172 message, 173 style: const TextStyle( 174 fontSize: 14, 175 color: AppColors.textSecondary, 176 ), 177 textAlign: TextAlign.center, 178 ), 179 const SizedBox(height: 24), 180 ElevatedButton( 181 onPressed: onBackPressed, 182 style: ElevatedButton.styleFrom( 183 backgroundColor: AppColors.primary, 184 ), 185 child: const Text('Go Back'), 186 ), 187 ], 188 ), 189 ), 190 ), 191 ); 192 } 193}