update api

This commit is contained in:
Phuoc Nguyen
2025-10-10 17:15:40 +07:00
parent b94c158004
commit 04f7042b8d
24 changed files with 3322 additions and 8 deletions

View 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;
}