diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index fbd8e0f..7a29273 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -14,6 +14,10 @@ class AppState { set setIsAuthenticated(v) => isAuthenticated = v; + String deviceToken = ""; + + set setDeviceToken(v) => deviceToken = v; + String appAuthToken = ""; set setAppAuthToken(v) => appAuthToken = v; diff --git a/lib/core/cache_consts.dart b/lib/core/cache_consts.dart new file mode 100644 index 0000000..b793f02 --- /dev/null +++ b/lib/core/cache_consts.dart @@ -0,0 +1,75 @@ +class CacheConst { + static const String isRememberMe = "remember_me"; + static const String username = "doctorId"; + static const String password = "password"; + static const String logInTokenId = "logInTokenID"; + static const String vidaAuthTokenId = "vidaAuthTokenID"; + static const String vidaRefreshTokenId = "vidaRefreshTokenID"; + static const String authenticationTokenId = "authenticationTokenID"; + static const String projectId = "projectID"; + static const String clinicId = "clinicId"; + static const String lastLoginDate = "lastLoginDate"; + static const String lastLoginTime = "lastLoginTime"; + static const String memberModel = "memberModel"; + + static const String isShowOnboarding = "is_show_onboarding"; + static const String appAuthToken = "app_auth_token"; + static const String appUserId = "app_user_id"; + static const String loggedInUserObj = "logged_in_user_obj"; + + static const String pushToken = "push_token"; + static const String apnsToken = "apns_token"; + static const String voipToken = "voip_token"; + static const String patientMrn = "patient_mrn"; + + static const String loggedInUserId = "logged_in_user_id"; + static const String loggedInUserPassword = "logged_in_user_password"; + + static const String userLat = 'user-lat'; + static const String userLong = 'user-long'; + + static const String token = 'token'; + static const String appLanguage = 'language'; + static const String userProfile = 'user-profile'; + static const String oneSignalApnsToken = 'onesignal-apns-token'; + static const String registerDataForRegister = 'register-data-for-register'; + static const String loginTokenIdDuplicate = 'register-data-for-register'; + static const String registerDataForLogin = 'register-data-for-login'; + static const String lastLogin = 'last-login'; + static const String erCheckinRiskScore = 'er-checkin-risk-score'; + static const String onlySms = 'only-sms'; + static const String authData = 'auth-data'; + static const String imeiUserData = 'imei-user-data'; + static const String nhicData = 'nhic-data'; + static const String familyFile = 'family-file'; + static const String isGoToParking = 'IS_GO_TO_PARKING'; + static const String isSearchAppo = 'is-search-appo'; + static const String isLivecareAppointment = 'is_livecare_appointment'; + static const String isVibration = 'is_vibration'; + static const String themeValue = 'is_vibration'; + static const String mainUser = 'main-user'; + static const String pharmacyLastVisitedProducts = 'last-visited'; + static const String pharmacyCustomerId = 'costumer-id'; + static const String pharmacyCustomerGuid = 'customer-guid'; + static const String pharmacyCustomerObject = 'pharmacy-customer-object'; + static const String isRobotVisible = 'robot-visible'; + static const String isRobotInit = 'robot-init'; + static const String hmgGeofences = 'hmg-geo-fences'; + static const String weather = 'weather'; + static const String bloodType = 'blood-type'; + static const String notificationCount = 'notification-count'; + static const String pharmacySelectedAddress = 'selected-address'; + static const String pharmacyAutorzieToken = 'PHARMACY_AUTORZIE_TOKEN'; + static const String h2oUnit = 'H2O_UNIT'; + static const String h2oReminder = 'H2O_REMINDER'; + static const String livecareClinicData = 'LIVECARE_CLINIC_DATA'; + static const String doctorScheduleDateSel = 'DOCTOR_SCHEDULE_DATE_SEL'; + static const String appointmentHistoryMedical = 'APPOINTMENT_HISTORY_MEDICAL'; + static const String clinicsList = 'CLINICS_LIST'; + static const String covidQaList = 'COVID_QA_LIST'; + static const String isCovidConsentShown = 'IS_COVID_CONSENT_SHOWN'; + static const String registerInfoDubai = 'register-info-dubai'; + static const String isLastAppointmentRateShown = 'is-last-appointment-rate-shown'; + static const String patientOccupationList = 'patient-occupation-list'; + static const String hasEnabledQuickLogin = 'has-enabled-quick-login'; +} diff --git a/lib/core/consts.dart b/lib/core/consts.dart deleted file mode 100644 index 216b9a7..0000000 --- a/lib/core/consts.dart +++ /dev/null @@ -1,32 +0,0 @@ - - -class SharedPrefsConsts { - static String isRememberMe = "remember_me"; - static String username = "doctorId"; - static String password = "password"; - static String logInTokenID = "logInTokenID"; - static String vidaAuthTokenID = "vidaAuthTokenID"; - static String vidaRefreshTokenID = "vidaRefreshTokenID"; - static String authenticationTokenID = "authenticationTokenID"; - static String projectID = "projectID"; - static String clinicId = "clinicId"; - static String lastLoginDate = "lastLoginDate"; - static String lastLoginTime = "lastLoginTime"; - static String memberModel = "memberModel"; - - static String isShowOnboarding = "is_show_onboarding"; - static String appAuthToken = "app_auth_token"; - static String appUserID = "app_user_id"; - static String loggedInUserObj = "logged_in_user_obj"; - - static String PUSH_TOKEN = "push_token"; - static String APNS_TOKEN = "apns_token"; - static String VOIP_TOKEN = "voip_token"; - static String PATIENT_MRN = "patient_mrn"; - - static String loggedInUserID = "logged_in_user_id"; - static String loggedInUserPassword = "logged_in_user_password"; - - static String user_lat = 'user-lat'; - static String user_long = 'user-long'; -} diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index 549eeed..b878ce5 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -1,3 +1,4 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; @@ -11,6 +12,7 @@ import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/services/firebase_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:logger/web.dart'; @@ -32,9 +34,16 @@ class AppDependencies { // Core Services getIt.registerLazySingleton(() => LoggerServiceImp(logger: logger)); + getIt.registerLazySingleton(() => FirebaseServiceImpl( + loggerService: getIt(), + appState: getIt(), + firebaseMessaging: FirebaseMessaging.instance, + )); + getIt.registerLazySingleton(() => NavigationService()); getIt.registerLazySingleton(() => GAnalytics()); getIt.registerLazySingleton(() => AppState(navigationService: getIt())); + getIt.registerLazySingleton(() => AppState(navigationService: getIt())); getIt.registerLazySingleton(() => LocationUtils( isShowConfirmDialog: false, navigationService: getIt(), @@ -48,14 +57,13 @@ class AppDependencies { )); final sharedPreferences = await SharedPreferences.getInstance(); - getIt.registerLazySingleton(() => CacheServiceImp(sharedPreferences: sharedPreferences)); + getIt.registerLazySingleton(() => CacheServiceImp(sharedPreferences: sharedPreferences, loggerService: getIt())); getIt.registerLazySingleton(() => ApiClientImp(loggerService: getIt(), dialogService: getIt(), appState: getIt())); // Repositories getIt.registerLazySingleton(() => CommonRepoImp(loggerService: getIt())); getIt.registerLazySingleton(() => AuthenticationRepoImp(loggerService: getIt(), apiClient: getIt())); - getIt.registerLazySingleton( - () => BookAppointmentsRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => BookAppointmentsRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => MyAppointmentsRepoImp(loggerService: getIt(), apiClient: getIt())); // ViewModels @@ -63,6 +71,8 @@ class AppDependencies { getIt.registerLazySingleton( () => AuthenticationViewModel( authenticationRepo: getIt(), + cacheService: getIt(), + navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), diff --git a/lib/core/location_util.dart b/lib/core/location_util.dart index dc6a0d6..d556034 100644 --- a/lib/core/location_util.dart +++ b/lib/core/location_util.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; -import 'package:hmg_patient_app_new/core/consts.dart'; +import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -143,8 +143,8 @@ class LocationUtils { } void setLocation(Position? position) { - Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, position?.latitude ?? 0.0); - Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, position?.longitude ?? 0.0); + Utils.saveNumFromPrefs(CacheConst.userLat, position?.latitude ?? 0.0); + Utils.saveNumFromPrefs(CacheConst.userLong, position?.longitude ?? 0.0); appState.setUserLat = position?.latitude ?? 0.0; appState.setUserLong = position?.longitude ?? 0.0; @@ -153,8 +153,8 @@ class LocationUtils { } void setZeroLocation() { - Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, 0.0); - Utils.saveNumFromPrefs(SharedPrefsConsts.user_lat, 0.0); + Utils.saveNumFromPrefs(CacheConst.userLat, 0.0); + Utils.saveNumFromPrefs(CacheConst.userLong, 0.0); appState.setUserLat = 0.0; appState.setUserLong = 0.0; diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart index b5a816e..1d2141e 100644 --- a/lib/core/utils/push_notification_handler.dart +++ b/lib/core/utils/push_notification_handler.dart @@ -15,7 +15,7 @@ import 'package:hmg_patient_app_new/core/utils/local_notifications.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:permission_handler/permission_handler.dart'; -import '../consts.dart'; +import '../cache_consts.dart'; // |--> Push Notification Background @pragma('vm:entry-point') @@ -256,7 +256,7 @@ class PushNotificationHandler { final permission = await FirebaseMessaging.instance.requestPermission(); await FirebaseMessaging.instance.getAPNSToken().then((value) async { log("APNS token: " + value.toString()); - await Utils.saveStringFromPrefs(SharedPrefsConsts.APNS_TOKEN, value.toString()); + await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString()); }); await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, // Required to display a heads up notification @@ -269,11 +269,11 @@ class PushNotificationHandler { try { FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async { if (message != null) { - if (Platform.isIOS) + if (Platform.isIOS) { await Future.delayed(Duration(milliseconds: 3000)).then((value) { if (message != null) newMessage(message); }); - else if (message != null) newMessage(message); + } else if (message != null) newMessage(message); } }); } catch (ex) {} @@ -281,22 +281,24 @@ class PushNotificationHandler { FirebaseMessaging.onMessage.listen((RemoteMessage message) async { print("Firebase onMessage!!!"); // showCallkitIncoming(); - if (Platform.isIOS) + if (Platform.isIOS) { await Future.delayed(Duration(milliseconds: 3000)).then((value) { newMessage(message); }); - else + } else { newMessage(message); + } }); FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { print("Firebase onMessageOpenedApp!!!"); - if (Platform.isIOS) + if (Platform.isIOS) { await Future.delayed(Duration(milliseconds: 3000)).then((value) { newMessage(message); }); - else + } else { newMessage(message); + } }); FirebaseMessaging.instance.getToken().then((String? token) { @@ -350,7 +352,7 @@ class PushNotificationHandler { onToken(String token) async { print("Push Notification Token: " + token); - await Utils.saveStringFromPrefs(SharedPrefsConsts.PUSH_TOKEN, token); + await Utils.saveStringFromPrefs(CacheConst.pushToken, token); } onResume() async { @@ -363,9 +365,7 @@ class PushNotificationHandler { Future requestPermissions() async { try { if (Platform.isIOS) { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation() - ?.requestPermissions(alert: true, badge: true, sound: true); + await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); } else if (Platform.isAndroid) { Map statuses = await [ Permission.notification, diff --git a/lib/core/utils/size_config.dart b/lib/core/utils/size_config.dart index 9c09b09..9f9d835 100644 --- a/lib/core/utils/size_config.dart +++ b/lib/core/utils/size_config.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; -import 'package:hmg_patient_app_new/core/consts.dart'; +import 'package:hmg_patient_app_new/core/cache_consts.dart'; class SizeConfig { static double _blockWidth = 0; diff --git a/lib/extensions/route_extensions.dart b/lib/extensions/route_extensions.dart index 71f5d2d..0dcc54b 100644 --- a/lib/extensions/route_extensions.dart +++ b/lib/extensions/route_extensions.dart @@ -20,4 +20,8 @@ extension NavigationExtensions on BuildContext { void navigateTo(Widget page) { Navigator.push(this, MaterialPageRoute(builder: (context) => page)); } + + void popUntilNamed(String routeName) { + Navigator.popUntil(this, ModalRoute.withName(routeName)); + } } diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 0be6eaf..6459eff 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -20,7 +20,17 @@ abstract class AuthenticationRepo { required CheckPatientAuthenticationReq checkPatientAuthenticationReq, }); - Future>> sendActivationCodeRegister({required CheckPatientAuthenticationReq checkPatientAuthenticationReq, String? languageID}); + Future>> sendActivationCodeRepo({ + required CheckPatientAuthenticationReq checkPatientAuthenticationReq, + String? languageID, + bool isRegister = false, + }); + + Future>> checkActivationCodeRepo({ + required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq + required String? activationCode, + required bool isRegister, + }); } class AuthenticationRepoImp implements AuthenticationRepo { @@ -74,8 +84,8 @@ class AuthenticationRepoImp implements AuthenticationRepo { String? languageID, }) async { int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1; - //TODO : We will use all these from AppState directly in the ApiClient + //TODO : We will use all these from AppState directly in the ApiClient checkPatientAuthenticationReq.versionID = VERSION_ID; checkPatientAuthenticationReq.channel = CHANNEL; checkPatientAuthenticationReq.iPAdress = IP_ADDRESS; @@ -113,24 +123,31 @@ class AuthenticationRepoImp implements AuthenticationRepo { } @override - Future>> sendActivationCodeRegister({required CheckPatientAuthenticationReq checkPatientAuthenticationReq, String? languageID}) async { + Future>> sendActivationCodeRepo({ + required CheckPatientAuthenticationReq checkPatientAuthenticationReq, + String? languageID, + bool isRegister = false, + }) async { int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1; - //TODO : We will use all these from AppState directly in the ApiClient + //TODO : We will use all these from AppState directly in the ApiClient checkPatientAuthenticationReq.versionID = VERSION_ID; checkPatientAuthenticationReq.channel = CHANNEL; checkPatientAuthenticationReq.iPAdress = IP_ADDRESS; checkPatientAuthenticationReq.generalid = GENERAL_ID; - checkPatientAuthenticationReq.languageID = (languageID == 'ar' ? 1 : 2); + checkPatientAuthenticationReq.languageID = isRegister ? (languageID == 'ar' ? 1 : 2) : 2; checkPatientAuthenticationReq.deviceTypeID = Platform.isIOS ? 1 : 2; checkPatientAuthenticationReq.patientOutSA = isOutKsa; checkPatientAuthenticationReq.isDentalAllowedBackend = false; + // Pick correct endpoint + try { GenericApiModel? apiResponse; Failure? failure; + await apiClient.post( - SEND_ACTIVATION_CODE_REGISTER, + isRegister ? SEND_ACTIVATION_CODE_REGISTER : SEND_ACTIVATION_CODE, body: checkPatientAuthenticationReq.toJson(), onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -148,6 +165,60 @@ class AuthenticationRepoImp implements AuthenticationRepo { } }, ); + + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future>> checkActivationCodeRepo({ + required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq + required String? activationCode, + required bool isRegister, + }) async { + newRequest.activationCode = activationCode ?? "0000"; + newRequest.isSilentLogin = activationCode != null ? false : true; + + newRequest.versionID = VERSION_ID; + newRequest.channel = CHANNEL; + newRequest.iPAdress = IP_ADDRESS; + newRequest.generalid = GENERAL_ID; + newRequest.deviceTypeID = Platform.isIOS ? 1 : 2; + newRequest.projectOutSA = newRequest.zipCode == '966' ? false : true; + newRequest.isDentalAllowedBackend = false; + newRequest.forRegisteration = newRequest.isRegister ?? false; + newRequest.isRegister = false; + + final endpoint = isRegister ? CHECK_ACTIVATION_CODE_REGISTER : CHECK_ACTIVATION_CODE; + + try { + GenericApiModel? apiResponse; + Failure? failure; + + await apiClient.post( + endpoint, + body: newRequest.toJson(), + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); if (apiResponse == null) return Left(ServerFailure("Unknown error")); return Right(apiResponse!); diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 10038ba..4c9de27 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -1,24 +1,35 @@ import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/request_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart'; import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_patient_authentication_request_model.dart'; +import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart'; +import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; +import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; +import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; class AuthenticationViewModel extends ChangeNotifier { AuthenticationRepo authenticationRepo; AppState appState; ErrorHandlerService errorHandlerService; DialogService dialogService; + NavigationService navigationService; + CacheService cacheService; AuthenticationViewModel({ required this.appState, required this.authenticationRepo, required this.errorHandlerService, required this.dialogService, + required this.navigationService, + required this.cacheService, }); final TextEditingController nationalIdController = TextEditingController(); @@ -26,29 +37,96 @@ class AuthenticationViewModel extends ChangeNotifier { void login() { if (ValidationUtils.isValidatePhoneAndId(nationalId: nationalIdController.text, phoneNumber: phoneNumberController.text)) { - } else { - - } + } else {} } - Future selectDeviceImei({Function(dynamic)? onSuccess, Function(String)? onError}) async { - String firebaseToken = "dOGRRszQQMGe_9wA5Hx3kO:APA91bFV5IcIJXvcCXXk0tc2ddtZgWwCPq7sGSuPr-YW7iiJpQZKgFGN9GAzCVOWL8MfheaP1slE8MdxB7lczdPBGdONQ7WbMmhgHcsUCUktq-hsapGXXqc"; + //checkUserAuthentication(); + bool isDubai = false; + bool authenticated = false; + late int mobileNumber; + String errorMsg = ''; + var registerd_data; + bool isMoreOption = false; + var zipCode; + var patientOutSA; + var loginTokenID; + var loginType; + var deviceToken; + var lastLogin; + final FocusNode myFocusNode = FocusNode(); + late int selectedOption = 1; + bool onlySMSBox = false; + int fingrePrintBefore = 0; + var dob; + late int isHijri; + var healthId; + + Future selectDeviceImei({required Function(dynamic data) onSuccess, Function(String)? onError}) async { + String firebaseToken = appState.deviceToken == "" + ? "dOGRRszQQMGe_9wA5Hx3kO:APA91bFV5IcIJXvcCXXk0tc2ddtZgWwCPq7sGSuPr-YW7iiJpQZKgFGN9GAzCVOWL8MfheaP1slE8MdxB7lczdPBGdONQ7WbMmhgHcsUCUktq-hsapGXXqc" + : appState.deviceToken; final result = await authenticationRepo.selectDeviceByImei(firebaseToken: firebaseToken); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) { - if (apiResponse.messageStatus == 2) { - //TODO: NEXT CREATION - dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); - } else if (apiResponse.messageStatus == 1) { - //todo: move to next api call + if (apiResponse.messageStatus == 1) { + onSuccess(apiResponse.data); + } else if (apiResponse.messageStatus == 2) { + dialogService.showErrorDialog(message: "Message Status = 2", onOkPressed: () {}); } }, ); } - Future checkUserAuthentication({OTPTypeEnum otpTypeEnum, Function(dynamic)? onSuccess, Function(String)? onError}) async { + Future onLoginPressed() async { + var data = await cacheService.getObject(key: CacheConst.imeiUserData); + //TODO: Why??? + cacheService.remove(key: CacheConst.registerDataForLogin); + if (data != null) { + SelectDeviceByImeiRespModelElement savedData = SelectDeviceByImeiRespModelElement.fromJson(data); + // TODO : SavedLogin Page is not there or renamed. + // navigationService.pushPage(page: SavedLogin(savedData)); + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (BuildContext context) => SavedLogin(savedData), + // ), + // ); + } else { + // Todo: Show Loader Here + // GifLoaderDialogUtils.showMyDialog(context); + + selectDeviceImei( + onSuccess: (dynamic respData) async { + var data = await cacheService.getObject(key: CacheConst.imeiUserData); + if (respData != null) { + cacheService.saveObject(key: CacheConst.imeiUserData, value: respData); + + // SelectDeviceByImeiRespModelElement savedData = SelectDeviceByImeiRespModelElement.fromJson(data); + // setUserValues(value); + // TODO : SavedLogin Page is not there or renamed. + // navigationService.pushPage(page: SavedLogin(savedData)); + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (BuildContext context) => SavedLogin(savedData), + // ), + // ); + } else { + //Todo: Hide Loader Here + // GifLoaderDialogUtils.hideDialog(context); + navigationService.pushPage(page: LoginScreen()); + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (BuildContext context) => WelcomeLogin(), + // ), + // ); + } + }, + ); + } + } + + Future checkUserAuthentication({required OTPTypeEnum otpTypeEnum, Function(dynamic)? onSuccess, Function(String)? onError}) async { CheckPatientAuthenticationReq checkPatientAuthenticationReq = RequestUtils.getCommonRequestWelcome( phoneNumber: '0567184134', otpTypeEnum: OTPTypeEnum.sms, @@ -60,37 +138,6 @@ class AuthenticationViewModel extends ChangeNotifier { nationIdText: '1234567890', countryCode: 'SA', ); -// Future checkUserAuthentication({Function(dynamic)? onSuccess, Function(String)? onError}) async { -// CheckPatientAuthenticationReq checkPatientAuthenticationReq = RequestUtils.getCommonRequestWelcome( -// phoneNumber: '0567184134', -// otpTypeEnum: OTPTypeEnum.sms, -// deviceToken: 'dummyDeviceToken123', -// patientOutSA: true, -// loginTokenID: 'dummyLoginToken456', -// registeredData: null, -// patientId: 12345, -// nationIdText: '1234567890', -// countryCode: 'SA', -// ); -// -// final result = await authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); -// result.fold( -// (failure) async => await errorHandlerService.handleError(failure: failure), -// (apiResponse) { -// if (apiResponse.data['isSMSSent']) { -// // TODO: set this in AppState -// // sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']); -// // loginTokenID = value['LogInTokenID'], -// // sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), -// sendActivationCode(type); -// } else { -// if (apiResponse.data['IsAuthenticated']) { -// checkActivationCode(onWrongActivationCode: (String? message) {}); -// } -// } -// }, -// ); -// } final result = await authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); result.fold( @@ -104,71 +151,153 @@ class AuthenticationViewModel extends ChangeNotifier { sendActivationCode(otpTypeEnum: otpTypeEnum); } else { if (apiResponse.data['IsAuthenticated']) { - checkActivationCode(onWrongActivationCode: (String? message) {}); + checkActivationCode(onWrongActivationCode: (String? message) {}, activationCode: 0000); } } }, ); } -// Future sendActivationCode({required OTPTypeEnum otpTypeEnum}) async { -// var request = RequestUtils.getCommonRequestAuthProvider( -// otpTypeEnum: otpTypeEnum, -// registeredData: null, -// deviceToken: "dummyLoginToken456", -// mobileNumber: "0567184134", -// zipCode: "SA", -// patientOutSA: true, -// loginTokenID: "dummyLoginToken456", -// selectedOption: selectedOption, -// patientId: 12345, -// ); -// -// request.sMSSignature = await SMSOTP.getSignature(); -// selectedOption = type; -// // GifLoaderDialogUtils.showMyDialog(context); -// if (healthId != null || isDubai) { -// if (!isDubai) { -// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); -// } -// request.healthId = healthId; -// request.isHijri = isHijri; -// await this.apiClient.sendActivationCodeRegister(request).then((result) { -// // GifLoaderDialogUtils.hideDialog(context); -// if (result != null && result['isSMSSent'] == true) { -// this.startSMSService(type); -// } -// }).catchError((r) { -// GifLoaderDialogUtils.hideDialog(context); -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: r.toString(), -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// )); -// // AppToast.showErrorToast(message: r); -// }); -// } else { -// request.dob = ""; -// request.healthId = ""; -// request.isHijri = 0; -// await this.authService.sendActivationCode(request).then((result) { -// GifLoaderDialogUtils.hideDialog(context); -// if (result != null && result['isSMSSent'] == true) { -// this.startSMSService(type); -// } -// }).catchError((r) { -// GifLoaderDialogUtils.hideDialog(context); -// context.showBottomSheet( -// child: ExceptionBottomSheet( -// message: r.toString(), -// onOkPressed: () { -// Navigator.of(context).pop(); -// }, -// )); -// // AppToast.showErrorToast(message: r.toString()); -// }); -// } -// } + Future sendActivationCode({ + required OTPTypeEnum otpTypeEnum, + }) async { + var request = RequestUtils.getCommonRequestAuthProvider( + otpTypeEnum: otpTypeEnum, + registeredData: null, + deviceToken: "dummyLoginToken456", + mobileNumber: "0567184134", + zipCode: "SA", + patientOutSA: true, + loginTokenID: "dummyLoginToken456", + selectedOption: otpTypeEnum.toInt(), + patientId: 12345, + ); + + // TODO: GET APP SMS SIGNATURE HERE + request.sMSSignature = ""; + // GifLoaderDialogUtils.showMyDialog(context); + + bool isForRegister = healthId != null || isDubai; + if (isForRegister) { + if (!isDubai) { + request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); + } + request.healthId = healthId; + request.isHijri = isHijri; + } else { + request.dob = ""; + request.healthId = ""; + request.isHijri = 0; + } + + final resultEither = await authenticationRepo.sendActivationCodeRepo( + checkPatientAuthenticationReq: request, + isRegister: isForRegister, + languageID: 'er', + ); + resultEither.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.data != null && apiResponse.data['isSMSSent'] == true) { + // startSMSService(otpTypeEnum.toInt()); + navigateToOTPScreen(otpTypeEnum: otpTypeEnum, phoneNumber: request.mobileNumber); + } + }, + ); + } + + Future checkActivationCode({ + required int activationCode, + required Function(String? message) onWrongActivationCode, + }) async { + final request = RequestUtils.getCommonRequestWelcome( + phoneNumber: '0567184134', + otpTypeEnum: OTPTypeEnum.sms, + deviceToken: 'dummyDeviceToken123', + patientOutSA: true, + loginTokenID: 'dummyLoginToken456', + registeredData: null, + patientId: 12345, + nationIdText: '1234567890', + countryCode: 'SA', + ).toJson(); + dynamic res; + + bool isForRegister = healthId != null || isDubai; + if (isForRegister) { + if (isDubai) request['DOB'] = dob; + request['HealthId'] = healthId; + request['IsHijri'] = isHijri; + + final resultEither = await authenticationRepo.checkActivationCodeRepo( + newRequest: request, + activationCode: activationCode.toString(), + isRegister: true, + ); + res = resultEither; + + resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) { + final activation = CheckActivationCode.fromJson(apiResponse.data as Map); + if (registerd_data?.isRegister == true) { + navigationService.popUntilNamed(AppRoutes.registerNewScreen); + // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)); + return; + } + }); + } else { + final resultEither = await authenticationRepo.checkActivationCodeRepo( + newRequest: request, + activationCode: activationCode.toString(), + isRegister: false, + ); + res = resultEither; + + resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) { + final activation = CheckActivationCode.fromJson(resultEither as Map); + if (activation.errorCode == '699') { + // Todo: Hide Loader + // GifLoaderDialogUtils.hideDialog(context); + onWrongActivationCode(activation.errorEndUserMessage); + return; + } else if (registerd_data?.isRegister == true) { + navigationService.popUntilNamed(AppRoutes.registerNewScreen); + // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)); + return; + } else { + // TODO: setPreferences and stuff + // sharedPref.remove(FAMILY_FILE); + // activation.list!.isFamily = false; + // userData = activation.list; + // sharedPref.setString(BLOOD_TYPE, activation.patientBloodType ?? ""); + // authenticatedUserObject.user = activation.list!; + // projectViewModel.setPrivilege(privilegeList: res); + // await sharedPref.setObject(MAIN_USER, activation.list); + // await sharedPref.setObject(USER_PROFILE, activation.list); + // loginTokenID = activation.logInTokenID; + // await sharedPref.setObject(LOGIN_TOKEN_ID, activation.logInTokenID); + // await sharedPref.setString(TOKEN, activation.authenticationTokenID!); + // checkIfUserAgreedBefore(activation); + // projectViewModel.analytics.loginRegistration.login_successful(); + } + }); + } + } + + Future navigateToOTPScreen({required OTPTypeEnum otpTypeEnum, required String phoneNumber}) async { + navigationService.pushToOtpScreen( + phoneNumber: phoneNumber, + checkActivationCode: (int activationCode) async { + await checkActivationCode( + activationCode: activationCode, + onWrongActivationCode: (String? value) { + onWrongActivationCode(message: value); + }); + }, + onResendOTPPressed: (String phoneNumber) {}, + ); + } + + Future onWrongActivationCode({String? message}) async { + // TODO: HANDLE THIS VIA BOTTOM SHEET + } } diff --git a/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart b/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart new file mode 100644 index 0000000..d752a13 --- /dev/null +++ b/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart @@ -0,0 +1,121 @@ +class CheckActivationCodeRegisterReq { + int? patientMobileNumber; + String? mobileNo; + String? deviceToken; + bool? projectOutSA; + int? loginType; + String? zipCode; + bool? isRegister; + String? logInTokenID; + int? searchType; + int? patientID; + String? nationalID; + String? patientIdentificationID; + String? activationCode; + bool? isSilentLogin; + double? versionID; + int? channel; + int? languageID; + String? iPAdress; + String? generalid; + int? patientOutSA; + dynamic sessionID; + bool? isDentalAllowedBackend; + int? deviceTypeID; + bool? forRegisteration; + String? dob; + int? isHijri; + String? healthId; + + CheckActivationCodeRegisterReq({ + this.patientMobileNumber, + this.mobileNo, + this.deviceToken, + this.projectOutSA, + this.loginType, + this.zipCode, + this.isRegister, + this.logInTokenID, + this.searchType, + this.patientID, + this.nationalID, + this.patientIdentificationID, + this.activationCode, + this.isSilentLogin, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.forRegisteration, + this.dob, + this.isHijri, + this.healthId, + }); + + CheckActivationCodeRegisterReq.fromJson(Map json) { + patientMobileNumber = json['PatientMobileNumber']; + mobileNo = json['MobileNo']; + deviceToken = json['DeviceToken']; + projectOutSA = json['ProjectOutSA']; + loginType = json['LoginType']; + zipCode = json['ZipCode']; + isRegister = json['isRegister']; + logInTokenID = json['LogInTokenID']; + searchType = json['SearchType']; + patientID = json['PatientID']; + nationalID = json['NationalID']; + patientIdentificationID = json['PatientIdentificationID']; + activationCode = json['activationCode']; + isSilentLogin = json['IsSilentLogin']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + forRegisteration = json['ForRegisteration']; + dob = json['DOB']; + isHijri = json['IsHijri']; + healthId = json['HealthId']; + } + + Map toJson() { + final Map data = {}; + data['PatientMobileNumber'] = patientMobileNumber; + data['MobileNo'] = mobileNo; + data['DeviceToken'] = deviceToken; + data['ProjectOutSA'] = projectOutSA; + data['LoginType'] = loginType; + data['ZipCode'] = zipCode; + data['isRegister'] = isRegister; + data['LogInTokenID'] = logInTokenID; + data['SearchType'] = searchType; + data['PatientID'] = patientID; + data['NationalID'] = nationalID; + data['PatientIdentificationID'] = patientIdentificationID; + data['activationCode'] = activationCode; + data['IsSilentLogin'] = isSilentLogin; + data['VersionID'] = versionID; + data['Channel'] = channel; + data['LanguageID'] = languageID; + data['IPAdress'] = iPAdress; + data['generalid'] = generalid; + data['PatientOutSA'] = patientOutSA; + data['SessionID'] = sessionID; + data['isDentalAllowedBackend'] = isDentalAllowedBackend; + data['DeviceTypeID'] = deviceTypeID; + data['ForRegisteration'] = forRegisteration; + data['DOB'] = dob; + data['IsHijri'] = isHijri; + data['HealthId'] = healthId; + return data; + } +} diff --git a/lib/widgets/otp/otp.dart b/lib/features/authentication/widgets/otp_verification_screen.dart similarity index 92% rename from lib/widgets/otp/otp.dart rename to lib/features/authentication/widgets/otp_verification_screen.dart index 5cfd3e9..5ff4fdf 100644 --- a/lib/widgets/otp/otp.dart +++ b/lib/features/authentication/widgets/otp_verification_screen.dart @@ -1,20 +1,28 @@ import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; -class OTPVerificationPage extends StatefulWidget { +class OTPVerificationScreen extends StatefulWidget { final String phoneNumber; + final Function(int code) checkActivationCode; + final Function(String phoneNumber) onResendOTPPressed; - const OTPVerificationPage({Key? key, required this.phoneNumber}) : super(key: key); + const OTPVerificationScreen({ + super.key, + required this.phoneNumber, + required this.checkActivationCode, + required this.onResendOTPPressed, + }); @override - State createState() => _OTPVerificationPageState(); + State createState() => _OTPVerificationScreenState(); } -class _OTPVerificationPageState extends State { +class _OTPVerificationScreenState extends State { final int _otpLength = 4; late final List _controllers; late final List _focusNodes; @@ -40,8 +48,12 @@ class _OTPVerificationPageState extends State { @override void dispose() { - for (final c in _controllers) c.dispose(); - for (final f in _focusNodes) f.dispose(); + for (final c in _controllers) { + c.dispose(); + } + for (final f in _focusNodes) { + f.dispose(); + } _resendTimer?.cancel(); super.dispose(); } diff --git a/lib/main.dart b/lib/main.dart index bb4332b..f528886 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -60,6 +60,8 @@ void main() async { appState: getIt(), dialogService: getIt(), errorHandlerService: getIt(), + navigationService: getIt(), + cacheService: getIt(), ), ), ], child: MyApp()), diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index b445631..af90758 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -15,9 +15,7 @@ import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; import 'package:hmg_patient_app_new/widgets/bottomsheet/generic_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart' show CustomButton; import 'package:hmg_patient_app_new/widgets/dropdown/country_dropdown_widget.dart'; -import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:hmg_patient_app_new/widgets/otp/otp.dart'; class RegisterNew extends StatefulWidget { @override @@ -68,12 +66,7 @@ class _RegisterNew extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.showLottie(context: context, - assetPath: 'assets/animations/lottie/register.json', - width: 200.h, - height: 200.h, - fit: BoxFit.cover, - repeat: true), + Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.h, height: 200.h, fit: BoxFit.cover, repeat: true), SizedBox(height: 16.h), LocaleKeys.prepareToElevate.tr().toText32(isBold: true), SizedBox(height: 24.h), @@ -207,109 +200,103 @@ class _RegisterNew extends State { isDismissible: false, useSafeArea: true, backgroundColor: Colors.transparent, - builder: (bottomSheetContext) => - Padding( - padding: EdgeInsets.only(bottom: MediaQuery - .of(bottomSheetContext) - .viewInsets - .bottom), - child: SingleChildScrollView( - child: GenericBottomSheet( - countryCode: "966", - initialPhoneNumber: "", - textController: TextEditingController(), - onChange: (String? value) {}, - buttons: [ - Padding( - padding: const EdgeInsets.only(bottom: 10), - child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute(builder: (BuildContext context) => OTPVerificationPage(phoneNumber: '12234567',))); + builder: (bottomSheetContext) => Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), + child: SingleChildScrollView( + child: GenericBottomSheet( + countryCode: "966", + initialPhoneNumber: "", + textController: TextEditingController(), + onChange: (String? value) {}, + buttons: [ + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton( + text: LocaleKeys.sendOTPSMS.tr(), + onPressed: () { + // TODO: MOVE TO OTP SCREEN - - // if (mobileNo.isEmpty) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else if (!Utils.validateMobileNumber(mobileNo)) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterValidMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else { - // registerUser(1); - // } - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedBorderColor, - textColor: AppColors.whiteColor, - icon: AppAssets.message, - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 8.h), - child: LocaleKeys.oR.tr().toText16(color: AppColors.textColor), - ), - ], - ), + // if (mobileNo.isEmpty) { + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: TranslationBase.of(context).pleaseEnterMobile, + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // } else if (!Utils.validateMobileNumber(mobileNo)) { + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: TranslationBase.of(context).pleaseEnterValidMobile, + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // } else { + // registerUser(1); + // } + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedBorderColor, + textColor: AppColors.whiteColor, + icon: AppAssets.message, + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ Padding( - padding: EdgeInsets.only(bottom: 10.h, top: 10.h), - child: CustomButton( - text: LocaleKeys.sendOTPWHATSAPP.tr(), - onPressed: () { - // if (mobileNo.isEmpty) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else if (!Utils.validateMobileNumber(mobileNo)) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterValidMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else { - // registerUser(4); - // } - // int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, mobileNo, context); - // registerUser(val); - }, - backgroundColor: AppColors.whiteColor, - borderColor: AppColors.borderOnlyColor, - textColor: AppColors.textColor, - icon: AppAssets.whatsapp, - ), + padding: EdgeInsets.symmetric(horizontal: 8.h), + child: LocaleKeys.oR.tr().toText16(color: AppColors.textColor), ), ], ), - ), + Padding( + padding: EdgeInsets.only(bottom: 10.h, top: 10.h), + child: CustomButton( + text: LocaleKeys.sendOTPWHATSAPP.tr(), + onPressed: () { + // if (mobileNo.isEmpty) { + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: TranslationBase.of(context).pleaseEnterMobile, + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // } else if (!Utils.validateMobileNumber(mobileNo)) { + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: TranslationBase.of(context).pleaseEnterValidMobile, + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // } else { + // registerUser(4); + // } + // int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, mobileNo, context); + // registerUser(val); + }, + backgroundColor: AppColors.whiteColor, + borderColor: AppColors.borderOnlyColor, + textColor: AppColors.textColor, + icon: AppAssets.whatsapp, + ), + ), + ], ), + ), + ), ); } } diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index f2017b2..972958b 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -51,7 +51,6 @@ class _LandingPageState extends State { CustomButton( text: LocaleKeys.loginOrRegister.tr(context: context), onPressed: () async { - // await authenticationViewModel.selectDeviceImei(); Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => LoginScreen())); }, diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index d16cc62..4369157 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -4,10 +4,11 @@ import 'package:hmg_patient_app_new/splashPage.dart'; class AppRoutes { static const String initialRoute = '/initialRoute'; - static const String login = '/login'; + static const String loginScreen = '/loginScreen'; + static const String registerNewScreen = '/registerNewScreen'; static Map get routes => { initialRoute: (context) => SplashPage(), - login: (context) => LoginScreen(), + loginScreen: (context) => LoginScreen(), }; } diff --git a/lib/services/cache_service.dart b/lib/services/cache_service.dart index f25409e..8a015d8 100644 --- a/lib/services/cache_service.dart +++ b/lib/services/cache_service.dart @@ -1,14 +1,116 @@ +import 'dart:convert'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; abstract class CacheService { + Future saveString({required String key, required String value}); + Future saveInt({required String key, required int value}); + + Future saveDouble({required String key, required double value}); + + Future saveBool({required String key, required bool value}); + + Future saveStringList({required String key, required List value}); + + String? getString({required String key}); + + int? getInt({required String key}); + + double? getDouble({required String key}); + + bool? getBool({required String key}); + + List? getStringList({required String key}); + + Future getObject({required String key}); + + Future saveObject({required String key, required dynamic value}); + + Future remove({required String key}); + + Future clear(); } class CacheServiceImp implements CacheService { - SharedPreferences sharedPreferences; + final SharedPreferences sharedPreferences; + final LoggerService loggerService; + + CacheServiceImp({ + required this.sharedPreferences, + required this.loggerService, + }); + + @override + Future saveString({required String key, required String value}) async { + await sharedPreferences.setString(key, value); + } + + @override + Future saveInt({required String key, required int value}) async { + await sharedPreferences.setInt(key, value); + } + + @override + Future saveDouble({required String key, required double value}) async { + await sharedPreferences.setDouble(key, value); + } + + @override + Future saveBool({required String key, required bool value}) async { + await sharedPreferences.setBool(key, value); + } + + @override + Future saveStringList({required String key, required List value}) async { + await sharedPreferences.setStringList(key, value); + } + + @override + String? getString({required String key}) => sharedPreferences.getString(key); + + @override + int? getInt({required String key}) => sharedPreferences.getInt(key); + + @override + double? getDouble({required String key}) => sharedPreferences.getDouble(key); + + @override + bool? getBool({required String key}) => sharedPreferences.getBool(key); + + @override + List? getStringList({required String key}) => sharedPreferences.getStringList(key); + + @override + Future remove({required String key}) async { + await sharedPreferences.remove(key); + } - CacheServiceImp({required this.sharedPreferences}); + @override + Future getObject({required String key}) async { + try { + await sharedPreferences.reload(); + var string = sharedPreferences.getString(key); + if (string == null) return null; + return json.decode(string); + } catch (ex) { + loggerService.errorLogs(ex.toString()); + return null; + } + } + @override + Future saveObject({required String key, required dynamic value}) async { + try { + await sharedPreferences.setString(key, json.encode(value)); + } catch (ex) { + loggerService.errorLogs(ex.toString()); + } + } + @override + Future clear() async { + await sharedPreferences.clear(); + } } diff --git a/lib/services/firebase_service.dart b/lib/services/firebase_service.dart new file mode 100644 index 0000000..f6c712e --- /dev/null +++ b/lib/services/firebase_service.dart @@ -0,0 +1,31 @@ +import 'package:firebase_messaging/firebase_messaging.dart' show FirebaseMessaging; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; + +abstract class FirebaseService { + Future getDeviceToken(); +} + +class FirebaseServiceImpl implements FirebaseService { + final FirebaseMessaging firebaseMessaging; + final LoggerService loggerService; + final AppState appState; + + FirebaseServiceImpl({ + required this.firebaseMessaging, + required this.loggerService, + required this.appState, + }); + + @override + Future getDeviceToken() async { + try { + String? deviceToken = await firebaseMessaging.getToken(); + appState.setDeviceToken = deviceToken; + return deviceToken ?? ""; + } catch (e) { + loggerService.logInfo(e.toString()); + return ""; + } + } +} diff --git a/lib/services/navigation_service.dart b/lib/services/navigation_service.dart index d814cf5..6dd4a54 100644 --- a/lib/services/navigation_service.dart +++ b/lib/services/navigation_service.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/features/authentication/widgets/otp_verification_screen.dart'; class NavigationService { final GlobalKey navigatorKey = GlobalKey(); @@ -12,4 +13,38 @@ class NavigationService { void pop([T? result]) { navigatorKey.currentState!.pop(result); } + + void popUntilNamed(String routeName) { + navigatorKey.currentState?.popUntil(ModalRoute.withName(routeName)); + } + + Future pushToOtpScreen({ + required String phoneNumber, + required Function(int code) checkActivationCode, + required Function(String phoneNumber) onResendOTPPressed, + }) { + return navigatorKey.currentState!.push( + MaterialPageRoute( + builder: (_) => OTPVerificationScreen( + phoneNumber: phoneNumber, + checkActivationCode: checkActivationCode, + onResendOTPPressed: onResendOTPPressed, + ), + ), + ); + } + + Future pushPage({ + required Widget page, + bool fullscreenDialog = false, + bool maintainState = true, + }) { + return navigatorKey.currentState!.push( + MaterialPageRoute( + builder: (_) => page, + fullscreenDialog: fullscreenDialog, + maintainState: maintainState, + ), + ); + } } diff --git a/lib/splashPage.dart b/lib/splashPage.dart index bc3e542..292b2ee 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -15,7 +15,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; -import 'core/consts.dart'; +import 'core/cache_consts.dart'; import 'core/utils/local_notifications.dart'; import 'core/utils/push_notification_handler.dart';