add dropdown

This commit is contained in:
Phuoc Nguyen
2025-10-28 16:24:17 +07:00
parent 0010446298
commit 5cfc56f40d
20 changed files with 912 additions and 12 deletions

View File

@@ -34,6 +34,13 @@ class ApiEndpoints {
/// GET: (requires auth token)
static const String profile = '$apiVersion/auth/profile';
// ==================== User Endpoints ====================
/// Get all users (short info)
/// GET: /PortalUser/GetAllMemberUserShortInfo (requires auth token)
/// Response: List of users
static const String users = '/PortalUser/GetAllMemberUserShortInfo';
// ==================== Warehouse Endpoints ====================
/// Get all warehouses

View File

@@ -18,6 +18,14 @@ import '../../features/warehouse/data/repositories/warehouse_repository_impl.dar
import '../../features/warehouse/domain/repositories/warehouse_repository.dart';
import '../../features/warehouse/domain/usecases/get_warehouses_usecase.dart';
import '../../features/warehouse/presentation/providers/warehouse_provider.dart';
import '../../features/users/data/datasources/users_local_datasource.dart';
import '../../features/users/data/datasources/users_remote_datasource.dart';
import '../../features/users/data/repositories/users_repository_impl.dart';
import '../../features/users/domain/repositories/users_repository.dart';
import '../../features/users/domain/usecases/get_users_usecase.dart';
import '../../features/users/domain/usecases/sync_users_usecase.dart';
import '../../features/users/presentation/providers/users_provider.dart';
import '../../features/users/presentation/providers/users_state.dart';
import '../network/api_client.dart';
import '../storage/secure_storage.dart';
@@ -392,6 +400,105 @@ final productDetailErrorProvider = Provider.family<String?, String>((ref, key) {
return state.error;
});
/// ========================================================================
/// USERS FEATURE PROVIDERS
/// ========================================================================
/// Providers for users feature following clean architecture
// Data Layer
/// Users local data source provider
/// Handles local storage operations for users using Hive
final usersLocalDataSourceProvider = Provider<UsersLocalDataSource>((ref) {
return UsersLocalDataSourceImpl();
});
/// Users remote data source provider
/// Handles API calls for users
final usersRemoteDataSourceProvider = Provider<UsersRemoteDataSource>((ref) {
final apiClient = ref.watch(apiClientProvider);
return UsersRemoteDataSourceImpl(apiClient);
});
/// Users repository provider
/// Implements domain repository interface
/// Coordinates between local and remote data sources
final usersRepositoryProvider = Provider<UsersRepository>((ref) {
final remoteDataSource = ref.watch(usersRemoteDataSourceProvider);
final localDataSource = ref.watch(usersLocalDataSourceProvider);
return UsersRepositoryImpl(
remoteDataSource: remoteDataSource,
localDataSource: localDataSource,
);
});
// Domain Layer
/// Get users use case provider
/// Encapsulates user fetching business logic (local-first strategy)
final getUsersUseCaseProvider = Provider<GetUsersUseCase>((ref) {
final repository = ref.watch(usersRepositoryProvider);
return GetUsersUseCase(repository);
});
/// Sync users use case provider
/// Encapsulates user syncing business logic (force refresh from API)
final syncUsersUseCaseProvider = Provider<SyncUsersUseCase>((ref) {
final repository = ref.watch(usersRepositoryProvider);
return SyncUsersUseCase(repository);
});
// Presentation Layer
/// Users state notifier provider
/// Manages users state including list, loading, and errors
final usersProvider = StateNotifierProvider<UsersNotifier, UsersState>((ref) {
final getUsersUseCase = ref.watch(getUsersUseCaseProvider);
final syncUsersUseCase = ref.watch(syncUsersUseCaseProvider);
return UsersNotifier(
getUsersUseCase: getUsersUseCase,
syncUsersUseCase: syncUsersUseCase,
);
});
/// Convenient providers for users state
/// Provider to get list of users
/// Usage: ref.watch(usersListProvider)
final usersListProvider = Provider((ref) {
final usersState = ref.watch(usersProvider);
return usersState.users;
});
/// Provider to check if users are loading
/// Usage: ref.watch(isUsersLoadingProvider)
final isUsersLoadingProvider = Provider<bool>((ref) {
final usersState = ref.watch(usersProvider);
return usersState.isLoading;
});
/// Provider to check if users list has items
/// Usage: ref.watch(hasUsersProvider)
final hasUsersProvider = Provider<bool>((ref) {
final usersState = ref.watch(usersProvider);
return usersState.users.isNotEmpty;
});
/// Provider to get users count
/// Usage: ref.watch(usersCountProvider)
final usersCountProvider = Provider<int>((ref) {
final usersState = ref.watch(usersProvider);
return usersState.users.length;
});
/// Provider to get users error
/// Returns null if no error
/// Usage: ref.watch(usersErrorProvider)
final usersErrorProvider = Provider<String?>((ref) {
final usersState = ref.watch(usersProvider);
return usersState.error;
});
/// ========================================================================
/// USAGE EXAMPLES
/// ========================================================================