update api
This commit is contained in:
215
lib/features/auth/presentation/providers/auth_provider.dart
Normal file
215
lib/features/auth/presentation/providers/auth_provider.dart
Normal file
@@ -0,0 +1,215 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import '../../../../core/di/injection_container.dart';
|
||||
import '../../domain/entities/user.dart';
|
||||
import '../../domain/repositories/auth_repository.dart';
|
||||
|
||||
part 'auth_provider.g.dart';
|
||||
|
||||
/// Provider for AuthRepository
|
||||
@riverpod
|
||||
AuthRepository authRepository(Ref ref) {
|
||||
return sl<AuthRepository>();
|
||||
}
|
||||
|
||||
/// Auth state class
|
||||
class AuthState {
|
||||
final User? user;
|
||||
final bool isAuthenticated;
|
||||
final bool isLoading;
|
||||
final String? errorMessage;
|
||||
|
||||
const AuthState({
|
||||
this.user,
|
||||
this.isAuthenticated = false,
|
||||
this.isLoading = false,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
AuthState copyWith({
|
||||
User? user,
|
||||
bool? isAuthenticated,
|
||||
bool? isLoading,
|
||||
String? errorMessage,
|
||||
}) {
|
||||
return AuthState(
|
||||
user: user ?? this.user,
|
||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Auth state notifier provider
|
||||
@riverpod
|
||||
class Auth extends _$Auth {
|
||||
@override
|
||||
AuthState build() {
|
||||
_checkAuthStatus();
|
||||
return const AuthState();
|
||||
}
|
||||
|
||||
AuthRepository get _repository => ref.read(authRepositoryProvider);
|
||||
|
||||
/// Check if user is authenticated on app start
|
||||
Future<void> _checkAuthStatus() async {
|
||||
state = state.copyWith(isLoading: true);
|
||||
|
||||
final isAuthenticated = await _repository.isAuthenticated();
|
||||
|
||||
if (isAuthenticated) {
|
||||
// Get user profile
|
||||
final result = await _repository.getProfile();
|
||||
result.fold(
|
||||
(failure) {
|
||||
state = const AuthState(
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
);
|
||||
},
|
||||
(user) {
|
||||
state = AuthState(
|
||||
user: user,
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state = const AuthState(
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Login user
|
||||
Future<bool> login({
|
||||
required String email,
|
||||
required String password,
|
||||
}) async {
|
||||
state = state.copyWith(isLoading: true, errorMessage: null);
|
||||
|
||||
final result = await _repository.login(email: email, password: password);
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: failure.message,
|
||||
);
|
||||
return false;
|
||||
},
|
||||
(authResponse) {
|
||||
state = AuthState(
|
||||
user: authResponse.user,
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
errorMessage: null,
|
||||
);
|
||||
return true;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Register new user
|
||||
Future<bool> register({
|
||||
required String name,
|
||||
required String email,
|
||||
required String password,
|
||||
List<String> roles = const ['user'],
|
||||
}) async {
|
||||
state = state.copyWith(isLoading: true, errorMessage: null);
|
||||
|
||||
final result = await _repository.register(
|
||||
name: name,
|
||||
email: email,
|
||||
password: password,
|
||||
roles: roles,
|
||||
);
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: failure.message,
|
||||
);
|
||||
return false;
|
||||
},
|
||||
(authResponse) {
|
||||
state = AuthState(
|
||||
user: authResponse.user,
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
errorMessage: null,
|
||||
);
|
||||
return true;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Get user profile (refresh user data)
|
||||
Future<void> getProfile() async {
|
||||
state = state.copyWith(isLoading: true, errorMessage: null);
|
||||
|
||||
final result = await _repository.getProfile();
|
||||
|
||||
result.fold(
|
||||
(failure) {
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: failure.message,
|
||||
);
|
||||
},
|
||||
(user) {
|
||||
state = state.copyWith(
|
||||
user: user,
|
||||
isLoading: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Refresh access token
|
||||
Future<bool> refreshToken() async {
|
||||
final result = await _repository.refreshToken();
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
// If token refresh fails, logout user
|
||||
logout();
|
||||
return false;
|
||||
},
|
||||
(authResponse) {
|
||||
state = state.copyWith(user: authResponse.user);
|
||||
return true;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Logout user
|
||||
Future<void> logout() async {
|
||||
state = state.copyWith(isLoading: true);
|
||||
|
||||
await _repository.logout();
|
||||
|
||||
state = const AuthState(
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Current authenticated user provider
|
||||
@riverpod
|
||||
User? currentUser(Ref ref) {
|
||||
final authState = ref.watch(authProvider);
|
||||
return authState.user;
|
||||
}
|
||||
|
||||
/// Is authenticated provider
|
||||
@riverpod
|
||||
bool isAuthenticated(Ref ref) {
|
||||
final authState = ref.watch(authProvider);
|
||||
return authState.isAuthenticated;
|
||||
}
|
||||
204
lib/features/auth/presentation/providers/auth_provider.g.dart
Normal file
204
lib/features/auth/presentation/providers/auth_provider.g.dart
Normal file
@@ -0,0 +1,204 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'auth_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Provider for AuthRepository
|
||||
|
||||
@ProviderFor(authRepository)
|
||||
const authRepositoryProvider = AuthRepositoryProvider._();
|
||||
|
||||
/// Provider for AuthRepository
|
||||
|
||||
final class AuthRepositoryProvider
|
||||
extends $FunctionalProvider<AuthRepository, AuthRepository, AuthRepository>
|
||||
with $Provider<AuthRepository> {
|
||||
/// Provider for AuthRepository
|
||||
const AuthRepositoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'authRepositoryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$authRepositoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<AuthRepository> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
AuthRepository create(Ref ref) {
|
||||
return authRepository(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(AuthRepository value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<AuthRepository>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$authRepositoryHash() => r'0483b13ac95333b56a1a82f6c9fdb64ae46f287d';
|
||||
|
||||
/// Auth state notifier provider
|
||||
|
||||
@ProviderFor(Auth)
|
||||
const authProvider = AuthProvider._();
|
||||
|
||||
/// Auth state notifier provider
|
||||
final class AuthProvider extends $NotifierProvider<Auth, AuthState> {
|
||||
/// Auth state notifier provider
|
||||
const AuthProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'authProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$authHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
Auth create() => Auth();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(AuthState value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<AuthState>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$authHash() => r'c88e150224fa855ed0ddfba30bef9e2b289f329d';
|
||||
|
||||
/// Auth state notifier provider
|
||||
|
||||
abstract class _$Auth extends $Notifier<AuthState> {
|
||||
AuthState build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<AuthState, AuthState>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<AuthState, AuthState>,
|
||||
AuthState,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Current authenticated user provider
|
||||
|
||||
@ProviderFor(currentUser)
|
||||
const currentUserProvider = CurrentUserProvider._();
|
||||
|
||||
/// Current authenticated user provider
|
||||
|
||||
final class CurrentUserProvider extends $FunctionalProvider<User?, User?, User?>
|
||||
with $Provider<User?> {
|
||||
/// Current authenticated user provider
|
||||
const CurrentUserProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'currentUserProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$currentUserHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<User?> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
User? create(Ref ref) {
|
||||
return currentUser(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(User? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<User?>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$currentUserHash() => r'4c8cb60cef35a4fd001291434558037d6c85faf5';
|
||||
|
||||
/// Is authenticated provider
|
||||
|
||||
@ProviderFor(isAuthenticated)
|
||||
const isAuthenticatedProvider = IsAuthenticatedProvider._();
|
||||
|
||||
/// Is authenticated provider
|
||||
|
||||
final class IsAuthenticatedProvider
|
||||
extends $FunctionalProvider<bool, bool, bool>
|
||||
with $Provider<bool> {
|
||||
/// Is authenticated provider
|
||||
const IsAuthenticatedProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'isAuthenticatedProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$isAuthenticatedHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<bool> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
bool create(Ref ref) {
|
||||
return isAuthenticated(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(bool value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<bool>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$isAuthenticatedHash() => r'003f7e85bfa5ae774792659ce771b5b59ebf04f8';
|
||||
Reference in New Issue
Block a user