update info
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
/// Provider: User Info Provider
|
||||
///
|
||||
/// Manages the state of user information using Riverpod.
|
||||
/// Fetches data from API and provides it to the UI.
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/core/network/dio_client.dart';
|
||||
import 'package:worker/features/account/data/datasources/user_info_remote_datasource.dart';
|
||||
import 'package:worker/features/account/data/repositories/user_info_repository_impl.dart';
|
||||
import 'package:worker/features/account/domain/entities/user_info.dart'
|
||||
as domain;
|
||||
import 'package:worker/features/account/domain/repositories/user_info_repository.dart';
|
||||
import 'package:worker/features/account/domain/usecases/get_user_info.dart';
|
||||
|
||||
part 'user_info_provider.g.dart';
|
||||
|
||||
// ============================================================================
|
||||
// DATA SOURCE PROVIDERS
|
||||
// ============================================================================
|
||||
|
||||
/// User Info Remote Data Source Provider
|
||||
@riverpod
|
||||
Future<UserInfoRemoteDataSource> userInfoRemoteDataSource(Ref ref) async {
|
||||
final dioClient = await ref.watch(dioClientProvider.future);
|
||||
return UserInfoRemoteDataSource(dioClient);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// REPOSITORY PROVIDERS
|
||||
// ============================================================================
|
||||
|
||||
/// User Info Repository Provider
|
||||
@riverpod
|
||||
Future<UserInfoRepository> userInfoRepository(Ref ref) async {
|
||||
final remoteDataSource = await ref.watch(
|
||||
userInfoRemoteDataSourceProvider.future,
|
||||
);
|
||||
return UserInfoRepositoryImpl(remoteDataSource: remoteDataSource);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// USE CASE PROVIDERS
|
||||
// ============================================================================
|
||||
|
||||
/// Get User Info Use Case Provider
|
||||
@riverpod
|
||||
Future<GetUserInfo> getUserInfoUseCase(Ref ref) async {
|
||||
final repository = await ref.watch(userInfoRepositoryProvider.future);
|
||||
return GetUserInfo(repository);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// STATE PROVIDERS
|
||||
// ============================================================================
|
||||
|
||||
/// User Info Provider
|
||||
///
|
||||
/// Fetches and manages user information state.
|
||||
/// Automatically loads user info on initialization.
|
||||
/// Provides refresh functionality for manual updates.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// // In a widget
|
||||
/// final userInfoAsync = ref.watch(userInfoProvider);
|
||||
///
|
||||
/// userInfoAsync.when(
|
||||
/// data: (userInfo) => Text(userInfo.fullName),
|
||||
/// loading: () => CircularProgressIndicator(),
|
||||
/// error: (error, stack) => ErrorWidget(error),
|
||||
/// );
|
||||
///
|
||||
/// // To refresh
|
||||
/// ref.read(userInfoProvider.notifier).refresh();
|
||||
/// ```
|
||||
@riverpod
|
||||
class UserInfo extends _$UserInfo {
|
||||
@override
|
||||
Future<domain.UserInfo> build() async {
|
||||
// Fetch user info on initialization
|
||||
final useCase = await ref.watch(getUserInfoUseCaseProvider.future);
|
||||
return await useCase();
|
||||
}
|
||||
|
||||
/// Refresh user information
|
||||
///
|
||||
/// Forces a fresh fetch from the API.
|
||||
/// Updates the state with new data.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// await ref.read(userInfoProvider.notifier).refresh();
|
||||
/// ```
|
||||
Future<void> refresh() async {
|
||||
// Set loading state
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
// Fetch fresh data
|
||||
state = await AsyncValue.guard(() async {
|
||||
final useCase = await ref.read(getUserInfoUseCaseProvider.future);
|
||||
return await useCase.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/// Update user info locally
|
||||
///
|
||||
/// Updates the cached state without fetching from API.
|
||||
/// Useful after local profile updates.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// ref.read(userInfoProvider.notifier).updateLocal(updatedUserInfo);
|
||||
/// ```
|
||||
void updateLocal(domain.UserInfo updatedInfo) {
|
||||
state = AsyncValue.data(updatedInfo);
|
||||
}
|
||||
|
||||
/// Clear user info
|
||||
///
|
||||
/// Resets the state to loading.
|
||||
/// Useful on logout or session expiry.
|
||||
void clear() {
|
||||
state = const AsyncValue.loading();
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// COMPUTED PROVIDERS
|
||||
// ============================================================================
|
||||
|
||||
/// User Display Name Provider
|
||||
///
|
||||
/// Provides the user's display name (full name).
|
||||
/// Returns null if user info is not loaded.
|
||||
@riverpod
|
||||
String? userDisplayName(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.fullName;
|
||||
}
|
||||
|
||||
/// User Loyalty Tier Provider
|
||||
///
|
||||
/// Provides the user's current loyalty tier.
|
||||
/// Returns null if user info is not loaded.
|
||||
@riverpod
|
||||
String? userLoyaltyTier(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.tierDisplayName;
|
||||
}
|
||||
|
||||
/// User Total Points Provider
|
||||
///
|
||||
/// Provides the user's total loyalty points.
|
||||
/// Returns 0 if user info is not loaded.
|
||||
@riverpod
|
||||
int userTotalPoints(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.totalPoints ?? 0;
|
||||
}
|
||||
|
||||
/// User Available Points Provider
|
||||
///
|
||||
/// Provides the user's available points for redemption.
|
||||
/// Returns 0 if user info is not loaded.
|
||||
@riverpod
|
||||
int userAvailablePoints(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.availablePoints ?? 0;
|
||||
}
|
||||
|
||||
/// User Avatar URL Provider
|
||||
///
|
||||
/// Provides the user's avatar URL.
|
||||
/// Returns null if user info is not loaded or no avatar set.
|
||||
@riverpod
|
||||
String? userAvatarUrl(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.avatarUrl;
|
||||
}
|
||||
|
||||
/// User Has Company Info Provider
|
||||
///
|
||||
/// Checks if the user has company information.
|
||||
/// Returns false if user info is not loaded.
|
||||
@riverpod
|
||||
bool userHasCompanyInfo(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.hasCompanyInfo ?? false;
|
||||
}
|
||||
|
||||
/// User Is Active Provider
|
||||
///
|
||||
/// Checks if the user's account is active.
|
||||
/// Returns false if user info is not loaded.
|
||||
@riverpod
|
||||
bool userIsActive(Ref ref) {
|
||||
final userInfoAsync = ref.watch(userInfoProvider);
|
||||
return userInfoAsync.value?.isActive ?? false;
|
||||
}
|
||||
Reference in New Issue
Block a user