From 4f303d8496f271cd295d3cfb15331e179a5afe31 Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Thu, 12 Mar 2026 14:30:46 +0300 Subject: [PATCH] other country login done. --- assets/langs/ar-SA.json | 1 + assets/langs/en-US.json | 1 + lib/core/api/api_client.dart | 44 +++++------ lib/core/api_consts.dart | 4 + lib/core/app_assets.dart | 1 + lib/core/app_state.dart | 1 + lib/core/enums.dart | 2 +- lib/core/utils/request_utils.dart | 46 +++++++---- lib/core/utils/validation_utils.dart | 14 +++- lib/extensions/string_extensions.dart | 11 +++ .../authentication/authentication_repo.dart | 56 ++++++++++++-- .../authentication_view_model.dart | 62 +++++++++------ ...ctivation_code_register_request_model.dart | 16 +++- .../patient_insert_device_imei_request.dart | 6 +- .../send_activation_request_model.dart | 14 +++- .../resp_models/select_device_by_imei.dart | 5 +- lib/generated/locale_keys.g.dart | 1 + lib/presentation/authentication/login.dart | 77 +++++++++++-------- lib/presentation/authentication/register.dart | 2 +- .../authentication/saved_login_screen.dart | 60 ++++++++++----- lib/presentation/home/landing_page.dart | 2 + .../bottomsheet/generic_bottom_sheet.dart | 2 +- .../dropdown/country_dropdown_widget.dart | 20 +++-- .../family_files/family_file_add_widget.dart | 2 +- 24 files changed, 307 insertions(+), 143 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 0886f376..f929b1ae 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -814,6 +814,7 @@ "ready": "جاهز", "enterValidNationalId": "الرجاء إدخال رقم الهوية الوطنية أو رقم الملف الصحيح", "enterValidPhoneNumber": "الرجاء إدخال رقم هاتف صالح", + "cannotEnterSaudiOrUAENumber": "لا يمكنك إدخال أرقام هواتف السعودية (00966) أو الإمارات (00971) عند اختيار دولة 'أخرى'", "medicalCentersWithCount": "{count} مراكز طبية", "medicalCenters": "مراكز طبية", "hospitalsWithCount": "{count} مستشفيات", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 294201db..b1cc5b08 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -804,6 +804,7 @@ "awaitingApproval": "Awaiting Approval", "enterValidNationalId": "Please enter a valid national ID or file number", "enterValidPhoneNumber": "Please enter a valid phone number", + "cannotEnterSaudiOrUAENumber": "You cannot enter Saudi Arabia (00966) or UAE (00971) phone numbers when 'Others' country is selected", "ready": "Ready", "medicalCentersWithCount": "{count} Medical Centers", "medicalCenters": " Medical Centers", diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index b17db626..916f9b89 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -129,8 +129,7 @@ class ApiClientImp implements ApiClient { } else {} if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = - body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] ?? IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; + body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') ? body['isDentalAllowedBackend'] ?? IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND; } if (!body.containsKey('IsPublicRequest')) { @@ -194,6 +193,11 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } + if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { + url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; + body['TokenID'] = "@dm!n"; + } + // body['TokenID'] = "@dm!n"; // body['PatientID'] = 4773715; // body['PatientTypeID'] = 1; @@ -207,7 +211,7 @@ class ApiClientImp implements ApiClient { // body['PatientID'] = 809289; } - if(!url.contains("/paymentApi")) { + if (!url.contains("/paymentApi")) { body['IsNewFlutterApp'] = true; } @@ -261,10 +265,9 @@ class ApiClientImp implements ApiClient { ApiClient._navigationService.pushAndRemoveUntil( CustomPageRoute( page: AppUpdatePage( - appUpdateMessage: parsed['ErrorEndUserMessage'], - )), - ModalRoute.withName("/appUpdate") - ); + appUpdateMessage: parsed['ErrorEndUserMessage'], + )), + ModalRoute.withName("/appUpdate")); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (parsed['ErrorType'] == 2) { @@ -272,24 +275,19 @@ class ApiClientImp implements ApiClient { onFailure( parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode, - failureType: - UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), + failureType: UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), ); // logApiEndpointError(endPoint, "session logged out", statusCode); } if (isAllowAny) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['IsAuthenticated'] == null) { if (parsed['isSMSSent'] == true) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['MessageStatus'] == 1) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['Result'] == 'OK') { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { onFailure( parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], @@ -299,19 +297,16 @@ class ApiClientImp implements ApiClient { logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else if (parsed['IsAuthenticated'] == false) { onFailure( "User is not Authenticated", statusCode, - failureType: - UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), + failureType: UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), ); } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { @@ -340,8 +335,7 @@ class ApiClientImp implements ApiClient { } } else { if (parsed['SameClinicApptList'] != null) { - onSuccess(parsed, statusCode, - messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); + onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); } else { if (parsed['message'] != null) { onFailure( diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index ecfbc70a..a529c740 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -112,10 +112,13 @@ class ApiConsts { static final String selectDeviceImei = 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; static final String checkPatientAuth = 'Services/Authentication.svc/REST/CheckPatientAuthentication'; + static final String checkPatientAuthOthers = 'Services/Authentication.svc/REST/CheckPatientAuthentication_Others'; static final String sendActivationCode = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType'; + static final String sendActivationCodeOthers = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType_Others'; static final String sendActivationCodeRegister = 'Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration'; static final String checkActivationCode = 'Services/Authentication.svc/REST/CheckActivationCode'; + static final String checkActivationCodeOthers = 'Services/Authentication.svc/REST/CheckActivationCode_Others'; 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'; @@ -124,6 +127,7 @@ class ApiConsts { static final String checkUserStatus = 'Services/NHIC.svc/REST/GetPatientInfo'; static final String insertPatientDeviceIMEIData = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI'; + static final String insertPatientDeviceIMEIDataOthers = 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI_Others'; static final String insertPatientMobileData = 'Services/MobileNotifications.svc/REST/Insert_PatientMobileDeviceInfo'; static final String getPatientMobileData = '/Services/Authentication.svc/REST/GetMobileLoginInfo'; static final String getPrivileges = 'Services/Patients.svc/REST/Service_Privilege'; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index efe62775..fdd32814 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -16,6 +16,7 @@ class AppAssets { static const String call = '$svgBasePath/call.svg'; static const String email = '$svgBasePath/email.svg'; static const String globe = '$svgBasePath/globe.svg'; + static const String globeOther = '$svgBasePath/globe_other.svg'; static const String cancel = '$svgBasePath/cancel.svg'; static const String bell = '$svgBasePath/bell.svg'; static const String login1 = '$svgBasePath/login1.svg'; diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index e1d6e05b..b95b883f 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -116,6 +116,7 @@ class AppState { set setIsAuthenticated(v) => isAuthenticated = v; + String deviceTypeID = ""; set setDeviceTypeID(v) => deviceTypeID = v; diff --git a/lib/core/enums.dart b/lib/core/enums.dart index 66137021..8bb8330c 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -12,7 +12,7 @@ enum AuthMethodTypesEnum { sms, whatsApp, fingerPrint, faceID, moreOptions } enum ViewStateEnum { hide, idle, busy, error, busyLocal, errorLocal } -enum CountryEnum { saudiArabia, unitedArabEmirates } +enum CountryEnum { saudiArabia, unitedArabEmirates, others } enum CalenderEnum { gregorian, hijri } diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart index dd81a13c..bb947398 100644 --- a/lib/core/utils/request_utils.dart +++ b/lib/core/utils/request_utils.dart @@ -27,14 +27,21 @@ class RequestUtils { }) { bool fileNo = false; if (nationId.isNotEmpty) { - fileNo = nationId.length < 10; + final numericRegex = RegExp(r'^[0-9]+$'); + fileNo = nationId.length < 10 && numericRegex.hasMatch(nationId); + //fileNo = nationId.length < 10 && nationId.isNumericOnly() ; if (fileNo) { patientId = int.tryParse(nationId); } } var request = SendActivationRequest(); if (phoneNumber.isNotEmpty) { - request.patientMobileNumber = int.parse(phoneNumber); + // If zipCode is "0", it means "Others" country is selected + if (zipCode == "0") { + request.patientMobileNumberOthers = phoneNumber; + } else { + request.patientMobileNumber = int.parse(phoneNumber); + } } request.oTPSendType = otpTypeEnum.toInt(); // could map OTPTypeEnum if needed request.zipCode = zipCode; // or countryCode if defined elsewhere @@ -53,9 +60,9 @@ class RequestUtils { request.patientIdentificationID = request.nationalID; request.searchType = 2; } else { - request.patientID = 0; + request.patientID = 0; request.searchType = 1; - request.patientIdentificationID = request.nationalID = nationId.isNotEmpty ? int.parse(nationId) : 0; + request.patientIdentificationID = request.nationalID = nationId.isNotEmpty ? nationId : '0'; } request.isRegister = false; } @@ -75,11 +82,18 @@ class RequestUtils { required int loginType}) { bool fileNo = false; if (nationIdText.isNotEmpty) { - fileNo = nationIdText.length < 10; + final numericRegex = RegExp(r'^[0-9]+$'); + fileNo = nationIdText.length < 10 && numericRegex.hasMatch(nationIdText); } var request = SendActivationRequest(); - request.patientMobileNumber = int.parse(phoneNumber); - request.mobileNo = '0$phoneNumber'; + // If countryCode is "0", it means "Others" country is selected + if (countryCode == "0") { + request.patientMobileNumberOthers = phoneNumber; + request.mobileNo = phoneNumber; + } else { + request.patientMobileNumber = int.parse(phoneNumber); + request.mobileNo = '0$phoneNumber'; + } request.deviceToken = deviceToken; request.projectOutSA = patientOutSA; request.loginType = loginType; @@ -102,14 +116,14 @@ class RequestUtils { } else { if (fileNo) { request.patientID = patientId ?? int.parse(nationIdText); - request.patientIdentificationID = request.nationalID = 0; + request.patientIdentificationID = request.nationalID = '0'; request.searchType = 2; //TODO: Issue HEre is Not Login } else { request.patientID = 0; request.searchType = 1; //TODO: Issue HEre is Not Login - request.patientIdentificationID = request.nationalID = (nationIdText.isNotEmpty ? int.parse(nationIdText) : 0); + request.patientIdentificationID = request.nationalID = (nationIdText.isNotEmpty ? nationIdText : '0'); } request.isRegister = false; } @@ -123,7 +137,7 @@ class RequestUtils { required String mobileNumber, required String zipCode, required int? patientId, - required int? nationalId, + required dynamic nationalId, required bool patientOutSA, required int selectedLoginType, required bool isForRegister, @@ -136,9 +150,15 @@ class RequestUtils { AppState _appState = getIt.get(); var request = SendActivationRequest(); if (mobileNumber.isNotEmpty) { - request.patientMobileNumber = int.parse(mobileNumber); + // If zipCode is "0", it means "Others" country is selected + if (zipCode == "0") { + request.patientMobileNumberOthers = mobileNumber; + request.mobileNo = mobileNumber; + } else { + request.patientMobileNumber = int.parse(mobileNumber); + request.mobileNo = '0$mobileNumber'; + } } - request.mobileNo = '0$mobileNumber'; request.projectOutSA = patientOutSA; request.loginType = selectedLoginType; request.oTPSendType = otpTypeEnum.toInt(); //this.selectedOption == 1 ? 1 : 2; @@ -159,7 +179,7 @@ class RequestUtils { request.searchType = isFileNo ? 2 : 1; request.patientID = patientId ?? 0; request.nationalID = nationalId ?? 0; - request.patientIdentificationID = (nationalId ?? '0') as int?; + request.patientIdentificationID = (nationalId ?? '0'); request.isRegister = false; } request.deviceTypeID = request.searchType; diff --git a/lib/core/utils/validation_utils.dart b/lib/core/utils/validation_utils.dart index abba4477..a8bc03d3 100644 --- a/lib/core/utils/validation_utils.dart +++ b/lib/core/utils/validation_utils.dart @@ -60,11 +60,23 @@ class ValidationUtils { return isCorrectID; } - static bool isValidatePhone({String? phoneNumber, required Function() onOkPress}) { + static bool isValidatePhone({String? phoneNumber, required Function() onOkPress, CountryEnum? selectedCountry}) { if (phoneNumber == null || phoneNumber.isEmpty) { _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidPhoneNumber.tr(), onOkPressed: onOkPress); return false; } + + // Check if "Others" country is selected and phone number starts with restricted codes + if (selectedCountry == CountryEnum.others) { + if (phoneNumber.startsWith('00966') || phoneNumber.startsWith('00971')) { + _dialogService.showExceptionBottomSheet( + message: LocaleKeys.cannotEnterSaudiOrUAENumber.tr(), + onOkPressed: onOkPress + ); + return false; + } + } + return true; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index ba646cd2..3f9327fc 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -470,6 +470,8 @@ extension CountryExtension on CountryEnum { return "Kingdom Of Saudi Arabia"; case CountryEnum.unitedArabEmirates: return "United Arab Emirates"; + case CountryEnum.others: + return "Others"; } } @@ -479,6 +481,8 @@ extension CountryExtension on CountryEnum { return "المملكة العربية السعودية"; case CountryEnum.unitedArabEmirates: return "الإمارات العربية المتحدة"; + case CountryEnum.others: + return "آخرون"; } } @@ -488,6 +492,8 @@ extension CountryExtension on CountryEnum { return AppAssets.ksa; case CountryEnum.unitedArabEmirates: return AppAssets.uae; + case CountryEnum.others: + return AppAssets.globeOther; } } @@ -497,6 +503,8 @@ extension CountryExtension on CountryEnum { return "966"; case CountryEnum.unitedArabEmirates: return "971"; + case CountryEnum.others: + return "0"; } } @@ -508,6 +516,9 @@ extension CountryExtension on CountryEnum { case "United Arab Emirates": case "الإمارات العربية المتحدة": return CountryEnum.unitedArabEmirates; + case "Others": + case "آخرون": + return CountryEnum.others; default: throw Exception("Invalid country name"); } diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 9b09c43c..f3b14c67 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -102,11 +102,16 @@ class AuthenticationRepoImp implements AuthenticationRepo { Future>> checkPatientAuthentication({required dynamic checkPatientAuthenticationReq, String? languageID}) async { int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1; checkPatientAuthenticationReq.patientOutSA = isOutKsa; + + // Determine which API to use based on zipCode + final isOthersCountry = checkPatientAuthenticationReq.zipCode == '0'; + final apiEndpoint = isOthersCountry ? ApiConsts.checkPatientAuthOthers : ApiConsts.checkPatientAuth; + try { GenericApiModel? apiResponse; Failure? failure; await apiClient.post( - ApiConsts.checkPatientAuth, + apiEndpoint, body: checkPatientAuthenticationReq.toJson(), onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -150,16 +155,25 @@ class AuthenticationRepoImp implements AuthenticationRepo { // payload.remove("ResponseID"); } + // Determine which API to use based on zipCode + final isOthersCountry = sendActivationCodeReq.zipCode == '0'; + String apiEndpoint; + if (isFormFamilyFile) { + apiEndpoint = ApiConsts.sendFamilyFileActivation; + } else if (isRegister) { + apiEndpoint = ApiConsts.sendActivationCodeRegister; + } else if (isOthersCountry) { + apiEndpoint = ApiConsts.sendActivationCodeOthers; + } else { + apiEndpoint = ApiConsts.sendActivationCode; + } + try { GenericApiModel? apiResponse; Failure? failure; await apiClient.post( - isFormFamilyFile - ? ApiConsts.sendFamilyFileActivation - : isRegister - ? ApiConsts.sendActivationCodeRegister - : ApiConsts.sendActivationCode, + apiEndpoint, body: isFormFamilyFile ? payload : sendActivationCodeReq.toJson(), onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -186,6 +200,8 @@ class AuthenticationRepoImp implements AuthenticationRepo { } } + + @override Future>> checkActivationCodeRepo( {required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq @@ -304,11 +320,16 @@ class AuthenticationRepoImp implements AuthenticationRepo { } } + // Determine which API to use based on zipCode + final zipCode = _getZipCodeFromRequest(newRequest); + final isOthersCountry = zipCode == '0'; final endpoint = isFormFamilyFile ? ApiConsts.checkActivationCodeForFamily : isRegister ? ApiConsts.checkActivationCodeRegister - : ApiConsts.checkActivationCode; + : isOthersCountry + ? ApiConsts.checkActivationCodeOthers + : ApiConsts.checkActivationCode; try { GenericApiModel? apiResponse; @@ -521,8 +542,14 @@ class AuthenticationRepoImp implements AuthenticationRepo { try { GenericApiModel? apiResponse; Failure? failure; + + // Determine which API to use based on zipCode + final zipCode = patientIMEIDataRequest['ZipCode']; + final isOthersCountry = zipCode == '0'; + final apiEndpoint = isOthersCountry ? ApiConsts.insertPatientDeviceIMEIDataOthers : ApiConsts.insertPatientDeviceIMEIData; + return apiClient.post( - ApiConsts.insertPatientDeviceIMEIData, + apiEndpoint, body: patientIMEIDataRequest, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -648,4 +675,17 @@ class AuthenticationRepoImp implements AuthenticationRepo { return Future.value(Left(UnknownFailure(e.toString()))); } } + + /// Helper method to safely get zipCode from dynamic request (Map or Object) + String _getZipCodeFromRequest(dynamic request) { + if (request is Map) { + return request['ZipCode']?.toString() ?? request['zipCode']?.toString() ?? ''; + } else { + try { + return request.zipCode?.toString() ?? ''; + } catch (e) { + return ''; + } + } + } } diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 6fc36191..ce54c69f 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -70,7 +70,7 @@ class AuthenticationViewModel extends ChangeNotifier { _errorHandlerService = errorHandlerService, _appState = appState, _authenticationRepo = authenticationRepo, - _localAuthService = localAuthService; + _localAuthService = localAuthService {} final TextEditingController nationalIdController = TextEditingController(), phoneNumberController = TextEditingController(), dobController = TextEditingController(), @@ -182,6 +182,17 @@ class AuthenticationViewModel extends ChangeNotifier { void onPhoneNumberChange(String? phoneNumber) { phoneNumberController.text = phoneNumber!; + + // Real-time validation for Others country - prevent entering Saudi/UAE numbers + if (selectedCountrySignup == CountryEnum.others) { + if (phoneNumber.startsWith('00966') || phoneNumber.startsWith('00971')) { + // Remove the restricted prefix + phoneNumberController.text = phoneNumber.replaceAll(RegExp(r'^(00966|00971)'), ''); + phoneNumberController.selection = TextSelection.fromPosition( + TextPosition(offset: phoneNumberController.text.length), + ); + } + } } void onTermAccepted() { @@ -301,9 +312,11 @@ class AuthenticationViewModel extends ChangeNotifier { patientOutSA: false, otpTypeEnum: otpTypeEnum, patientId: 0, - zipCode: _appState.getSelectDeviceByImeiRespModelElement != null && _appState.getSelectDeviceByImeiRespModelElement!.outSa == true - ? CountryEnum.unitedArabEmirates.countryCode - : selectedCountrySignup.countryCode, + zipCode: selectedCountrySignup == CountryEnum.others + ? "0" + : (_appState.getSelectDeviceByImeiRespModelElement != null && _appState.getSelectDeviceByImeiRespModelElement!.outSa == true + ? CountryEnum.unitedArabEmirates.countryCode + : selectedCountrySignup.countryCode), calenderType: calenderType); final result = await _authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); @@ -368,7 +381,7 @@ class AuthenticationViewModel extends ChangeNotifier { mobileNumber: phoneNumber, selectedLoginType: otpTypeEnum.toInt(), zipCode: selectedCountrySignup.countryCode, - nationalId: int.parse(nationalIdOrFileNumber), + nationalId:nationalIdOrFileNumber, isFileNo: isForRegister ? isPatientHasFile(request: payload) : false, patientId: isFormFamilyFile ? _appState.getAuthenticatedUser()!.patientId : 0, isForRegister: isForRegister, @@ -607,6 +620,7 @@ class AuthenticationViewModel extends ChangeNotifier { activation.list!.first.isParentUser = true; } activation.list!.first.bloodGroup = activation.patientBlodType; + activation.list!.first.zipCode = selectedCountrySignup == CountryEnum.others ? '0' : selectedCountrySignup.countryCode; _appState.setAuthenticatedUser(activation.list!.first); _appState.setPrivilegeModelList(activation.list!.first.listPrivilege!); _appState.setUserBloodGroup = activation.patientBlodType ?? "N/A"; @@ -854,7 +868,9 @@ class AuthenticationViewModel extends ChangeNotifier { await clearDefaultInputValues(); // This will Clear All Default Values Of User. Future.delayed(Duration(seconds: 1), () { LoadingUtils.hideFullScreenLoader(); - _navigationService.pushAndReplace(AppRoutes.loginScreen); + // _navigationService.pushAndReplace(AppRoutes.loginScreen); + _navigationService.pushAndRemoveUntil(CustomPageRoute(page: LandingNavigation()), (r) => false); + _navigationService.push(CustomPageRoute(page: LoginScreen())); }); } } @@ -948,22 +964,24 @@ class AuthenticationViewModel extends ChangeNotifier { Future insertPatientIMEIData(int loginType) async { final resultEither = await _authenticationRepo.insertPatientIMEIData( patientIMEIDataRequest: PatientInsertDeviceImei( - imei: _appState.deviceToken, - deviceTypeId: _appState.getDeviceTypeID(), - patientId: _appState.getAuthenticatedUser()!.patientId!, - patientIdentificationNo: _appState.getAuthenticatedUser()!.patientIdentificationNo!, - identificationNo: _appState.getAuthenticatedUser()!.patientIdentificationNo!, - firstName: _appState.getAuthenticatedUser()!.firstName!, - lastName: _appState.getAuthenticatedUser()!.lastName!, - patientTypeId: _appState.getAuthenticatedUser()!.patientType, - mobileNo: _appState.getAuthenticatedUser()!.mobileNumber!, - logInTypeId: loginType, - patientOutSa: _appState.getAuthenticatedUser()!.outSa!, - outSa: _appState.getAuthenticatedUser()!.outSa == 1 ? true : false, - biometricEnabled: loginType == 1 || loginType == 2 ? false : true, - firstNameN: _appState.getAuthenticatedUser()!.firstNameN, - lastNameN: _appState.getAuthenticatedUser()!.lastNameN, - ).toJson()); + imei: _appState.deviceToken, + deviceTypeId: _appState.getDeviceTypeID(), + patientId: _appState.getAuthenticatedUser()!.patientId!, + patientIdentificationNo: _appState.getAuthenticatedUser()!.patientIdentificationNo!, + identificationNo: _appState.getAuthenticatedUser()!.patientIdentificationNo!, + firstName: _appState.getAuthenticatedUser()!.firstName!, + lastName: _appState.getAuthenticatedUser()!.lastName!, + patientTypeId: _appState.getAuthenticatedUser()!.patientType, + mobileNo: _appState.getAuthenticatedUser()!.mobileNumber!, + logInTypeId: loginType, + patientOutSa: _appState.getAuthenticatedUser()!.outSa!, + outSa: _appState.getAuthenticatedUser()!.outSa == 1 ? true : false, + biometricEnabled: loginType == 1 || loginType == 2 ? false : true, + firstNameN: _appState.getAuthenticatedUser()!.firstNameN, + lastNameN: _appState.getAuthenticatedUser()!.lastNameN, + zipCode: _appState.getAuthenticatedUser()!.zipCode //selectedCountrySignup == CountryEnum.others ? '0': selectedCountrySignup.countryCode, + ) + .toJson()); resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { if (apiResponse.messageStatus == 1) { log("Insert IMEI Success"); diff --git a/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart b/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart index ebae7bc8..be9b8994 100644 --- a/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart +++ b/lib/features/authentication/models/request_models/check_activation_code_register_request_model.dart @@ -1,5 +1,6 @@ class CheckActivationCodeRegisterReq { int? patientMobileNumber; + String? patientMobileNumberOthers; String? mobileNo; String? deviceToken; bool? projectOutSA; @@ -9,8 +10,8 @@ class CheckActivationCodeRegisterReq { String? logInTokenID; int? searchType; int? patientID; - int? nationalID; - int? patientIdentificationID; + dynamic nationalID; + dynamic patientIdentificationID; String? activationCode; bool? isSilentLogin; double? versionID; @@ -29,6 +30,7 @@ class CheckActivationCodeRegisterReq { CheckActivationCodeRegisterReq({ this.patientMobileNumber, + this.patientMobileNumberOthers, this.mobileNo, this.deviceToken, this.projectOutSA, @@ -59,6 +61,7 @@ class CheckActivationCodeRegisterReq { CheckActivationCodeRegisterReq.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; + patientMobileNumberOthers = json['PatientMobileNumber_Others']; mobileNo = json['MobileNo']; deviceToken = json['DeviceToken']; projectOutSA = json['ProjectOutSA']; @@ -89,9 +92,14 @@ class CheckActivationCodeRegisterReq { Map toJson() { final Map data = {}; - data['PatientMobileNumber'] = patientMobileNumber; - data['MobileNo'] = mobileNo; + // Only send PatientMobileNumber_Others if it's set, otherwise send PatientMobileNumber + if (patientMobileNumberOthers != null) { + data['PatientMobileNumber_Others'] = patientMobileNumberOthers; + } else if (patientMobileNumber != null) { + data['PatientMobileNumber'] = patientMobileNumber; + } data['DeviceToken'] = deviceToken; + data['MobileNo'] = mobileNo; data['ProjectOutSA'] = projectOutSA; data['LoginType'] = loginType; data['ZipCode'] = zipCode; diff --git a/lib/features/authentication/models/request_models/patient_insert_device_imei_request.dart b/lib/features/authentication/models/request_models/patient_insert_device_imei_request.dart index 0b2a99f3..09e262e7 100644 --- a/lib/features/authentication/models/request_models/patient_insert_device_imei_request.dart +++ b/lib/features/authentication/models/request_models/patient_insert_device_imei_request.dart @@ -28,6 +28,7 @@ class PatientInsertDeviceImei { int? patientOutSa; String? sessionId; String? lastName; + String? zipCode; PatientInsertDeviceImei({ this.setupId, @@ -56,7 +57,8 @@ class PatientInsertDeviceImei { this.patientTypeId, this.patientOutSa, this.sessionId, - this.lastName + this.lastName, + this.zipCode, }); factory PatientInsertDeviceImei.fromRawJson(String str) => PatientInsertDeviceImei.fromJson(json.decode(str)); @@ -91,6 +93,7 @@ class PatientInsertDeviceImei { patientOutSa: json["PatientOutSA"], sessionId: json["SessionID"], lastName: json["LastName"], + zipCode: json["ZipCode"], ); @@ -122,5 +125,6 @@ class PatientInsertDeviceImei { "PatientOutSA": patientOutSa, "SessionID": sessionId, "LastName": lastName, + "ZipCode": zipCode, }; } diff --git a/lib/features/authentication/models/request_models/send_activation_request_model.dart b/lib/features/authentication/models/request_models/send_activation_request_model.dart index 6bd48b44..2908f7ec 100644 --- a/lib/features/authentication/models/request_models/send_activation_request_model.dart +++ b/lib/features/authentication/models/request_models/send_activation_request_model.dart @@ -1,5 +1,6 @@ class SendActivationRequest { int? patientMobileNumber; + String? patientMobileNumberOthers; String? mobileNo; String? deviceToken; bool? projectOutSA; @@ -9,8 +10,8 @@ class SendActivationRequest { String? logInTokenID; int? searchType; int? patientID; - int? nationalID; - int? patientIdentificationID; + dynamic nationalID; + dynamic patientIdentificationID; int? oTPSendType; int? languageID; double? versionID; @@ -32,6 +33,7 @@ class SendActivationRequest { SendActivationRequest( {this.patientMobileNumber, + this.patientMobileNumberOthers, this.mobileNo, this.deviceToken, this.projectOutSA, @@ -64,6 +66,7 @@ class SendActivationRequest { SendActivationRequest.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; + patientMobileNumberOthers = json['PatientMobileNumber_Others']; mobileNo = json['MobileNo']; deviceToken = json['DeviceToken']; projectOutSA = json['ProjectOutSA']; @@ -97,7 +100,12 @@ class SendActivationRequest { Map toJson() { final Map data = new Map(); - data['PatientMobileNumber'] = patientMobileNumber; + // Only send PatientMobileNumber_Others if it's set, otherwise send PatientMobileNumber + if (patientMobileNumberOthers != null) { + data['PatientMobileNumber_Others'] = patientMobileNumberOthers; + } else if (patientMobileNumber != null) { + data['PatientMobileNumber'] = patientMobileNumber; + } data['MobileNo'] = mobileNo; data['DeviceToken'] = deviceToken; data['ProjectOutSA'] = projectOutSA; diff --git a/lib/features/authentication/models/resp_models/select_device_by_imei.dart b/lib/features/authentication/models/resp_models/select_device_by_imei.dart index 398f7918..20a876f4 100644 --- a/lib/features/authentication/models/resp_models/select_device_by_imei.dart +++ b/lib/features/authentication/models/resp_models/select_device_by_imei.dart @@ -19,7 +19,7 @@ class SelectDeviceByImeiRespModelElement { bool? biometricEnabled; int? patientType; int? preferredLanguage; - + bool? isOther; SelectDeviceByImeiRespModelElement({ this.id, this.imei, @@ -35,6 +35,7 @@ class SelectDeviceByImeiRespModelElement { this.biometricEnabled, this.patientType, this.preferredLanguage, + this.isOther }); factory SelectDeviceByImeiRespModelElement.fromJson(Map json) => SelectDeviceByImeiRespModelElement( @@ -52,6 +53,7 @@ class SelectDeviceByImeiRespModelElement { biometricEnabled: json["BiometricEnabled"] as bool?, patientType: json["PatientType"] as int?, preferredLanguage: json["PreferredLanguage"] as int?, + isOther: json["IsOther"] as bool? ); Map toJson() => { @@ -69,5 +71,6 @@ class SelectDeviceByImeiRespModelElement { "BiometricEnabled": biometricEnabled, "PatientType": patientType, "PreferredLanguage": preferredLanguage, + "IsOther": isOther, }; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 58639f9c..1a33df93 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -812,6 +812,7 @@ abstract class LocaleKeys { static const ready = 'ready'; static const enterValidNationalId = 'enterValidNationalId'; static const enterValidPhoneNumber = 'enterValidPhoneNumber'; + static const cannotEnterSaudiOrUAENumber = 'cannotEnterSaudiOrUAENumber'; static const medicalCentersWithCount = 'medicalCentersWithCount'; static const medicalCenters = 'medicalCenters'; static const hospitalsWithCount = 'hospitalsWithCount'; diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index 28b47304..62b207ac 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -79,7 +79,7 @@ class LoginScreenState extends State { hintText: "xxxxxxxxx", controller: authVm.nationalIdController, focusNode: _nationalIdFocusNode, - keyboardType: TextInputType.number, + keyboardType: TextInputType.text, isEnable: true, prefix: null, autoFocus: true, @@ -165,51 +165,60 @@ class LoginScreenState extends State { child: SingleChildScrollView( child: GenericBottomSheet( countryCode: authViewModel.selectedCountrySignup.countryCode, + initialPhoneNumber: "", textController: phoneNumberController, isEnableCountryDropdown: true, - onCountryChange: authViewModel.onCountryChange, + onCountryChange: (country) { + authViewModel.onCountryChange(country); + setModalState(() {}); + }, onChange: authViewModel.onPhoneNumberChange, buttons: [ - Padding( - padding: EdgeInsets.only(bottom: 10.h), - child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(context: context), - onPressed: () async { - if (ValidationUtils.isValidatePhone( - phoneNumber: phoneNumberController!.text, - onOkPress: () { - Navigator.of(context).pop(); - })) { - Navigator.of(context).pop(); - appState.setSelectDeviceByImeiRespModelElement(null); - await authViewModel.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms); - } - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedBorderColor, - textColor: Colors.white, - iconColor: Colors.white, - icon: AppAssets.message, - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 8.h), - child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor), + if (authViewModel.selectedCountrySignup != CountryEnum.others) + Padding( + padding: EdgeInsets.only(bottom: 10.h), + child: CustomButton( + text: LocaleKeys.sendOTPSMS.tr(context: context), + onPressed: () async { + if (ValidationUtils.isValidatePhone( + phoneNumber: phoneNumberController!.text, + selectedCountry: authViewModel.selectedCountrySignup, + onOkPress: () { + Navigator.of(context).pop(); + })) { + Navigator.of(context).pop(); + appState.setSelectDeviceByImeiRespModelElement(null); + await authViewModel.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms); + } + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedBorderColor, + textColor: Colors.white, + iconColor: Colors.white, + icon: AppAssets.message, ), - ], - ), + ), + if (authViewModel.selectedCountrySignup != CountryEnum.others) + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.h), + child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor), + ), + ], + ), Padding( padding: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), + onPressed: () async { if (ValidationUtils.isValidatePhone( phoneNumber: phoneNumberController!.text, + selectedCountry: authViewModel.selectedCountrySignup, onOkPress: () { Navigator.of(context).pop(); })) { @@ -220,7 +229,7 @@ class LoginScreenState extends State { }, backgroundColor: Colors.white, borderColor: AppColors.borderOnlyColor, - textColor: AppColors.whiteColor, + textColor: AppColors.borderOnlyColor, icon: AppAssets.whatsapp, iconColor: null, applyThemeColor: false, diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index 9d67920f..535cdff1 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -90,7 +90,7 @@ class _RegisterNew extends State { child: Column( children: [ CustomCountryDropdown( - countryList: CountryEnum.values, + countryList: CountryEnum.values.where((c) => c != CountryEnum.others).toList(), onCountryChange: authVm.onCountryChange, // isRtl: Directionality.of(context) == TextDirection.LTR, ).withVerticalPadding(8.h), diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index 231d7d14..00673cd7 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -31,7 +31,7 @@ class _SavedLogin extends State { LoginTypeEnum loginType = LoginTypeEnum.sms; late AuthenticationViewModel authVm; late AppState appState; - + bool? isOther; @override void initState() { authVm = context.read(); @@ -43,6 +43,15 @@ class _SavedLogin extends State { : appState.getSelectDeviceByImeiRespModelElement!.mobile!; authVm.nationalIdController.text = appState.getSelectDeviceByImeiRespModelElement!.identificationNo!; + // Check if this is an "Others" country user + isOther = appState.getSelectDeviceByImeiRespModelElement!.isOther == true; + + // Set country to Others if isOther flag is true - this ensures _Others APIs are called + if (isOther!) { + authVm.phoneNumberController.text = appState.getSelectDeviceByImeiRespModelElement!.mobile!; + authVm.selectedCountrySignup = CountryEnum.others; + } + if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { authVm.loginWithFingerPrintFace(() {}); } @@ -90,9 +99,9 @@ class _SavedLogin extends State { ), child: Column( children: [ - // Last login info + // Last login info - show WhatsApp only if isOther AND loginType is SMS - ("${LocaleKeys.lastLoginBy.tr()} ${loginType.displayName}") + ("${LocaleKeys.lastLoginBy.tr()} ${(isOther == true && loginType == LoginTypeEnum.sms) ? LoginTypeEnum.whatsapp.displayName : loginType.displayName}") .toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -1), Directionality( textDirection: ui.TextDirection.ltr, @@ -108,20 +117,27 @@ class _SavedLogin extends State { ? Container( margin: EdgeInsets.all(16.h), child: Utils.buildSvgWithAssets( - icon: getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!), + icon: (isOther == true && loginType == LoginTypeEnum.sms) ? AppAssets.whatsapp : getTypeIcons(appState.getSelectDeviceByImeiRespModelElement!.logInType!), height: 54.h, width: 54.w, - iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)) + iconColor: (isOther == true && loginType == LoginTypeEnum.sms) || loginType.toInt == 4 ? null : AppColors.primaryRedColor)) : SizedBox(), - // Face ID login button + // Main login button - for isOther with SMS, show WhatsApp, otherwise keep original login type CustomButton( - text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}", + text: (isOther == true && loginType == LoginTypeEnum.sms) + ? "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}" + : "${LocaleKeys.loginBy.tr()} ${loginType.displayName}", onPressed: () { if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { authVm.loginWithFingerPrintFace(() {}); } else { - authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp); + // For isOther with SMS, use WhatsApp; otherwise use the original login type + authVm.checkUserAuthentication( + otpTypeEnum: (isOther == true && loginType == LoginTypeEnum.sms) + ? OTPTypeEnum.whatsapp + : (loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp), + ); } }, backgroundColor: AppColors.primaryRedColor, @@ -132,24 +148,25 @@ class _SavedLogin extends State { borderRadius: 12.r, height: 40.h, padding: EdgeInsets.symmetric(vertical: 10.h), - icon: getTypeIcons(loginType.toInt), - //loginType == LoginTypeEnum.sms ? AppAssets.sms :AppAssets.whatsapp, - iconColor: loginType != LoginTypeEnum.whatsapp ? Colors.white : null, + icon: (isOther == true && loginType == LoginTypeEnum.sms) ? AppAssets.whatsapp : getTypeIcons(loginType.toInt), + iconColor: (isOther == true && loginType == LoginTypeEnum.sms) || loginType == LoginTypeEnum.whatsapp ? null : Colors.white, ), ], ), ), SizedBox(height: 24.h), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16.w), - child: Text( - LocaleKeys.oR.tr(), - style: context.dynamicTextStyle(fontSize: 16.f, fontWeight: FontWeight.w500), + // Hide OR + OTP login options entirely when isOther is true + if (isOther != true) ...[ + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.w), + child: Text( + LocaleKeys.oR.tr(), + style: context.dynamicTextStyle(fontSize: 16.f, fontWeight: FontWeight.w500), + ), ), - ), - SizedBox(height: 24.h), - // OTP login button - loginType.toInt != 1 + SizedBox(height: 24.h), + // OTP login button + loginType.toInt != 1 ? Column( children: [ loginType.toInt != 1 @@ -256,9 +273,10 @@ class _SavedLogin extends State { borderWidth: 2.w, padding: EdgeInsets.fromLTRB(0, 14.h, 0, 14.h), ), + ], + const Spacer(flex: 2), // OR divider - SizedBox(height: 24.h), // Guest and Switch account Row( diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 607a47f7..a7ae78b9 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -10,6 +10,7 @@ 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/cache_consts.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'; @@ -1051,6 +1052,7 @@ class _LandingPageState extends State { isDone: isDone, onPressed: () { // sharedPref.setBool(HAS_ENABLED_QUICK_LOGIN, true); + authVM.loginWithFingerPrintFace(() async { isDone = true; cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: true); diff --git a/lib/widgets/bottomsheet/generic_bottom_sheet.dart b/lib/widgets/bottomsheet/generic_bottom_sheet.dart index fd79b7c1..21cc076f 100644 --- a/lib/widgets/bottomsheet/generic_bottom_sheet.dart +++ b/lib/widgets/bottomsheet/generic_bottom_sheet.dart @@ -158,7 +158,7 @@ class GenericBottomSheetState extends State { prefix: widget.isForEmail ? null : widget.countryCode, isBorderAllowed: false, isAllowLeadingIcon: true, - fontSize: 18.f, + fontSize: 14.f, isCountryDropDown: widget.isEnableCountryDropdown, leadingIcon: widget.isForEmail ? AppAssets.email : AppAssets.smart_phone, fontFamily: "Poppins", diff --git a/lib/widgets/dropdown/country_dropdown_widget.dart b/lib/widgets/dropdown/country_dropdown_widget.dart index bc4b5edf..c0efbc98 100644 --- a/lib/widgets/dropdown/country_dropdown_widget.dart +++ b/lib/widgets/dropdown/country_dropdown_widget.dart @@ -98,11 +98,12 @@ class CustomCountryDropdownState extends State { Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - Text( - selectedCountry!.countryCode, - style: TextStyle(fontSize: 12.f, fontWeight: FontWeight.w600, letterSpacing: -0.4, height: 1.5, fontFamily: "Poppins"), - ), - SizedBox(width: 4.h), + if (selectedCountry != CountryEnum.others) + Text( + selectedCountry!.countryCode, + style: TextStyle(fontSize: 12.f, fontWeight: FontWeight.w600, letterSpacing: -0.4, height: 1.5, fontFamily: "Poppins"), + ), + if (selectedCountry != CountryEnum.others) SizedBox(width: 4.h), if (widget.isEnableTextField) SizedBox( height: 20.h, @@ -112,7 +113,14 @@ class CustomCountryDropdownState extends State { child: TextField( focusNode: textFocusNode, style: TextStyle(fontSize: 12.f, fontWeight: FontWeight.w600, letterSpacing: -0.4, height: 1.5, fontFamily: "Poppins"), - decoration: InputDecoration(hintText: "", isDense: true, border: InputBorder.none, contentPadding: EdgeInsets.zero), + + decoration: InputDecoration( + hintText: selectedCountry == CountryEnum.others ? "001*******" : "", + isDense: true, + border: InputBorder.none, + contentPadding: EdgeInsets.zero, + + ), keyboardType: TextInputType.phone, onChanged: widget.onPhoneNumberChanged, ), diff --git a/lib/widgets/family_files/family_file_add_widget.dart b/lib/widgets/family_files/family_file_add_widget.dart index d8b4d13e..c4f43248 100644 --- a/lib/widgets/family_files/family_file_add_widget.dart +++ b/lib/widgets/family_files/family_file_add_widget.dart @@ -44,7 +44,7 @@ class _FamilyFileAddWidgetState extends State { child: Column( children: [ CustomCountryDropdown( - countryList: CountryEnum.values, + countryList: CountryEnum.values.where((c) => c != CountryEnum.others).toList(), onCountryChange: authVm.onCountryChange, ).paddingOnly(top: 8.h, bottom: 16.h), Divider(height: 1.h, color: AppColors.spacerLineColor),