From e8cc6407b62ff3f6965378074b476e51bf6ad246 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 4 Sep 2025 14:58:00 +0300 Subject: [PATCH] Insurance update implementation contd. --- assets/images/svg/cancel_circle.svg | 3 + assets/images/svg/insurance_history_icon.svg | 4 + assets/images/svg/update_insurance_card.svg | 4 + lib/core/app_assets.dart | 3 + lib/core/dependencies.dart | 10 ++ lib/features/insurance/insurance_repo.dart | 77 +++++++++++ .../insurance/insurance_view_model.dart | 43 ++++++ ...ient_insurance_details_response_model.dart | 96 +++++++++++++ lib/main.dart | 7 + lib/presentation/home/navigation_screen.dart | 15 +- .../home/widgets/small_service_card.dart | 6 + .../insurance/insurance_home_page.dart | 82 +++++++++++ .../widgets/patient_insurance_card.dart | 128 ++++++++++++++++++ .../medical_file/medical_file_page.dart | 112 +++------------ 14 files changed, 485 insertions(+), 105 deletions(-) create mode 100644 assets/images/svg/cancel_circle.svg create mode 100644 assets/images/svg/insurance_history_icon.svg create mode 100644 assets/images/svg/update_insurance_card.svg create mode 100644 lib/features/insurance/insurance_repo.dart create mode 100644 lib/features/insurance/insurance_view_model.dart create mode 100644 lib/features/insurance/models/resp_models/patient_insurance_details_response_model.dart create mode 100644 lib/presentation/insurance/insurance_home_page.dart create mode 100644 lib/presentation/insurance/widgets/patient_insurance_card.dart diff --git a/assets/images/svg/cancel_circle.svg b/assets/images/svg/cancel_circle.svg new file mode 100644 index 0000000..3ceda6f --- /dev/null +++ b/assets/images/svg/cancel_circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/insurance_history_icon.svg b/assets/images/svg/insurance_history_icon.svg new file mode 100644 index 0000000..4ae2a1c --- /dev/null +++ b/assets/images/svg/insurance_history_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/update_insurance_card.svg b/assets/images/svg/update_insurance_card.svg new file mode 100644 index 0000000..9b21aab --- /dev/null +++ b/assets/images/svg/update_insurance_card.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 7d32262..530064e 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -68,6 +68,9 @@ class AppAssets { static const String doctor_calendar_icon = '$svgBasePath/doctor_calendar_icon.svg'; static const String prescription_remarks_icon = '$svgBasePath/prescription_remarks_icon.svg'; static const String prescription_reminder_icon = '$svgBasePath/prescription_reminder_icon.svg'; + static const String insurance_history_icon = '$svgBasePath/insurance_history_icon.svg'; + static const String cancel_circle_icon = '$svgBasePath/cancel_circle.svg'; + static const String update_insurance_card_icon = '$svgBasePath/update_insurance_card.svg'; //bottom navigation// diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index 65fd2c6..aa32fa6 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -6,6 +6,8 @@ import 'package:hmg_patient_app_new/features/authentication/authentication_repo. import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart'; import 'package:hmg_patient_app_new/features/common/common_repo.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_repo.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart'; @@ -65,6 +67,7 @@ class AppDependencies { getIt.registerLazySingleton(() => LabRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => RadiologyRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => PrescriptionsRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => InsuranceRepoImp(loggerService: getIt(), apiClient: getIt())); // ViewModels // Global/shared VMs → LazySingleton @@ -90,6 +93,13 @@ class AppDependencies { ), ); + getIt.registerLazySingleton( + () => InsuranceViewModel( + insuranceRepo: getIt(), + errorHandlerService: getIt(), + ), + ); + getIt.registerLazySingleton( () => AuthenticationViewModel( authenticationRepo: getIt(), diff --git a/lib/features/insurance/insurance_repo.dart b/lib/features/insurance/insurance_repo.dart new file mode 100644 index 0000000..a5c624f --- /dev/null +++ b/lib/features/insurance/insurance_repo.dart @@ -0,0 +1,77 @@ +import 'package:dartz/dartz.dart'; +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/insurance/models/resp_models/patient_insurance_details_response_model.dart'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; + +abstract class InsuranceRepo { + Future>>> getPatientInsuranceDetails({required String patientId}); +} + +class InsuranceRepoImp implements InsuranceRepo { + final ApiClient apiClient; + final LoggerService loggerService; + + InsuranceRepoImp({required this.loggerService, required this.apiClient}); + + @override + Future>>> getPatientInsuranceDetails({required String patientId}) async { + final mapDevice = { + "isDentalAllowedBackend": false, + "VersionID": 50.0, + "Channel": 3, + "LanguageID": 2, + "IPAdress": "10.20.10.20", + "generalid": "Cs2020@2016\$2958", + "Latitude": 0.0, + "Longitude": 0.0, + "DeviceTypeID": 1, + "PatientType": 1, + "PatientTypeID": 1, + "TokenID": "@dm!n", + "PatientID": "3628599", + "PatientOutSA": "0", + "SessionID": "03478TYC02N80874CTYN04883475!?" + }; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_PAtIENTS_INSURANCE, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus}) { + try { + final list = response['List_PatientInsuranceCard']; + if (list == null || list.isEmpty) { + throw Exception("insurance list is empty"); + } + + final labOrders = list.map((item) => PatientInsuranceDetailsResponseModel.fromJson(item as Map)).toList().cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: labOrders, + ); + } 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())); + } + + throw UnimplementedError(); + } +} diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart new file mode 100644 index 0000000..545a32a --- /dev/null +++ b/lib/features/insurance/insurance_view_model.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_repo.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/lab/lab_repo.dart'; +import 'package:hmg_patient_app_new/services/error_handler_service.dart'; + +class InsuranceViewModel extends ChangeNotifier { + bool isInsuranceLoading = false; + + InsuranceRepo insuranceRepo; + ErrorHandlerService errorHandlerService; + + List patientInsuranceList = []; + + InsuranceViewModel({required this.insuranceRepo, required this.errorHandlerService}); + + initInsuranceProvider() { + patientInsuranceList.clear(); + isInsuranceLoading = true; + getPatientInsuranceDetails(); + notifyListeners(); + } + + Future getPatientInsuranceDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await insuranceRepo.getPatientInsuranceDetails(patientId: "1231755"); + + 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) { + patientInsuranceList = apiResponse.data!; + isInsuranceLoading = false; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } +} diff --git a/lib/features/insurance/models/resp_models/patient_insurance_details_response_model.dart b/lib/features/insurance/models/resp_models/patient_insurance_details_response_model.dart new file mode 100644 index 0000000..b734abc --- /dev/null +++ b/lib/features/insurance/models/resp_models/patient_insurance_details_response_model.dart @@ -0,0 +1,96 @@ +class PatientInsuranceDetailsResponseModel { + String? setupID; + int? projectID; + bool? isActive; + int? patientID; + int? companyID; + int? subCategoryID; + dynamic companyType; + String? patientCardID; + String? cardValidTo; + int? patientCreditLimit; + String? subPolicyNo; + String? companyName; + String? companyNameN; + String? subCategoryDesc; + dynamic subCategoryDescN; + bool? isElectronicClaim; + String? subCategoryValidTo; + dynamic groupID; + String? groupName; + dynamic groupNameN; + String? insurancePolicyNo; + + PatientInsuranceDetailsResponseModel( + {this.setupID, + this.projectID, + this.isActive, + this.patientID, + this.companyID, + this.subCategoryID, + this.companyType, + this.patientCardID, + this.cardValidTo, + this.patientCreditLimit, + this.subPolicyNo, + this.companyName, + this.companyNameN, + this.subCategoryDesc, + this.subCategoryDescN, + this.isElectronicClaim, + this.subCategoryValidTo, + this.groupID, + this.groupName, + this.groupNameN, + this.insurancePolicyNo}); + + PatientInsuranceDetailsResponseModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + isActive = json['IsActive']; + patientID = json['PatientID']; + companyID = json['CompanyID']; + subCategoryID = json['SubCategoryID']; + companyType = json['CompanyType']; + patientCardID = json['PatientCardID']; + cardValidTo = json['CardValidTo']; + patientCreditLimit = json['PatientCreditLimit']; + subPolicyNo = json['SubPolicyNo']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + subCategoryDesc = json['SubCategoryDesc']; + subCategoryDescN = json['SubCategoryDescN']; + isElectronicClaim = json['IsElectronicClaim']; + subCategoryValidTo = json['SubCategoryValidTo']; + groupID = json['GroupID']; + groupName = json['GroupName']; + groupNameN = json['GroupNameN']; + insurancePolicyNo = json['InsurancePolicyNo']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['IsActive'] = this.isActive; + data['PatientID'] = this.patientID; + data['CompanyID'] = this.companyID; + data['SubCategoryID'] = this.subCategoryID; + data['CompanyType'] = this.companyType; + data['PatientCardID'] = this.patientCardID; + data['CardValidTo'] = this.cardValidTo; + data['PatientCreditLimit'] = this.patientCreditLimit; + data['SubPolicyNo'] = this.subPolicyNo; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['SubCategoryDesc'] = this.subCategoryDesc; + data['SubCategoryDescN'] = this.subCategoryDescN; + data['IsElectronicClaim'] = this.isElectronicClaim; + data['SubCategoryValidTo'] = this.subCategoryValidTo; + data['GroupID'] = this.groupID; + data['GroupName'] = this.groupName; + data['GroupNameN'] = this.groupNameN; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + return data; + } +} diff --git a/lib/main.dart b/lib/main.dart index 035c6bf..ce69f5d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart'; @@ -71,6 +72,12 @@ void main() async { errorHandlerService: getIt(), ), ), + ChangeNotifierProvider( + create: (_) => InsuranceViewModel( + insuranceRepo: getIt(), + errorHandlerService: getIt(), + ), + ), ChangeNotifierProvider( create: (_) => AuthenticationViewModel( authenticationRepo: getIt(), diff --git a/lib/presentation/home/navigation_screen.dart b/lib/presentation/home/navigation_screen.dart index f3e088b..152bbd2 100644 --- a/lib/presentation/home/navigation_screen.dart +++ b/lib/presentation/home/navigation_screen.dart @@ -20,22 +20,19 @@ class _LandingNavigationState extends State { body: PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), - children: const [ - LandingPage(), + children: [ + const LandingPage(), MedicalFilePage(), - LandingPage(), - LandingPage(), - LandingPage(), + const LandingPage(), + const LandingPage(), + const LandingPage(), ], ), bottomNavigationBar: BottomNavigation( currentIndex: _currentIndex, onTap: (index) { setState(() => _currentIndex = index); - _pageController.animateToPage( - index, - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOut); + _pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut); }, ), ); diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index 297ed2b..f988e18 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.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/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; @@ -78,6 +79,11 @@ class SmallServiceCard extends StatelessWidget { ); break; case "insurance_update": + Navigator.of(context).push( + FadePage( + page: InsuranceHomePage(), + ), + ); break; default: // Handle unknown service diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart new file mode 100644 index 0000000..d348f8d --- /dev/null +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -0,0 +1,82 @@ +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'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; +import 'package:provider/provider.dart'; + +class InsuranceHomePage extends StatefulWidget { + const InsuranceHomePage({super.key}); + + @override + State createState() => _InsuranceHomePageState(); +} + +class _InsuranceHomePageState extends State { + late InsuranceViewModel insuranceViewModel; + + @override + void initState() { + scheduleMicrotask(() { + insuranceViewModel.initInsuranceProvider(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + insuranceViewModel = Provider.of(context); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + appBar: AppBar( + title: LocaleKeys.insurance.tr(context: context).toText18(), + backgroundColor: AppColors.bgScaffoldColor, + ), + body: SingleChildScrollView( + child: Consumer(builder: (context, insuranceVM, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${LocaleKeys.insurance.tr(context: context)} ${LocaleKeys.updateInsurance.tr(context: context)}".toText24(isBold: true), + CustomButton( + icon: AppAssets.insurance_history_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 21.h, + text: LocaleKeys.history.tr(context: context), + onPressed: () {}, + backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), + borderColor: AppColors.primaryRedColor.withOpacity(0.0), + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w600, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(24.h, 24.h), + insuranceVM.isInsuranceLoading + ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0) + : PatientInsuranceCard( + insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, + isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))), + ], + ); + }), + ), + ); + } +} diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart new file mode 100644 index 0000000..7726b94 --- /dev/null +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -0,0 +1,128 @@ +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/utils/date_util.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/insurance/models/resp_models/patient_insurance_details_response_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'; + +class PatientInsuranceCard extends StatelessWidget { + PatientInsuranceCard({super.key, required this.insuranceCardDetailsModel, required this.isInsuranceExpired}); + + PatientInsuranceDetailsResponseModel insuranceCardDetailsModel; + bool isInsuranceExpired = false; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Haroon Amjad".toText18(isBold: true), + "Policy: ${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor), + ], + ), + CustomButton( + icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon, + iconColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, + iconSize: 13.h, + text: isInsuranceExpired ? "Insurance Expired" : "Insurance Active", + onPressed: () {}, + backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.15) : AppColors.successColor.withOpacity(0.15), + borderColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.01) : AppColors.successColor.withOpacity(0.01), + textColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + ], + ), + SizedBox(height: 12.h), + insuranceCardDetailsModel.groupName!.toText12(isBold: true), + insuranceCardDetailsModel.companyName!.toText12(isBold: true), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 6.h, + runSpacing: 6.h, + children: [ + Row( + children: [ + CustomButton( + icon: AppAssets.doctor_calendar_icon, + iconColor: AppColors.blackColor, + iconSize: 13.h, + text: "${LocaleKeys.expiryDate.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceCardDetailsModel.cardValidTo), false)}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + ], + ), + Row( + children: [ + CustomButton( + text: "Patient Card ID: ${insuranceCardDetailsModel.patientCardID}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + ], + ), + ], + ), + SizedBox(height: 10.h), + isInsuranceExpired + ? CustomButton( + icon: AppAssets.update_insurance_card_icon, + iconColor: AppColors.successColor, + iconSize: 15.h, + text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + onPressed: () {}, + backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), + borderColor: AppColors.bgGreenColor.withOpacity(0.0), + textColor: AppColors.bgGreenColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ) + : Container(), + ], + ), + ), + ).paddingSymmetrical(24.h, 0.h); + } +} diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 7fa4fe9..da5227a 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -1,20 +1,28 @@ 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/utils/date_util.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/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.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:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; +import 'package:provider/provider.dart'; class MedicalFilePage extends StatelessWidget { - const MedicalFilePage({super.key}); + MedicalFilePage({super.key}); + + late InsuranceViewModel insuranceViewModel; @override Widget build(BuildContext context) { + insuranceViewModel = Provider.of(context); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, appBar: AppBar( @@ -162,101 +170,13 @@ class MedicalFilePage extends StatelessWidget { ), SizedBox(height: 16.h), //Insurance Tab Data - Container( - // height: 150.h, - width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Haroon Amjad".toText18(isBold: true), - "Policy: 223123345".toText12(isBold: true, color: AppColors.lightGrayColor), - ], - ), - CustomButton( - icon: AppAssets.cross_circle, - iconColor: AppColors.primaryRedColor, - iconSize: 13.h, - text: "Insurance Expired", - onPressed: () {}, - backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), - borderColor: AppColors.primaryRedColor.withOpacity(0.0), - textColor: AppColors.primaryRedColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - SizedBox(height: 12.h), - "NCCI".toText12(isBold: true), - "NC_Dr Sulaiman Al Habib Medical Group".toText12(isBold: true), - SizedBox(height: 8.h), - Row( - children: [ - CustomButton( - icon: AppAssets.cross_circle, - iconColor: AppColors.primaryRedColor, - iconSize: 13.h, - text: "Expiry: 18 Mar, 2025", - onPressed: () {}, - backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), - borderColor: AppColors.primaryRedColor.withOpacity(0.0), - textColor: AppColors.primaryRedColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - SizedBox(width: 5.h), - CustomButton( - text: "Patient Card ID: 3628599", - 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(height: 10.h), - CustomButton( - icon: AppAssets.cross_circle, - iconColor: AppColors.primaryRedColor, - iconSize: 13.h, - text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", - onPressed: () {}, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.bgGreenColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - ], - ), - ), - ), + Consumer(builder: (context, insuranceVM, child) { + return insuranceVM.isInsuranceLoading + ? const MoviesShimmerWidget() + : PatientInsuranceCard( + insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, + isInsuranceExpired: DateTime.now().isBefore(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))); + }), SizedBox(height: 10.h), GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13),