import 'package:flutter/cupertino.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; import 'package:yimaru_app/app/app.locator.dart'; import 'package:yimaru_app/app/app.router.dart'; import 'package:yimaru_app/models/user.dart'; import '../../../services/api_service.dart'; import '../../../services/authentication_service.dart'; import '../../../services/google_auth_service.dart'; import '../../../services/status_checker_service.dart'; import '../../common/enmus.dart'; import '../../common/ui_helpers.dart'; class LoginViewModel extends ReactiveViewModel with FormStateHelper implements FormViewModel { final _apiService = locator(); final _statusChecker = locator(); final _navigationService = locator(); final _googleAuthService = locator(); final _authenticationService = locator(); @override List get listenableServices => [_googleAuthService]; // Google user GoogleSignInAccount? get _googleUser => _googleAuthService.googleUser; GoogleSignInAccount? get googleUser => _googleUser; // In-app navigation int _currentPage = 0; int get currentPage => _currentPage; // Email bool _focusEmail = false; bool get focusEmail => _focusEmail; // Password bool _focusPassword = false; bool get focusPassword => _focusPassword; bool _obscurePassword = true; bool get obscurePassword => _obscurePassword; // Phone number bool _focusPhoneNumber = false; bool get focusPhoneNumber => _focusPhoneNumber; // Focus otp bool _focusOtp = false; bool get focusOtp => _focusOtp; // Focus node final FocusNode _focusNode = FocusNode(); FocusNode get focusNode => _focusNode; // Resend button state bool _buttonActive = false; bool get buttonActive => _buttonActive; DateTime _resendTime = DateTime.now().add(const Duration(minutes: 3, seconds: 0)); DateTime get resendTime => _resendTime; // User data final Map _userData = {}; Map get userData => _userData; // Email void setEmailFocus() { _focusEmail = true; rebuildUi(); } // Password void setPasswordFocus() { _focusPassword = true; rebuildUi(); } void setObscurePassword() { _obscurePassword = !_obscurePassword; rebuildUi(); } // Phone number void setPhoneNumberFocus() { _focusPhoneNumber = true; rebuildUi(); } // Otp void setOtpFocus() { _focusOtp = true; rebuildUi(); } // Validate otp Future validateOtp(String otp) async {} void setResendButton() { _buttonActive = true; rebuildUi(); } void resetButton() { _buttonActive = false; _resendTime = DateTime.now().add(const Duration(minutes: 3, seconds: 0)); } // User data void clearUserData() { _userData.clear(); } void addUserData(Map data) { _userData.addAll(data); } // In app navigation void goBack() { if (_currentPage == 1) { _currentPage = 0; rebuildUi(); } else if (_currentPage == 2) { _currentPage = 1; rebuildUi(); } else { _navigationService.back(); } } void goTo(int page) { _currentPage = page; rebuildUi(); } // Navigation Future replaceWithHome() async => await _navigationService.clearStackAndShow(Routes.homeView); Future navigateToRegister() async => await _navigationService.navigateToRegisterView(); Future navigateToForgetPassword() async => await _navigationService.navigateToForgetPasswordView(); // Remote api calls // Login with email Future loginWithEmail() async => await runBusyFuture(_loginWithEmail(), busyObject: StateObjects.loginWithEmail); Future _loginWithEmail() async { if (await _statusChecker.checkConnection()) { Map response = await _apiService.login(_userData); if (response['status'] == ResponseStatus.success) { User user = response['data'] as User; Map data = { 'userId': user.userId, 'accessToken': user.accessToken, 'refreshToken': user.refreshToken }; await _authenticationService.saveUserCredential(data); clearUserData(); await replaceWithHome(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); } } } // Sign-in with google Future _googleAuth() async { if (await _statusChecker.checkConnection()) { await _googleAuthService.googleAuth(); Map data = { 'id_token': _googleUser?.authentication.idToken ?? '', }; Map response = await _apiService.googleAuth(data); if (response['status'] == ResponseStatus.success) { User user = response['data'] as User; Map data = { 'userId': user.userId, 'accessToken': user.accessToken, 'refreshToken': user.refreshToken }; await _authenticationService.saveUserCredential(data); clearUserData(); await replaceWithHome(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); } } } Future signInWithGoogle() async => await runBusyFuture(_googleAuth(), busyObject: StateObjects.loginWithGoogle); // Login with phone Future loginWithPhoneNumber() async => await runBusyFuture(_loginWithPhoneNumber(), busyObject: StateObjects.loginWithPhoneNumber); Future _loginWithPhoneNumber() async { if (await _statusChecker.checkConnection()) { Map response = await _apiService.resendOtp(_userData); if (response['status'] == ResponseStatus.success) { goTo(2); showSuccessToast(response['message']); } else { showErrorToast(response['message']); } } } // Verify otp Future _verifyOtp() async { if (await _statusChecker.checkConnection()) { Map response = await _apiService.verifyOtp(_userData); if (response['status'] == ResponseStatus.success) { User user = response['data'] as User; Map data = { 'userId': user.userId, 'accessToken': user.accessToken, 'refreshToken': user.refreshToken }; await _authenticationService.saveUserCredential(data); await replaceWithHome(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); } } } Future verifyOtp() async => await runBusyFuture(_verifyOtp(), busyObject: StateObjects.verifyOtp); // Resend otp Future _resendOtp() async { if (await _statusChecker.checkConnection()) { resetButton(); Map response = await _apiService.resendOtp(_userData); if (response['status'] == ResponseStatus.success) { showSuccessToast(response['message']); } else { showErrorToast(response['message']); } } } Future resendOtp() async => await runBusyFuture(_resendOtp(), busyObject: StateObjects.resendOtp); }