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