import 'package:e_scan/backend/api/api_calls.dart'; import 'package:e_scan/backend/schema/auth/auth_model.dart'; import 'package:e_scan/backend/schema/user/user_struct.dart'; import 'package:e_scan/services/secure_storage.dart'; import 'package:e_scan/services/token_provider.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'login_page_model.freezed.dart'; /// The provider for the AuthViewModel, using Riverpod's StateNotifierProvider /// with autoDispose to manage the lifecycle of the view model. final loginPageModelProvider = StateNotifierProvider((ref) { return LoginPageModel( secureStorage: ref.read(sharedPrefsProvider), tokenProvider: ref.read(tokenProvider), userConnectedProvider: ref.read(userConnectedProvider), ); }); class LoginPageModel extends StateNotifier { /// Constructor initializes the TaskRepository using the provider reference. LoginPageModel({ required this.secureStorage, required this.tokenProvider, required this.userConnectedProvider, }) : super(const LoginPageState()); late FlutterSecureStorage secureStorage; late TokenProvider tokenProvider; final UserConnectedProvider userConnectedProvider; Future checkHasUserConnected() async { try { state = state.copyWith( loading: true, status: LoginPageStateStatus.logOut, ); final token = await secureStorage.read(key: TokenProvider.tokenKey); state = state.copyWith( loading: false, status: token != null ? LoginPageStateStatus.logged : LoginPageStateStatus.logOut, ); } catch (e) { debugPrint("Error reading secure storage, clearing storage..."); await secureStorage .deleteAll(); // Suppression des anciennes données en cas d'erreur } } Future signIn({ required String email, required String password, VoidCallback? onSuccess, VoidCallback? onError, }) async { try { state = state.copyWith(loading: true); final res = await ApiCalls.signIn(email: email, password: password); res.when( (auth) async { setTokenInLocal(auth); onSuccess?.call(); }, (error) { state = state.copyWith( loading: false, status: LoginPageStateStatus.logOut, ); onError?.call(); }, ); } catch (e) { state = state.copyWith( loading: false, status: LoginPageStateStatus.logOut, ); debugPrint("$e"); // Toast.showError(e.toString()); } } Future setTokenInLocal(AuthModel auth) async { await Future.wait([ tokenProvider.setToken(auth.accessToken ?? ''), tokenProvider.setRefreshToken(auth.accessToken ?? ''), userConnectedProvider.set( UserStruct( id: auth.uid.toString(), firstName: auth.name, lastName: auth.name, email: auth.username, ), ), ]); state = state.copyWith(loading: false, status: LoginPageStateStatus.logged); debugPrint(auth.accessToken); } Future logOut() async { await secureStorage.delete(key: TokenProvider.tokenKey); await checkHasUserConnected(); } } @freezed abstract class LoginPageState with _$LoginPageState { const factory LoginPageState({ @Default(LoginPageStateStatus.logOut) LoginPageStateStatus status, @Default(false) bool hasLangSelected, @Default(false) bool loading, @Default(false) bool googleSigninloading, }) = _LoginPageState; } enum LoginPageStateStatus { otpSent, logged, logOut } extension LoginPageStateStatusExt on LoginPageStateStatus { bool get isLogged => this == LoginPageStateStatus.logged; bool get isLogOut => this == LoginPageStateStatus.logOut; }