Main coves client
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}