From 85ccf41d04daa68b28a994f203ff0f7322820135 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 3 Feb 2026 14:58:37 +0300 Subject: [PATCH] Updates & fixes for Habib Wallet, Insurance update, Immediate LiveCare --- lib/core/api/api_client.dart | 2 +- lib/core/api_consts.dart | 2 +- lib/core/utils/utils.dart | 1 + .../habib_wallet/habib_wallet_view_model.dart | 6 + lib/features/insurance/insurance_repo.dart | 57 ++ .../insurance/insurance_view_model.dart | 41 ++ .../upload_insurance_card_response_model.dart | 1 + .../blood_donation/blood_donation_page.dart | 11 +- .../immediate_livecare_payment_details.dart | 496 +++++++++--------- .../call_ambulance/call_ambulance_page.dart | 6 +- .../habib_wallet/recharge_wallet_page.dart | 33 +- .../widgets/select-medical_file.dart | 25 +- .../insurance_update_details_card.dart | 44 +- .../my_family/widget/family_cards.dart | 19 +- lib/services/dialog_service.dart | 7 +- 15 files changed, 475 insertions(+), 276 deletions(-) create mode 100644 lib/features/insurance/models/resp_models/upload_insurance_card_response_model.dart diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 3eb8fa2..4286618 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -182,7 +182,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 4769038; + // body['PatientID'] = 4768663; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index bec908b..8319c9d 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -680,7 +680,7 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 10d3767..4d8fec0 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -977,4 +977,5 @@ class Utils { return checkDate == today; } + } diff --git a/lib/features/habib_wallet/habib_wallet_view_model.dart b/lib/features/habib_wallet/habib_wallet_view_model.dart index 5291646..2f33895 100644 --- a/lib/features/habib_wallet/habib_wallet_view_model.dart +++ b/lib/features/habib_wallet/habib_wallet_view_model.dart @@ -9,6 +9,7 @@ class HabibWalletViewModel extends ChangeNotifier { bool isWalletAmountLoading = false; num habibWalletAmount = 0; num walletRechargeAmount = 0; + String notesText = ""; bool isBottomSheetContentLoading = false; @@ -60,6 +61,11 @@ class HabibWalletViewModel extends ChangeNotifier { notifyListeners(); } + setNotesText(String notes) { + notesText = notes; + notifyListeners(); + } + setDepositorDetails(String fileNum, String depositor, String mobile) { fileNumber = fileNum; depositorName = depositor; diff --git a/lib/features/insurance/insurance_repo.dart b/lib/features/insurance/insurance_repo.dart index 1aeb769..2719035 100644 --- a/lib/features/insurance/insurance_repo.dart +++ b/lib/features/insurance/insurance_repo.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patien import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_update_response_model.dart'; +import 'package:hmg_patient_app_new/features/insurance/models/resp_models/upload_insurance_card_response_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class InsuranceRepo { @@ -17,6 +18,14 @@ abstract class InsuranceRepo { Future>> getPatientInsuranceDetailsForUpdate({required String patientId, required String identificationNo}); Future>>> getPatientInsuranceApprovalsList(); + + Future>> updatePatientInsuranceCard({ + required int patientID, + required int patientType, + required String mobileNo, + required String patientIdentificationID, + required String insuranceCardImage, + }); } class InsuranceRepoImp implements InsuranceRepo { @@ -183,4 +192,52 @@ class InsuranceRepoImp implements InsuranceRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>> updatePatientInsuranceCard({ + required int patientID, + required int patientType, + required String mobileNo, + required String patientIdentificationID, + required String insuranceCardImage, + }) async { + Map mapDevice = { + "PatientID": patientID, + "PatientType": patientType, + "MobileNo": mobileNo, + "PatientIdentificationID": patientIdentificationID, + "InsuranceCardImage": insuranceCardImage, + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + UPLOAD_INSURANCE_CARD, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + // final uploadResponse = UploadInsuranceCardResponseModel.fromJson(response); + + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: apiResponse, + ); + } 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/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index 0bbdda2..261bda2 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patien import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_update_response_model.dart'; +import 'package:hmg_patient_app_new/features/insurance/models/resp_models/upload_insurance_card_response_model.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; class InsuranceViewModel extends ChangeNotifier { @@ -171,4 +172,44 @@ class InsuranceViewModel extends ChangeNotifier { }, ); } + + Future updatePatientInsuranceCard({ + required int patientID, + required int patientType, + required String mobileNo, + required String patientIdentificationID, + required String insuranceCardImage, + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + final result = await insuranceRepo.updatePatientInsuranceCard( + patientID: patientID, + patientType: patientType, + mobileNo: mobileNo, + patientIdentificationID: patientIdentificationID, + insuranceCardImage: insuranceCardImage, + ); + + result.fold( + (failure) async { + notifyListeners(); + if (onError != null) { + onError(failure.toString()); + } + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + notifyListeners(); + if (onError != null) { + onError(apiResponse.errorMessage ?? "Error updating insurance card"); + } + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } } diff --git a/lib/features/insurance/models/resp_models/upload_insurance_card_response_model.dart b/lib/features/insurance/models/resp_models/upload_insurance_card_response_model.dart new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/features/insurance/models/resp_models/upload_insurance_card_response_model.dart @@ -0,0 +1 @@ + diff --git a/lib/presentation/blood_donation/blood_donation_page.dart b/lib/presentation/blood_donation/blood_donation_page.dart index 26da599..7c6c625 100644 --- a/lib/presentation/blood_donation/blood_donation_page.dart +++ b/lib/presentation/blood_donation/blood_donation_page.dart @@ -263,13 +263,20 @@ class _BloodDonationPageState extends State { Row( children: [ Text( - LocaleKeys.iAcceptThe.tr(), + "${LocaleKeys.iAcceptThe.tr()} ", style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), ), GestureDetector( onTap: () { // Navigate to terms and conditions page - Navigator.of(context).pushNamed('/terms'); + // Navigator.of(context).pushNamed('/terms'); + appState.isArabic() + ? Utils.openWebView( + url: 'https://hmg.com/ar/Pages/Terms.aspx', + ) + : Utils.openWebView( + url: 'https://hmg.com/en/Pages/Terms.aspx', + ); }, child: Text( LocaleKeys.termsConditoins.tr(), diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart index d522b45..6b2620b 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart @@ -33,71 +33,30 @@ import 'package:smooth_corner/smooth_corner.dart'; class ImmediateLiveCarePaymentDetails extends StatelessWidget { ImmediateLiveCarePaymentDetails({super.key}); - late ImmediateLiveCareViewModel immediateLiveCareViewModel; + // late ImmediateLiveCareViewModel immediateLiveCareViewModel; late AppState appState; @override Widget build(BuildContext context) { - immediateLiveCareViewModel = Provider.of(context, listen: false); + // immediateLiveCareViewModel = Provider.of(context, listen: false); appState = getIt.get(); return Scaffold( backgroundColor: AppColors.scaffoldBgColor, - body: Column( - children: [ - Expanded( - child: CollapsingListView( - title: LocaleKeys.reviewLiveCareRequest.tr(context: context), - child: SingleChildScrollView( - padding: EdgeInsets.symmetric(horizontal: 24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 24.h), - LocaleKeys.patientInfo.tr(context: context).toText16(isBold: true), - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Image.asset( - appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, - width: 52.h, - height: 52.h, - ), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText16(isBold: true), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.h, - runSpacing: 4.h, - children: [ - AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} ${LocaleKeys.yearsOld.tr(context: context)}"), - AppCustomChipWidget( - labelText: - "${LocaleKeys.clinic.tr()}: ${(appState.isArabic() ? immediateLiveCareViewModel.immediateLiveCareSelectedClinic.serviceNameN : immediateLiveCareViewModel.immediateLiveCareSelectedClinic.serviceName)!}"), - ], - ), - ], - ), - ], - ), - ), - ), - SizedBox(height: 24.h), - LocaleKeys.selectedLiveCareType.tr(context: context).toText16(isBold: true), - SizedBox(height: 16.h), - Consumer(builder: (context, bookAppointmentsVM, child) { - return Container( + body: Consumer(builder: (context, immediateLiveCareVM, child) { + return Column( + children: [ + Expanded( + child: CollapsingListView( + title: LocaleKeys.reviewLiveCareRequest.tr(context: context), + child: SingleChildScrollView( + padding: EdgeInsets.symmetric(horizontal: 24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + LocaleKeys.patientInfo.tr(context: context).toText16(isBold: true), + SizedBox(height: 16.h), + Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 24.h, @@ -106,217 +65,262 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { child: Padding( padding: EdgeInsets.all(16.h), child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( + Image.asset( + appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, + width: 52.h, + height: 52.h, + ), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain), - SizedBox(width: 8.h), - getLiveCareType(context, immediateLiveCareViewModel.liveCareSelectedCallType).toText16(isBold: true), + "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText16(isBold: true), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} ${LocaleKeys.yearsOld.tr(context: context)}"), + AppCustomChipWidget( + labelText: + "${LocaleKeys.clinic.tr()}: ${(appState.isArabic() ? immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceNameN : immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceName)!}"), + ], + ), ], ), - Utils.buildSvgWithAssets(icon: AppAssets.edit_icon, width: 24.h, height: 24.h, fit: BoxFit.contain), ], ), ), - ).onPress(() { - showCommonBottomSheetWithoutHeight(context, child: SelectLiveCareCallType(immediateLiveCareViewModel: immediateLiveCareViewModel), callBackFunc: () async { - debugPrint("Selected Call Type: ${immediateLiveCareViewModel.liveCareSelectedCallType}"); - }, title: LocaleKeys.selectLiveCareCallType.tr(context: context), isCloseButtonVisible: true, isFullScreen: false); - }); - }), - SizedBox(height: 24.h) - ], + ), + SizedBox(height: 24.h), + LocaleKeys.selectedLiveCareType.tr(context: context).toText16(isBold: true), + SizedBox(height: 16.h), + Consumer(builder: (context, bookAppointmentsVM, child) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain), + SizedBox(width: 8.h), + getLiveCareType(context, immediateLiveCareVM.liveCareSelectedCallType).toText16(isBold: true), + ], + ), + Utils.buildSvgWithAssets(icon: AppAssets.edit_icon, width: 24.h, height: 24.h, fit: BoxFit.contain), + ], + ), + ), + ).onPress(() { + showCommonBottomSheetWithoutHeight(context, child: SelectLiveCareCallType(immediateLiveCareViewModel: immediateLiveCareVM), callBackFunc: () async { + debugPrint("Selected Call Type: ${immediateLiveCareVM.liveCareSelectedCallType}"); + }, title: LocaleKeys.selectLiveCareCallType.tr(context: context), isCloseButtonVisible: true, isFullScreen: false); + }); + }), + SizedBox(height: 24.h) + ], + ), ), ), ), - ), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: false, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - (immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.isCash ?? true) - ? Container( - height: 50.h, - decoration: ShapeDecoration( - color: AppColors.secondaryLightRedBorderColor, - shape: SmoothRectangleBorder( - borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), - smoothness: 1, + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: false, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.isCash ?? true) + ? Container( + height: 50.h, + decoration: ShapeDecoration( + color: AppColors.secondaryLightRedBorderColor, + shape: SmoothRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), + smoothness: 1, + ), ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(24.h, 0.h), - CustomButton( - text: LocaleKeys.updateInsurance.tr(context: context), - onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: InsuranceHomePage(), - ), - ); - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.secondaryLightRedBorderColor, - textColor: AppColors.whiteColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(15, 0, 15, 0), - height: 30.h, - ).paddingSymmetrical(24.h, 0.h), - ], - ), - ) - : const SizedBox(), - SizedBox(height: 24.h), - LocaleKeys.totalAmountToPay.tr(context: context).toText18(isBold: true).paddingSymmetrical(24.h, 0.h), - SizedBox(height: 17.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true), - Utils.getPaymentAmountWithSymbol(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.amount!.toText16(isBold: true), AppColors.blackColor, 13, - isSaudiCurrency: immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), - ], - ).paddingSymmetrical(24.h, 0.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.vat15.tr(context: context).toText14(isBold: true, color: AppColors.greyTextColor), - Utils.getPaymentAmountWithSymbol( - immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.tax!.toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13, - isSaudiCurrency: immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), - ], - ).paddingSymmetrical(24.h, 0.h), - SizedBox(height: 17.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox(width: 150.h, child: Utils.getPaymentMethods()), - Utils.getPaymentAmountWithSymbol(immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true), AppColors.blackColor, 17, - isSaudiCurrency: immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), - ], - ).paddingSymmetrical(24.h, 0.h), - (immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total == "0" || immediateLiveCareViewModel.liveCareImmediateAppointmentFeesList.total == "0.0") - ? CustomButton( - text: LocaleKeys.confirmLiveCare.tr(context: context), - onPressed: () async { - await askVideoCallPermission(context).then((val) async { - if (val) { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingLiveCareRequest.tr(context: context)); - - await immediateLiveCareViewModel.addNewCallRequestForImmediateLiveCare("${appState.getAuthenticatedUser()!.patientId}${DateTime.now().millisecondsSinceEpoch}"); - await immediateLiveCareViewModel.getPatientLiveCareHistory(); - LoaderBottomSheet.hideLoader(); - if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { - Navigator.pushAndRemoveUntil( - context, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(24.h, 0.h), + CustomButton( + text: LocaleKeys.updateInsurance.tr(context: context), + onPressed: () { + Navigator.of(context).push( CustomPageRoute( - page: LandingNavigation(), + page: InsuranceHomePage(), ), + ); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.secondaryLightRedBorderColor, + textColor: AppColors.whiteColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(15, 0, 15, 0), + height: 30.h, + ).paddingSymmetrical(24.h, 0.h), + ], + ), + ) + : const SizedBox(), + SizedBox(height: 24.h), + LocaleKeys.totalAmountToPay.tr(context: context).toText18(isBold: true).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 17.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true), + Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount!.toText16(isBold: true), AppColors.blackColor, 13, + isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), + ], + ).paddingSymmetrical(24.h, 0.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.vat15.tr(context: context).toText14(isBold: true, color: AppColors.greyTextColor), + Utils.getPaymentAmountWithSymbol( + immediateLiveCareVM.liveCareImmediateAppointmentFeesList.tax!.toText14(isBold: true, color: AppColors.greyTextColor), AppColors.greyTextColor, 13, + isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), + ], + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 17.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(width: 150.h, child: Utils.getPaymentMethods()), + Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true), AppColors.blackColor, 17, + isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar"), + ], + ).paddingSymmetrical(24.h, 0.h), + (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0" || immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0.0") + ? CustomButton( + text: LocaleKeys.confirmLiveCare.tr(context: context), + onPressed: () async { + await askVideoCallPermission(context).then((val) async { + if (val) { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingLiveCareRequest.tr(context: context)); + + await immediateLiveCareVM.addNewCallRequestForImmediateLiveCare("${appState.getAuthenticatedUser()!.patientId}${DateTime + .now() + .millisecondsSinceEpoch}"); + await immediateLiveCareVM.getPatientLiveCareHistory(); + LoaderBottomSheet.hideLoader(); + if (immediateLiveCareVM.patientHasPendingLiveCareRequest) { + Navigator.pushAndRemoveUntil( + context, + CustomPageRoute( + page: LandingNavigation(), + ), (r) => false); - Navigator.of(context).push( - CustomPageRoute( - page: ImmediateLiveCarePendingRequestPage(), - ), - ); + Navigator.of(context).push( + CustomPageRoute( + page: ImmediateLiveCarePendingRequestPage(), + ), + ); + } else { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: LocaleKeys.unknownErrorOccurred.tr(context: context)), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } } else { showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), context, - child: Utils.getErrorWidget(loadingText: LocaleKeys.unknownErrorOccurred.tr(context: context)), + child: Utils.getWarningWidget( + loadingText: LocaleKeys.liveCarePermissionsMessage.tr(context: context), + isShowActionButtons: true, + onCancelTap: () { + Navigator.pop(context); + }, + onConfirmTap: () async { + openAppSettings(); + }), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, ); } - } else { - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: context), - context, - child: Utils.getWarningWidget( - loadingText: LocaleKeys.liveCarePermissionsMessage.tr(context: context), - isShowActionButtons: true, - onCancelTap: () { - Navigator.pop(context); - }, - onConfirmTap: () async { - openAppSettings(); - }), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - } - }); - }, - backgroundColor: AppColors.successColor, - borderColor: AppColors.successColor, - textColor: AppColors.whiteColor, - fontSize: 16, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50.h, - icon: AppAssets.livecare_book_icon, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ).paddingSymmetrical(24.h, 24.h) - : CustomButton( - text: LocaleKeys.payNow.tr(context: context), - onPressed: () async { - await askVideoCallPermission(context).then((val) { - if (val) { - Navigator.of(context).push( - CustomPageRoute( - page: ImmediateLiveCarePaymentPage(), - ), - ); - } - // else { - // showCommonBottomSheetWithoutHeight( - // title: LocaleKeys.notice.tr(context: context), - // context, - // child: Utils.getWarningWidget( - // loadingText: LocaleKeys.liveCarePermissionsMessage.tr(context: context), - // isShowActionButtons: true, - // onCancelTap: () { - // Navigator.pop(context); - // }, - // onConfirmTap: () async { - // openAppSettings(); - // }), - // callBackFunc: () {}, - // isFullScreen: false, - // isCloseButtonVisible: true, - // ); - // } - }); - }, - backgroundColor: AppColors.infoColor, - borderColor: AppColors.infoColor, - textColor: AppColors.whiteColor, - fontSize: 16, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50.h, - icon: AppAssets.appointment_pay_icon, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ).paddingSymmetrical(24.h, 24.h), - ], + }); + }, + backgroundColor: AppColors.successColor, + borderColor: AppColors.successColor, + textColor: AppColors.whiteColor, + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + icon: AppAssets.livecare_book_icon, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).paddingSymmetrical(24.h, 24.h) + : CustomButton( + text: LocaleKeys.payNow.tr(context: context), + onPressed: () async { + await askVideoCallPermission(context).then((val) { + if (val) { + Navigator.of(context).push( + CustomPageRoute( + page: ImmediateLiveCarePaymentPage(), + ), + ); + } + // else { + // showCommonBottomSheetWithoutHeight( + // title: LocaleKeys.notice.tr(context: context), + // context, + // child: Utils.getWarningWidget( + // loadingText: LocaleKeys.liveCarePermissionsMessage.tr(context: context), + // isShowActionButtons: true, + // onCancelTap: () { + // Navigator.pop(context); + // }, + // onConfirmTap: () async { + // openAppSettings(); + // }), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); + // } + }); + }, + backgroundColor: AppColors.infoColor, + borderColor: AppColors.infoColor, + textColor: AppColors.whiteColor, + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + icon: AppAssets.appointment_pay_icon, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).paddingSymmetrical(24.h, 24.h), + ], + ), ), - ), - ], - ), + ], + ); + }), ); } diff --git a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart index e86104b..5a368a3 100644 --- a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart @@ -526,8 +526,8 @@ class CallAmbulancePage extends StatelessWidget { textPlaceInput(context) { return Consumer(builder: (_, vm, __) { - print("the data is ${vm.geocodeResponse?.results.first.formattedAddress ?? vm.selectedPrediction?.description}"); - return SizedBox( + // print("the data is ${vm.geocodeResponse?.results.first.formattedAddress ?? vm.selectedPrediction?.description}"); + return (vm.geocodeResponse != null && vm.geocodeResponse!.results.isNotEmpty) ? SizedBox( width: MediaQuery.sizeOf(context).width, child: TextInputWidget( labelText: LocaleKeys.enterPickupLocationManually.tr(context: context), @@ -549,7 +549,7 @@ class CallAmbulancePage extends StatelessWidget { ).onPress(() { openLocationInputBottomSheet(context); }), - ); + ) : SizedBox.shrink(); }); } diff --git a/lib/presentation/habib_wallet/recharge_wallet_page.dart b/lib/presentation/habib_wallet/recharge_wallet_page.dart index b8e2d01..22e854a 100644 --- a/lib/presentation/habib_wallet/recharge_wallet_page.dart +++ b/lib/presentation/habib_wallet/recharge_wallet_page.dart @@ -36,6 +36,7 @@ class _RechargeWalletPageState extends State { late HabibWalletViewModel habibWalletVM; late AppState appState; final TextEditingController amountTextController = TextEditingController(); + final TextEditingController notesTextController = TextEditingController(); @override void initState() { @@ -209,23 +210,20 @@ class _RechargeWalletPageState extends State { SizedBox(height: 16.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - 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".toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2), - ], - ), - ], - ), - ], + TextInputWidget( + labelText: LocaleKeys.notes.tr(context: context), + hintText: "", + controller: notesTextController, + keyboardType: TextInputType.text, + isEnable: true, + prefix: null, + autoFocus: true, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + leadingIcon: AppAssets.notes_icon, + errorMessage: LocaleKeys.enterValidIDorIqama.tr(context: context), + hasError: false, ), SizedBox(height: 8.h), ], @@ -271,6 +269,7 @@ class _RechargeWalletPageState extends State { ); } else { habibWalletVM.setWalletRechargeAmount(num.parse(amountTextController.text)); + habibWalletVM.setNotesText(notesTextController.text); // habibWalletVM.setDepositorDetails(appState.getAuthenticatedUser()!.patientId.toString(), "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", // appState.getAuthenticatedUser()!.mobileNumber!); Navigator.of(context).push( diff --git a/lib/presentation/habib_wallet/widgets/select-medical_file.dart b/lib/presentation/habib_wallet/widgets/select-medical_file.dart index aaa0036..6fed652 100644 --- a/lib/presentation/habib_wallet/widgets/select-medical_file.dart +++ b/lib/presentation/habib_wallet/widgets/select-medical_file.dart @@ -28,6 +28,8 @@ 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/medical_file/medical_file_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -145,6 +147,10 @@ class _MultiPageBottomSheetState extends State { ], ).paddingAll(16.h), ).onPress(() { + habibWalletVM.setDepositorDetails(appState.getAuthenticatedUser()!.patientId!.toString(), + "${appState.getAuthenticatedUser()!.firstName.toString()} ${appState.getAuthenticatedUser()!.lastName.toString()}", appState.getAuthenticatedUser()!.mobileNumber!.toString()); + habibWalletVM.setCurrentIndex(0); + habibWalletVM.setSelectedRechargeType(1); Navigator.of(context).pop(); }), SizedBox(height: 16.h), @@ -167,7 +173,24 @@ class _MultiPageBottomSheetState extends State { Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h), ], ).paddingAll(16.h), - ), + ).onPress(() { + DialogService dialogService = getIt.get(); + dialogService.showFamilyBottomSheetWithoutH( + label: LocaleKeys.familyTitle.tr(context: context), + message: "", + isShowManageButton: false, + isForWalletRecharge: true, + onSwitchPress: (FamilyFileResponseModelLists profile) { + habibWalletVM.setDepositorDetails(profile.responseId.toString(), profile.patientName.toString(), profile.mobileNumber.toString()); + habibWalletVM.setCurrentIndex(0); + habibWalletVM.setSelectedRechargeType(2); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + // medicalFileViewModel.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + }, + profiles: getIt.get().patientFamilyFiles); + }), SizedBox(height: 16.h), Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index c737732..35be7f9 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -1,6 +1,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -11,16 +13,20 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_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/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:provider/provider.dart'; class PatientInsuranceCardUpdateCard extends StatelessWidget { PatientInsuranceCardUpdateCard({super.key}); late InsuranceViewModel insuranceViewModel; + late AppState appState; @override Widget build(BuildContext context) { insuranceViewModel = Provider.of(context); + appState = getIt.get(); return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -49,7 +55,7 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Haroon Amjad".toText16(weight: FontWeight.w600), + insuranceViewModel.patientInsuranceUpdateResponseModel!.memberName!.toText16(weight: FontWeight.w600), "Policy: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.policyNumber}".toText12(isBold: true, color: AppColors.lightGrayColor), SizedBox(height: 8.h), Row( @@ -99,7 +105,41 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { iconColor: AppColors.whiteColor, iconSize: 20.w, text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", - onPressed: () {}, + onPressed: () { + LoaderBottomSheet.showLoader(); + insuranceViewModel.updatePatientInsuranceCard( + patientID: appState.getAuthenticatedUser()!.patientId!, + patientType: appState.getAuthenticatedUser()!.patientType!, + patientIdentificationID: appState.getAuthenticatedUser()!.patientIdentificationNo!, + mobileNo: appState.getAuthenticatedUser()!.mobileNumber!, + insuranceCardImage: "", + onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.success.tr(context: context), + context, + child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr(context: context)), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), + context, + child: Utils.getErrorWidget(loadingText: err.toString()), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }, backgroundColor: insuranceViewModel.patientInsuranceUpdateResponseModel != null ? AppColors.successColor : AppColors.lightGrayBGColor, borderColor: AppColors.successColor.withOpacity(0.01), textColor: AppColors.whiteColor, diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index 175cfb1..ea305b0 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/core/enums.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/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; @@ -25,6 +26,7 @@ class FamilyCards extends StatefulWidget { final bool isRequestDesign; final bool isLeftAligned; final bool isShowRemoveButton; + final bool isForWalletRecharge; const FamilyCards( {super.key, @@ -35,6 +37,7 @@ class FamilyCards extends StatefulWidget { this.isBottomSheet = false, this.isRequestDesign = false, this.isLeftAligned = false, + this.isForWalletRecharge = false, this.isShowRemoveButton = false}); @override @@ -206,7 +209,21 @@ class _FamilyCardsState extends State { height: 4.h, ), Spacer(), - CustomButton( + widget.isForWalletRecharge ? CustomButton( + height: 40.h, + onPressed: () { + widget.onSelect(profile); + // if (canSwitch) widget.onSelect(profile); + }, + text: LocaleKeys.select.tr(context: context), + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 13.h, + icon: AppAssets.activeCheck, + iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ).paddingOnly(top: 0, bottom: 0) : CustomButton( height: 40.h, onPressed: () { if (canSwitch) widget.onSelect(profile); diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index b185d89..0b3a521 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -32,7 +32,8 @@ abstract class DialogService { required String message, required Function(FamilyFileResponseModelLists response) onSwitchPress, required List profiles, - bool isShowManageButton = false}); + bool isShowManageButton = false, + bool isForWalletRecharge = false}); Future showFamilyBottomSheetWithoutHWithChild({String? label, required String message, Widget? child, required Function() onOkPressed, Function()? onCancelPressed}); @@ -143,7 +144,8 @@ class DialogServiceImp implements DialogService { required String message, required Function(FamilyFileResponseModelLists response) onSwitchPress, required List profiles, - bool isShowManageButton = false}) async { + bool isShowManageButton = false, + bool isForWalletRecharge = false}) async { final context = navigationService.navigatorKey.currentContext; if (context == null) return; showCommonBottomSheetWithoutHeight(context, @@ -161,6 +163,7 @@ class DialogServiceImp implements DialogService { }, onRemove: (FamilyFileResponseModelLists profile) {}, isShowDetails: false, + isForWalletRecharge: isForWalletRecharge, ), SizedBox(height: isShowManageButton ? 15.h : 24.h), if (isShowManageButton)