diff --git a/assets/images/png/female_img.png b/assets/images/png/female_img.png new file mode 100644 index 0000000..3307034 Binary files /dev/null and b/assets/images/png/female_img.png differ diff --git a/assets/images/png/lock-icon.png b/assets/images/png/lock-icon.png new file mode 100644 index 0000000..3964588 Binary files /dev/null and b/assets/images/png/lock-icon.png differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index ede5e64..933afa4 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -806,5 +806,10 @@ "loginBy": "تسجيل الدخول بواسطة", "loginByOTP": "تسجيل الدخول بواسطة OTP", "guest": "زائر", - "switchAccount": "تبديل الحساب" + "switchAccount": "تبديل الحساب", + "lastLoginBy":"آخر تسجيل دخول بواسطة", + "allSet": "جاهز! الآن يمكنك تسجيل الدخول باستخدام Face ID / Biometric أو البصمة", + "enableQuickLogin":"تمكين تسجيل الدخول السريع", + "enableMsg":"تمكين تسجيل الدخول السريع سيسمح بالتحقق من خلال Face ID / Biometric الخاص بجهازك الحالي", + "notNow": "ليس الآن" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 8ccd2c4..0b29886 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -802,5 +802,10 @@ "loginBy": "Login By", "loginByOTP": "Login By OTP", "guest": "Guest", - "switchAccount": "Switch Account" + "switchAccount": "Switch Account", + "lastloginBy": "Last login by", + "allSet": "All Set! Now you can login with Face ID or Biometric", + "enableQuickLogin": "Enable Quick Login", + "enableMsg": "Enabling the quick login will verify through your existing device Face ID / Biometric", + "notNow": "Not Now" } \ No newline at end of file diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index ca76ae3..a308031 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -106,7 +106,7 @@ class ApiClientImp implements ApiClient { } } try { - var user = _appState.getAuthenticatedUser; + var user = _appState.getAuthenticatedUser(); Map headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}; if (!isExternal) { String? token = _appState.appAuthToken; @@ -136,10 +136,12 @@ class ApiClientImp implements ApiClient { // TODO : These should be from the appState if (user != null) { body['TokenID'] = body['TokenID'] ?? token; - body['PatientID'] = body['PatientID'] ?? user.patientID; + body['PatientID'] = body['PatientID'] ?? user.patientId; - body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] ?? user.outSA : user.outSA; - body['SessionID'] = getSessionId(body['TokenID'] ?? ""); //getSe + body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] ?? user.outSa : user.outSa; + // body['SessionID'] = body['TokenID'] == null + // ? ApiConsts.sessionID //Added By Aamir + // : getSessionId(body['TokenID'] ?? ""); //getSe } } } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 8ae9304..03f73d6 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -793,10 +793,13 @@ class ApiConsts { static final String sendActivationCodeRegister = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration'; static final String checkActivationCode = 'Services/Authentication.svc/REST/CheckActivationCode'; static final String checkActivationCodeRegister = 'Services/Authentication.svc/REST/CheckActivationCodeForRegistration'; + static final String checkUsageAgreement = 'Services/Patients.svc/REST/CheckForUsageAgreement'; + static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText'; // static values for Api static final double appVersionID = 18.7; static final int appChannelId = 3; static final String appIpAddress = "10.20.10.20"; static final String appGeneralId = "Cs2020@2016\$2958"; + static final String sessionID = 'TMRhVmkGhOsvamErw'; } diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index d641598..eff2ccc 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -84,6 +84,8 @@ class AppAssets { static const String uae_dirham_symbol = '$svgBasePath/uae_dirham_symbol.svg'; static const String directions_icon = '$svgBasePath/directions_icon.svg'; static const String apple_pay_button = '$svgBasePath/pay_with_apple_pay.svg'; + static const String bell = '$svgBasePath/bell.svg'; + //bottom navigation// static const String homeBottom = '$svgBasePath/home_bottom.svg'; @@ -97,12 +99,13 @@ class AppAssets { static const String hmg_logo = '$pngBasePath/hmg_logo.png'; static const String livecare_service = '$pngBasePath/livecare_service.png'; static const String male_img = '$pngBasePath/male_img.png'; - + static const String femaleImg = '$pngBasePath/female_img.png'; static const String apple_pay = '$pngBasePath/Apple_Pay.png'; static const String mada = '$pngBasePath/Mada.png'; static const String Mastercard = '$pngBasePath/Mastercard.png'; static const String tamara_en = '$pngBasePath/tamara_en.png'; static const String visa = '$pngBasePath/visa.png'; + static const String lockIcon = '$pngBasePath/lock-icon.png'; } class AppAnimations { diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index b94aff4..24181dd 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:hmg_patient_app_new/core/common_models/VidaPlusProjectListModel.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; @@ -21,15 +23,35 @@ class AppState { int getLanguageID() => EasyLocalization.of(navigationService.navigatorKey.currentContext!)?.locale.languageCode == "ar" ? 1 : 2; + int getDeviceTypeID() => Platform.isIOS ? 1 : 2; + String? getLanguageCode() => EasyLocalization.of(navigationService.navigatorKey.currentContext!)?.locale.languageCode; - AuthenticatedUser? _authenticatedUser; + AuthenticatedUser? _authenticatedRootUser; + AuthenticatedUser? _authenticatedChildUser; + + void setAuthenticatedUser(AuthenticatedUser authenticatedUser, {bool isFamily = false}) { + if (isFamily) { + _authenticatedChildUser = authenticatedUser; + } else { + setIsAuthenticated = true; + _authenticatedRootUser = authenticatedUser; + } + } - void setAuthenticatedUser(AuthenticatedUser authenticatedUser) { - _authenticatedUser = authenticatedUser; + AuthenticatedUser? getAuthenticatedUser({bool isFamily = false}) { + if (isFamily) { + return _authenticatedChildUser; + } else { + return _authenticatedRootUser; + } } - AuthenticatedUser? get getAuthenticatedUser => _authenticatedUser; + String _userBloodGroup = ""; + + String get getUserBloodGroup => _userBloodGroup; + + set setUserBloodGroup(String value) => _userBloodGroup = value; SelectDeviceByImeiRespModelElement? _selectDeviceByImeiRespModelElement; @@ -59,7 +81,7 @@ class AppState { set setSessionId(v) => sessionId = v; - bool isAuthenticated = true; + bool isAuthenticated = false; set setIsAuthenticated(v) => isAuthenticated = v; diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index b6e72f6..0afa53c 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -24,8 +24,10 @@ 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/localauth_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; +import 'package:local_auth/local_auth.dart'; import 'package:logger/web.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -52,6 +54,8 @@ class AppDependencies { )); getIt.registerLazySingleton(() => NavigationService()); + getIt.registerLazySingleton(() => LocalAuthentication()); + getIt.registerLazySingleton(() => GAnalytics()); getIt.registerLazySingleton(() => AppState(navigationService: getIt())); getIt.registerLazySingleton(() => LocationUtils( @@ -80,6 +84,7 @@ class AppDependencies { getIt.registerLazySingleton(() => PrescriptionsRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => InsuranceRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => PayfortRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => LocalAuthService(loggerService: getIt(), localAuth: getIt())); // ViewModels // Global/shared VMs → LazySingleton @@ -134,6 +139,7 @@ class AppDependencies { dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), + localAuthService: getIt() ), ); diff --git a/lib/core/enums.dart b/lib/core/enums.dart index 0ab055f..3392218 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -32,7 +32,7 @@ enum MaritalStatusTypeEnum { single, married, divorced, widowed } enum ChipTypeEnum { success, error, alert, info, warning } -enum OTPTypeEnum { sms, whatsapp } +enum OTPTypeEnum { sms, whatsapp, faceIDFingerprint } enum LoginTypeEnum { sms, whatsapp, face, fingerprint } @@ -89,6 +89,8 @@ extension OTPTypeEnumExtension on OTPTypeEnum { return 1; case OTPTypeEnum.whatsapp: return 2; + case OTPTypeEnum.faceIDFingerprint: + return 0; } } diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart index e83dd46..8f33fad 100644 --- a/lib/core/utils/request_utils.dart +++ b/lib/core/utils/request_utils.dart @@ -1,5 +1,9 @@ +import 'package:hmg_patient_app_new/core/api_consts.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart'; +import 'package:hmg_patient_app_new/features/common/models/commong_authanticated_req_model.dart'; class RequestUtils { static dynamic getPatientAuthenticationRequest({ @@ -50,7 +54,7 @@ class RequestUtils { required bool patientOutSA, required String? loginTokenID, required var registeredData, - required int? patientId, + int? patientId, required String nationIdText, required String countryCode, }) { @@ -128,4 +132,24 @@ class RequestUtils { request.deviceTypeID = request.searchType; return request; } + + static getAuthanticatedCommonRequest() { + AppState _appState = getIt.get(); + var request = CommonAuthanticatedRequest(); + request.sessionId = ApiConsts.sessionID; + request.latitude = _appState.userLat; + request.longitude = _appState.userLong; + request.languageId = _appState.getLanguageID(); + request.versionId = ApiConsts.appVersionID; + request.ipAdress = ApiConsts.appIpAddress; + request.deviceTypeId = _appState.getDeviceTypeID(); + request.patientTypeId = _appState.getAuthenticatedUser()?.patientType; + request.patientType = _appState.getAuthenticatedUser()?.patientType; + request.generalid = ApiConsts.appGeneralId; + request.channel = ApiConsts.appChannelId; + request.patientId = _appState.getAuthenticatedUser()!.patientId; + request.patientOutSa = _appState.getAuthenticatedUser()!.outSa; + request.tokenId = null; + return request; + } } diff --git a/lib/extensions/context_extensions.dart b/lib/extensions/context_extensions.dart index 4e9da0d..27d4cf4 100644 --- a/lib/extensions/context_extensions.dart +++ b/lib/extensions/context_extensions.dart @@ -5,6 +5,11 @@ extension ContextUtils on BuildContext { double get screenWidth => MediaQuery.of(this).size.width; + EdgeInsets get padding => MediaQuery.of(this).padding; + + bool get safeInsets => padding.top > 0 || padding.bottom > 0 || padding.left > 0 || padding.right > 0; + + ThemeData get theme => Theme.of(this); TextTheme get textTheme => theme.textTheme; diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index f8ceff4..030b75e 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -5,27 +5,25 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_activation_code_register_request_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class AuthenticationRepo { - Future>> selectDeviceByImei({ - required String firebaseToken, - }); + Future>> selectDeviceByImei({required String firebaseToken}); Future>> checkPatientAuthentication({required dynamic checkPatientAuthenticationReq}); - Future>> sendActivationCodeRepo({ - required dynamic sendActivationCodeReq, - String? languageID, - bool isRegister = false, - }); + Future>> sendActivationCodeRepo({required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false}); - Future>> checkActivationCodeRepo({ - required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq - required String? activationCode, - required bool isRegister, - }); + Future>> checkActivationCodeRepo( + {required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq + required String? activationCode, + required bool isRegister}); + + Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest}); + + Future>> getUserAgreementContent({required dynamic commonAuthanticatedRequest}); } class AuthenticationRepoImp implements AuthenticationRepo { @@ -198,4 +196,74 @@ class AuthenticationRepoImp implements AuthenticationRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest}) async { + commonAuthanticatedRequest['Region'] = 1; + print("dsfsdd"); + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + ApiConsts.checkUsageAgreement, + body: commonAuthanticatedRequest, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + 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!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future>> getUserAgreementContent({required dynamic commonAuthanticatedRequest}) async { + commonAuthanticatedRequest['Region'] = 1; + print("dsfsdd"); + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + ApiConsts.getUserAgreementContent, + body: commonAuthanticatedRequest, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + 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!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index e856d3e..52c83e7 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -10,13 +10,16 @@ import 'package:hmg_patient_app_new/core/utils/request_utils.dart'; import 'package:hmg_patient_app_new/core/utils/validation_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart'; +import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_activation_code_register_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/presentation/authentication/saved_login_screen.dart'; import 'package:hmg_patient_app_new/routes/app_routes.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/localauth_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; class AuthenticationViewModel extends ChangeNotifier { @@ -25,7 +28,7 @@ class AuthenticationViewModel extends ChangeNotifier { final ErrorHandlerService _errorHandlerService; final DialogService _dialogService; final NavigationService _navigationService; - + final LocalAuthService _localAuthService; AuthenticationViewModel({ required AppState appState, required AuthenticationRepo authenticationRepo, @@ -33,11 +36,13 @@ class AuthenticationViewModel extends ChangeNotifier { required DialogService dialogService, required NavigationService navigationService, required CacheService cacheService, + required LocalAuthService localAuthService, }) : _navigationService = navigationService, _dialogService = dialogService, _errorHandlerService = errorHandlerService, _appState = appState, - _authenticationRepo = authenticationRepo; + _authenticationRepo = authenticationRepo, + _localAuthService = localAuthService; final TextEditingController nationalIdController = TextEditingController(), phoneNumberController = TextEditingController(), dobController = TextEditingController(); CountryEnum selectedCountrySignup = CountryEnum.saudiArabia; @@ -72,7 +77,7 @@ class AuthenticationViewModel extends ChangeNotifier { try { LoadingUtils.showFullScreenLoader(); //TODO: We will remove this delay - await Future.delayed(Duration(seconds: 3)); + // await Future.delayed(Duration(seconds: 3)); var data = _appState.getSelectDeviceByImeiRespModelElement; log("Cached IMEI data: ${data?.toJson()}"); if (data != null) { @@ -87,7 +92,7 @@ class AuthenticationViewModel extends ChangeNotifier { } } - void clearDefaults() { + void clearDefaultInputValues() { nationalIdController.clear(); phoneNumberController.clear(); dobController.clear(); @@ -165,8 +170,8 @@ class AuthenticationViewModel extends ChangeNotifier { if (savedData != null) { // TODO: Navigate to SavedLogin when available - _navigationService.pushPage(page: LoginScreen()); - // navigationService.pushPage(page: SavedLogin(savedData)); + //_navigationService.pushPage(page: LoginScreen()); + _navigationService.pushPage(page: SavedLogin()); } } catch (e) { log("Error handling existing IMEI data: $e"); @@ -186,8 +191,8 @@ class AuthenticationViewModel extends ChangeNotifier { // TODO: Navigate to SavedLogin when available // SelectDeviceByImeiRespModelElement savedData = // SelectDeviceByImeiRespModelElement.fromJson(respData); - // navigationService.pushPage(page: SavedLogin(savedData)); - _navigationService.pushPage(page: LoginScreen()); + _navigationService.pushPage(page: SavedLogin()); + // _navigationService.pushPage(page: LoginScreen()); } else { LoadingUtils.hideFullScreenLoader(); _navigationService.pushPage(page: LoginScreen()); @@ -227,7 +232,7 @@ class AuthenticationViewModel extends ChangeNotifier { patientOutSA: false, otpTypeEnum: otpTypeEnum, patientId: 0, - zipCode: '966', + zipCode: selectedCountrySignup.countryCode, ); final result = await _authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); @@ -248,6 +253,7 @@ class AuthenticationViewModel extends ChangeNotifier { } else { if (apiResponse.data['IsAuthenticated']) { await checkActivationCode( + otpTypeEnum: otpTypeEnum, onWrongActivationCode: (String? message) {}, activationCode: 0000, ); @@ -267,7 +273,7 @@ class AuthenticationViewModel extends ChangeNotifier { otpTypeEnum: otpTypeEnum, mobileNumber: phoneNumber, selectedLoginType: otpTypeEnum.toInt(), - zipCode: "966", + zipCode: selectedCountrySignup.countryCode, nationalId: nationalIdOrFileNumber, isFileNo: false, patientId: 0, @@ -317,18 +323,18 @@ class AuthenticationViewModel extends ChangeNotifier { Future checkActivationCode({ required int activationCode, + required OTPTypeEnum otpTypeEnum, required Function(String? message) onWrongActivationCode, }) async { final request = RequestUtils.getCommonRequestWelcome( - phoneNumber: '0567184134', - otpTypeEnum: OTPTypeEnum.sms, - deviceToken: 'dummyDeviceToken123', + phoneNumber: phoneNumberController.text, + otpTypeEnum: otpTypeEnum, + deviceToken: _appState.deviceToken, patientOutSA: true, - loginTokenID: 'dummyLoginToken456', + loginTokenID: _appState.appLoginTokenID, registeredData: null, - patientId: 12345, - nationIdText: '1234567890', - countryCode: 'SA', + nationIdText: nationalIdController.text, + countryCode: selectedCountrySignup.countryCode, ).toJson(); bool isForRegister = healthId != null || isDubai; @@ -337,11 +343,7 @@ class AuthenticationViewModel extends ChangeNotifier { request['HealthId'] = healthId; request['IsHijri'] = isHijri; - final resultEither = await _authenticationRepo.checkActivationCodeRepo( - newRequest: request, - activationCode: activationCode.toString(), - isRegister: true, - ); + final resultEither = await _authenticationRepo.checkActivationCodeRepo(newRequest: request, activationCode: activationCode.toString(), isRegister: true); resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) { final activation = CheckActivationCode.fromJson(apiResponse.data as Map); @@ -353,23 +355,42 @@ class AuthenticationViewModel extends ChangeNotifier { }); } else { final resultEither = await _authenticationRepo.checkActivationCodeRepo( - newRequest: request, + newRequest: CheckActivationCodeRegisterReq.fromJson(request), activationCode: activationCode.toString(), isRegister: false, ); - resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) { - final activation = CheckActivationCode.fromJson(resultEither as Map); + resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { + final activation = CheckActivationCode.fromJson(apiResponse.data as Map); if (activation.errorCode == '699') { // Todo: Hide Loader // GifLoaderDialogUtils.hideDialog(context); onWrongActivationCode(activation.errorEndUserMessage); return; + } else if(activation.messageStatus ==2){ + 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 { + if (activation.list != null && activation.list!.isNotEmpty) { + _appState.setAuthenticatedUser(activation.list!.first); + + } + _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); + _appState.setAppLoginTokenID = activation.authenticationTokenId; + final request = RequestUtils.getAuthanticatedCommonRequest().toJson(); + bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request); + clearDefaultInputValues(); + if (isUserAgreedBefore) { + navigateToHomeScreen(); + } else { + navigateToHomeScreen(); + //Agreement page not designed yet so we are navigating to home screen directly + // getUserAgreementContent(request: request); + } // TODO: setPreferences and stuff // sharedPref.remove(FAMILY_FILE); // activation.list!.isFamily = false; @@ -382,29 +403,96 @@ class AuthenticationViewModel extends ChangeNotifier { // 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 checkIfUserAgreedBefore({required dynamic request}) async { + bool isAgreed = false; + if (havePrivilege(109)) { + final resultEither = await _authenticationRepo.checkIfUserAgreed(commonAuthanticatedRequest: request); + resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) { + if (apiResponse.data['IsPatientAlreadyAgreed']) { + return true; + } + }); + } + return isAgreed; + } + + Future getUserAgreementContent({required dynamic request}) async { + final resultEither = await _authenticationRepo.getUserAgreementContent(commonAuthanticatedRequest: request); + resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { + // _navigationService.pushAndReplace(routeName) + //TODO: Add User Agreement Page Here + }); + } + + bool havePrivilege(int id) { + bool isHavePrivilege = false; + try { + for (var element in _appState.getAuthenticatedUser()!.listPrivilege!) { + if (element.id == id) isHavePrivilege = element.previlege!; + } + } catch (e) { + print(e); + } + return isHavePrivilege; + } + + Future navigateToHomeScreen() async { + _navigationService.pushAndReplace(AppRoutes.landingScreen); + } + Future navigateToOTPScreen({required OTPTypeEnum otpTypeEnum, required String phoneNumber}) async { _navigationService.pushToOtpScreen( phoneNumber: phoneNumber, checkActivationCode: (int activationCode) async { await checkActivationCode( activationCode: activationCode, + otpTypeEnum: otpTypeEnum, onWrongActivationCode: (String? value) { onWrongActivationCode(message: value); }); + + // Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => RegisterNewStep2(null, {"nationalID": "12345678654321"}))); }, onResendOTPPressed: (String phoneNumber) {}, ); } Future onWrongActivationCode({String? message}) async { - // TODO: HANDLE THIS VIA BOTTOM SHEET + await _dialogService.showErrorBottomSheet(message: message ?? "Something went wrong. ", onOkPressed: () {}); + } + + loginWithFingerPrintFace(int selectedOption) async { + _localAuthService.authenticate().then((value) { + if (value) { + // we have to handle this if verification true; + checkActivationCode(otpTypeEnum: OTPTypeEnum.faceIDFingerprint, activationCode: 0000, onWrongActivationCode: (String? message) { }); + // authenticated = true; + notifyListeners(); + // navigateToHomeScreen(); + } else { + //authenticated = false; + notifyListeners(); + } + }); + this.selectedOption = selectedOption; + notifyListeners(); + + } + + checkLastLoginStatus(Function() onSuccess) async { + if(_appState.getSelectDeviceByImeiRespModelElement !=null && (_appState.getSelectDeviceByImeiRespModelElement!.logInType ==1 || _appState.getSelectDeviceByImeiRespModelElement!.logInType ==4)){ + Future.delayed(Duration(seconds: 1),(){ + onSuccess(); + }); + + } } @override diff --git a/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart b/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart index 2a071bb..8848fde 100644 --- a/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart +++ b/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart @@ -1,292 +1,321 @@ -import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'dart:convert'; class AuthenticatedUser { - String? setupID; + String? setupId; int? patientType; - int? patientID; + int? patientId; String? firstName; String? middleName; String? lastName; String? firstNameN; String? middleNameN; String? lastNameN; - int? relationshipID; + int? relationshipId; int? gender; String? dateofBirth; - DateTime? dateofBirthDataTime; dynamic dateofBirthN; - String? nationalityID; - dynamic phoneResi; - dynamic phoneOffice; + String? nationalityId; + String? phoneResi; + String? phoneOffice; String? mobileNumber; - dynamic faxNumber; + String? faxNumber; String? emailAddress; dynamic bloodGroup; - dynamic rHFactor; + dynamic rhFactor; bool? isEmailAlertRequired; - bool? isSMSAlertRequired; + bool? isSmsAlertRequired; String? preferredLanguage; bool? isPrivilegedMember; - dynamic memberID; + dynamic memberId; dynamic expiryDate; dynamic isHmgEmployee; - dynamic employeeID; - dynamic emergencyContactName; - dynamic emergencyContactNo; + dynamic employeeId; + String? emergencyContactName; + String? emergencyContactNo; int? patientPayType; - dynamic dHCCPatientRefID; + dynamic dhccPatientRefId; bool? isPatientDummy; int? status; dynamic isStatusCleared; int? patientIdentificationType; String? patientIdentificationNo; - int? projectID; - int? infoSourceID; + int? projectId; + int? infoSourceId; dynamic address; int? age; String? ageDesc; - int? areaID; + int? areaId; + int? crsVerificationStatus; + String? crsVerificationStatusDesc; + String? crsVerificationStatusDescN; int? createdBy; String? genderDescription; - dynamic iR; - dynamic iSOCityID; - dynamic iSOCountryID; + String? healthIdFromNhicViaVida; + dynamic ir; + dynamic isoCityId; + dynamic isoCountryId; + bool? isVerfiedFromNhic; List? listPrivilege; dynamic marital; - int? outSA; - dynamic pOBox; + dynamic occupationId; + int? outSa; + dynamic poBox; bool? receiveHealthSummaryReport; int? sourceType; dynamic strDateofBirth; dynamic tempAddress; dynamic zipCode; - dynamic isFamily; - dynamic cRSVerificationStatus; - // dynamic patientPayType; - // dynamic patientType; - // dynamic status; + dynamic eHealthIdField; + dynamic authenticatedUserPatientPayType; + dynamic authenticatedUserPatientType; + dynamic authenticatedUserStatus; - AuthenticatedUser( - {this.setupID, - this.patientType, - this.patientID, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.relationshipID, - this.gender, - this.dateofBirth, - this.dateofBirthN, - this.nationalityID, - this.phoneResi, - this.phoneOffice, - this.mobileNumber, - this.faxNumber, - this.emailAddress, - this.bloodGroup, - this.rHFactor, - this.isEmailAlertRequired, - this.isSMSAlertRequired, - this.preferredLanguage, - this.isPrivilegedMember, - this.memberID, - this.expiryDate, - this.isHmgEmployee, - this.employeeID, - this.emergencyContactName, - this.emergencyContactNo, - this.patientPayType, - this.dHCCPatientRefID, - this.isPatientDummy, - this.status, - this.isStatusCleared, - this.patientIdentificationType, - this.patientIdentificationNo, - this.projectID, - this.infoSourceID, - this.address, - this.age, - this.ageDesc, - this.areaID, - this.createdBy, - this.genderDescription, - this.iR, - this.iSOCityID, - this.iSOCountryID, - this.listPrivilege, - this.marital, - this.outSA, - this.pOBox, - this.receiveHealthSummaryReport, - this.sourceType, - this.strDateofBirth, - this.tempAddress, - this.zipCode, - this.isFamily, - this.cRSVerificationStatus}); + AuthenticatedUser({ + this.setupId, + this.patientType, + this.patientId, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.relationshipId, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.nationalityId, + this.phoneResi, + this.phoneOffice, + this.mobileNumber, + this.faxNumber, + this.emailAddress, + this.bloodGroup, + this.rhFactor, + this.isEmailAlertRequired, + this.isSmsAlertRequired, + this.preferredLanguage, + this.isPrivilegedMember, + this.memberId, + this.expiryDate, + this.isHmgEmployee, + this.employeeId, + this.emergencyContactName, + this.emergencyContactNo, + this.patientPayType, + this.dhccPatientRefId, + this.isPatientDummy, + this.status, + this.isStatusCleared, + this.patientIdentificationType, + this.patientIdentificationNo, + this.projectId, + this.infoSourceId, + this.address, + this.age, + this.ageDesc, + this.areaId, + this.crsVerificationStatus, + this.crsVerificationStatusDesc, + this.crsVerificationStatusDescN, + this.createdBy, + this.genderDescription, + this.healthIdFromNhicViaVida, + this.ir, + this.isoCityId, + this.isoCountryId, + this.isVerfiedFromNhic, + this.listPrivilege, + this.marital, + this.occupationId, + this.outSa, + this.poBox, + this.receiveHealthSummaryReport, + this.sourceType, + this.strDateofBirth, + this.tempAddress, + this.zipCode, + this.eHealthIdField, + this.authenticatedUserPatientPayType, + this.authenticatedUserPatientType, + this.authenticatedUserStatus, + }); - AuthenticatedUser.fromJson(Map json) { - setupID = json['SetupID']; - patientType = json['PatientType']; - patientID = json['PatientID']; - firstName = json['FirstName']; - middleName = json['MiddleName']; - lastName = json['LastName']; - firstNameN = json['FirstNameN']; - middleNameN = json['MiddleNameN']; - lastNameN = json['LastNameN']; - relationshipID = json['RelationshipID']; - gender = json['Gender']; - dateofBirth = json['DateofBirth']; - dateofBirthDataTime = DateUtil.convertStringToDate(json['DateofBirth']); - dateofBirthN = json['DateofBirthN']; - nationalityID = json['NationalityID']; - phoneResi = json['PhoneResi']; - phoneOffice = json['PhoneOffice']; - mobileNumber = json['MobileNumber']; - faxNumber = json['FaxNumber']; - emailAddress = json['EmailAddress']; - bloodGroup = json['BloodGroup']; - rHFactor = json['RHFactor']; - isEmailAlertRequired = json['IsEmailAlertRequired']; - isSMSAlertRequired = json['IsSMSAlertRequired']; - preferredLanguage = json['PreferredLanguage']; - isPrivilegedMember = json['IsPrivilegedMember']; - memberID = json['MemberID']; - expiryDate = json['ExpiryDate']; - isHmgEmployee = json['IsHmgEmployee']; - employeeID = json['EmployeeID']; - emergencyContactName = json['EmergencyContactName']; - emergencyContactNo = json['EmergencyContactNo']; - patientPayType = json['PatientPayType']; - dHCCPatientRefID = json['DHCCPatientRefID']; - isPatientDummy = json['IsPatientDummy']; - status = json['Status']; - isStatusCleared = json['IsStatusCleared']; - patientIdentificationType = json['PatientIdentificationType']; - patientIdentificationNo = json['PatientIdentificationNo']; - projectID = json['ProjectID']; - infoSourceID = json['InfoSourceID']; - address = json['Address']; - age = json['Age']; - ageDesc = json['AgeDesc']; - areaID = json['AreaID']; - createdBy = json['CreatedBy']; - genderDescription = json['GenderDescription']; - iR = json['IR']; - iSOCityID = json['ISOCityID']; - iSOCountryID = json['ISOCountryID']; - if (json['ListPrivilege'] != null) { - listPrivilege = []; - json['ListPrivilege'].forEach((v) { - listPrivilege!.add(new ListPrivilege.fromJson(v)); - }); - } - marital = json['Marital']; - outSA = json['OutSA']; - pOBox = json['POBox']; - receiveHealthSummaryReport = json['ReceiveHealthSummaryReport']; - sourceType = json['SourceType']; - strDateofBirth = json['StrDateofBirth']; - tempAddress = json['TempAddress']; - zipCode = json['ZipCode']; - isFamily = json['IsFamily']; - cRSVerificationStatus = json['CRSVerificationStatus']; - } + factory AuthenticatedUser.fromRawJson(String str) => AuthenticatedUser.fromJson(json.decode(str)); - Map toJson() { - final Map data = new Map(); - data['SetupID'] = this.setupID; - data['PatientType'] = this.patientType; - data['PatientID'] = this.patientID; - data['FirstName'] = this.firstName; - data['MiddleName'] = this.middleName; - data['LastName'] = this.lastName; - data['FirstNameN'] = this.firstNameN; - data['MiddleNameN'] = this.middleNameN; - data['LastNameN'] = this.lastNameN; - data['RelationshipID'] = this.relationshipID; - data['Gender'] = this.gender; - data['DateofBirth'] = this.dateofBirth; - data['DateofBirthN'] = this.dateofBirthN; - data['NationalityID'] = this.nationalityID; - data['PhoneResi'] = this.phoneResi; - data['PhoneOffice'] = this.phoneOffice; - data['MobileNumber'] = this.mobileNumber; - data['FaxNumber'] = this.faxNumber; - data['EmailAddress'] = this.emailAddress; - data['BloodGroup'] = this.bloodGroup; - data['RHFactor'] = this.rHFactor; - data['IsEmailAlertRequired'] = this.isEmailAlertRequired; - data['IsSMSAlertRequired'] = this.isSMSAlertRequired; - data['PreferredLanguage'] = this.preferredLanguage; - data['IsPrivilegedMember'] = this.isPrivilegedMember; - data['MemberID'] = this.memberID; - data['ExpiryDate'] = this.expiryDate; - data['IsHmgEmployee'] = this.isHmgEmployee; - data['EmployeeID'] = this.employeeID; - data['EmergencyContactName'] = this.emergencyContactName; - data['EmergencyContactNo'] = this.emergencyContactNo; - data['PatientPayType'] = this.patientPayType; - data['DHCCPatientRefID'] = this.dHCCPatientRefID; - data['IsPatientDummy'] = this.isPatientDummy; - data['Status'] = this.status; - data['IsStatusCleared'] = this.isStatusCleared; - data['PatientIdentificationType'] = this.patientIdentificationType; - data['PatientIdentificationNo'] = this.patientIdentificationNo; - data['ProjectID'] = this.projectID; - data['InfoSourceID'] = this.infoSourceID; - data['Address'] = this.address; - data['Age'] = this.age; - data['AgeDesc'] = this.ageDesc; - data['AreaID'] = this.areaID; - data['CreatedBy'] = this.createdBy; - data['GenderDescription'] = this.genderDescription; - data['IR'] = this.iR; - data['ISOCityID'] = this.iSOCityID; - data['ISOCountryID'] = this.iSOCountryID; - if (this.listPrivilege != null) { - data['ListPrivilege'] = - this.listPrivilege!.map((v) => v.toJson()).toList(); - } - data['Marital'] = this.marital; - data['OutSA'] = this.outSA; - data['POBox'] = this.pOBox; - data['ReceiveHealthSummaryReport'] = this.receiveHealthSummaryReport; - data['SourceType'] = this.sourceType; - data['StrDateofBirth'] = this.strDateofBirth; - data['TempAddress'] = this.tempAddress; - data['ZipCode'] = this.zipCode; - data['IsFamily'] = this.isFamily; - data['CRSVerificationStatus'] = this.cRSVerificationStatus; - return data; - } + String toRawJson() => json.encode(toJson()); + + factory AuthenticatedUser.fromJson(Map json) => AuthenticatedUser( + setupId: json["SetupID"], + patientType: json["PatientType"], + patientId: json["PatientID"], + firstName: json["FirstName"], + middleName: json["MiddleName"], + lastName: json["LastName"], + firstNameN: json["FirstNameN"], + middleNameN: json["MiddleNameN"], + lastNameN: json["LastNameN"], + relationshipId: json["RelationshipID"], + gender: json["Gender"], + dateofBirth: json["DateofBirth"], + dateofBirthN: json["DateofBirthN"], + nationalityId: json["NationalityID"], + phoneResi: json["PhoneResi"], + phoneOffice: json["PhoneOffice"], + mobileNumber: json["MobileNumber"], + faxNumber: json["FaxNumber"], + emailAddress: json["EmailAddress"], + bloodGroup: json["BloodGroup"], + rhFactor: json["RHFactor"], + isEmailAlertRequired: json["IsEmailAlertRequired"], + isSmsAlertRequired: json["IsSMSAlertRequired"], + preferredLanguage: json["PreferredLanguage"], + isPrivilegedMember: json["IsPrivilegedMember"], + memberId: json["MemberID"], + expiryDate: json["ExpiryDate"], + isHmgEmployee: json["IsHmgEmployee"], + employeeId: json["EmployeeID"], + emergencyContactName: json["EmergencyContactName"], + emergencyContactNo: json["EmergencyContactNo"], + patientPayType: json["PatientPayType"], + dhccPatientRefId: json["DHCCPatientRefID"], + isPatientDummy: json["IsPatientDummy"], + status: json["Status"], + isStatusCleared: json["IsStatusCleared"], + patientIdentificationType: json["PatientIdentificationType"], + patientIdentificationNo: json["PatientIdentificationNo"], + projectId: json["ProjectID"], + infoSourceId: json["InfoSourceID"], + address: json["Address"], + age: json["Age"], + ageDesc: json["AgeDesc"], + areaId: json["AreaID"], + crsVerificationStatus: json["CRSVerificationStatus"], + crsVerificationStatusDesc: json["CRSVerificationStatusDesc"], + crsVerificationStatusDescN: json["CRSVerificationStatusDescN"], + createdBy: json["CreatedBy"], + genderDescription: json["GenderDescription"], + healthIdFromNhicViaVida: json["HealthIDFromNHICViaVida"], + ir: json["IR"], + isoCityId: json["ISOCityID"], + isoCountryId: json["ISOCountryID"], + isVerfiedFromNhic: json["IsVerfiedFromNHIC"], + listPrivilege: json["ListPrivilege"] == null ? [] : List.from(json["ListPrivilege"]!.map((x) => ListPrivilege.fromJson(x))), + marital: json["Marital"], + occupationId: json["OccupationID"], + outSa: json["OutSA"], + poBox: json["POBox"], + receiveHealthSummaryReport: json["ReceiveHealthSummaryReport"], + sourceType: json["SourceType"], + strDateofBirth: json["StrDateofBirth"], + tempAddress: json["TempAddress"], + zipCode: json["ZipCode"], + eHealthIdField: json["eHealthIDField"], + authenticatedUserPatientPayType: json["patientPayType"], + authenticatedUserPatientType: json["patientType"], + authenticatedUserStatus: json["status"], + ); + + Map toJson() => { + "SetupID": setupId, + "PatientType": patientType, + "PatientID": patientId, + "FirstName": firstName, + "MiddleName": middleName, + "LastName": lastName, + "FirstNameN": firstNameN, + "MiddleNameN": middleNameN, + "LastNameN": lastNameN, + "RelationshipID": relationshipId, + "Gender": gender, + "DateofBirth": dateofBirth, + "DateofBirthN": dateofBirthN, + "NationalityID": nationalityId, + "PhoneResi": phoneResi, + "PhoneOffice": phoneOffice, + "MobileNumber": mobileNumber, + "FaxNumber": faxNumber, + "EmailAddress": emailAddress, + "BloodGroup": bloodGroup, + "RHFactor": rhFactor, + "IsEmailAlertRequired": isEmailAlertRequired, + "IsSMSAlertRequired": isSmsAlertRequired, + "PreferredLanguage": preferredLanguage, + "IsPrivilegedMember": isPrivilegedMember, + "MemberID": memberId, + "ExpiryDate": expiryDate, + "IsHmgEmployee": isHmgEmployee, + "EmployeeID": employeeId, + "EmergencyContactName": emergencyContactName, + "EmergencyContactNo": emergencyContactNo, + "PatientPayType": patientPayType, + "DHCCPatientRefID": dhccPatientRefId, + "IsPatientDummy": isPatientDummy, + "Status": status, + "IsStatusCleared": isStatusCleared, + "PatientIdentificationType": patientIdentificationType, + "PatientIdentificationNo": patientIdentificationNo, + "ProjectID": projectId, + "InfoSourceID": infoSourceId, + "Address": address, + "Age": age, + "AgeDesc": ageDesc, + "AreaID": areaId, + "CRSVerificationStatus": crsVerificationStatus, + "CRSVerificationStatusDesc": crsVerificationStatusDesc, + "CRSVerificationStatusDescN": crsVerificationStatusDescN, + "CreatedBy": createdBy, + "GenderDescription": genderDescription, + "HealthIDFromNHICViaVida": healthIdFromNhicViaVida, + "IR": ir, + "ISOCityID": isoCityId, + "ISOCountryID": isoCountryId, + "IsVerfiedFromNHIC": isVerfiedFromNhic, + "ListPrivilege": listPrivilege == null ? [] : List.from(listPrivilege!.map((x) => x.toJson())), + "Marital": marital, + "OccupationID": occupationId, + "OutSA": outSa, + "POBox": poBox, + "ReceiveHealthSummaryReport": receiveHealthSummaryReport, + "SourceType": sourceType, + "StrDateofBirth": strDateofBirth, + "TempAddress": tempAddress, + "ZipCode": zipCode, + "eHealthIDField": eHealthIdField, + "patientPayType": authenticatedUserPatientPayType, + "patientType": authenticatedUserPatientType, + "status": authenticatedUserStatus, + }; } class ListPrivilege { - int? iD; + int? id; String? serviceName; bool? previlege; dynamic region; - ListPrivilege({this.iD, this.serviceName, this.previlege, this.region}); + ListPrivilege({ + this.id, + this.serviceName, + this.previlege, + this.region, + }); + + factory ListPrivilege.fromRawJson(String str) => ListPrivilege.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); - ListPrivilege.fromJson(Map json) { - iD = json['ID']; - serviceName = json['ServiceName']; - previlege = json['Previlege']; - region = json['Region']; - } + factory ListPrivilege.fromJson(Map json) => ListPrivilege( + id: json["ID"], + serviceName: json["ServiceName"], + previlege: json["Previlege"], + region: json["Region"], + ); - Map toJson() { - final Map data = new Map(); - data['ID'] = this.iD; - data['ServiceName'] = this.serviceName; - data['Previlege'] = this.previlege; - data['Region'] = this.region; - return data; - } + Map toJson() => { + "ID": id, + "ServiceName": serviceName, + "Previlege": previlege, + "Region": region, + }; } diff --git a/lib/features/authentication/models/resp_models/check_activation_code_resp_model.dart b/lib/features/authentication/models/resp_models/check_activation_code_resp_model.dart index 89a101b..2682f0a 100644 --- a/lib/features/authentication/models/resp_models/check_activation_code_resp_model.dart +++ b/lib/features/authentication/models/resp_models/check_activation_code_resp_model.dart @@ -1,22 +1,26 @@ +import 'dart:convert'; + import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; class CheckActivationCode { dynamic date; - int? languageID; + int? languageId; int? serviceName; dynamic time; dynamic androidLink; - String? authenticationTokenID; + String? authenticationTokenId; dynamic data; bool? dataw; int? dietType; + int? dietTypeId; dynamic errorCode; dynamic errorEndUserMessage; dynamic errorEndUserMessageN; dynamic errorMessage; + int? errorStatusCode; int? errorType; int? foodCategory; - dynamic iOSLink; + dynamic iosLink; bool? isAuthenticated; int? mealOrderStatus; int? mealType; @@ -25,34 +29,46 @@ class CheckActivationCode { dynamic patientBlodType; dynamic successMsg; dynamic successMsgN; + dynamic vidaUpdatedResponse; dynamic doctorInformationList; dynamic getAllPendingRecordsList; dynamic getAllSharedRecordsByStatusList; + dynamic getMaritalstatusLst; + dynamic getOccupationLst; dynamic getResponseFileList; - bool? isHMGPatient; + dynamic hisPatientModelVpPortal; + bool? isHmgPatient; bool? isLoginSuccessfully; bool? isNeedUpdateIdintificationNo; - bool? kioskSendSMS; - AuthenticatedUser? list; + bool? isPatientAuthorized; + bool? isVidaPlus; + bool? kioskSendSms; + List? list; dynamic listAskHabibMobileLoginInfo; dynamic listAskHabibPatientFile; + dynamic listFamilyRelationships; dynamic listMergeFiles; dynamic listMobileLoginInfo; dynamic listPatientCount; - dynamic logInTokenID; + dynamic logInTokenId; dynamic mohemmPrivilegeList; - int? pateintID; - String? patientBloodType; + int? pateintId; + dynamic patientBloodType; + dynamic patientErAdminDriverFileList; + dynamic patientErAdminFile; + dynamic patientErDriverFile; + dynamic patientErDriverFileList; bool? patientHasFile; dynamic patientMergedIDs; - bool? patientOutSA; - int? patientShareRequestID; + bool? patientOutSa; + int? patientShareRequestId; int? patientType; - int? projectIDOut; + int? projectIdOut; dynamic returnMessage; - bool? sMSLoginRequired; + bool? smsLoginRequired; dynamic servicePrivilegeList; dynamic sharePatientName; + bool? userAccountIsActivated; dynamic verificationCode; dynamic email; dynamic errorList; @@ -60,236 +76,572 @@ class CheckActivationCode { bool? isActiveCode; bool? isMerged; bool? isNeedUserAgreement; - bool? isSMSSent; + bool? isSmsSent; dynamic memberList; dynamic message; int? statusCode; - CheckActivationCode( - {this.date, - this.languageID, - this.serviceName, - this.time, - this.androidLink, - this.authenticationTokenID, - this.data, - this.dataw, - this.dietType, - this.errorCode, - this.errorEndUserMessage, - this.errorEndUserMessageN, - this.errorMessage, - this.errorType, - this.foodCategory, - this.iOSLink, - this.isAuthenticated, - this.mealOrderStatus, - this.mealType, - this.messageStatus, - this.numberOfResultRecords, - this.patientBlodType, - this.successMsg, - this.successMsgN, - this.doctorInformationList, - this.getAllPendingRecordsList, - this.getAllSharedRecordsByStatusList, - this.getResponseFileList, - this.isHMGPatient, - this.isLoginSuccessfully, - this.isNeedUpdateIdintificationNo, - this.kioskSendSMS, - this.list, - this.listAskHabibMobileLoginInfo, - this.listAskHabibPatientFile, - this.listMergeFiles, - this.listMobileLoginInfo, - this.listPatientCount, - this.logInTokenID, - this.mohemmPrivilegeList, - this.pateintID, - this.patientBloodType, - this.patientHasFile, - this.patientMergedIDs, - this.patientOutSA, - this.patientShareRequestID, - this.patientType, - this.projectIDOut, - this.returnMessage, - this.sMSLoginRequired, - this.servicePrivilegeList, - this.sharePatientName, - this.verificationCode, - this.email, - this.errorList, - this.hasFile, - this.isActiveCode, - this.isMerged, - this.isNeedUserAgreement, - this.isSMSSent, - this.memberList, - this.message, - this.statusCode}); + CheckActivationCode({ + this.date, + this.languageId, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenId, + this.data, + this.dataw, + this.dietType, + this.dietTypeId, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorStatusCode, + this.errorType, + this.foodCategory, + this.iosLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.doctorInformationList, + this.getAllPendingRecordsList, + this.getAllSharedRecordsByStatusList, + this.getMaritalstatusLst, + this.getOccupationLst, + this.getResponseFileList, + this.hisPatientModelVpPortal, + this.isHmgPatient, + this.isLoginSuccessfully, + this.isNeedUpdateIdintificationNo, + this.isPatientAuthorized, + this.isVidaPlus, + this.kioskSendSms, + this.list, + this.listAskHabibMobileLoginInfo, + this.listAskHabibPatientFile, + this.listFamilyRelationships, + this.listMergeFiles, + this.listMobileLoginInfo, + this.listPatientCount, + this.logInTokenId, + this.mohemmPrivilegeList, + this.pateintId, + this.patientBloodType, + this.patientErAdminDriverFileList, + this.patientErAdminFile, + this.patientErDriverFile, + this.patientErDriverFileList, + this.patientHasFile, + this.patientMergedIDs, + this.patientOutSa, + this.patientShareRequestId, + this.patientType, + this.projectIdOut, + this.returnMessage, + this.smsLoginRequired, + this.servicePrivilegeList, + this.sharePatientName, + this.userAccountIsActivated, + this.verificationCode, + this.email, + this.errorList, + this.hasFile, + this.isActiveCode, + this.isMerged, + this.isNeedUserAgreement, + this.isSmsSent, + this.memberList, + this.message, + this.statusCode, + }); + + factory CheckActivationCode.fromRawJson(String str) => CheckActivationCode.fromJson(json.decode(str)); - CheckActivationCode.fromJson(Map json) { - date = json['Date']; - languageID = json['LanguageID']; - serviceName = json['ServiceName']; - time = json['Time']; - androidLink = json['AndroidLink']; - authenticationTokenID = json['AuthenticationTokenID']; - data = json['Data']; - dataw = json['Dataw']; - dietType = json['DietType']; - errorCode = json['ErrorCode']; - errorEndUserMessage = json['ErrorEndUserMessage']; - errorEndUserMessageN = json['ErrorEndUserMessageN']; - errorMessage = json['ErrorMessage']; - errorType = json['ErrorType']; - foodCategory = json['FoodCategory']; - iOSLink = json['IOSLink']; - isAuthenticated = json['IsAuthenticated']; - mealOrderStatus = json['MealOrderStatus']; - mealType = json['MealType']; - messageStatus = json['MessageStatus']; - numberOfResultRecords = json['NumberOfResultRecords']; - patientBlodType = json['PatientBlodType']; - successMsg = json['SuccessMsg']; - successMsgN = json['SuccessMsgN']; - doctorInformationList = json['DoctorInformation_List']; - getAllPendingRecordsList = json['GetAllPendingRecordsList']; - getAllSharedRecordsByStatusList = json['GetAllSharedRecordsByStatusList']; - getResponseFileList = json['GetResponseFileList']; - isHMGPatient = json['IsHMGPatient']; - isLoginSuccessfully = json['IsLoginSuccessfully']; - isNeedUpdateIdintificationNo = json['IsNeedUpdateIdintificationNo']; - kioskSendSMS = json['KioskSendSMS']; - if (json['List'] != null) { - list = AuthenticatedUser.fromJson(json['List'][0]); - } - listAskHabibMobileLoginInfo = json['List_AskHabibMobileLoginInfo']; - listAskHabibPatientFile = json['List_AskHabibPatientFile']; - listMergeFiles = json['List_MergeFiles']; - listMobileLoginInfo = json['List_MobileLoginInfo']; - listPatientCount = json['List_PatientCount']; - logInTokenID = json['LogInTokenID']; - mohemmPrivilegeList = json['MohemmPrivilege_List']; - pateintID = json['PateintID']; - patientBloodType = json['PatientBloodType']; - patientHasFile = json['PatientHasFile']; - patientMergedIDs = json['PatientMergedIDs']; - patientOutSA = json['PatientOutSA']; - patientShareRequestID = json['PatientShareRequestID']; - patientType = json['PatientType']; - projectIDOut = json['ProjectIDOut']; - returnMessage = json['ReturnMessage']; - sMSLoginRequired = json['SMSLoginRequired']; - servicePrivilegeList = json['ServicePrivilege_List']; - sharePatientName = json['SharePatientName']; - verificationCode = json['VerificationCode']; - email = json['email']; - errorList = json['errorList']; - hasFile = json['hasFile']; - isActiveCode = json['isActiveCode']; - isMerged = json['isMerged']; - isNeedUserAgreement = json['isNeedUserAgreement']; - isSMSSent = json['isSMSSent']; - memberList = json['memberList']; - message = json['message']; - statusCode = json['statusCode']; - } + String toRawJson() => json.encode(toJson()); - Map toJson() { - final Map data = {}; - data['Date'] = date; - data['LanguageID'] = languageID; - data['ServiceName'] = serviceName; - data['Time'] = time; - data['AndroidLink'] = androidLink; - data['AuthenticationTokenID'] = authenticationTokenID; - data['Data'] = this.data; - data['Dataw'] = dataw; - data['DietType'] = dietType; - data['ErrorCode'] = errorCode; - data['ErrorEndUserMessage'] = errorEndUserMessage; - data['ErrorEndUserMessageN'] = errorEndUserMessageN; - data['ErrorMessage'] = errorMessage; - data['ErrorType'] = errorType; - data['FoodCategory'] = foodCategory; - data['IOSLink'] = iOSLink; - data['IsAuthenticated'] = isAuthenticated; - data['MealOrderStatus'] = mealOrderStatus; - data['MealType'] = mealType; - data['MessageStatus'] = messageStatus; - data['NumberOfResultRecords'] = numberOfResultRecords; - data['PatientBlodType'] = patientBlodType; - data['SuccessMsg'] = successMsg; - data['SuccessMsgN'] = successMsgN; - data['DoctorInformation_List'] = doctorInformationList; - data['GetAllPendingRecordsList'] = getAllPendingRecordsList; - data['GetAllSharedRecordsByStatusList'] = getAllSharedRecordsByStatusList; - data['GetResponseFileList'] = getResponseFileList; - data['IsHMGPatient'] = isHMGPatient; - data['IsLoginSuccessfully'] = isLoginSuccessfully; - data['IsNeedUpdateIdintificationNo'] = isNeedUpdateIdintificationNo; - data['KioskSendSMS'] = kioskSendSMS; - if (list != null) { - data['List'] = list; - } - data['List_AskHabibMobileLoginInfo'] = listAskHabibMobileLoginInfo; - data['List_AskHabibPatientFile'] = listAskHabibPatientFile; - data['List_MergeFiles'] = listMergeFiles; - data['List_MobileLoginInfo'] = listMobileLoginInfo; - data['List_PatientCount'] = listPatientCount; - data['LogInTokenID'] = logInTokenID; - data['MohemmPrivilege_List'] = mohemmPrivilegeList; - data['PateintID'] = pateintID; - data['PatientBloodType'] = patientBloodType; - data['PatientHasFile'] = patientHasFile; - data['PatientMergedIDs'] = patientMergedIDs; - data['PatientOutSA'] = patientOutSA; - data['PatientShareRequestID'] = patientShareRequestID; - data['PatientType'] = patientType; - data['ProjectIDOut'] = projectIDOut; - data['ReturnMessage'] = returnMessage; - data['SMSLoginRequired'] = sMSLoginRequired; - data['ServicePrivilege_List'] = servicePrivilegeList; - data['SharePatientName'] = sharePatientName; - data['VerificationCode'] = verificationCode; - data['email'] = email; - data['errorList'] = errorList; - data['hasFile'] = hasFile; - data['isActiveCode'] = isActiveCode; - data['isMerged'] = isMerged; - data['isNeedUserAgreement'] = isNeedUserAgreement; - data['isSMSSent'] = isSMSSent; - data['memberList'] = memberList; - data['message'] = message; - data['statusCode'] = statusCode; - return data; - } + factory CheckActivationCode.fromJson(Map json) => CheckActivationCode( + date: json["Date"], + languageId: json["LanguageID"], + serviceName: json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"], + dietType: json["DietType"], + dietTypeId: json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorStatusCode: json["ErrorStatusCode"], + errorType: json["ErrorType"], + foodCategory: json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"], + mealType: json["MealType"], + messageStatus: json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + doctorInformationList: json["DoctorInformation_List"], + getAllPendingRecordsList: json["GetAllPendingRecordsList"], + getAllSharedRecordsByStatusList: json["GetAllSharedRecordsByStatusList"], + getMaritalstatusLst: json["GetMaritalstatusLst"], + getOccupationLst: json["GetOccupationLst"], + getResponseFileList: json["GetResponseFileList"], + hisPatientModelVpPortal: json["HIS_PatientModel_VPPortal"], + isHmgPatient: json["IsHMGPatient"], + isLoginSuccessfully: json["IsLoginSuccessfully"], + isNeedUpdateIdintificationNo: json["IsNeedUpdateIdintificationNo"], + isPatientAuthorized: json["IsPatientAuthorized"], + isVidaPlus: json["IsVidaPlus"], + kioskSendSms: json["KioskSendSMS"], + list: json["List"] == null ? [] : List.from(json["List"]!.map((x) => AuthenticatedUser.fromJson(x))), + listAskHabibMobileLoginInfo: json["List_AskHabibMobileLoginInfo"], + listAskHabibPatientFile: json["List_AskHabibPatientFile"], + listFamilyRelationships: json["List_FamilyRelationships"], + listMergeFiles: json["List_MergeFiles"], + listMobileLoginInfo: json["List_MobileLoginInfo"], + listPatientCount: json["List_PatientCount"], + logInTokenId: json["LogInTokenID"], + mohemmPrivilegeList: json["MohemmPrivilege_List"], + pateintId: json["PateintID"], + patientBloodType: json["PatientBloodType"], + patientErAdminDriverFileList: json["PatientER_AdminDriverFileList"], + patientErAdminFile: json["PatientER_AdminFile"], + patientErDriverFile: json["PatientER_DriverFile"], + patientErDriverFileList: json["PatientER_DriverFileList"], + patientHasFile: json["PatientHasFile"], + patientMergedIDs: json["PatientMergedIDs"], + patientOutSa: json["PatientOutSA"], + patientShareRequestId: json["PatientShareRequestID"], + patientType: json["PatientType"], + projectIdOut: json["ProjectIDOut"], + returnMessage: json["ReturnMessage"], + smsLoginRequired: json["SMSLoginRequired"], + servicePrivilegeList: json["ServicePrivilege_List"], + sharePatientName: json["SharePatientName"], + userAccountIsActivated: json["UserAccountIsActivated"], + verificationCode: json["VerificationCode"], + email: json["email"], + errorList: json["errorList"], + hasFile: json["hasFile"], + isActiveCode: json["isActiveCode"], + isMerged: json["isMerged"], + isNeedUserAgreement: json["isNeedUserAgreement"], + isSmsSent: json["isSMSSent"], + memberList: json["memberList"], + message: json["message"], + statusCode: json["statusCode"], + ); + + Map toJson() => { + "Date": date, + "LanguageID": languageId, + "ServiceName": serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw, + "DietType": dietType, + "DietTypeID": dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorStatusCode": errorStatusCode, + "ErrorType": errorType, + "FoodCategory": foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated, + "MealOrderStatus": mealOrderStatus, + "MealType": mealType, + "MessageStatus": messageStatus, + "NumberOfResultRecords": numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "DoctorInformation_List": doctorInformationList, + "GetAllPendingRecordsList": getAllPendingRecordsList, + "GetAllSharedRecordsByStatusList": getAllSharedRecordsByStatusList, + "GetMaritalstatusLst": getMaritalstatusLst, + "GetOccupationLst": getOccupationLst, + "GetResponseFileList": getResponseFileList, + "HIS_PatientModel_VPPortal": hisPatientModelVpPortal, + "IsHMGPatient": isHmgPatient, + "IsLoginSuccessfully": isLoginSuccessfully, + "IsNeedUpdateIdintificationNo": isNeedUpdateIdintificationNo, + "IsPatientAuthorized": isPatientAuthorized, + "IsVidaPlus": isVidaPlus, + "KioskSendSMS": kioskSendSms, + "List": list == null ? [] : List.from(list!.map((x) => x.toJson())), + "List_AskHabibMobileLoginInfo": listAskHabibMobileLoginInfo, + "List_AskHabibPatientFile": listAskHabibPatientFile, + "List_FamilyRelationships": listFamilyRelationships, + "List_MergeFiles": listMergeFiles, + "List_MobileLoginInfo": listMobileLoginInfo, + "List_PatientCount": listPatientCount, + "LogInTokenID": logInTokenId, + "MohemmPrivilege_List": mohemmPrivilegeList, + "PateintID": pateintId, + "PatientBloodType": patientBloodType, + "PatientER_AdminDriverFileList": patientErAdminDriverFileList, + "PatientER_AdminFile": patientErAdminFile, + "PatientER_DriverFile": patientErDriverFile, + "PatientER_DriverFileList": patientErDriverFileList, + "PatientHasFile": patientHasFile, + "PatientMergedIDs": patientMergedIDs, + "PatientOutSA": patientOutSa, + "PatientShareRequestID": patientShareRequestId, + "PatientType": patientType, + "ProjectIDOut": projectIdOut, + "ReturnMessage": returnMessage, + "SMSLoginRequired": smsLoginRequired, + "ServicePrivilege_List": servicePrivilegeList, + "SharePatientName": sharePatientName, + "UserAccountIsActivated": userAccountIsActivated, + "VerificationCode": verificationCode, + "email": email, + "errorList": errorList, + "hasFile": hasFile, + "isActiveCode": isActiveCode, + "isMerged": isMerged, + "isNeedUserAgreement": isNeedUserAgreement, + "isSMSSent": isSmsSent, + "memberList": memberList, + "message": message, + "statusCode": statusCode, + }; +} + +class ListElement { + String? setupId; + int? patientType; + int? patientId; + String? firstName; + String? middleName; + String? lastName; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? relationshipId; + int? gender; + String? dateofBirth; + dynamic dateofBirthN; + String? nationalityId; + String? phoneResi; + String? phoneOffice; + String? mobileNumber; + String? faxNumber; + String? emailAddress; + dynamic bloodGroup; + dynamic rhFactor; + bool? isEmailAlertRequired; + bool? isSmsAlertRequired; + String? preferredLanguage; + bool? isPrivilegedMember; + dynamic memberId; + dynamic expiryDate; + dynamic isHmgEmployee; + dynamic employeeId; + String? emergencyContactName; + String? emergencyContactNo; + int? patientPayType; + dynamic dhccPatientRefId; + bool? isPatientDummy; + int? status; + dynamic isStatusCleared; + int? patientIdentificationType; + String? patientIdentificationNo; + int? projectId; + int? infoSourceId; + dynamic address; + int? age; + String? ageDesc; + int? areaId; + int? crsVerificationStatus; + String? crsVerificationStatusDesc; + String? crsVerificationStatusDescN; + int? createdBy; + String? genderDescription; + String? healthIdFromNhicViaVida; + dynamic ir; + dynamic isoCityId; + dynamic isoCountryId; + bool? isVerfiedFromNhic; + List? listPrivilege; + dynamic marital; + dynamic occupationId; + int? outSa; + dynamic poBox; + bool? receiveHealthSummaryReport; + int? sourceType; + dynamic strDateofBirth; + dynamic tempAddress; + dynamic zipCode; + dynamic eHealthIdField; + dynamic listPatientPayType; + dynamic listPatientType; + dynamic listStatus; + + ListElement({ + this.setupId, + this.patientType, + this.patientId, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.relationshipId, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.nationalityId, + this.phoneResi, + this.phoneOffice, + this.mobileNumber, + this.faxNumber, + this.emailAddress, + this.bloodGroup, + this.rhFactor, + this.isEmailAlertRequired, + this.isSmsAlertRequired, + this.preferredLanguage, + this.isPrivilegedMember, + this.memberId, + this.expiryDate, + this.isHmgEmployee, + this.employeeId, + this.emergencyContactName, + this.emergencyContactNo, + this.patientPayType, + this.dhccPatientRefId, + this.isPatientDummy, + this.status, + this.isStatusCleared, + this.patientIdentificationType, + this.patientIdentificationNo, + this.projectId, + this.infoSourceId, + this.address, + this.age, + this.ageDesc, + this.areaId, + this.crsVerificationStatus, + this.crsVerificationStatusDesc, + this.crsVerificationStatusDescN, + this.createdBy, + this.genderDescription, + this.healthIdFromNhicViaVida, + this.ir, + this.isoCityId, + this.isoCountryId, + this.isVerfiedFromNhic, + this.listPrivilege, + this.marital, + this.occupationId, + this.outSa, + this.poBox, + this.receiveHealthSummaryReport, + this.sourceType, + this.strDateofBirth, + this.tempAddress, + this.zipCode, + this.eHealthIdField, + this.listPatientPayType, + this.listPatientType, + this.listStatus, + }); + + factory ListElement.fromRawJson(String str) => ListElement.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory ListElement.fromJson(Map json) => ListElement( + setupId: json["SetupID"], + patientType: json["PatientType"], + patientId: json["PatientID"], + firstName: json["FirstName"], + middleName: json["MiddleName"], + lastName: json["LastName"], + firstNameN: json["FirstNameN"], + middleNameN: json["MiddleNameN"], + lastNameN: json["LastNameN"], + relationshipId: json["RelationshipID"], + gender: json["Gender"], + dateofBirth: json["DateofBirth"], + dateofBirthN: json["DateofBirthN"], + nationalityId: json["NationalityID"], + phoneResi: json["PhoneResi"], + phoneOffice: json["PhoneOffice"], + mobileNumber: json["MobileNumber"], + faxNumber: json["FaxNumber"], + emailAddress: json["EmailAddress"], + bloodGroup: json["BloodGroup"], + rhFactor: json["RHFactor"], + isEmailAlertRequired: json["IsEmailAlertRequired"], + isSmsAlertRequired: json["IsSMSAlertRequired"], + preferredLanguage: json["PreferredLanguage"], + isPrivilegedMember: json["IsPrivilegedMember"], + memberId: json["MemberID"], + expiryDate: json["ExpiryDate"], + isHmgEmployee: json["IsHmgEmployee"], + employeeId: json["EmployeeID"], + emergencyContactName: json["EmergencyContactName"], + emergencyContactNo: json["EmergencyContactNo"], + patientPayType: json["PatientPayType"], + dhccPatientRefId: json["DHCCPatientRefID"], + isPatientDummy: json["IsPatientDummy"], + status: json["Status"], + isStatusCleared: json["IsStatusCleared"], + patientIdentificationType: json["PatientIdentificationType"], + patientIdentificationNo: json["PatientIdentificationNo"], + projectId: json["ProjectID"], + infoSourceId: json["InfoSourceID"], + address: json["Address"], + age: json["Age"], + ageDesc: json["AgeDesc"], + areaId: json["AreaID"], + crsVerificationStatus: json["CRSVerificationStatus"], + crsVerificationStatusDesc: json["CRSVerificationStatusDesc"], + crsVerificationStatusDescN: json["CRSVerificationStatusDescN"], + createdBy: json["CreatedBy"], + genderDescription: json["GenderDescription"], + healthIdFromNhicViaVida: json["HealthIDFromNHICViaVida"], + ir: json["IR"], + isoCityId: json["ISOCityID"], + isoCountryId: json["ISOCountryID"], + isVerfiedFromNhic: json["IsVerfiedFromNHIC"], + listPrivilege: json["ListPrivilege"] == null ? [] : List.from(json["ListPrivilege"]!.map((x) => ListPrivilege.fromJson(x))), + marital: json["Marital"], + occupationId: json["OccupationID"], + outSa: json["OutSA"], + poBox: json["POBox"], + receiveHealthSummaryReport: json["ReceiveHealthSummaryReport"], + sourceType: json["SourceType"], + strDateofBirth: json["StrDateofBirth"], + tempAddress: json["TempAddress"], + zipCode: json["ZipCode"], + eHealthIdField: json["eHealthIDField"], + listPatientPayType: json["patientPayType"], + listPatientType: json["patientType"], + listStatus: json["status"], + ); + + Map toJson() => { + "SetupID": setupId, + "PatientType": patientType, + "PatientID": patientId, + "FirstName": firstName, + "MiddleName": middleName, + "LastName": lastName, + "FirstNameN": firstNameN, + "MiddleNameN": middleNameN, + "LastNameN": lastNameN, + "RelationshipID": relationshipId, + "Gender": gender, + "DateofBirth": dateofBirth, + "DateofBirthN": dateofBirthN, + "NationalityID": nationalityId, + "PhoneResi": phoneResi, + "PhoneOffice": phoneOffice, + "MobileNumber": mobileNumber, + "FaxNumber": faxNumber, + "EmailAddress": emailAddress, + "BloodGroup": bloodGroup, + "RHFactor": rhFactor, + "IsEmailAlertRequired": isEmailAlertRequired, + "IsSMSAlertRequired": isSmsAlertRequired, + "PreferredLanguage": preferredLanguage, + "IsPrivilegedMember": isPrivilegedMember, + "MemberID": memberId, + "ExpiryDate": expiryDate, + "IsHmgEmployee": isHmgEmployee, + "EmployeeID": employeeId, + "EmergencyContactName": emergencyContactName, + "EmergencyContactNo": emergencyContactNo, + "PatientPayType": patientPayType, + "DHCCPatientRefID": dhccPatientRefId, + "IsPatientDummy": isPatientDummy, + "Status": status, + "IsStatusCleared": isStatusCleared, + "PatientIdentificationType": patientIdentificationType, + "PatientIdentificationNo": patientIdentificationNo, + "ProjectID": projectId, + "InfoSourceID": infoSourceId, + "Address": address, + "Age": age, + "AgeDesc": ageDesc, + "AreaID": areaId, + "CRSVerificationStatus": crsVerificationStatus, + "CRSVerificationStatusDesc": crsVerificationStatusDesc, + "CRSVerificationStatusDescN": crsVerificationStatusDescN, + "CreatedBy": createdBy, + "GenderDescription": genderDescription, + "HealthIDFromNHICViaVida": healthIdFromNhicViaVida, + "IR": ir, + "ISOCityID": isoCityId, + "ISOCountryID": isoCountryId, + "IsVerfiedFromNHIC": isVerfiedFromNhic, + "ListPrivilege": listPrivilege == null ? [] : List.from(listPrivilege!.map((x) => x.toJson())), + "Marital": marital, + "OccupationID": occupationId, + "OutSA": outSa, + "POBox": poBox, + "ReceiveHealthSummaryReport": receiveHealthSummaryReport, + "SourceType": sourceType, + "StrDateofBirth": strDateofBirth, + "TempAddress": tempAddress, + "ZipCode": zipCode, + "eHealthIDField": eHealthIdField, + "patientPayType": listPatientPayType, + "patientType": listPatientType, + "status": listStatus, + }; } class ListPrivilege { - int? iD; + int? id; String? serviceName; bool? previlege; dynamic region; - ListPrivilege({this.iD, this.serviceName, this.previlege, this.region}); + ListPrivilege({ + this.id, + this.serviceName, + this.previlege, + this.region, + }); + + factory ListPrivilege.fromRawJson(String str) => ListPrivilege.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); - ListPrivilege.fromJson(Map json) { - iD = json['ID']; - serviceName = json['ServiceName']; - previlege = json['Previlege']; - region = json['Region']; - } + factory ListPrivilege.fromJson(Map json) => ListPrivilege( + id: json["ID"], + serviceName: json["ServiceName"], + previlege: json["Previlege"], + region: json["Region"], + ); - Map toJson() { - final Map data = {}; - data['ID'] = iD; - data['ServiceName'] = serviceName; - data['Previlege'] = previlege; - data['Region'] = region; - return data; - } + Map toJson() => { + "ID": id, + "ServiceName": serviceName, + "Previlege": previlege, + "Region": region, + }; } diff --git a/lib/features/authentication/widgets/otp_verification_screen.dart b/lib/features/authentication/widgets/otp_verification_screen.dart index 9ea1b9e..caaf535 100644 --- a/lib/features/authentication/widgets/otp_verification_screen.dart +++ b/lib/features/authentication/widgets/otp_verification_screen.dart @@ -218,11 +218,12 @@ class _OTPVerificationScreenState extends State { final otp = _controllers.map((c) => c.text).join(); debugPrint('Verifying OTP: $otp'); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Verifying OTP: $otp')), - ); + widget.checkActivationCode(int.parse(otp)); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('Verifying OTP: $otp')), + // ); - Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => RegisterNewStep2(null, {"nationalID": "12345678654321"}))); + // Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => RegisterNewStep2(null, {"nationalID": "12345678654321"}))); } /// Auto fill OTP into text fields diff --git a/lib/features/common/models/commong_authanticated_req_model.dart b/lib/features/common/models/commong_authanticated_req_model.dart new file mode 100644 index 0000000..19d9f30 --- /dev/null +++ b/lib/features/common/models/commong_authanticated_req_model.dart @@ -0,0 +1,73 @@ +import 'dart:convert'; + +class CommonAuthanticatedRequest { + String? sessionId; + double? versionId; + int? channel; + int? languageId; + String? ipAdress; + String? generalid; + double? latitude; + double? longitude; + int? deviceTypeId; + int? patientType; + int? patientTypeId; + String? tokenId; + int? patientId; + int? patientOutSa; + + CommonAuthanticatedRequest({ + this.sessionId, + this.versionId, + this.channel, + this.languageId, + this.ipAdress, + this.generalid, + this.latitude, + this.longitude, + this.deviceTypeId, + this.patientType, + this.patientTypeId, + this.tokenId, + this.patientId, + this.patientOutSa, + }); + + factory CommonAuthanticatedRequest.fromRawJson(String str) => CommonAuthanticatedRequest.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory CommonAuthanticatedRequest.fromJson(Map json) => CommonAuthanticatedRequest( + sessionId: json["SessionID"], + versionId: json["VersionID"]?.toDouble(), + channel: json["Channel"], + languageId: json["LanguageID"], + ipAdress: json["IPAdress"], + generalid: json["generalid"], + latitude: json["Latitude"], + longitude: json["Longitude"], + deviceTypeId: json["DeviceTypeID"], + patientType: json["PatientType"], + patientTypeId: json["PatientTypeID"], + tokenId: json["TokenID"], + patientId: json["PatientID"], + patientOutSa: json["PatientOutSA"], + ); + + Map toJson() => { + "SessionID": sessionId, + "VersionID": versionId, + "Channel": channel, + "LanguageID": languageId, + "IPAdress": ipAdress, + "generalid": generalid, + "Latitude": latitude, + "Longitude": longitude, + "DeviceTypeID": deviceTypeId, + "PatientType": patientType, + "PatientTypeID": patientTypeId, + "TokenID": tokenId, + "PatientID": patientId, + "PatientOutSA": patientOutSa, + }; +} diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index 94ddd87..52f470d 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -11,7 +11,8 @@ class LabViewModel extends ChangeNotifier { ErrorHandlerService errorHandlerService; List patientLabOrders = []; - + List filteredLabOrders = []; + List tempLabOrdersList = []; late List _labSuggestionsList = []; List get labSuggestions => _labSuggestionsList; @@ -20,6 +21,7 @@ class LabViewModel extends ChangeNotifier { initLabProvider() { patientLabOrders.clear(); + filteredLabOrders.clear(); isLabOrdersLoading = true; isLabResultsLoading = true; getPatientLabOrders(); @@ -36,6 +38,8 @@ class LabViewModel extends ChangeNotifier { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); } else if (apiResponse.messageStatus == 1) { patientLabOrders = apiResponse.data!; + filteredLabOrders = List.from(patientLabOrders); + tempLabOrdersList = apiResponse.data!; isLabOrdersLoading = false; isLabResultsLoading = false; filterSuggestions(); @@ -48,14 +52,27 @@ class LabViewModel extends ChangeNotifier { ); } - filterSuggestions(){ + filterSuggestions() { final List labels = patientLabOrders - .expand((order) => order.testDetails!) // flatten testDetails - .map((detail) => detail.description) // pick description - .whereType() // remove nulls if any + .expand((order) => order.testDetails!) + .map((detail) => detail.description) + .whereType() .toList(); - _labSuggestionsList = labels.toSet().toList(); // remove duplicates by converting to a set and back to a list + _labSuggestionsList = labels.toSet().toList(); + + notifyListeners(); + } + filterLabReports(String query) { + if (query.isEmpty) { + filteredLabOrders = List.from(patientLabOrders); // reset + } else { + filteredLabOrders = patientLabOrders.where((order) { + final descriptions = order.testDetails?.map((d) => d.description?.toLowerCase()).toList() ?? []; + return descriptions.any((desc) => desc != null && desc.contains(query.toLowerCase())); + }).toList(); + patientLabOrders = filteredLabOrders; + } notifyListeners(); } } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 7831616..dc71850 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -805,5 +805,9 @@ abstract class LocaleKeys { static const checkAvailability = 'checkAvailability'; static const readInstructions = 'readInstructions'; static const searchLabReport = 'searchLabReport'; - + static const lastloginBy = 'lastloginBy'; + static const allSet ='allSet'; + static const enableQuickLogin = 'enableQuickLogin'; + static const enableMsg = 'enableMsg'; + static const notNow = 'notNow'; } diff --git a/lib/main.dart b/lib/main.dart index 2a8ef63..70a2158 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -117,6 +117,7 @@ void main() async { errorHandlerService: getIt(), navigationService: getIt(), cacheService: getIt(), + localAuthService: getIt(), ), ), ], child: MyApp()), diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index d6bdc36..609d881 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -335,7 +335,7 @@ class _AppointmentPaymentPageState extends State { // } } else { showCommonBottomSheet(context, - child: Utils.getLoadingWidget(), callBackFunc: () {}, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: false, isDismissible: false, isFullScreen: false); + child: Utils.getLoadingWidget(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: false, isDismissible: false, isFullScreen: false); await payfortViewModel.checkPaymentStatus( transactionID: transID, onSuccess: (apiResponse) async { @@ -399,7 +399,7 @@ class _AppointmentPaymentPageState extends State { "1", "Haroon Amjad", "3628599", - AuthenticatedUser(outSA: 0, mobileNumber: "0593233758"), + AuthenticatedUser(outSa: 0, mobileNumber: "0593233758"), browser!, widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false, "2", diff --git a/lib/presentation/authentication/quick_login.dart b/lib/presentation/authentication/quick_login.dart new file mode 100644 index 0000000..9cf0431 --- /dev/null +++ b/lib/presentation/authentication/quick_login.dart @@ -0,0 +1,136 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; + +class QuickLogin extends StatefulWidget { + final VoidCallback onPressed; + final bool isDone; + + const QuickLogin({super.key, required this.onPressed, this.isDone = false}); + + @override + _QuickLogin createState() => _QuickLogin(); +} + +class _QuickLogin extends State { + @override + Widget build(BuildContext context) { + return Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(24), + topRight: Radius.circular(24), + ), + ), + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + widget.isDone + ? Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + onTap: () { + Navigator.pop(context, true); + }, + child: Utils.buildSvgWithAssets(icon: AppAssets.cross_circle)), + ], + ), + Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120, height: 120, repeat: true), + LocaleKeys.allSet.tr().toText16(textAlign: + TextAlign.center, weight: FontWeight.w500) + // Text( + // ' TranslationBase.of(context).allSet', + // textAlign: TextAlign.center, + // style: context.dynamicTextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w500, + // color: Colors.black, + // ), + // ), + ], + ) + : Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + AppAssets.lockIcon, + height: 101, + ), + const SizedBox(height: 10), + LocaleKeys.enableQuickLogin.tr().toText26(isBold: true), + // Text( + // ' TranslationBase.of(context).enableQuickLogin', + // style: context.dynamicTextStyle( + // fontSize: 26, + // fontWeight: FontWeight.bold, + // color: Colors.black, + // ), + // ), + const SizedBox(height: 5), + LocaleKeys.enableQuickLogin.tr().toText16(color: AppColors.quickLoginColor), + // Description + // Text( + // 'TranslationBase.of(context).enableMsg', + // style: context.dynamicTextStyle( + // fontSize: 16, + // color: Color(0xFF666666), + // height: 1.5, + // ), + //), + const SizedBox(height: 24), + // Buttons + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: CustomButton( + text:LocaleKeys.enableQuickLogin.tr(), + onPressed: () { + widget.onPressed(); + }, + backgroundColor: Color(0xffED1C2B), + borderColor: Color(0xffED1C2B), + textColor: Colors.white, + icon:AppAssets.apple_finder, + )), + ], + ), + SizedBox( + height: 16, + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.notNow.tr(), + onPressed: () { + Navigator.pop(context, true); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Colors.red, + // icon: "assets/images/svg/apple-finder.svg", + )), + ], + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/presentation/authentication/register_step2.dart b/lib/presentation/authentication/register_step2.dart index 151a4c8..1e4c650 100644 --- a/lib/presentation/authentication/register_step2.dart +++ b/lib/presentation/authentication/register_step2.dart @@ -43,7 +43,7 @@ class _RegisterNew extends State { @override void dispose() { super.dispose(); - authVM!.clearDefaults(); + authVM!.clearDefaultInputValues(); } @override @@ -53,7 +53,7 @@ class _RegisterNew extends State { appBar: CustomAppBar( onBackPressed: () { Navigator.of(context).pop(); - authVM!.clearDefaults(); + authVM!.clearDefaultInputValues(); }, onLanguageChanged: (lang) {}, hideLogoAndLang: true, @@ -263,7 +263,7 @@ class _RegisterNew extends State { icon: AppAssets.cancel, onPressed: () { Navigator.of(context).pop(); - authVM!.clearDefaults(); + authVM!.clearDefaultInputValues(); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index da04c40..fe2c760 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -2,37 +2,51 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; 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'; +import 'package:provider/provider.dart'; + class SavedLogin extends StatefulWidget { - // final SelectDeviceIMEIRES savedLoginData; - // const SavedLogin(this.savedLoginData, {Key? key}) : super(key: key); - const SavedLogin(); + + const SavedLogin({Key? key}) : super(key: key); @override _SavedLogin createState() => _SavedLogin(); } class _SavedLogin extends State { - LoginTypeEnum loginType = LoginTypeEnum.sms; + LoginTypeEnum loginType = LoginTypeEnum.sms; + late AuthenticationViewModel authVm; + late AppState appState; @override void initState() { + authVm = context.read(); + appState = getIt.get(); + authVm.phoneNumberController.text = appState.getSelectDeviceByImeiRespModelElement!.mobile!; + authVm.nationalIdController.text = appState.getSelectDeviceByImeiRespModelElement!.identificationNo!; + super.initState(); } @override Widget build(BuildContext context) { + + return Scaffold( appBar: CustomAppBar( onBackPressed: () {}, @@ -48,7 +62,7 @@ class _SavedLogin extends State { // Welcome back text LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor), SizedBox(height: 16.h), - ("widget.savedLoginData.name!.toLowerCase().capitalizeFirstofEach").toText26(isBold: true, height: 26 / 36, color: AppColors.textColor), + appState.getSelectDeviceByImeiRespModelElement!.name!.toCamelCase.toText26(isBold: true, height: 26 / 36, color: AppColors.textColor), SizedBox(height: 24.h), Container( padding: EdgeInsets.all(16.h), @@ -63,22 +77,25 @@ class _SavedLogin extends State { child: Column( children: [ // Last login info - ('LocaleKeys.lastloginBy.tr()' + ' {getType(widget.savedLoginData.logInType!, context)}').toText14(isBold: true, color: AppColors.greyTextColor), - ('widget.savedLoginData.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate(widget.savedLoginData.createdOn!), "d MMMM, y at HH:mm") : --') + + ("${LocaleKeys.lastloginBy.tr() } ${LoginTypeExtension.fromValue(appState.getSelectDeviceByImeiRespModelElement!.logInType!)!.displayName}" + ).toText14(isBold: true, color: AppColors.greyTextColor), + (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!), "d MMMM, y at HH:mm") : '--') .toText16(isBold: true, color: AppColors.textColor), - Container(margin: EdgeInsets.all(16.h), child: Utils.buildSvgWithAssets(icon: getTypeIcons(loginType.toInt), iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)), + Container(margin: EdgeInsets.all(16.h), child: Utils.buildSvgWithAssets(icon: getTypeIcons(loginType.toInt), height: 54, width: 54, iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)), // Face ID login button - Container( + SizedBox( height: 45, child: CustomButton( text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}", onPressed: () { if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { - // loginWithFingerPrintFace(loginType.toInt, widget.savedLoginData.iMEI!); - } else { - int? val = loginType.toInt; - //checkUserAuthentication(val); + authVm.loginWithFingerPrintFace(loginType.toInt); + } + else { + // int? val = loginType.toInt; + authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp); } }, backgroundColor: Color(0xffED1C2B), @@ -104,7 +121,7 @@ class _SavedLogin extends State { ), const SizedBox(height: 24), // OTP login button - loginType != null && loginType.toInt != 1 + loginType.toInt != 1 ? Column( children: [ loginType.toInt != 1 @@ -140,7 +157,7 @@ class _SavedLogin extends State { Navigator.of(context).pop(); loginType = LoginTypeEnum.sms; int? val = loginType.toInt; - // checkUserAuthentication(val); + authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.sms ); }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedBorderColor, @@ -163,7 +180,7 @@ class _SavedLogin extends State { Navigator.of(context).pop(); loginType = LoginTypeEnum.whatsapp; int? val = loginType.toInt; - // checkUserAuthentication(val); + authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.whatsapp ); }, backgroundColor: AppColors.transparent, borderColor: AppColors.textColor, @@ -195,11 +212,12 @@ class _SavedLogin extends State { text: "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}", onPressed: () { if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { - // loginWithFingerPrintFace(loginType.toInt, "iMEI"); + authVm.loginWithFingerPrintFace(loginType.toInt); } else { loginType = LoginTypeEnum.whatsapp; int? val = loginType.toInt; - // checkUserAuthentication(val); + authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.whatsapp ); + } }, backgroundColor: AppColors.whiteColor, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index e21e044..611be7d 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -11,14 +11,17 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/authentication/quick_login.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; +import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart' show CustomTabBar; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; @@ -31,11 +34,25 @@ class LandingPage extends StatefulWidget { } class _LandingPageState extends State { + late final AuthenticationViewModel authVM; + + @override + void initState() { + authVM = context.read(); + if(mounted) { + authVM.checkLastLoginStatus(() { + + showQuickLogin(context, false); + }); + } + super.initState(); + } + @override Widget build(BuildContext context) { AppState appState = getIt.get(); NavigationService navigationService = getIt.get(); - final AuthenticationViewModel authenticationViewModel = context.read(); + return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: SingleChildScrollView( @@ -46,32 +63,54 @@ class _LandingPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - CustomButton( - text: LocaleKeys.loginOrRegister.tr(context: context), - onPressed: () async { - await authenticationViewModel.onLoginPressed(); - }, - backgroundColor: Color(0xffFEE9EA), - borderColor: Color(0xffFEE9EA), - textColor: Color(0xffED1C2B), - fontSize: 16, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50, - ), - Utils.buildSvgWithAssets( - icon: AppAssets.contact_icon, - width: 24, - height: 24, - ).onPress(() { - Navigator.of(context).push( - FadePage( - page: MedicalFilePage(), - // page: LoginScreen(), - ), - ); - }), + appState.isAuthenticated + ? WelcomeWidget( + onTap: () {}, + name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), + imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg, + ) + : CustomButton( + text: LocaleKeys.loginOrRegister.tr(context: context), + onPressed: () async { + await authVM.onLoginPressed(); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50, + ), + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 20, width: 20).onPress(() { + Navigator.of(context).push( + FadePage( + page: MedicalFilePage(), + // page: LoginScreen(), + ), + ); + }).paddingSymmetrical(8.h, 0), + Utils.buildSvgWithAssets(icon: AppAssets.search_icon, height: 20, width: 20).onPress(() { + Navigator.of(context).push( + FadePage( + page: MedicalFilePage(), + // page: LoginScreen(), + ), + ); + }).paddingSymmetrical(8.h, 0), + Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 20, width: 20).onPress(() { + Navigator.of(context).push( + FadePage( + page: MedicalFilePage(), + // page: LoginScreen(), + ), + ); + }).paddingSymmetrical(8.h, 0), + ], + ) ], ).paddingSymmetrical(24.h, 0.h), ), @@ -281,4 +320,21 @@ class _LandingPageState extends State { ), ); } + + void showQuickLogin(BuildContext context, bool isDone) { + showCommonBottomSheet( + context, + title: "", + child: QuickLogin( + isDone: isDone, + onPressed: () { + // sharedPref.setBool(HAS_ENABLED_QUICK_LOGIN, true); + // loginWithFingerPrintFace(3, 1, user, deviceToken); + }, + ), + height: 400, + isFullScreen: false, + callBackFunc: (str) {}, + ); + } } diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart new file mode 100644 index 0000000..d761a7f --- /dev/null +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; + +class WelcomeWidget extends StatelessWidget { + final String name; + final String imageUrl; + final VoidCallback? onTap; + + const WelcomeWidget({ + super.key, + required this.name, + required this.imageUrl, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(30), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + // Profile image + + Image.asset(imageUrl, width: 40, height: 40), + + const SizedBox(width: 10), + + // Text column + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + "Welcome".toText14(color: AppColors.greyTextColor), + + + Row( + children: [ + + name.toText16(isBold: true), + + const SizedBox(width: 4), + const Icon(Icons.keyboard_arrow_down, size: 20, color: Colors.black), + ], + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index 131c454..451eeee 100644 --- a/lib/presentation/insurance/insurance_home_page.dart +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -64,7 +64,7 @@ class _InsuranceHomePageState extends State { insuranceVM.setIsInsuranceHistoryLoading(true); insuranceVM.getPatientInsuranceCardHistory(); showCommonBottomSheet(context, - child: InsuranceHistory(), callBackFunc: () {}, title: "", height: ResponsiveExtension.screenHeight * 0.65, isCloseButtonVisible: false, isFullScreen: false); + child: InsuranceHistory(), callBackFunc: (str){}, title: "", height: ResponsiveExtension.screenHeight * 0.65, isCloseButtonVisible: false, isFullScreen: false); }, backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), borderColor: AppColors.primaryRedColor.withOpacity(0.0), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 1edef84..4906493 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -120,7 +120,7 @@ class PatientInsuranceCard extends StatelessWidget { insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); insuranceViewModel.getPatientInsuranceDetailsForUpdate(); showCommonBottomSheet(context, - child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", height: ResponsiveExtension.screenHeight * 0.42, isCloseButtonVisible: false, isFullScreen: false); + child: PatientInsuranceCardUpdateCard(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.42, isCloseButtonVisible: false, isFullScreen: false); }, backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), borderColor: AppColors.bgGreenColor.withOpacity(0.0), diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 153505b..4705a2a 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -15,6 +16,7 @@ import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -30,7 +32,7 @@ class _LabOrdersPageState extends State { late LabViewModel labProvider; List?> labSuggestions = []; int? expandedIndex; - + String? selectedFilterText=''; @override void initState() { scheduleMicrotask(() { @@ -63,10 +65,13 @@ class _LabOrdersPageState extends State { Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(() { if (model.isLabOrdersLoading) { return; - } else { - showCommonBottomSheet(context, - child: SearchLabResultsContent(labSuggestionsList: model.labSuggestions), - callBackFunc: () {}, + }else { + + showCommonBottomSheet(context, child: SearchLabResultsContent(labSuggestionsList: model.labSuggestions), + callBackFunc: (value) { + selectedFilterText = value; + model.filterLabReports(value!); + }, title: LocaleKeys.searchLabReport.tr(), height: ResponsiveExtension.screenHeight, isFullScreen: true, @@ -79,6 +84,8 @@ class _LabOrdersPageState extends State { // Build Tab Bar SizedBox(height: 16.h), // Expandable list + + selectedFilterText!.isNotEmpty ? CustomChipWidget(chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 4369157..0039705 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -1,14 +1,17 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; +import 'package:hmg_patient_app_new/presentation/home/landing_page.dart'; import 'package:hmg_patient_app_new/splashPage.dart'; class AppRoutes { static const String initialRoute = '/initialRoute'; static const String loginScreen = '/loginScreen'; static const String registerNewScreen = '/registerNewScreen'; + static const String landingScreen = '/landingScreen'; static Map get routes => { initialRoute: (context) => SplashPage(), loginScreen: (context) => LoginScreen(), + landingScreen: (context) => LandingPage(), }; } diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 28b77e1..9ba939b 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; abstract class DialogService { @@ -70,7 +71,9 @@ class _ErrorBottomSheet extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), ), - child: const Text("OK"), + child: const Text("OK", style: TextStyle(color: Colors.white)).onPress((){ + Navigator.of(context).pop(); + }), ), ], ), diff --git a/lib/services/localauth_service.dart b/lib/services/localauth_service.dart new file mode 100644 index 0000000..a01d1c1 --- /dev/null +++ b/lib/services/localauth_service.dart @@ -0,0 +1,40 @@ +import 'package:local_auth/local_auth.dart'; + +import 'logger_service.dart'; + +class LocalAuthService { + final LocalAuthentication localAuth; + final LoggerService loggerService; + LocalAuthService({required this.localAuth, required this.loggerService}); + + Future authenticate() async { + try { + bool isAuthenticated = await localAuth.authenticate( + localizedReason: 'Please authenticate to proceed', + options: const AuthenticationOptions( + biometricOnly: true, + stickyAuth: true, + ), + ); + return isAuthenticated; + } catch (e) { + return false; + } + } + + Future canCheckBiometrics() async { + try { + return await localAuth.canCheckBiometrics; + } catch (e) { + return false; + } + } + + Future> getAvailableBiometrics() async { + try { + return await localAuth.getAvailableBiometrics(); + } catch (e) { + return []; + } + } +} \ No newline at end of file diff --git a/lib/services/navigation_service.dart b/lib/services/navigation_service.dart index 6dd4a54..9835bba 100644 --- a/lib/services/navigation_service.dart +++ b/lib/services/navigation_service.dart @@ -18,6 +18,10 @@ class NavigationService { navigatorKey.currentState?.popUntil(ModalRoute.withName(routeName)); } + void pushAndReplace(String routeName) { + navigatorKey.currentState?.pushReplacementNamed(routeName); + } + Future pushToOtpScreen({ required String phoneNumber, required Function(int code) checkActivationCode, diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 5cb9ced..c8eaa87 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -58,4 +58,6 @@ static const Color warningLightColor = Color(0xFFFFCC00); static const Color greyLightColor = Color(0xFFEFEFF0); static const Color bottomNAVBorder = Color(0xFFEEEEEE); + +static const Color quickLoginColor = Color(0xFF666666); } diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 78b9480..25df532 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -7,7 +7,7 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; void showCommonBottomSheet(BuildContext context, - {required Widget child, required VoidCallback callBackFunc, String? title, required double height, bool isCloseButtonVisible = true, bool isFullScreen = true, bool isDismissible = true}) { + {required Widget child, Function(String?)? callBackFunc, String? title, required double height, bool isCloseButtonVisible = true, bool isFullScreen = true, bool isDismissible = true}) { showModalBottomSheet( sheetAnimationStyle: AnimationStyle( duration: Duration(milliseconds: 500), // Custom animation duration @@ -30,7 +30,9 @@ void showCommonBottomSheet(BuildContext context, ), ); }).then((value) { - callBackFunc(); + if(value != null) { + callBackFunc!(value); + } }); } @@ -64,12 +66,14 @@ class ButtonSheetContent extends StatelessWidget { // Close button isCloseButtonVisible && isFullScreen - ? Padding( - padding: EdgeInsets.symmetric(horizontal: 16), + ? Column(children: [ + SizedBox(height: 40.h,), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16,), child: Utils.buildSvgWithAssets(icon: AppAssets.closeBottomNav, width: 32, height: 32).onPress(() { Navigator.of(context).pop(); }), - ) + )]) : SizedBox(), isFullScreen diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart index bea8e60..3fe0de9 100644 --- a/lib/widgets/in_app_browser/InAppBrowser.dart +++ b/lib/widgets/in_app_browser/InAppBrowser.dart @@ -207,7 +207,7 @@ class MyInAppBrowser extends InAppBrowser { tamaraRequestModel.appointmentNo = (appoNo != null && appoNo != "") ? appoNo.toString() : "0"; tamaraRequestModel.customerName = patientName; tamaraRequestModel.fileNumber = patientID.toString(); - tamaraRequestModel.patientOutSA = authenticatedUser.outSA == 1 ? true : false; + tamaraRequestModel.patientOutSA = authenticatedUser.outSa == 1 ? true : false; tamaraRequestModel.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken); tamaraRequestModel.latitude = appState.userLat.toString(); tamaraRequestModel.longitude = appState.userLong.toString(); @@ -276,7 +276,7 @@ class MyInAppBrowser extends InAppBrowser { form = form.replaceFirst('PROJECT_ID_VALUE', projId); form = form.replaceFirst('PAYMENT_OPTION_VALUE', paymentMethod); form = form.replaceFirst('LANG_VALUE', currentLanguageID); - form = form.replaceFirst('PATIENT_OUT_SA', authUser.outSA == 0 ? false.toString() : true.toString()); + form = form.replaceFirst('PATIENT_OUT_SA', authUser.outSa == 0 ? false.toString() : true.toString()); form = form.replaceFirst('PATIENT_TYPE_ID', patientData == null ? patientType.toString() : "1"); Platform.isIOS @@ -338,10 +338,10 @@ class MyInAppBrowser extends InAppBrowser { form = form.replaceFirst('INSTALLMENTS_VALUE', installments); form = form.replaceFirst('CUSTNATIONALID_VALUE', authUser.patientIdentificationNo!); form = form.replaceFirst('CUSTMOBILE_VALUE', authUser.mobileNumber!); - form = form.replaceFirst('CUSTDOB_VALUE', DateUtil.getDayMonthYearDateFormatted(authUser.dateofBirthDataTime!)); + form = form.replaceFirst('CUSTDOB_VALUE', DateUtil.getDayMonthYearDateFormatted(authUser.strDateofBirth!)); - form = form.replaceFirst('CURRENCY_VALUE', authUser.outSA == 0 ? "SAR" : "AED"); - form = form.replaceFirst('COUNTRY_CODE_VALUE', authUser.outSA == 0 ? "966" : "971"); + form = form.replaceFirst('CURRENCY_VALUE', authUser.outSa == 0 ? "SAR" : "AED"); + form = form.replaceFirst('COUNTRY_CODE_VALUE', authUser.outSa == 0 ? "966" : "971"); form = form.replaceFirst('CUSTNAME_VALUE', patientName); form = form.replaceFirst('CUSTLASTNAME_VALUE', patientName); form = form.replaceFirst('CUSTID_VALUE', patientID.toString()); diff --git a/pubspec.yaml b/pubspec.yaml index 75f9992..7536aaa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: google_api_availability: ^5.0.1 firebase_analytics: ^11.5.1 jiffy: ^6.4.3 - hijri_gregorian_calendar: ^0.0.4 + hijri_gregorian_calendar: ^0.1.0 web: any flutter_staggered_animations: ^1.1.1 @@ -84,6 +84,7 @@ flutter: uses-material-design: true assets: - assets/ + - assets/json/ - assets/fonts/ - assets/langs/ - assets/images/