diff --git a/assets/images/svg/visa_mastercard.svg b/assets/images/svg/visa_mastercard.svg new file mode 100644 index 0000000..22e19fa --- /dev/null +++ b/assets/images/svg/visa_mastercard.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index aead424..57e0ebc 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -132,6 +132,7 @@ class AppAssets { static const String touch_face_id = '$svgBasePath/touch_face_id.svg'; static const String minus = '$svgBasePath/minus.svg'; static const String home_lab_result_icon = '$svgBasePath/home_lab_result_icon.svg'; + static const String visa_mastercard_icon = '$svgBasePath/visa_mastercard.svg'; //bottom navigation// static const String homeBottom = '$svgBasePath/home_bottom.svg'; diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index e9abeaa..c906374 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -44,6 +44,7 @@ class AppState { setIsAuthenticated = true; _authenticatedRootUser = authenticatedUser; } + } AuthenticatedUser? getAuthenticatedUser({bool isFamily = false}) { @@ -97,7 +98,7 @@ class AppState { set setDeviceTypeID(v) => deviceTypeID = v; List vidaPlusProjectList = []; - List privilegeModelList = []; + List privilegeModelList = []; List hMCProjectListModel = []; List projectDetailListModel = []; @@ -105,7 +106,7 @@ class AppState { vidaPlusProjectList = vidaPlusProjectListModelInput; } - setPrivilegeModelList(List privilegeModelListInput) { + setPrivilegeModelList(List privilegeModelListInput) { privilegeModelList = privilegeModelListInput; } diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 6b74a7b..e0eeb23 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -650,7 +650,7 @@ class Utils { ); } - static Widget getPaymentAmountWithSymbol2(num habibWalletAmount, Color iconColor, double iconSize, {bool isSaudiCurrency = true, bool isExpanded = true}) { + static Widget getPaymentAmountWithSymbol2(num habibWalletAmount, {double iconSize = 14, Color iconColor = AppColors.textColor, Color textColor = AppColors.blackColor, bool isSaudiCurrency = true, bool isExpanded = true}) { return RichText( maxLines: 1, text: TextSpan( @@ -658,11 +658,11 @@ class Utils { WidgetSpan( alignment: PlaceholderAlignment.baseline, baseline: TextBaseline.alphabetic, - child: Utils.buildSvgWithAssets(icon: AppAssets.saudi_riyal_icon, width: 14.h, height: 14.h, iconColor: Colors.black.withValues(alpha: 0.31)), + child: Utils.buildSvgWithAssets(icon: AppAssets.saudi_riyal_icon, width: iconSize.h, height: iconSize.h, iconColor: iconColor), ), TextSpan( text: " $habibWalletAmount", - style: TextStyle(color: AppColors.blackColor, fontSize: 32.fSize, letterSpacing: -4, fontWeight: FontWeight.w600, height: 1), + style: TextStyle(color: textColor, fontSize: 32.fSize, letterSpacing: -4, fontWeight: FontWeight.w600, height: 1), ), ], ), @@ -708,4 +708,16 @@ class Utils { await file.writeAsBytes(bytes); return file.path; } + + static bool havePrivilege(int id) { + bool isHavePrivilege = false; + try { + for (var element in appState.privilegeModelList) { + if (element.id == id) isHavePrivilege = element.previlege!; + } + } catch (e) { + print(e); + } + return isHavePrivilege; + } } diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index c0b20b5..9afdc97 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -23,6 +23,7 @@ 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/request_models/registration_payload_model.dart'; +import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_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/check_user_staus_nhic_response_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; @@ -59,8 +60,7 @@ class AuthenticationViewModel extends ChangeNotifier { required NavigationService navigationService, required CacheService cacheService, required LocalAuthService localAuthService, - }) - : _navigationService = navigationService, + }) : _navigationService = navigationService, _dialogService = dialogService, _errorHandlerService = errorHandlerService, _appState = appState, @@ -205,13 +205,13 @@ class AuthenticationViewModel extends ChangeNotifier { final result = await _authenticationRepo.selectDeviceByImei(firebaseToken: firebaseToken); result.fold( - (failure) async { + (failure) async { // LoadingUtils.hideFullScreenLoader(); // await _errorHandlerService.handleError(failure: failure); LoaderBottomSheet.hideLoader(); _navigationService.pushPage(page: LoginScreen()); }, - (apiResponse) { + (apiResponse) { // LoadingUtils.hideFullScreenLoader(); log("apiResponse: ${apiResponse.data.toString()}"); log("messageStatus: ${apiResponse.messageStatus.toString()}"); @@ -301,8 +301,7 @@ class AuthenticationViewModel extends ChangeNotifier { final result = await _authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); result.fold( - (failure) async => - await _errorHandlerService.handleError( + (failure) async => await _errorHandlerService.handleError( failure: failure, onUnHandledFailure: (failure) async { LoaderBottomSheet.hideLoader(); @@ -316,7 +315,7 @@ class AuthenticationViewModel extends ChangeNotifier { _navigationService.pop(); }); }), - (apiResponse) async { + (apiResponse) async { if (apiResponse.messageStatus == 2) { LoaderBottomSheet.hideLoader(); await _dialogService.showErrorBottomSheet(message: apiResponse.errorMessage ?? "ErrorEmpty", onOkPressed: () {}); @@ -359,8 +358,8 @@ class AuthenticationViewModel extends ChangeNotifier { patientOutSA: isForRegister ? isPatientOutsideSA(request: payload) : selectedCountrySignup.countryCode == CountryEnum.saudiArabia - ? false - : true, + ? false + : true, payload: payload, ); @@ -374,8 +373,8 @@ class AuthenticationViewModel extends ChangeNotifier { final resultEither = await _authenticationRepo.sendActivationCodeRepo(sendActivationCodeReq: request, isRegister: checkIsUserComingForRegister(request: payload), languageID: 'er'); resultEither.fold( - (failure) async => await _errorHandlerService.handleError(failure: failure), - (apiResponse) async { + (failure) async => await _errorHandlerService.handleError(failure: failure), + (apiResponse) async { if (apiResponse.messageStatus == 2) { LoaderBottomSheet.hideLoader(); await _dialogService.showCommonBottomSheetWithoutH( @@ -409,27 +408,27 @@ class AuthenticationViewModel extends ChangeNotifier { bool isForRegister = (_appState.getUserRegistrationPayload.healthId != null || _appState.getUserRegistrationPayload.patientOutSa == true || _appState.getUserRegistrationPayload.patientOutSa == 1); final request = RequestUtils.getCommonRequestWelcome( - phoneNumber: phoneNumberController.text, - otpTypeEnum: otpTypeEnum, - deviceToken: _appState.deviceToken, - // patientOutSA: _appState.getUserRegistrationPayload.projectOutSa == 1 ? true : false, - patientOutSA: isForRegister - ? _appState.getUserRegistrationPayload.projectOutSa == true - ? true - : false - : _appState.getSelectDeviceByImeiRespModelElement != null - ? _appState.getSelectDeviceByImeiRespModelElement!.outSa! - : selectedCountrySignup == CountryEnum.saudiArabia - ? false - : true, - loginTokenID: _appState.appAuthToken, - registeredData: isForRegister ? _appState.getUserRegistrationPayload : null, - nationIdText: nationalIdController.text, - countryCode: _appState.getSelectDeviceByImeiRespModelElement != null && _appState.getSelectDeviceByImeiRespModelElement!.outSa == true - ? CountryEnum.unitedArabEmirates.countryCode - : selectedCountrySignup.countryCode, - //TODO: Error Here IN Zip Code. - loginType: loginTypeEnum.toInt) + phoneNumber: phoneNumberController.text, + otpTypeEnum: otpTypeEnum, + deviceToken: _appState.deviceToken, + // patientOutSA: _appState.getUserRegistrationPayload.projectOutSa == 1 ? true : false, + patientOutSA: isForRegister + ? _appState.getUserRegistrationPayload.projectOutSa == true + ? true + : false + : _appState.getSelectDeviceByImeiRespModelElement != null + ? _appState.getSelectDeviceByImeiRespModelElement!.outSa! + : selectedCountrySignup == CountryEnum.saudiArabia + ? false + : true, + loginTokenID: _appState.appAuthToken, + registeredData: isForRegister ? _appState.getUserRegistrationPayload : null, + nationIdText: nationalIdController.text, + countryCode: _appState.getSelectDeviceByImeiRespModelElement != null && _appState.getSelectDeviceByImeiRespModelElement!.outSa == true + ? CountryEnum.unitedArabEmirates.countryCode + : selectedCountrySignup.countryCode, + //TODO: Error Here IN Zip Code. + loginType: loginTypeEnum.toInt) .toJson(); LoaderBottomSheet.showLoader(); if (isForRegister) { @@ -445,8 +444,7 @@ class AuthenticationViewModel extends ChangeNotifier { LoaderBottomSheet.hideLoader(); resultEither.fold( - (failure) async => - await _errorHandlerService.handleError( + (failure) async => await _errorHandlerService.handleError( failure: failure, onUnHandledFailure: (failure) async { LoaderBottomSheet.hideLoader(); @@ -473,8 +471,7 @@ class AuthenticationViewModel extends ChangeNotifier { final resultEither = await _authenticationRepo.checkActivationCodeRepo(newRequest: CheckActivationCodeRegisterReq.fromJson(request), activationCode: activationCode, isRegister: false); resultEither.fold( - (failure) async => - await _errorHandlerService.handleError( + (failure) async => await _errorHandlerService.handleError( failure: failure, onUnHandledFailure: (failure) async { LoaderBottomSheet.hideLoader(); @@ -504,6 +501,7 @@ class AuthenticationViewModel extends ChangeNotifier { } else { if (activation.list != null && activation.list!.isNotEmpty) { _appState.setAuthenticatedUser(activation.list!.first); + _appState.setPrivilegeModelList(activation.list!.first.listPrivilege!); } _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); _appState.setAppAuthToken = activation.authenticationTokenId; @@ -658,15 +656,15 @@ class AuthenticationViewModel extends ChangeNotifier { bool isOutSidePatient = selectedCountrySignup.countryCode == CountryEnum.unitedArabEmirates.countryCode ? true : false; LoaderBottomSheet.showLoader(); final request = await RequestUtils.getPatientAuthenticationRequest( - phoneNumber: phoneNumberController.text, - nationId: nationalIdController.text, - patientOutSA: isOutSidePatient, - otpTypeEnum: otpTypeEnum, - isForRegister: true, - patientId: 0, - zipCode: selectedCountrySignup.countryCode, - calenderType: calenderType, - dob: dob) + phoneNumber: phoneNumberController.text, + nationId: nationalIdController.text, + patientOutSA: isOutSidePatient, + otpTypeEnum: otpTypeEnum, + isForRegister: true, + patientId: 0, + zipCode: selectedCountrySignup.countryCode, + calenderType: calenderType, + dob: dob) .toJson(); var nRequest = Map.from(request); @@ -802,22 +800,22 @@ 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, + ).toJson()); resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { if (apiResponse.messageStatus == 1) { log("Insert IMEI Success"); @@ -831,20 +829,20 @@ class AuthenticationViewModel extends ChangeNotifier { Future insertPatientDeviceData(int loginType) async { final resultEither = await _authenticationRepo.insertPatientDeviceData( patientDeviceDataRequest: InsertPatientMobileDeviceInfo( - deviceToken: _appState.deviceToken, - deviceTypeId: _appState.getDeviceTypeID(), - patientId: _appState.getAuthenticatedUser()!.patientId!, - patientTypeId: _appState.getAuthenticatedUser()!.patientType, - patientOutSa: _appState.getAuthenticatedUser()!.outSa!, - loginType: loginType, - languageId: _appState.getLanguageID(), - latitude: _appState.userLat, - longitude: _appState.userLong, - voipToken: "", - deviceType: _appState.deviceTypeID, - patientMobileNumber: _appState.getAuthenticatedUser()!.mobileNumber, - nationalId: _appState.getAuthenticatedUser()!.patientIdentificationNo, - gender: _appState.getAuthenticatedUser()!.gender) + deviceToken: _appState.deviceToken, + deviceTypeId: _appState.getDeviceTypeID(), + patientId: _appState.getAuthenticatedUser()!.patientId!, + patientTypeId: _appState.getAuthenticatedUser()!.patientType, + patientOutSa: _appState.getAuthenticatedUser()!.outSa!, + loginType: loginType, + languageId: _appState.getLanguageID(), + latitude: _appState.userLat, + longitude: _appState.userLong, + voipToken: "", + deviceType: _appState.deviceTypeID, + patientMobileNumber: _appState.getAuthenticatedUser()!.mobileNumber, + nationalId: _appState.getAuthenticatedUser()!.patientIdentificationNo, + gender: _appState.getAuthenticatedUser()!.gender) .toJson()); resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { if (apiResponse.messageStatus == 1) { @@ -858,18 +856,18 @@ class AuthenticationViewModel extends ChangeNotifier { Future getPatientDeviceData(int loginType) async { final resultEither = await _authenticationRepo.getPatientDeviceData( patientDeviceDataRequest: GetUserMobileDeviceData( - deviceToken: _appState.deviceToken, - deviceTypeId: _appState.getDeviceTypeID(), - patientId: _appState.getSelectDeviceByImeiRespModelElement!.patientId!, - patientType: _appState.getSelectDeviceByImeiRespModelElement!.patientType, - patientOutSa: _appState.getSelectDeviceByImeiRespModelElement!.outSa == true ? 1 : 0, - loginType: loginType, - languageId: _appState.getLanguageID(), - latitude: _appState.userLat, - longitude: _appState.userLong, - mobileNo: _appState.getSelectDeviceByImeiRespModelElement!.mobile!, - patientMobileNumber: int.parse(_appState.getSelectDeviceByImeiRespModelElement!.mobile!), - nationalId: _appState.getSelectDeviceByImeiRespModelElement!.identificationNo) + deviceToken: _appState.deviceToken, + deviceTypeId: _appState.getDeviceTypeID(), + patientId: _appState.getSelectDeviceByImeiRespModelElement!.patientId!, + patientType: _appState.getSelectDeviceByImeiRespModelElement!.patientType, + patientOutSa: _appState.getSelectDeviceByImeiRespModelElement!.outSa == true ? 1 : 0, + loginType: loginType, + languageId: _appState.getLanguageID(), + latitude: _appState.userLat, + longitude: _appState.userLong, + mobileNo: _appState.getSelectDeviceByImeiRespModelElement!.mobile!, + patientMobileNumber: int.parse(_appState.getSelectDeviceByImeiRespModelElement!.mobile!), + nationalId: _appState.getSelectDeviceByImeiRespModelElement!.identificationNo) .toJson()); resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { if (apiResponse.messageStatus == 1) { @@ -885,11 +883,15 @@ class AuthenticationViewModel extends ChangeNotifier { message: apiResponse.errorMessage ?? "", label: LocaleKeys.notice.tr(), onOkPressed: () { - _dialogService.showPhoneNumberPickerSheet(label:"Where would you like to receive OTP?", message:"Please select from the below options to receive OTP.", onSMSPress: () { - checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms); - }, onWhatsappPress: () { - checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp); - }); + _dialogService.showPhoneNumberPickerSheet( + label: "Where would you like to receive OTP?", + message: "Please select from the below options to receive OTP.", + onSMSPress: () { + checkUserAuthentication(otpTypeEnum: OTPTypeEnum.sms); + }, + onWhatsappPress: () { + checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp); + }); }, onCancelPressed: () { _navigationService.pop(); @@ -908,21 +910,21 @@ class AuthenticationViewModel extends ChangeNotifier { Future getServicePrivilege() async { final resultEither = await _authenticationRepo.getServicePrivilege(); - List privilegeModelList = []; + List privilegeModelList = []; List vidaPlusProjectListModel = []; List hMCProjectListModel = []; List projectDetailListModel = []; resultEither.fold( - (failure) async => await _errorHandlerService.handleError(failure: failure), - (apiResponse) async { + (failure) async => await _errorHandlerService.handleError(failure: failure), + (apiResponse) async { if (apiResponse.messageStatus == 2) { await _dialogService.showErrorBottomSheet(message: apiResponse.errorMessage ?? "ErrorEmpty"); } else { apiResponse.data["ServicePrivilegeList"].forEach((v) { - privilegeModelList.add(PrivilegeModel.fromJson(v)); + privilegeModelList.add(ListPrivilege.fromJson(v)); }); - _appState.setPrivilegeModelList(privilegeModelList); + _appState.setPrivilegeModelList(privilegeModelList.cast()); apiResponse.data["ProjectListVidaPlus"].forEach((v) { vidaPlusProjectListModel.add(VidaPlusProjectListModel.fromJson(v)); 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 2682f0a..67848c6 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 @@ -613,35 +613,3 @@ class ListElement { "status": listStatus, }; } - -class ListPrivilege { - int? id; - String? serviceName; - bool? previlege; - dynamic 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()); - - factory ListPrivilege.fromJson(Map json) => ListPrivilege( - id: json["ID"], - serviceName: json["ServiceName"], - previlege: json["Previlege"], - region: json["Region"], - ); - - Map toJson() => { - "ID": id, - "ServiceName": serviceName, - "Previlege": previlege, - "Region": region, - }; -} diff --git a/lib/features/book_appointments/book_appointments_repo.dart b/lib/features/book_appointments/book_appointments_repo.dart index 7454b80..81faf91 100644 --- a/lib/features/book_appointments/book_appointments_repo.dart +++ b/lib/features/book_appointments/book_appointments_repo.dart @@ -42,11 +42,9 @@ abstract class BookAppointmentsRepo { Function(dynamic)? onSuccess, Function(String)? onError}); - Future>>> - getProjectList(); + Future>>> getProjectList(); Future>>> getClinicsWithRespectToClinicId(String projectID); - } class BookAppointmentsRepoImp implements BookAppointmentsRepo { @@ -371,8 +369,7 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo { } @override - Future>>> - getProjectList() async { + Future>>> getProjectList() async { Map request = {}; try { @@ -388,11 +385,7 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo { try { final list = response['ListProject']; - final appointmentsList = list - .map((item) => - HospitalsModel.fromJson(item as Map)) - .toList() - .cast(); + final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast(); apiResponse = GenericApiModel>( messageStatus: messageStatus, diff --git a/lib/features/habib_wallet/habib_wallet_repo.dart b/lib/features/habib_wallet/habib_wallet_repo.dart index 5f47f6c..659510d 100644 --- a/lib/features/habib_wallet/habib_wallet_repo.dart +++ b/lib/features/habib_wallet/habib_wallet_repo.dart @@ -3,10 +3,20 @@ 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/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class HabibWalletRepo { Future>> getPatientBalanceAmount(); + + Future>>> getProjectList(); + + Future>> HISCreateAdvancePayment( + {required String paymentMethodName, required num paidAmount, required String paymentReference, required String patientID, required int projectID, required String depositorName}); + + Future>> addAdvanceNumberRequest({required String advanceNumber, required String paymentReference}); + + Future>> getPatientInfoByPatientID({required String patientID}); } class HabibWalletRepoImp implements HabibWalletRepo { @@ -55,4 +65,165 @@ class HabibWalletRepoImp implements HabibWalletRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>>> getProjectList() async { + Map request = {"IsOnlineCheckIn": true, "IsAdvancePayment": true}; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_PROJECT_LIST, + body: request, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = response['ListProject']; + + final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: appointmentsList, + ); + } 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> HISCreateAdvancePayment( + {required String paymentMethodName, required num paidAmount, required String paymentReference, required String patientID, required int projectID, required String depositorName}) async { + Map request = { + "CustName": depositorName, + "CustID": patientID, + "SetupID": "010266", + "ProjectID": projectID, + "PatientID": patientID, + "AccountID": patientID, + "PaymentAmount": paidAmount, + "NationalityID": null, + "DepositorName": depositorName, + "CreatedBy": 3, + "PaymentMethodName": paymentMethodName, + "PaymentReference": paymentReference, + "PaymentMethod": paymentMethodName, + "IsAncillaryOrder": false + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + HIS_CREATE_ADVANCE_PAYMENT, + body: request, + 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> addAdvanceNumberRequest({required String advanceNumber, required String paymentReference}) async { + Map requestBody = { + "AdvanceNumber": advanceNumber, + "AdvanceNumber_VP": advanceNumber, + "PaymentReferenceNumber": paymentReference, + "AppointmentID": 0, + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + ADD_ADVANCE_NUMBER_REQUEST, + body: requestBody, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future> getPatientInfoByPatientID({required String patientID}) async { + Map requestBody = {"SearchPatientID": patientID}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + GET_PATIENT_INFO_BY_ID, + body: requestBody, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/habib_wallet/habib_wallet_view_model.dart b/lib/features/habib_wallet/habib_wallet_view_model.dart index 8e4fc26..c620b08 100644 --- a/lib/features/habib_wallet/habib_wallet_view_model.dart +++ b/lib/features/habib_wallet/habib_wallet_view_model.dart @@ -1,23 +1,66 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; class HabibWalletViewModel extends ChangeNotifier { bool isWalletAmountLoading = false; num habibWalletAmount = 0; + num walletRechargeAmount = 0; + + int currentIndex = 0; + + List advancePaymentHospitals = []; + + HospitalsModel? selectedHospital; HabibWalletRepo habibWalletRepo; ErrorHandlerService errorHandlerService; + String fileNumber = ''; + String depositorName = ''; + String mobileNumber = ''; + HabibWalletViewModel({required this.habibWalletRepo, required this.errorHandlerService}); initHabibWalletProvider() { isWalletAmountLoading = true; habibWalletAmount = 0; + walletRechargeAmount = 0; + advancePaymentHospitals.clear(); + selectedHospital = null; + fileNumber = ''; + depositorName = ''; + mobileNumber = ''; + notifyListeners(); + } + + setSelectedHospital(HospitalsModel hospital) { + selectedHospital = hospital; + notifyListeners(); + } + + setWalletRechargeAmount(num amount) { + walletRechargeAmount = amount; + notifyListeners(); + } + + setDepositorDetails(String fileNum, String depositor, String mobile) { + fileNumber = fileNum; + depositorName = depositor; + mobileNumber = mobile; + notifyListeners(); + } + + setCurrentIndex(int index) { + currentIndex = index; notifyListeners(); } Future getPatientBalanceAmount({Function(dynamic)? onSuccess, Function(String)? onError}) async { + isWalletAmountLoading = true; + notifyListeners(); + final result = await habibWalletRepo.getPatientBalanceAmount(); result.fold( @@ -36,4 +79,85 @@ class HabibWalletViewModel extends ChangeNotifier { }, ); } + + Future getProjectsList() async { + advancePaymentHospitals.clear(); + notifyListeners(); + final result = await habibWalletRepo.getProjectList(); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) async { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + advancePaymentHospitals = apiResponse.data!; + notifyListeners(); + } + }, + ); + } + + Future HISCreateAdvancePayment( + {required String paymentMethodName, + required num paidAmount, + required String paymentReference, + required String patientID, + required int projectID, + required String depositorName, + Function(dynamic)? onSuccess, + Function(String)? onError}) async { + final result = await habibWalletRepo.HISCreateAdvancePayment( + paymentMethodName: paymentMethodName, paidAmount: paidAmount, paymentReference: paymentReference, patientID: patientID, projectID: projectID, depositorName: depositorName); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + Future addAdvanceNumberRequest({required String advanceNumber, required String paymentReference, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await habibWalletRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + Future getPatientInfoByPatientID({required String patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await habibWalletRepo.getPatientInfoByPatientID(patientID: patientID); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } } diff --git a/lib/features/payfort/payfort_view_model.dart b/lib/features/payfort/payfort_view_model.dart index d99de80..6b67ce9 100644 --- a/lib/features/payfort/payfort_view_model.dart +++ b/lib/features/payfort/payfort_view_model.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/features/payfort/models/payfort_project_deta import 'package:hmg_patient_app_new/features/payfort/models/sdk_token_response_model.dart'; import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:network_info_plus/network_info_plus.dart'; class PayfortViewModel extends ChangeNotifier { @@ -183,6 +184,7 @@ class PayfortViewModel extends ChangeNotifier { isApplePayConfigurationLoading = false; notifyListeners(); + LoaderBottomSheet.hideLoader(); _payfort.callPayFortForApplePay( request: request, diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index 4d5fd8f..e68e000 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -273,7 +273,6 @@ class _AppointmentPaymentPageState extends State { isSaudiCurrency: true), ], ).paddingSymmetrical(24.h, 0.h), - //TODO: Add Apple Pay Privileges Platform.isIOS ? Utils.buildSvgWithAssets( icon: AppAssets.apple_pay_button, @@ -282,7 +281,11 @@ class _AppointmentPaymentPageState extends State { fit: BoxFit.contain, ).paddingSymmetrical(24.h, 0.h).onPress(() { // payfortVM.setIsApplePayConfigurationLoading(true); - startApplePay(); + if (Utils.havePrivilege(103)) { + startApplePay(); + } else { + openPaymentURL(selectedPaymentMethod); + } }) : SizedBox(height: 12.h), SizedBox(height: 12.h), @@ -363,8 +366,8 @@ class _AppointmentPaymentPageState extends State { appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), payedAmount: payfortViewModel.payfortCheckPaymentStatusResponseModel!.amount!, paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, - patientID: "4767477", - patientType: 1, + patientID: appState.getAuthenticatedUser()!.patientId.toString(), + patientType: appState.getAuthenticatedUser()!.patientType!, onSuccess: (value) async { print(value); await myAppointmentsViewModel.addAdvanceNumberRequest( diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart index 41fb924..81cc318 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart @@ -17,8 +17,7 @@ class HospitalListItem extends StatelessWidget { late AppState appState; - HospitalListItem( - {super.key, required this.hospitalData, required this.isLocationEnabled}); + HospitalListItem({super.key, required this.hospitalData, required this.isLocationEnabled}); @override Widget build(BuildContext context) { @@ -70,24 +69,17 @@ class HospitalListItem extends StatelessWidget { ); Widget get distanceInfo => Row( - children: [ Visibility( - visible: (hospitalData?.distanceInKMs != "0"), - child: - - - AppCustomChipWidget( - labelText: - "${hospitalData?.distanceInKMs ?? ""} km".needTranslation, - deleteIcon: AppAssets.location_red, - deleteIconSize: Size(9, 12), - backgroundColor: AppColors.secondaryLightRedColor, - textColor: AppColors.errorColor, - ), - - - ), + visible: (hospitalData?.distanceInKMs != "0"), + child: AppCustomChipWidget( + labelText: "${hospitalData?.distanceInKMs ?? ""} km".needTranslation, + deleteIcon: AppAssets.location_red, + deleteIconSize: Size(9, 12), + backgroundColor: AppColors.secondaryLightRedColor, + textColor: AppColors.errorColor, + ), + ), Visibility( visible: (hospitalData?.distanceInKMs == "0"), child: Row( @@ -96,8 +88,9 @@ class HospitalListItem extends StatelessWidget { labelText: "Distance not available".needTranslation, textColor: AppColors.blackColor, ), - SizedBox(width: 8.h,) - + SizedBox( + width: 8.h, + ) ], )), Visibility( diff --git a/lib/presentation/habib_wallet/habib_wallet_page.dart b/lib/presentation/habib_wallet/habib_wallet_page.dart index 6add7bd..e1d1ba2 100644 --- a/lib/presentation/habib_wallet/habib_wallet_page.dart +++ b/lib/presentation/habib_wallet/habib_wallet_page.dart @@ -14,7 +14,6 @@ import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; class HabibWalletPage extends StatefulWidget { @@ -25,8 +24,11 @@ class HabibWalletPage extends StatefulWidget { } class _HabibWalletState extends State { + late HabibWalletViewModel habibWalletVM; + @override Widget build(BuildContext context) { + habibWalletVM = Provider.of(context, listen: false); AppState _appState = getIt.get(); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, @@ -66,10 +68,10 @@ class _HabibWalletState extends State { ), Spacer(), LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.whiteColor), + SizedBox(height: 4.h), Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol(habibWalletVM.habibWalletAmount.toString().toText32(isBold: true, color: AppColors.whiteColor), AppColors.whiteColor, 13.h, - isExpanded: false) - .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h); + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: AppColors.whiteColor, iconColor: AppColors.whiteColor, iconSize: 13, isExpanded: false) + .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h); }), ], ), @@ -84,11 +86,15 @@ class _HabibWalletState extends State { iconSize: 21.h, text: "Recharge".needTranslation, onPressed: () { - Navigator.of(context).push( + Navigator.of(context) + .push( CustomPageRoute( page: RechargeWalletPage(), ), - ); + ) + .then((val) { + habibWalletVM.getPatientBalanceAmount(); + }); }, backgroundColor: AppColors.infoColor, borderColor: AppColors.infoColor, diff --git a/lib/presentation/habib_wallet/recharge_wallet_page.dart b/lib/presentation/habib_wallet/recharge_wallet_page.dart index 8b35f8b..098610b 100644 --- a/lib/presentation/habib_wallet/recharge_wallet_page.dart +++ b/lib/presentation/habib_wallet/recharge_wallet_page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -7,12 +9,17 @@ 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/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/wallet_payment_confirm_page.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart'; import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/input_widget.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; import 'widgets/select-medical_file.dart'; @@ -26,8 +33,20 @@ class RechargeWalletPage extends StatefulWidget { class _RechargeWalletPageState extends State { FocusNode textFocusNode = FocusNode(); + late HabibWalletViewModel habibWalletVM; + final TextEditingController amountTextController = TextEditingController(); + + @override + void initState() { + scheduleMicrotask(() { + habibWalletVM.getProjectsList(); + }); + super.initState(); + } + @override Widget build(BuildContext context) { + habibWalletVM = Provider.of(context, listen: false); AppState appState = getIt.get(); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, @@ -35,171 +54,197 @@ class _RechargeWalletPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( - child: CollapsingListView( - title: LocaleKeys.createAdvancedPayment.tr(context: context), - child: SingleChildScrollView( - child: Padding( - padding: EdgeInsets.all(24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 135.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: false, - side: BorderSide(color: AppColors.textColor, width: 2.h), - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Enter an amount".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), - Spacer(), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Utils.getPaymentAmountWithSymbol( - SizedBox( - width: 150.h, - child: TextInputWidget( - labelText: "", - hintText: "", - isEnable: true, - prefix: null, - isAllowRadius: true, - isBorderAllowed: false, - isAllowLeadingIcon: true, - autoFocus: true, - fontSize: 40, - padding: EdgeInsets.symmetric(horizontal: 8.h, vertical: 0.h), - focusNode: textFocusNode, - isWalletAmountInput: true, - // leadingIcon: AppAssets.student_card, + child: CollapsingListView( + title: LocaleKeys.createAdvancedPayment.tr(context: context), + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 135.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: false, + side: BorderSide(color: AppColors.textColor, width: 2.h), + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //TODO: Check with hussain to show AED or SAR + "Enter an amount".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + Spacer(), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Utils.getPaymentAmountWithSymbol( + SizedBox( + width: 150.h, + child: TextInputWidget( + controller: amountTextController, + labelText: "", + hintText: "", + isEnable: true, + prefix: null, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + autoFocus: true, + fontSize: 40, + padding: EdgeInsets.symmetric(horizontal: 8.h, vertical: 0.h), + focusNode: textFocusNode, + isWalletAmountInput: true, + keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), + // leadingIcon: AppAssets.student_card, + ), ), - ), - AppColors.textColor, - 13.h, - isExpanded: false), - const Spacer(), - "SAR".needTranslation.toText20(color: AppColors.greyTextColor, weight: FontWeight.w500), - ], - ), - ], + AppColors.textColor, + 13.h, + isExpanded: false), + const Spacer(), + "SAR".needTranslation.toText20(color: AppColors.greyTextColor, weight: FontWeight.w500), + ], + ), + ], + ), ), ), - ), - SizedBox(height: 24.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + SizedBox(height: 24.h), + Consumer(builder: (context, habibWalletVM, child) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.my_account_icon, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( children: [ - LocaleKeys.myAccount.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), - "${LocaleKeys.medicalFile.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}" - .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + Utils.buildSvgWithAssets(icon: AppAssets.my_account_icon, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.myAccount.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + "${LocaleKeys.medicalFile.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}" + .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + ], + ), ], ), + Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), ], - ), - Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), - ], - ).onPress(() async { - // showCommonBottomSheetWithoutHeight(context, title: "Select Medical File".needTranslation, child: SelectMedicalFile(), callBackFunc: () {}, isFullScreen: false); - showCommonBottomSheetWithoutHeight(context, title: "Select Medical File".needTranslation, child: const MultiPageBottomSheet(), callBackFunc: () {}, isFullScreen: false); - }), - SizedBox(height: 16.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + ).onPress(() async { + habibWalletVM.setCurrentIndex(0); + showCommonBottomSheetWithoutHeight(context, title: "Select Medical File".needTranslation, + titleWidget: Consumer(builder: (context, habibWalletVM, child) { + return habibWalletVM.currentIndex != 0 + ? IconButton( + icon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 24.h, height: 24.h), + padding: EdgeInsets.zero, + onPressed: () => habibWalletVM.setCurrentIndex(0), + highlightColor: Colors.transparent, + ) + : "Select Medical File".needTranslation.toText20(weight: FontWeight.w600); + }), child: Consumer(builder: (context, habibWalletVM, child) { + return MultiPageBottomSheet(); + }), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true); + }), + SizedBox(height: 16.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), + SizedBox(height: 16.h), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.select_hospital_icon, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( children: [ - LocaleKeys.hospital.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), - "Olaya".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + Utils.buildSvgWithAssets(icon: AppAssets.select_hospital_icon, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.hospital.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + SizedBox( + width: MediaQuery.of(context).size.width * 0.55, + child: (habibWalletVM.selectedHospital != null ? habibWalletVM.selectedHospital!.name : LocaleKeys.selectHospital.tr(context: context))! + .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + ), + ], + ), ], - ), + ).onPress(() { + showCommonBottomSheetWithoutHeight(context, + title: LocaleKeys.selectHospital.tr(context: context), isDismissible: false, child: SelectHospitalBottomSheet(), callBackFunc: () {}); + }), + Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), ], ), - Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), - ], - ), - SizedBox(height: 16.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + SizedBox(height: 16.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), + SizedBox(height: 16.h), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.email_icon, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( children: [ - LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), - "${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, weight: FontWeight.w500), + Utils.buildSvgWithAssets(icon: AppAssets.email_icon, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, weight: FontWeight.w500), + ], + ), ], ), ], ), - ], - ), - SizedBox(height: 16.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + SizedBox(height: 16.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), + SizedBox(height: 16.h), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.notes_icon, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + Row( children: [ - LocaleKeys.notes.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), - "Lorem Ipsum".toText16(color: AppColors.textColor, weight: FontWeight.w500), + Utils.buildSvgWithAssets(icon: AppAssets.notes_icon, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.notes.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "Lorem Ipsum".toText16(color: AppColors.textColor, weight: FontWeight.w500), + ], + ), ], ), ], ), + SizedBox(height: 8.h), ], ), - SizedBox(height: 8.h), - ], - ), - ), - ), - ], + ), + ); + }), + ], + ), ), ), ), - )), + ), + //TODO: Handle Family member selection & Other Account Selection Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -208,7 +253,38 @@ class _RechargeWalletPageState extends State { ), child: CustomButton( text: LocaleKeys.next.tr(context: context), - onPressed: () {}, + onPressed: () { + if (amountTextController.text.isEmpty) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Please enter amount to continue.".needTranslation), + callBackFunc: () { + textFocusNode.requestFocus(); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } else if (habibWalletVM.selectedHospital == null) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Please select hospital to continue.".needTranslation), + callBackFunc: () { + textFocusNode.requestFocus(); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } else { + habibWalletVM.setWalletRechargeAmount(num.parse(amountTextController.text)); + habibWalletVM.setDepositorDetails(appState.getAuthenticatedUser()!.patientId.toString(), "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", + appState.getAuthenticatedUser()!.mobileNumber!); + Navigator.of(context).push( + CustomPageRoute( + page: WalletPaymentConfirmPage(), + ), + ); + } + }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, textColor: AppColors.whiteColor, diff --git a/lib/presentation/habib_wallet/wallet_payment_confirm_page.dart b/lib/presentation/habib_wallet/wallet_payment_confirm_page.dart new file mode 100644 index 0000000..c22a939 --- /dev/null +++ b/lib/presentation/habib_wallet/wallet_payment_confirm_page.dart @@ -0,0 +1,385 @@ +import 'dart:async'; +import 'dart:developer'; +import 'dart:io'; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.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/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/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/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; +import 'package:hmg_patient_app_new/features/payfort/models/apple_pay_request_insert_model.dart'; +import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class WalletPaymentConfirmPage extends StatefulWidget { + const WalletPaymentConfirmPage({super.key}); + + @override + State createState() => _WalletPaymentConfirmPageState(); +} + +class _WalletPaymentConfirmPageState extends State { + late PayfortViewModel payfortViewModel; + late AppState appState; + late HabibWalletViewModel habibWalletVM; + + MyInAppBrowser? browser; + String selectedPaymentMethod = ""; + + String transID = ""; + + @override + void initState() { + scheduleMicrotask(() { + payfortViewModel.initPayfortViewModel(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + appState = getIt.get(); + habibWalletVM = Provider.of(context, listen: false); + payfortViewModel = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: CollapsingListView( + title: "Select Payment Method", + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset(AppAssets.mada, width: 72.h, height: 25.h).toShimmer2(isShow: false), + SizedBox(height: 16.h), + "Mada".needTranslation.toText16(isBold: true).toShimmer2(isShow: false), + ], + ), + SizedBox(width: 8.h), + const Spacer(), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18.h, + height: 13.h, + fit: BoxFit.contain, + ).toShimmer2(isShow: false), + ], + ).paddingSymmetrical(16.h, 16.h), + ).paddingSymmetrical(24.h, 0.h).onPress(() { + selectedPaymentMethod = "MADA"; + // openPaymentURL("mada"); + }), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset(AppAssets.visa, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Image.asset(AppAssets.Mastercard, width: 40.h, height: 40.h), + ], + ).toShimmer2(isShow: false), + SizedBox(height: 16.h), + "Visa or Mastercard".needTranslation.toText16(isBold: true).toShimmer2(isShow: false), + ], + ), + SizedBox(width: 8.h), + const Spacer(), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18.h, + height: 13.h, + fit: BoxFit.contain, + ).toShimmer2(isShow: false), + ], + ).paddingSymmetrical(16.h, 16.h), + ).paddingSymmetrical(24.h, 0.h).onPress(() { + selectedPaymentMethod = "VISA"; + // openPaymentURL("visa"); + }), + ], + ), + ), + ), + ), + Container( + // height: 200.h, + width: MediaQuery.of(context).size.width, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + habibWalletVM.depositorName.toText18(isBold: true).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 12.h), + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget(labelText: "${LocaleKeys.fileno.tr(context: context)}.: ${habibWalletVM.fileNumber}"), + AppCustomChipWidget(labelText: "${LocaleKeys.mobileNumber.tr(context: context)}: ${habibWalletVM.mobileNumber}"), + AppCustomChipWidget(labelText: "${habibWalletVM.selectedHospital!.name}"), + ], + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 16.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Total amount to pay".needTranslation.toText16(isBold: true), + Utils.getPaymentAmountWithSymbol(habibWalletVM.walletRechargeAmount.toString().toText24(isBold: true), AppColors.blackColor, 15.h, isSaudiCurrency: true), + ], + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 12.h), + Platform.isIOS + ? Utils.buildSvgWithAssets( + icon: AppAssets.apple_pay_button, + width: 200.h, + height: 56.h, + fit: BoxFit.contain, + ).paddingSymmetrical(24.h, 0.h).onPress(() { + if (Utils.havePrivilege(103)) { + startApplePay(); + } else {} + }) + : SizedBox(height: 12.h), + SizedBox(height: 32.h), + ], + ), + ), + ], + ), + ); + } + + startApplePay() async { + LoaderBottomSheet.showLoader(); + ApplePayInsertRequest applePayInsertRequest = ApplePayInsertRequest(); + + transID = Utils.getAdvancePaymentTransID(habibWalletVM.selectedHospital!.iD!, int.parse(habibWalletVM.fileNumber)); + + await payfortViewModel.getPayfortConfigurations(serviceId: ServiceTypeEnum.advancePayment.getIdFromServiceEnum(), projectId: habibWalletVM.selectedHospital!.iD!, integrationId: 2); + + applePayInsertRequest.clientRequestID = transID; + applePayInsertRequest.clinicID = 0; + + applePayInsertRequest.currency = appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED"; + applePayInsertRequest.customerEmail = "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com"; + applePayInsertRequest.customerID = appState.getAuthenticatedUser()!.patientId.toString(); + applePayInsertRequest.customerName = "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}"; + + applePayInsertRequest.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken); + applePayInsertRequest.voipToken = await Utils.getStringFromPrefs(CacheConst.voipToken); + applePayInsertRequest.doctorID = 0; + applePayInsertRequest.projectID = habibWalletVM.selectedHospital!.iD!.toString(); + applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); + applePayInsertRequest.channelID = 3; + applePayInsertRequest.patientID = appState.getAuthenticatedUser()!.patientId.toString(); + applePayInsertRequest.patientTypeID = appState.getAuthenticatedUser()!.patientType; + applePayInsertRequest.patientOutSA = appState.getAuthenticatedUser()!.outSa; + applePayInsertRequest.appointmentDate = null; + applePayInsertRequest.appointmentNo = 0; + applePayInsertRequest.orderDescription = "Advance Payment"; + applePayInsertRequest.liveServiceID = "0"; + applePayInsertRequest.latitude = "0.0"; + applePayInsertRequest.longitude = "0.0"; + applePayInsertRequest.amount = habibWalletVM.walletRechargeAmount.toString(); + applePayInsertRequest.isSchedule = "0"; + applePayInsertRequest.language = appState.isArabic() ? 'ar' : 'en'; + applePayInsertRequest.languageID = appState.isArabic() ? 1 : 2; + applePayInsertRequest.userName = appState.getAuthenticatedUser()!.patientId; + applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; + applePayInsertRequest.paymentOption = "ApplePay"; + + applePayInsertRequest.isMobSDK = true; + applePayInsertRequest.merchantReference = transID; + applePayInsertRequest.merchantIdentifier = payfortViewModel.payfortProjectDetailsRespModel!.merchantIdentifier; + applePayInsertRequest.commandType = "PURCHASE"; + applePayInsertRequest.signature = payfortViewModel.payfortProjectDetailsRespModel!.signature; + applePayInsertRequest.accessCode = payfortViewModel.payfortProjectDetailsRespModel!.accessCode; + applePayInsertRequest.shaRequestPhrase = payfortViewModel.payfortProjectDetailsRespModel!.shaRequest; + applePayInsertRequest.shaResponsePhrase = payfortViewModel.payfortProjectDetailsRespModel!.shaResponse; + applePayInsertRequest.returnURL = ""; + + //TODO: Need to pass dynamic params to the Apple Pay instead of static values + await payfortViewModel.applePayRequestInsert(applePayInsertRequest: applePayInsertRequest).then((value) { + payfortViewModel.paymentWithApplePay( + customerName: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", + // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, + customerEmail: "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", + orderDescription: "Appointment Payment", + orderAmount: double.parse(habibWalletVM.walletRechargeAmount.toString()), + merchantReference: transID, + merchantIdentifier: payfortViewModel.payfortProjectDetailsRespModel!.merchantIdentifier, + applePayAccessCode: payfortViewModel.payfortProjectDetailsRespModel!.accessCode, + applePayShaRequestPhrase: payfortViewModel.payfortProjectDetailsRespModel!.shaRequest, + currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED", + onFailed: (failureResult) async { + log("failureResult: ${failureResult.message.toString()}"); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: failureResult.message.toString()), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }, + onSucceeded: (successResult) async { + log("successResult: ${successResult.responseMessage.toString()}"); + selectedPaymentMethod = successResult.paymentOption ?? "VISA"; + checkPaymentStatus(); + }, + ); + }); + } + + void checkPaymentStatus() async { + LoaderBottomSheet.showLoader(); + await payfortViewModel.checkPaymentStatus( + transactionID: transID, + onSuccess: (apiResponse) async { + print(apiResponse.data); + if (payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!.toLowerCase() == "success") { + await habibWalletVM.HISCreateAdvancePayment( + paymentMethodName: selectedPaymentMethod, + paidAmount: habibWalletVM.walletRechargeAmount, + paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, + patientID: habibWalletVM.fileNumber, + projectID: habibWalletVM.selectedHospital!.iD!, + depositorName: habibWalletVM.depositorName, + onSuccess: (value) async { + await habibWalletVM.addAdvanceNumberRequest( + advanceNumber: Utils.isVidaPlusProject(habibWalletVM.selectedHospital!.iD) + ? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, + onSuccess: (value) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getSuccessWidget(loadingText: "Payment Successful!".needTranslation), + callBackFunc: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Payment Failed - ${err}".needTranslation), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }, + onError: (err) {}); + + // await myAppointmentsViewModel.createAdvancePayment( + // paymentMethodName: selectedPaymentMethod, + // projectID: widget.patientAppointmentHistoryResponseModel.projectID, + // clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // payedAmount: payfortViewModel.payfortCheckPaymentStatusResponseModel!.amount!, + // paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, + // patientID: "4767477", + // patientType: 1, + // onSuccess: (value) async { + // print(value); + // await myAppointmentsViewModel.addAdvanceNumberRequest( + // advanceNumber: Utils.isVidaPlusProject(widget.patientAppointmentHistoryResponseModel.projectID) + // ? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + // : value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + // paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // onSuccess: (value) async { + // if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) { + // //TODO: Implement LiveCare Check-In API Call + // } else { + // await myAppointmentsViewModel.generateAppointmentQR( + // clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, + // projectID: widget.patientAppointmentHistoryResponseModel.projectID, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!, + // onSuccess: (apiResponse) { + // Future.delayed(Duration(milliseconds: 500), () { + // Navigator.of(context).pop(); + // Navigator.pushAndRemoveUntil( + // context, + // CustomPageRoute( + // page: LandingNavigation(), + // ), + // (r) => false); + // Navigator.of(context).push( + // CustomPageRoute(page: MyAppointmentsPage()), + // ); + // }); + // }); + // } + // }); + // }); + } else { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + }); + } +} diff --git a/lib/presentation/habib_wallet/widgets/hospital_list_item.dart b/lib/presentation/habib_wallet/widgets/hospital_list_item.dart new file mode 100644 index 0000000..e2151f2 --- /dev/null +++ b/lib/presentation/habib_wallet/widgets/hospital_list_item.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; + +class HospitalListItemAdvancePayment extends StatelessWidget { + final HospitalsModel hospitalModel; + final bool isLocationEnabled; + + late AppState appState; + + HospitalListItemAdvancePayment({super.key, required this.hospitalModel, required this.isLocationEnabled}); + + @override + Widget build(BuildContext context) { + appState = getIt.get(); + return DecoratedBox( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8.h, + children: [hospitalName], + ), + ), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18, + height: 13, + fit: BoxFit.contain, + ), + ], + ).paddingSymmetrical(16.h, 16.h), + ); + } + + Widget get hospitalName => Row( + children: [ + Utils.buildSvgWithAssets( + icon: (hospitalModel.isHMC == true) ? AppAssets.hmc : AppAssets.hmg, + ).paddingOnly(right: 10), + Expanded( + child: Text( + hospitalModel.name ?? "", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 16, + color: AppColors.blackColor, + ), + ), + ) + ], + ); + +// Widget get distanceInfo => Row( +// children: [ +// Visibility( +// visible: (hospitalModel.distanceInKMs != "0"), +// child: AppCustomChipWidget( +// labelText: "${hospitalData?.distanceInKMs ?? ""} km".needTranslation, +// deleteIcon: AppAssets.location_red, +// deleteIconSize: Size(9, 12), +// backgroundColor: AppColors.secondaryLightRedColor, +// textColor: AppColors.errorColor, +// ), +// ), +// Visibility( +// visible: (hospitalData?.distanceInKMs == "0"), +// child: Row( +// children: [ +// AppCustomChipWidget( +// labelText: "Distance not available".needTranslation, +// textColor: AppColors.blackColor, +// ), +// SizedBox( +// width: 8.h, +// ) +// ], +// )), +// Visibility( +// visible: !isLocationEnabled, +// child: AppCustomChipWidget( +// labelText: "Location turned off".needTranslation, +// deleteIcon: AppAssets.location_unavailable, +// deleteIconSize: Size(9, 12), +// textColor: AppColors.blackColor, +// )), +// ], +// ); +} diff --git a/lib/presentation/habib_wallet/widgets/select-medical_file.dart b/lib/presentation/habib_wallet/widgets/select-medical_file.dart index ab777c0..1c56cdd 100644 --- a/lib/presentation/habib_wallet/widgets/select-medical_file.dart +++ b/lib/presentation/habib_wallet/widgets/select-medical_file.dart @@ -27,8 +27,12 @@ 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/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.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'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:provider/provider.dart'; class MultiPageBottomSheet extends StatefulWidget { const MultiPageBottomSheet({Key? key}) : super(key: key); @@ -40,80 +44,139 @@ class MultiPageBottomSheet extends StatefulWidget { class _MultiPageBottomSheetState extends State { late AppState appState; + TextEditingController fileNumberEditingController = TextEditingController(); + @override Widget build(BuildContext context) { appState = getIt.get(); - return SizedBox( - height: MediaQuery.of(context).size.height * 0.38, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 16.h, - hasShadow: false, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.myMedicalFile.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), - "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), - ], - ), - Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), - ], - ).paddingAll(16.h), - ).onPress(() { - Navigator.of(context).pop(); - }), - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 16.h, - hasShadow: false, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.familyTitle.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), - "Select a medical file from your family".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), - ], - ), - Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), - ], - ).paddingAll(16.h), + return Consumer(builder: (context, habibWalletVM, child) { + return Padding( + padding: MediaQuery.of(context).viewInsets, + child: getCurrentIndexWidget(habibWalletVM), + ); + }); + } + + Widget getCurrentIndexWidget(HabibWalletViewModel habibWalletVM) { + switch (habibWalletVM.currentIndex) { + case 0: + return getSelectMedicalFileContent(habibWalletVM); + case 1: + return getOtherAccountContent(habibWalletVM); + case 2: + return getOtherAccountContent(habibWalletVM); + default: + return getSelectMedicalFileContent(habibWalletVM); + } + } + + Widget getOtherAccountContent(HabibWalletViewModel habibWalletVM) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Enter File Number".needTranslation.toText20(weight: FontWeight.w600), + SizedBox(height: 12.h), + TextInputWidget( + labelText: LocaleKeys.fileNumber.tr(), + hintText: "xxxxxxxxx", + controller: fileNumberEditingController, + // focusNode: _nationalIdFocusNode, + isEnable: true, + prefix: null, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + autoFocus: true, + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h), + leadingIcon: AppAssets.requests, + ).withVerticalPadding(8), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.submit.tr(), + onPressed: () async { + await habibWalletVM.getPatientInfoByPatientID(patientID: fileNumberEditingController.text, onSuccess: (response) { + print(response.data["GetPatientInfoByPatientIDList"][0]["FullName"]); + }, onError: (error) {}); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedBorderColor, + textColor: AppColors.whiteColor, + ), + ], + ); + } + + Widget getSelectMedicalFileContent(HabibWalletViewModel habibWalletVM) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 16.h, + hasShadow: false, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.myMedicalFile.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + ], + ), + Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), + ], + ).paddingAll(16.h), + ).onPress(() { + Navigator.of(context).pop(); + }), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 16.h, + hasShadow: false, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.familyTitle.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + "Select a medical file from your family".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + ], + ), + Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), + ], + ).paddingAll(16.h), + ), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 16.h, + hasShadow: false, ), - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 16.h, - hasShadow: false, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.otherAccount.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), - "Any active medical file from HMG".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), - ], - ), - Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), - ], - ).paddingAll(16.h), - ).onPress(() {}), - ], - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.otherAccount.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + "Any active medical file from HMG".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + ], + ), + Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), + ], + ).paddingAll(16.h), + ).onPress(() { + habibWalletVM.setCurrentIndex(2); + }), + ], ); } } diff --git a/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart b/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart new file mode 100644 index 0000000..54c6fb3 --- /dev/null +++ b/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart @@ -0,0 +1,96 @@ +import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +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/book_appointments/book_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/hospital_list_item.dart'; +import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:provider/provider.dart'; + +class SelectHospitalBottomSheet extends StatelessWidget { + late HabibWalletViewModel habibWalletVM; + final TextEditingController searchText = TextEditingController(); + + SelectHospitalBottomSheet({super.key}); + + @override + Widget build(BuildContext context) { + habibWalletVM = Provider.of(context, listen: false); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // LocaleKeys.selectHospital.tr(), + // style: TextStyle( + // fontSize: 21, + // fontWeight: FontWeight.w600, + // color: AppColors.blackColor, + // ), + // ), + Text( + "Please select the hospital you want to make an advance payment for.".needTranslation, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + ), + SizedBox(height: 16.h), + // TextInputWidget( + // labelText: LocaleKeys.search.tr(), + // hintText: "Search Hospital".tr(), + // controller: searchText, + // onChange: (value) { + // // appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType == + // // FacilitySelection.HMG.name); + // }, + // isEnable: true, + // prefix: null, + // autoFocus: false, + // isBorderAllowed: false, + // keyboardType: TextInputType.text, + // isAllowLeadingIcon: true, + // selectionType: SelectionTypeEnum.search, + // padding: EdgeInsets.symmetric( + // vertical: ResponsiveExtension(10).h, + // horizontal: ResponsiveExtension(15).h, + // ), + // ), + // SizedBox(height: 24.h), + // TypeSelectionWidget( + // hmcCount: "0", + // hmgCount: "0", + // ), + // SizedBox(height: 21.h), + SizedBox( + height: MediaQuery.sizeOf(context).height * .4, + child: ListView.separated( + itemBuilder: (_, index) { + return HospitalListItemAdvancePayment( + hospitalModel: habibWalletVM.advancePaymentHospitals[index], + isLocationEnabled: false, + ).onPress(() { + habibWalletVM.setSelectedHospital(habibWalletVM.advancePaymentHospitals[index]); + Navigator.of(context).pop(); + }); + }, + separatorBuilder: (_, __) => SizedBox( + height: 16.h, + ), + itemCount: habibWalletVM.advancePaymentHospitals.length), + ) + ], + ); + } +} diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 22de759..d5e5d5a 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -22,6 +22,7 @@ import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_mo import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart'; +import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart'; @@ -117,6 +118,7 @@ class _MedicalFilePageState extends State { child: Padding( padding: EdgeInsets.all(16.h), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -132,35 +134,19 @@ class _MedicalFilePageState extends State { children: [ "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true), SizedBox(height: 4.h), - Row( + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, children: [ - CustomButton( + AppCustomChipWidget( icon: AppAssets.file_icon, - iconColor: AppColors.blackColor, - iconSize: 12.h, - text: "File no: ${appState.getAuthenticatedUser()!.patientId}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.normal, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, + labelText: "File no: ${appState.getAuthenticatedUser()!.patientId}", ), - SizedBox(width: 4.h), - CustomButton( - text: LocaleKeys.verified.tr(context: context), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.normal, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, + AppCustomChipWidget( + icon: AppAssets.checkmark_icon, + labelText: LocaleKeys.verified.tr(context: context), + iconColor: AppColors.successColor, ), ], ), @@ -171,55 +157,21 @@ class _MedicalFilePageState extends State { SizedBox(height: 16.h), Divider(color: AppColors.dividerColor, height: 1.h), SizedBox(height: 16.h), - Row( + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, children: [ - CustomButton( - text: "${appState.getAuthenticatedUser()!.age} Years Old", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.normal, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, + AppCustomChipWidget( + labelText: "${appState.getAuthenticatedUser()!.age} Years Old", ), - SizedBox(width: 4.h), - CustomButton( + AppCustomChipWidget( icon: AppAssets.blood_icon, + labelText: "Blood: ${appState.getUserBloodGroup}", iconColor: AppColors.primaryRedColor, - iconSize: 13.h, - text: "Blood: ${appState.getUserBloodGroup}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.normal, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, ), - // SizedBox(width: 4.h), - // CustomButton( - // icon: AppAssets.insurance_active_icon, - // iconColor: AppColors.successColor, - // iconSize: 13.h, - // text: "Insurance Active", - // onPressed: () {}, - // backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - // borderColor: AppColors.bgGreenColor.withOpacity(0.0), - // textColor: AppColors.blackColor, - // fontSize: 10, - // fontWeight: FontWeight.normal, - // borderRadius: 12, - // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - // height: 30.h, - // ), ], ), - SizedBox(height: 8.h), ], ), ), @@ -327,7 +279,7 @@ class _MedicalFilePageState extends State { scrollDirection: Axis.horizontal, padding: EdgeInsets.only(top: 16.h, left: 24.h, right: 24.h, bottom: 0.h), shrinkWrap: true, - itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : myAppointmentsVM.patientAppointmentsHistoryList.length, + itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : (myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? myAppointmentsVM.patientAppointmentsHistoryList.length : 1), itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, @@ -345,14 +297,50 @@ class _MedicalFilePageState extends State { onRescheduleTap: () {}, onAskDoctorTap: () {}, ) - : MedicalFileAppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - onRescheduleTap: () { - openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); - }, - onAskDoctorTap: () {}, - ), + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? MedicalFileAppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + onRescheduleTap: () { + openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); + }, + onAskDoctorTap: () {}, + ) + : Container( + width: MediaQuery.of(context).size.width - 48.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24, hasShadow: true), + child: Padding( + padding: EdgeInsets.all(12.h), + child: Column( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), + SizedBox(height: 12.h), + "You do not have any appointments. Please book an appointment".needTranslation.toText12(isCenter: true), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.bookAppo.tr(context: context), + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: BookAppointmentPage(), + ), + ); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40, + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + ), + ], + ), + ), + ), ), ), ), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 6894d50..4328a58 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -106,7 +106,7 @@ class _ProfileSettingsState extends State { ), Spacer(), Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, AppColors.whiteColor, 13.h, isExpanded: false) + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h); }), CustomButton( diff --git a/pubspec.yaml b/pubspec.yaml index ea41d43..0466933 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,7 +55,7 @@ dependencies: uuid: ^4.5.1 health: ^13.1.3 # health: 12.0.1 - fl_chart: ^1.0.0 + fl_chart: ^1.1.1 geolocator: ^14.0.2 dropdown_search: ^6.0.2 google_maps_flutter: ^2.12.3