| import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
| import '../../../core/providers.dart';
|
| import '../data/auth_repository.dart';
|
| import '../domain/user_model.dart';
|
|
|
| enum AuthStatus { unknown, unauthenticated, authenticated }
|
|
|
| class AuthState {
|
| final AuthStatus status;
|
| final AppUser? user;
|
|
|
| const AuthState({this.status = AuthStatus.unknown, this.user});
|
|
|
| AuthState copyWith({AuthStatus? status, AppUser? user, bool clearUser = false}) {
|
| return AuthState(
|
| status: status ?? this.status,
|
| user: clearUser ? null : (user ?? this.user),
|
| );
|
| }
|
|
|
| String? get role => user?.role;
|
| }
|
|
|
| final authControllerProvider =
|
| NotifierProvider<AuthController, AuthState>(AuthController.new);
|
|
|
| class AuthController extends Notifier<AuthState> {
|
| AuthRepository get _repo => ref.read(authRepositoryProvider);
|
|
|
| @override
|
| AuthState build() {
|
|
|
| ref.read(dioClientProvider).onUnauthorized = () {
|
|
|
| logout();
|
| };
|
| return const AuthState();
|
| }
|
|
|
|
|
| Future<void> bootstrap() async {
|
| final token = await ref.read(tokenStorageProvider).readToken();
|
| if (token == null || token.isEmpty) {
|
| state = state.copyWith(status: AuthStatus.unauthenticated);
|
| return;
|
| }
|
| try {
|
| final user = await _repo.me();
|
| state = AuthState(status: AuthStatus.authenticated, user: user);
|
| } catch (_) {
|
| await ref.read(tokenStorageProvider).clear();
|
| state = state.copyWith(status: AuthStatus.unauthenticated, clearUser: true);
|
| }
|
| }
|
|
|
| Future<String?> sendOtp(String phone) => _repo.sendOtp(phone);
|
|
|
|
|
| Future<void> verifyOtp({
|
| required String phone,
|
| required String otp,
|
| required String role,
|
| String? name,
|
| }) async {
|
| final result = await _repo.verifyOtp(
|
| phone: phone,
|
| otp: otp,
|
| role: role,
|
| name: name,
|
| );
|
| await ref.read(tokenStorageProvider).save(
|
| token: result.accessToken,
|
| refreshToken: result.refreshToken,
|
| role: result.role,
|
| userId: result.userId,
|
| );
|
| final user = await _repo.me();
|
| state = AuthState(status: AuthStatus.authenticated, user: user);
|
| }
|
|
|
| void setUser(AppUser user) {
|
| state = state.copyWith(user: user);
|
| }
|
|
|
| Future<void> logout() async {
|
| final refresh = await ref.read(tokenStorageProvider).readRefresh();
|
| if (refresh != null && refresh.isNotEmpty) {
|
| await _repo.logout(refresh);
|
| }
|
| await ref.read(tokenStorageProvider).clear();
|
| state = const AuthState(status: AuthStatus.unauthenticated);
|
| }
|
| }
|
|
|