update loaing
This commit is contained in:
@@ -420,7 +420,7 @@ ref.watch(userProvider).when(
|
|||||||
|
|
||||||
data: (user) => UserView(user),
|
data: (user) => UserView(user),
|
||||||
|
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
|
|
||||||
error: (error, stack) => ErrorView(error),
|
error: (error, stack) => ErrorView(error),
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ switch (userState) {
|
|||||||
|
|
||||||
case AsyncLoading():
|
case AsyncLoading():
|
||||||
|
|
||||||
return CircularProgressIndicator();
|
return const CustomLoadingIndicator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1117,5 +1117,5 @@ All recent implementations follow:
|
|||||||
- ✅ AppBar standardization
|
- ✅ AppBar standardization
|
||||||
- ✅ CachedNetworkImage for all remote images
|
- ✅ CachedNetworkImage for all remote images
|
||||||
- ✅ Proper error handling
|
- ✅ Proper error handling
|
||||||
- ✅ Loading states (CircularProgressIndicator)
|
- ✅ Loading states (CustomLoadingIndicator)
|
||||||
- ✅ Empty states with helpful messages
|
- ✅ Empty states with helpful messages
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ class _CartPageState extends ConsumerState<CartPage> {
|
|||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: _isSyncing
|
child: _isSyncing
|
||||||
? CircularProgressIndicator() // Show loading while syncing
|
? const CustomLoadingIndicator() // Show loading while syncing
|
||||||
: Text('Tiến hành đặt hàng'),
|
: Text('Tiến hành đặt hàng'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -768,5 +768,5 @@ end
|
|||||||
- ✅ Vietnamese localization
|
- ✅ Vietnamese localization
|
||||||
- ✅ CachedNetworkImage for all remote images
|
- ✅ CachedNetworkImage for all remote images
|
||||||
- ✅ Proper error handling
|
- ✅ Proper error handling
|
||||||
- ✅ Loading states (CircularProgressIndicator)
|
- ✅ Loading states (CustomLoadingIndicator)
|
||||||
- ✅ Empty states with helpful messages
|
- ✅ Empty states with helpful messages
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ int stars = apiRatingToStars(0.8); // 4
|
|||||||
- Added date formatting function (`_formatDate`)
|
- Added date formatting function (`_formatDate`)
|
||||||
|
|
||||||
**States**:
|
**States**:
|
||||||
1. **Loading**: Shows CircularProgressIndicator
|
1. **Loading**: Shows CustomLoadingIndicator
|
||||||
2. **Error**: Shows error icon and message
|
2. **Error**: Shows error icon and message
|
||||||
3. **Empty**: Shows "Chưa có đánh giá nào" with call-to-action
|
3. **Empty**: Shows "Chưa có đánh giá nào" with call-to-action
|
||||||
4. **Data**: Shows rating overview and review list
|
4. **Data**: Shows rating overview and review list
|
||||||
@@ -553,7 +553,7 @@ Widget build(BuildContext context, WidgetRef ref) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Text('Error: $error'),
|
error: (error, stack) => Text('Error: $error'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ RatingProvider CountProvider in UI components)
|
|||||||
```
|
```
|
||||||
1. Initial State (Loading)
|
1. Initial State (Loading)
|
||||||
├─► productReviewsProvider returns AsyncValue.loading()
|
├─► productReviewsProvider returns AsyncValue.loading()
|
||||||
└─► UI shows CircularProgressIndicator
|
└─► UI shows CustomLoadingIndicator
|
||||||
|
|
||||||
2. Loading State → Data State
|
2. Loading State → Data State
|
||||||
├─► API call succeeds
|
├─► API call succeeds
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class ReviewsListPage extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Text('Error: $error'),
|
child: Text('Error: $error'),
|
||||||
@@ -263,7 +263,7 @@ class _SimpleReviewFormState extends ConsumerState<SimpleReviewForm> {
|
|||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: _isSubmitting ? null : _submitReview,
|
onPressed: _isSubmitting ? null : _submitReview,
|
||||||
child: _isSubmitting
|
child: _isSubmitting
|
||||||
? const CircularProgressIndicator()
|
? const const CustomLoadingIndicator()
|
||||||
: const Text('Submit Review'),
|
: const Text('Submit Review'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -351,7 +351,7 @@ class _PaginatedReviewsListState
|
|||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? const CircularProgressIndicator()
|
? const const CustomLoadingIndicator()
|
||||||
: ElevatedButton(
|
: ElevatedButton(
|
||||||
onPressed: _loadMoreReviews,
|
onPressed: _loadMoreReviews,
|
||||||
child: const Text('Load More'),
|
child: const Text('Load More'),
|
||||||
@@ -430,7 +430,7 @@ class RefreshableReviewsList extends ConsumerWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(40),
|
padding: EdgeInsets.all(40),
|
||||||
child: CircularProgressIndicator(),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -540,7 +540,7 @@ class _FilteredReviewsListState extends ConsumerState<FilteredReviewsList> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Text('Error: $error'),
|
child: Text('Error: $error'),
|
||||||
@@ -662,7 +662,7 @@ class ReviewsWithRetry extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ final reviewsAsync = ref.watch(productReviewsProvider(itemId));
|
|||||||
|
|
||||||
reviewsAsync.when(
|
reviewsAsync.when(
|
||||||
data: (reviews) => /* show reviews */,
|
data: (reviews) => /* show reviews */,
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => /* show error */,
|
error: (error, stack) => /* show error */,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Future<User> user(UserRef ref, String id) async {
|
|||||||
final userAsync = ref.watch(userProvider('123'));
|
final userAsync = ref.watch(userProvider('123'));
|
||||||
userAsync.when(
|
userAsync.when(
|
||||||
data: (user) => Text(user.name),
|
data: (user) => Text(user.name),
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (e, _) => Text('Error: $e'),
|
error: (e, _) => Text('Error: $e'),
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
@@ -202,7 +202,7 @@ final newValue = ref.refresh(userProvider);
|
|||||||
```dart
|
```dart
|
||||||
asyncValue.when(
|
asyncValue.when(
|
||||||
data: (value) => Text(value),
|
data: (value) => Text(value),
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Text('Error: $error'),
|
error: (error, stack) => Text('Error: $error'),
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
@@ -215,7 +215,7 @@ switch (asyncValue) {
|
|||||||
case AsyncError(:final error):
|
case AsyncError(:final error):
|
||||||
return Text('Error: $error');
|
return Text('Error: $error');
|
||||||
case AsyncLoading():
|
case AsyncLoading():
|
||||||
return CircularProgressIndicator();
|
return const CustomLoadingIndicator();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Connectivity connectivity(Ref ref) {
|
|||||||
/// final connectivityState = ref.watch(connectivityStreamProvider);
|
/// final connectivityState = ref.watch(connectivityStreamProvider);
|
||||||
/// connectivityState.when(
|
/// connectivityState.when(
|
||||||
/// data: (status) => Text('Status: $status'),
|
/// data: (status) => Text('Status: $status'),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, _) => Text('Error: $error'),
|
/// error: (error, _) => Text('Error: $error'),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
@@ -83,7 +83,7 @@ Future<ConnectivityStatus> currentConnectivity(Ref ref) async {
|
|||||||
/// final isOnlineAsync = ref.watch(isOnlineProvider);
|
/// final isOnlineAsync = ref.watch(isOnlineProvider);
|
||||||
/// isOnlineAsync.when(
|
/// isOnlineAsync.when(
|
||||||
/// data: (isOnline) => isOnline ? Text('Online') : Text('Offline'),
|
/// data: (isOnline) => isOnline ? Text('Online') : Text('Offline'),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, _) => Text('Error: $error'),
|
/// error: (error, _) => Text('Error: $error'),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ final version = ref.watch(appVersionProvider);
|
|||||||
final userData = ref.watch(userDataProvider);
|
final userData = ref.watch(userDataProvider);
|
||||||
userData.when(
|
userData.when(
|
||||||
data: (data) => Text(data),
|
data: (data) => Text(data),
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Text('Error: $error'),
|
error: (error, stack) => Text('Error: $error'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ switch (profileState) {
|
|||||||
case AsyncError(:final error):
|
case AsyncError(:final error):
|
||||||
return Text('Error: $error');
|
return Text('Error: $error');
|
||||||
case AsyncLoading():
|
case AsyncLoading():
|
||||||
return CircularProgressIndicator();
|
return const CustomLoadingIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
/// Button variant types for different use cases.
|
/// Button variant types for different use cases.
|
||||||
enum ButtonVariant {
|
enum ButtonVariant {
|
||||||
@@ -106,14 +107,7 @@ class CustomButton extends StatelessWidget {
|
|||||||
/// Builds the button content (text, icon, or loading indicator)
|
/// Builds the button content (text, icon, or loading indicator)
|
||||||
Widget _buildContent() {
|
Widget _buildContent() {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return const SizedBox(
|
return const CustomLoadingIndicator(size: 20, color: Colors.white);
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||||
|
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
|
|
||||||
/// Custom loading indicator widget with optional message text.
|
/// Custom loading indicator widget with optional message text.
|
||||||
///
|
///
|
||||||
/// Displays a centered circular progress indicator with an optional
|
/// Displays a centered three rotating dots animation with an optional
|
||||||
/// message below it. Used for loading states throughout the app.
|
/// message below it. Used for loading states throughout the app.
|
||||||
///
|
///
|
||||||
/// Example usage:
|
/// Example usage:
|
||||||
@@ -32,19 +33,14 @@ class CustomLoadingIndicator extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
return Center(
|
return Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
LoadingAnimationWidget.threeRotatingDots(
|
||||||
width: size,
|
color: color ?? colorScheme.primary,
|
||||||
height: size,
|
size: size,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 3,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
color ?? AppColors.primaryBlue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (message != null) ...[
|
if (message != null) ...[
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/database/hive_initializer.dart';
|
import 'package:worker/core/database/hive_initializer.dart';
|
||||||
import 'package:worker/core/database/models/enums.dart';
|
import 'package:worker/core/database/models/enums.dart';
|
||||||
@@ -360,12 +361,7 @@ class _ProfileCardSection extends ConsumerWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: colorScheme.primary,
|
|
||||||
strokeWidth: 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: AppSpacing.md),
|
const SizedBox(width: AppSpacing.md),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -492,11 +488,8 @@ class _ProfileCardSection extends ConsumerWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: colorScheme.primaryContainer,
|
color: colorScheme.primaryContainer,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: CustomLoadingIndicator(
|
||||||
child: CircularProgressIndicator(
|
color: colorScheme.onPrimaryContainer,
|
||||||
color: colorScheme.onPrimaryContainer,
|
|
||||||
strokeWidth: 2,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
@@ -676,7 +669,7 @@ class _LogoutButton extends ConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
CircularProgressIndicator(),
|
CustomLoadingIndicator(),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
Text('Đang đăng xuất...'),
|
Text('Đang đăng xuất...'),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -450,13 +451,9 @@ class AddressFormPage extends HookConsumerWidget {
|
|||||||
isSaving,
|
isSaving,
|
||||||
),
|
),
|
||||||
icon: isSaving.value
|
icon: isSaving.value
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
width: 18,
|
color: colorScheme.onPrimary,
|
||||||
height: 18,
|
size: 18,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
color: colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const FaIcon(FontAwesomeIcons.floppyDisk, size: 18),
|
: const FaIcon(FontAwesomeIcons.floppyDisk, size: 18),
|
||||||
label: Text(
|
label: Text(
|
||||||
@@ -800,13 +797,9 @@ class AddressFormPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
if (isLoading) ...[
|
if (isLoading) ...[
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
SizedBox(
|
CustomLoadingIndicator(
|
||||||
width: 12,
|
color: colorScheme.primary,
|
||||||
height: 12,
|
size: 12,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
color: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@@ -856,13 +849,9 @@ class AddressFormPage extends HookConsumerWidget {
|
|||||||
suffixIcon: isLoading
|
suffixIcon: isLoading
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.only(right: 12),
|
padding: const EdgeInsets.only(right: 12),
|
||||||
child: SizedBox(
|
child: CustomLoadingIndicator(
|
||||||
width: 20,
|
color: colorScheme.primary,
|
||||||
height: 20,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
color: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -253,7 +254,7 @@ class AddressesPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -61,21 +62,8 @@ class ProfileEditPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
),
|
),
|
||||||
body: Center(
|
body: const CustomLoadingIndicator(
|
||||||
child: Column(
|
message: 'Đang tải thông tin...',
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
CircularProgressIndicator(color: colorScheme.primary),
|
|
||||||
const SizedBox(height: AppSpacing.md),
|
|
||||||
Text(
|
|
||||||
'Đang tải thông tin...',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Scaffold(
|
error: (error, stack) => Scaffold(
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Future<GetUserInfo> getUserInfoUseCase(Ref ref) async {
|
|||||||
///
|
///
|
||||||
/// userInfoAsync.when(
|
/// userInfoAsync.when(
|
||||||
/// data: (userInfo) => Text(userInfo.fullName),
|
/// data: (userInfo) => Text(userInfo.fullName),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/core/utils/validators.dart';
|
import 'package:worker/core/utils/validators.dart';
|
||||||
@@ -294,15 +295,9 @@ class _ForgotPasswordPageState extends ConsumerState<ForgotPasswordPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
height: 20.0,
|
color: colorScheme.onPrimary,
|
||||||
width: 20.0,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2.0,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Text(
|
: const Text(
|
||||||
'Gửi mã OTP',
|
'Gửi mã OTP',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
@@ -483,15 +484,9 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: isLoading
|
child: isLoading
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
height: 20.0,
|
color: colorScheme.onPrimary,
|
||||||
width: 20.0,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2.0,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Text(
|
: const Text(
|
||||||
'Đăng nhập',
|
'Đăng nhập',
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
@@ -377,15 +378,9 @@ class _OtpVerificationPageState extends ConsumerState<OtpVerificationPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
height: 20,
|
color: colorScheme.onPrimary,
|
||||||
width: 20,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Text(
|
: const Text(
|
||||||
'Xác nhận',
|
'Xác nhận',
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
@@ -410,18 +411,8 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
|||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
),
|
),
|
||||||
body: _isLoadingData
|
body: _isLoadingData
|
||||||
? Center(
|
? const CustomLoadingIndicator(
|
||||||
child: Column(
|
message: 'Đang tải dữ liệu...',
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const CircularProgressIndicator(),
|
|
||||||
const SizedBox(height: AppSpacing.md),
|
|
||||||
Text(
|
|
||||||
'Đang tải dữ liệu...',
|
|
||||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: SafeArea(
|
: SafeArea(
|
||||||
child: Form(
|
child: Form(
|
||||||
@@ -646,15 +637,9 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
height: 20,
|
color: colorScheme.onPrimary,
|
||||||
width: 20,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Text(
|
: const Text(
|
||||||
'Đăng ký',
|
'Đăng ký',
|
||||||
@@ -801,9 +786,12 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const SizedBox(
|
loading: () => SizedBox(
|
||||||
height: 48,
|
height: 48,
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: CustomLoadingIndicator(
|
||||||
|
color: colorScheme.primary,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Container(
|
error: (error, stack) => Container(
|
||||||
height: 48,
|
height: 48,
|
||||||
@@ -867,9 +855,12 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const SizedBox(
|
loading: () => SizedBox(
|
||||||
height: 48,
|
height: 48,
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: CustomLoadingIndicator(
|
||||||
|
color: colorScheme.primary,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Container(
|
error: (error, stack) => Container(
|
||||||
height: 48,
|
height: 48,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
|
|
||||||
/// Splash Page
|
/// Splash Page
|
||||||
@@ -61,10 +62,7 @@ class SplashPage extends StatelessWidget {
|
|||||||
const SizedBox(height: 48.0),
|
const SizedBox(height: 48.0),
|
||||||
|
|
||||||
// Loading Indicator
|
// Loading Indicator
|
||||||
CircularProgressIndicator(
|
const CustomLoadingIndicator(),
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(colorScheme.primary),
|
|
||||||
strokeWidth: 3.0,
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 16.0),
|
const SizedBox(height: 16.0),
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
@@ -102,7 +103,7 @@ class _CartPageState extends ConsumerState<CartPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: cartState.isLoading && cartState.isEmpty
|
body: cartState.isLoading && cartState.isEmpty
|
||||||
? const Center(child: CircularProgressIndicator())
|
? const CustomLoadingIndicator()
|
||||||
: cartState.errorMessage != null && cartState.isEmpty
|
: cartState.errorMessage != null && cartState.isEmpty
|
||||||
? _buildErrorState(context, cartState.errorMessage!)
|
? _buildErrorState(context, cartState.errorMessage!)
|
||||||
: cartState.isEmpty
|
: cartState.isEmpty
|
||||||
@@ -132,9 +133,7 @@ class _CartPageState extends ConsumerState<CartPage> {
|
|||||||
if (cartState.isLoading)
|
if (cartState.isLoading)
|
||||||
Container(
|
Container(
|
||||||
color: colorScheme.onSurface.withValues(alpha: 0.1),
|
color: colorScheme.onSurface.withValues(alpha: 0.1),
|
||||||
child: const Center(
|
child: const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -315,14 +314,9 @@ class _CartPageState extends ConsumerState<CartPage> {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
child: _isSyncing
|
child: _isSyncing
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(
|
||||||
width: 20,
|
color: colorScheme.surface,
|
||||||
height: 20,
|
size: 20,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor:
|
|
||||||
AlwaysStoppedAnimation<Color>(colorScheme.surface),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
'Tiến hành đặt hàng',
|
'Tiến hành đặt hàng',
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
@@ -177,9 +178,7 @@ class CheckoutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: const Center(
|
child: const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
error: (error, stack) => Container(
|
error: (error, stack) => Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
margin: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/theme/typography.dart';
|
import 'package:worker/core/theme/typography.dart';
|
||||||
import 'package:worker/features/cart/presentation/providers/cart_provider.dart';
|
import 'package:worker/features/cart/presentation/providers/cart_provider.dart';
|
||||||
import 'package:worker/features/cart/presentation/providers/cart_state.dart';
|
import 'package:worker/features/cart/presentation/providers/cart_state.dart';
|
||||||
@@ -128,8 +129,8 @@ class _CartItemWidgetState extends ConsumerState<CartItemWidget> {
|
|||||||
width: 100,
|
width: 100,
|
||||||
height: 100,
|
height: 100,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ library;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
@@ -93,8 +94,8 @@ class CheckoutSubmitButton extends HookConsumerWidget {
|
|||||||
showDialog<void>(
|
showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (context) => const Center(
|
builder: (context) => Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CustomLoadingIndicator(color: Theme.of(context).colorScheme.primary, size: 40),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class FavoritesPage extends ConsumerWidget {
|
|||||||
return ProductCard(productId: productId);
|
return ProductCard(productId: productId);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Text('Error: $error'),
|
error: (error, stack) => Text('Error: $error'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class FavoritesPage extends ConsumerWidget {
|
|||||||
return ProductTile(productId: productId);
|
return ProductTile(productId: productId);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
loading: () => CircularProgressIndicator(),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => ErrorWidget(error),
|
error: (error, stack) => ErrorWidget(error),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,11 +204,11 @@ class FavoritesPage extends ConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: const CustomLoadingIndicator()),
|
||||||
error: (error, stack) => Center(child: Text('Error: $error')),
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: const CustomLoadingIndicator()),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -368,7 +368,7 @@ class FavoriteProductsList extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
loading: () => const CircularProgressIndicator(),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Text('Error: $error'),
|
error: (error, stack) => Text('Error: $error'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ class FavoritesPageWithRefresh extends ConsumerWidget {
|
|||||||
return ListTile(title: Text('Product: $productId'));
|
return ListTile(title: Text('Product: $productId'));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: const CustomLoadingIndicator()),
|
||||||
error: (error, stack) => Center(child: Text('Error: $error')),
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -466,7 +466,7 @@ class FavoriteButtonWithLoadingState extends ConsumerWidget {
|
|||||||
loading: () => const SizedBox(
|
loading: () => const SizedBox(
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(strokeWidth: 2),
|
||||||
),
|
),
|
||||||
error: (error, stack) => IconButton(
|
error: (error, stack) => IconButton(
|
||||||
icon: const Icon(Icons.error, color: Colors.grey),
|
icon: const Icon(Icons.error, color: Colors.grey),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -319,9 +320,7 @@ class FavoritesPage extends HookConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Text('Đang tải...'),
|
Text('Đang tải...'),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:shimmer/shimmer.dart';
|
import 'package:shimmer/shimmer.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/utils/extensions.dart';
|
import 'package:worker/core/utils/extensions.dart';
|
||||||
@@ -82,7 +83,7 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Container(
|
error: (error, stack) => Container(
|
||||||
margin: const EdgeInsets.all(16),
|
margin: const EdgeInsets.all(16),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ part 'member_card_provider.g.dart';
|
|||||||
///
|
///
|
||||||
/// memberCardAsync.when(
|
/// memberCardAsync.when(
|
||||||
/// data: (memberCard) => MemberCardWidget(memberCard: memberCard),
|
/// data: (memberCard) => MemberCardWidget(memberCard: memberCard),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const int _maxPromotions = 5;
|
|||||||
///
|
///
|
||||||
/// promotionsAsync.when(
|
/// promotionsAsync.when(
|
||||||
/// data: (promotions) => PromotionSlider(promotions: promotions),
|
/// data: (promotions) => PromotionSlider(promotions: promotions),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -126,7 +127,7 @@ class _PromotionCard extends StatelessWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 140,
|
height: 140,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 140,
|
height: 140,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/utils/extensions.dart';
|
import 'package:worker/core/utils/extensions.dart';
|
||||||
@@ -66,7 +67,7 @@ class InvoiceDetailPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: invoiceAsync.when(
|
body: invoiceAsync.when(
|
||||||
data: (invoice) => _buildContent(context, invoice),
|
data: (invoice) => _buildContent(context, invoice),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => _buildErrorState(context, ref, error),
|
error: (error, stack) => _buildErrorState(context, ref, error),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/utils/extensions.dart';
|
import 'package:worker/core/utils/extensions.dart';
|
||||||
@@ -74,7 +75,7 @@ class InvoicesPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => _buildErrorState(context, ref, error),
|
error: (error, stack) => _buildErrorState(context, ref, error),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/database/models/enums.dart';
|
import 'package:worker/core/database/models/enums.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
@@ -74,7 +75,7 @@ class PointsHistoryPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => _buildErrorState(error, colorScheme),
|
error: (error, stack) => _buildErrorState(error, colorScheme),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/loyalty/domain/entities/points_record.dart';
|
import 'package:worker/features/loyalty/domain/entities/points_record.dart';
|
||||||
@@ -183,9 +184,7 @@ class PointsRecordsPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => RefreshIndicator(
|
error: (error, stack) => RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await ref.read(allPointsRecordsProvider.notifier).refresh();
|
await ref.read(allPointsRecordsProvider.notifier).refresh();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/features/loyalty/domain/entities/gift_catalog.dart';
|
import 'package:worker/features/loyalty/domain/entities/gift_catalog.dart';
|
||||||
import 'package:worker/features/loyalty/presentation/providers/loyalty_points_provider.dart';
|
import 'package:worker/features/loyalty/presentation/providers/loyalty_points_provider.dart';
|
||||||
|
|
||||||
@@ -150,8 +151,8 @@ class RewardCard extends ConsumerWidget {
|
|||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: Theme.of(context).colorScheme.primary, size: 40),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_html/flutter_html.dart';
|
import 'package:flutter_html/flutter_html.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -60,7 +61,7 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
}
|
}
|
||||||
return _buildContent(context, article);
|
return _buildContent(context, article);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => _buildErrorState(context, error.toString()),
|
error: (error, stack) => _buildErrorState(context, error.toString()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -126,7 +127,7 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 250,
|
height: 250,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 250,
|
height: 250,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -98,7 +99,7 @@ class _NewsListPageState extends ConsumerState<NewsListPage> {
|
|||||||
loading: () => const SliverToBoxAdapter(
|
loading: () => const SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(AppSpacing.md),
|
padding: EdgeInsets.all(AppSpacing.md),
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) =>
|
error: (error, stack) =>
|
||||||
@@ -158,7 +159,7 @@ class _NewsListPageState extends ConsumerState<NewsListPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const SliverFillRemaining(
|
loading: () => const SliverFillRemaining(
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => SliverFillRemaining(
|
error: (error, stack) => SliverFillRemaining(
|
||||||
child: _buildErrorState(error.toString()),
|
child: _buildErrorState(error.toString()),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
@@ -65,7 +66,7 @@ class FeaturedNewsCard extends StatelessWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
@@ -61,7 +62,7 @@ class NewsCard extends StatelessWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
@@ -60,7 +61,7 @@ class RelatedArticleCard extends StatelessWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart' hide Notification;
|
import 'package:flutter/material.dart' hide Notification;
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -52,7 +53,7 @@ class NotificationsPage extends HookConsumerWidget {
|
|||||||
notifications,
|
notifications,
|
||||||
selectedCategory,
|
selectedCategory,
|
||||||
),
|
),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) =>
|
error: (error, stack) =>
|
||||||
_buildErrorState(ref, selectedCategory),
|
_buildErrorState(ref, selectedCategory),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import 'package:worker/core/enums/status_color.dart';
|
|||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/core/utils/extensions.dart';
|
import 'package:worker/core/utils/extensions.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/features/account/domain/entities/address.dart';
|
import 'package:worker/features/account/domain/entities/address.dart';
|
||||||
import 'package:worker/features/orders/domain/entities/order_detail.dart';
|
import 'package:worker/features/orders/domain/entities/order_detail.dart';
|
||||||
import 'package:worker/features/orders/presentation/providers/orders_provider.dart';
|
import 'package:worker/features/orders/presentation/providers/orders_provider.dart';
|
||||||
@@ -135,7 +136,7 @@ class OrderDetailPage extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -1001,7 +1002,7 @@ class OrderDetailPage extends ConsumerWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(
|
child: const Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
@@ -1524,13 +1525,9 @@ class OrderDetailPage extends ConsumerWidget {
|
|||||||
SnackBar(
|
SnackBar(
|
||||||
content: Row(
|
content: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
CustomLoadingIndicator(
|
||||||
width: 20,
|
size: 20,
|
||||||
height: 20,
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).colorScheme.onPrimary),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
const Text('Đang hủy đơn hàng...'),
|
const Text('Đang hủy đơn hàng...'),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -351,7 +352,7 @@ class _OrdersPageState extends ConsumerState<OrdersPage> {
|
|||||||
/// Build loading state
|
/// Build loading state
|
||||||
Widget _buildLoadingState() {
|
Widget _buildLoadingState() {
|
||||||
return const SliverFillRemaining(
|
return const SliverFillRemaining(
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: const CustomLoadingIndicator(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -192,7 +193,7 @@ class PaymentDetailPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -225,9 +226,7 @@ class PaymentQrPage extends HookConsumerWidget {
|
|||||||
border: Border.all(color: colorScheme.outlineVariant),
|
border: Border.all(color: colorScheme.outlineVariant),
|
||||||
),
|
),
|
||||||
child: isLoading
|
child: isLoading
|
||||||
? const Center(
|
? const const CustomLoadingIndicator()
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
)
|
|
||||||
: qrCodeData != null && qrCodeData.isNotEmpty
|
: qrCodeData != null && qrCodeData.isNotEmpty
|
||||||
? QrImageView(
|
? QrImageView(
|
||||||
data: qrCodeData,
|
data: qrCodeData,
|
||||||
@@ -580,10 +579,7 @@ class PaymentQrPage extends HookConsumerWidget {
|
|||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: 18,
|
width: 18,
|
||||||
height: 18,
|
height: 18,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(colorScheme.surface),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const FaIcon(FontAwesomeIcons.camera, size: 18),
|
: const FaIcon(FontAwesomeIcons.camera, size: 18),
|
||||||
label: Text(
|
label: Text(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -71,7 +72,7 @@ class PaymentsPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => _buildErrorState(context, ref, error),
|
error: (error, stack) => _buildErrorState(context, ref, error),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -164,7 +165,7 @@ class _PricePolicyPageState extends ConsumerState<PricePolicyPage>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ UI components and state management.
|
|||||||
|
|
||||||
### UI/UX Features
|
### UI/UX Features
|
||||||
- Pull-to-refresh support
|
- Pull-to-refresh support
|
||||||
- Loading states with CircularProgressIndicator
|
- Loading states with CustomLoadingIndicator
|
||||||
- Error states with retry button
|
- Error states with retry button
|
||||||
- Empty states with helpful messages
|
- Empty states with helpful messages
|
||||||
- Vietnamese localization
|
- Vietnamese localization
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/favorites/presentation/providers/favorites_provider.dart';
|
import 'package:worker/features/favorites/presentation/providers/favorites_provider.dart';
|
||||||
@@ -262,9 +263,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => Center(
|
loading: () => const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(color: colorScheme.primary),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/router/app_router.dart';
|
import 'package:worker/core/router/app_router.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
@@ -192,7 +193,7 @@ class ProductsPage extends ConsumerWidget {
|
|||||||
|
|
||||||
/// Build loading state
|
/// Build loading state
|
||||||
Widget _buildLoadingState(ColorScheme colorScheme) {
|
Widget _buildLoadingState(ColorScheme colorScheme) {
|
||||||
return Center(child: CircularProgressIndicator(color: colorScheme.primary));
|
return const CustomLoadingIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build error state
|
/// Build error state
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/products/domain/entities/product.dart';
|
import 'package:worker/features/products/domain/entities/product.dart';
|
||||||
@@ -186,7 +187,7 @@ class _WriteReviewPageState extends ConsumerState<WriteReviewPage> {
|
|||||||
|
|
||||||
body: productAsync.when(
|
body: productAsync.when(
|
||||||
data: (product) => _buildForm(product),
|
data: (product) => _buildForm(product),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -249,8 +250,8 @@ class _WriteReviewPageState extends ConsumerState<WriteReviewPage> {
|
|||||||
width: 80,
|
width: 80,
|
||||||
height: 80,
|
height: 80,
|
||||||
color: colorScheme.surfaceContainerLowest,
|
color: colorScheme.surfaceContainerLowest,
|
||||||
child: const Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
@@ -510,15 +511,7 @@ class _WriteReviewPageState extends ConsumerState<WriteReviewPage> {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
child: _isSubmitting
|
child: _isSubmitting
|
||||||
? SizedBox(
|
? CustomLoadingIndicator(color: colorScheme.onPrimary, size: 20)
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor:
|
|
||||||
AlwaysStoppedAnimation<Color>(colorScheme.onPrimary),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class FilterOption {
|
|||||||
///
|
///
|
||||||
/// filterOptionsAsync.when(
|
/// filterOptionsAsync.when(
|
||||||
/// data: (options) => ProductFilterDrawer(options: options),
|
/// data: (options) => ProductFilterDrawer(options: options),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Future<ProductsRepository> productsRepository(Ref ref) async {
|
|||||||
///
|
///
|
||||||
/// productsAsync.when(
|
/// productsAsync.when(
|
||||||
/// data: (products) => ProductGrid(products: products),
|
/// data: (products) => ProductGrid(products: products),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
@@ -251,7 +251,7 @@ Future<List<Product>> allProducts(Ref ref) async {
|
|||||||
///
|
///
|
||||||
/// productAsync.when(
|
/// productAsync.when(
|
||||||
/// data: (product) => ProductDetailView(product: product),
|
/// data: (product) => ProductDetailView(product: product),
|
||||||
/// loading: () => CircularProgressIndicator(),
|
/// loading: () => const CustomLoadingIndicator(),
|
||||||
/// error: (error, stack) => ErrorWidget(error),
|
/// error: (error, stack) => ErrorWidget(error),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ library;
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/features/products/presentation/providers/product_filter_options_provider.dart';
|
import 'package:worker/features/products/presentation/providers/product_filter_options_provider.dart';
|
||||||
import 'package:worker/features/products/presentation/providers/product_filters_provider.dart';
|
import 'package:worker/features/products/presentation/providers/product_filters_provider.dart';
|
||||||
@@ -105,10 +106,10 @@ class BrandFilterChips extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const SizedBox(
|
loading: () => SizedBox(
|
||||||
height: 48.0,
|
height: 48.0,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2.0),
|
child: CustomLoadingIndicator(color: Theme.of(context).colorScheme.primary, size: 40),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => const SizedBox.shrink(),
|
error: (error, stack) => const SizedBox.shrink(),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ library;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/products/domain/entities/product.dart';
|
import 'package:worker/features/products/domain/entities/product.dart';
|
||||||
@@ -469,9 +470,7 @@ class _ReviewsTab extends ConsumerWidget {
|
|||||||
loading: () => Center(
|
loading: () => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(40),
|
padding: const EdgeInsets.all(40),
|
||||||
child: CircularProgressIndicator(
|
child: const CustomLoadingIndicator(),
|
||||||
color: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stack) => _buildErrorState(colorScheme, error.toString()),
|
error: (error, stack) => _buildErrorState(colorScheme, error.toString()),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ library;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/products/presentation/providers/product_filters_provider.dart';
|
import 'package:worker/features/products/presentation/providers/product_filters_provider.dart';
|
||||||
@@ -209,11 +210,7 @@ class ProductFilterDrawer extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
loading: () => Center(
|
loading: () => const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(colorScheme.primary),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:worker/core/constants/ui_constants.dart';
|
import 'package:worker/core/constants/ui_constants.dart';
|
||||||
import 'package:worker/features/products/domain/entities/product.dart';
|
import 'package:worker/features/products/domain/entities/product.dart';
|
||||||
import 'package:worker/features/products/presentation/widgets/product_card.dart';
|
import 'package:worker/features/products/presentation/widgets/product_card.dart';
|
||||||
@@ -80,9 +81,7 @@ class _ProductGridState extends State<ProductGrid> {
|
|||||||
return Center(
|
return Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(AppSpacing.md),
|
padding: const EdgeInsets.all(AppSpacing.md),
|
||||||
child: CircularProgressIndicator(
|
child: const CustomLoadingIndicator(),
|
||||||
color: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -168,7 +169,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const CircularProgressIndicator(),
|
const CustomLoadingIndicator(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'Đang tải thông tin dự án...',
|
'Đang tải thông tin dự án...',
|
||||||
@@ -641,7 +642,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text('Đang tải...', style: TextStyle(color: colorScheme.onSurfaceVariant)),
|
Text('Đang tải...', style: TextStyle(color: colorScheme.onSurfaceVariant)),
|
||||||
@@ -787,10 +788,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: Colors.white, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -901,7 +899,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -931,10 +929,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: Colors.white, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1150,10 +1145,7 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
|
|||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: Colors.white, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: const Row(
|
: const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -179,9 +180,7 @@ class SubmissionsPage extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => RefreshIndicator(
|
error: (error, stack) => RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await ref.read(allSubmissionsProvider.notifier).refresh();
|
await ref.read(allSubmissionsProvider.notifier).refresh();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
@@ -69,7 +70,7 @@ class _PromotionDetailPageState extends ConsumerState<PromotionDetailPage> {
|
|||||||
foregroundColor: AppColors.grey900,
|
foregroundColor: AppColors.grey900,
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
),
|
),
|
||||||
body: const Center(child: CircularProgressIndicator()),
|
body: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
error: (error, stack) => Scaffold(
|
error: (error, stack) => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -201,7 +202,7 @@ class _PromotionDetailPageState extends ConsumerState<PromotionDetailPage> {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
color: AppColors.grey100,
|
color: AppColors.grey100,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -43,7 +44,7 @@ class PromotionsPage extends ConsumerWidget {
|
|||||||
child: promotionsAsync.when(
|
child: promotionsAsync.when(
|
||||||
data: (promotions) =>
|
data: (promotions) =>
|
||||||
_buildPromotionsContent(context, promotions),
|
_buildPromotionsContent(context, promotions),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -57,7 +58,7 @@ class PromotionCard extends StatelessWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 150,
|
height: 150,
|
||||||
color: AppColors.grey100,
|
color: AppColors.grey100,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 150,
|
height: 150,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -450,7 +451,7 @@ class _QuotesPageState extends ConsumerState<QuotesPage> {
|
|||||||
/// Build loading state
|
/// Build loading state
|
||||||
Widget _buildLoadingState() {
|
Widget _buildLoadingState() {
|
||||||
return const SliverFillRemaining(
|
return const SliverFillRemaining(
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: const CustomLoadingIndicator(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -810,10 +811,7 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
width: 20,
|
width: 20,
|
||||||
child: CircularProgressIndicator(
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
strokeWidth: 2,
|
|
||||||
color: colorScheme.surface,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -491,9 +492,7 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
loading: () => const Center(
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(40),
|
padding: const EdgeInsets.all(40),
|
||||||
@@ -560,7 +559,7 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(
|
child: const Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
@@ -85,9 +86,7 @@ class ModelHouseDetailPage extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
loading: () => const Center(
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(40),
|
padding: const EdgeInsets.all(40),
|
||||||
@@ -410,7 +409,7 @@ class ModelHouseDetailPage extends ConsumerWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(
|
child: const Center(
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CustomLoadingIndicator(color: colorScheme.primary, size: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
@@ -522,7 +521,7 @@ class _ImageViewerDialogState extends State<_ImageViewerDialog> {
|
|||||||
imageUrl: widget.images[index].fileUrl,
|
imageUrl: widget.images[index].fileUrl,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
placeholder: (context, url) => const Center(
|
placeholder: (context, url) => const Center(
|
||||||
child: CircularProgressIndicator(color: Colors.white),
|
child: CustomLoadingIndicator(color: Colors.white, size: 40),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => const Icon(
|
errorWidget: (context, url, error) => const Icon(
|
||||||
Icons.error,
|
Icons.error,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@@ -214,9 +215,7 @@ class _LibraryTab extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(40),
|
padding: const EdgeInsets.all(40),
|
||||||
@@ -288,7 +287,7 @@ class _LibraryCard extends StatelessWidget {
|
|||||||
placeholder: (context, url) => Container(
|
placeholder: (context, url) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
color: colorScheme.surfaceContainerHighest,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const const CustomLoadingIndicator(),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => Container(
|
errorWidget: (context, url, error) => Container(
|
||||||
height: 200,
|
height: 200,
|
||||||
@@ -425,9 +424,7 @@ class _DesignRequestsTab extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(
|
loading: () => const const CustomLoadingIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
error: (error, stack) => Center(
|
error: (error, stack) => Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(40),
|
padding: const EdgeInsets.all(40),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:worker/core/widgets/loading_indicator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:worker/features/showrooms/domain/entities/sample_project.dart';
|
import 'package:worker/features/showrooms/domain/entities/sample_project.dart';
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ class _ImageViewerDialogState extends State<ImageViewerDialog> {
|
|||||||
imageUrl: widget.images[index].fileUrl,
|
imageUrl: widget.images[index].fileUrl,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
placeholder: (context, url) => const Center(
|
placeholder: (context, url) => const Center(
|
||||||
child: CircularProgressIndicator(color: Colors.white),
|
child: CustomLoadingIndicator(color: Colors.white, size: 40),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => const Icon(
|
errorWidget: (context, url, error) => const Icon(
|
||||||
Icons.error,
|
Icons.error,
|
||||||
|
|||||||
@@ -876,6 +876,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
loading_animation_widget:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: loading_animation_widget
|
||||||
|
sha256: "9fe23381f3096e902f39e87e487648ff7f74925e86234353fa885bb9f6c98004"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ dependencies:
|
|||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
mobile_scanner: ^5.2.3
|
mobile_scanner: ^5.2.3
|
||||||
font_awesome_flutter: ^10.7.0
|
font_awesome_flutter: ^10.7.0
|
||||||
|
loading_animation_widget: ^1.3.0
|
||||||
|
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
|
|||||||
Reference in New Issue
Block a user