From b0708d85d9eefe00d81119998cfc240d21c8e92c Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 22 Jan 2026 16:33:23 +0300 Subject: [PATCH] updates & fixes --- lib/core/api_consts.dart | 2 +- lib/core/dependencies.dart | 2 +- .../health_trackers_view_model.dart | 17 +- .../utils/appointment_type.dart | 2 +- lib/main.dart | 2 +- .../add_health_tracker_entry_page.dart | 2 +- .../health_tracker_detail_page.dart | 2 +- .../widgets/tracker_last_value_card.dart | 2 +- lib/presentation/home/landing_page.dart | 593 ++++++++++-------- .../home/widgets/habib_wallet_card.dart | 1 + .../my_invoices/my_invoices_list.dart | 6 +- .../symptoms_checker/user_info_selection.dart | 2 + lib/widgets/buttons/custom_button.dart | 8 +- 13 files changed, 351 insertions(+), 290 deletions(-) rename lib/{presentation => features}/health_trackers/health_trackers_view_model.dart (98%) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index dbf3566..f715305 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/dependencies.dart b/lib/core/dependencies.dart index d020eaa..0560ff9 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -61,7 +61,7 @@ import 'package:hmg_patient_app_new/features/todo_section/todo_section_repo.dart import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart'; import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_repo.dart'; import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart'; -import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_view_model.dart'; +import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; diff --git a/lib/presentation/health_trackers/health_trackers_view_model.dart b/lib/features/health_trackers/health_trackers_view_model.dart similarity index 98% rename from lib/presentation/health_trackers/health_trackers_view_model.dart rename to lib/features/health_trackers/health_trackers_view_model.dart index ce1bdf2..ab54f59 100644 --- a/lib/presentation/health_trackers/health_trackers_view_model.dart +++ b/lib/features/health_trackers/health_trackers_view_model.dart @@ -215,7 +215,8 @@ class HealthTrackersViewModel extends ChangeNotifier { final averageResult = await healthTrackersRepo.getWeightMeasurementResultAverage(); averageResult.fold( - (failure) => errorHandlerService.handleError(failure: failure), + // (failure) => errorHandlerService.handleError(failure: failure), + (failure) => {}, (apiModel) { final data = apiModel.data; if (data is Map) { @@ -258,7 +259,8 @@ class HealthTrackersViewModel extends ChangeNotifier { final resultsResponse = await healthTrackersRepo.getWeightMeasurementResults(); resultsResponse.fold( - (failure) => errorHandlerService.handleError(failure: failure), + // (failure) => errorHandlerService.handleError(failure: failure), + (failure) => {}, (apiModel) { final data = apiModel.data; if (data is Map) { @@ -435,7 +437,8 @@ class HealthTrackersViewModel extends ChangeNotifier { final averageResult = await healthTrackersRepo.getBloodPressureResultAverage(); averageResult.fold( - (failure) => errorHandlerService.handleError(failure: failure), + // (failure) => errorHandlerService.handleError(failure: failure), + (failure) => {}, (apiModel) { final data = apiModel.data; @@ -479,7 +482,8 @@ class HealthTrackersViewModel extends ChangeNotifier { final resultsResponse = await healthTrackersRepo.getBloodPressureResults(); resultsResponse.fold( - (failure) => errorHandlerService.handleError(failure: failure), + // (failure) => errorHandlerService.handleError(failure: failure), + (failure) => {}, (apiModel) { final data = apiModel.data; if (data is Map) { @@ -636,7 +640,7 @@ class HealthTrackersViewModel extends ChangeNotifier { final averageResult = await healthTrackersRepo.getDiabeticResultAverage(); averageResult.fold( - (failure) => errorHandlerService.handleError(failure: failure), + (failure) {}, (apiModel) { final data = apiModel.data; if (data is Map) { @@ -679,7 +683,8 @@ class HealthTrackersViewModel extends ChangeNotifier { final resultsResponse = await healthTrackersRepo.getDiabeticResults(); resultsResponse.fold( - (failure) => errorHandlerService.handleError(failure: failure), + // (failure) => errorHandlerService.handleError(failure: failure), + (failure) {}, (apiModel) { final data = apiModel.data; if (data is Map) { diff --git a/lib/features/my_appointments/utils/appointment_type.dart b/lib/features/my_appointments/utils/appointment_type.dart index aa2ef38..ae3c751 100644 --- a/lib/features/my_appointments/utils/appointment_type.dart +++ b/lib/features/my_appointments/utils/appointment_type.dart @@ -69,7 +69,7 @@ class AppointmentType { case 10: return AppColors.successColor; case 15: - return AppColors.greyColor; + return AppColors.greyTextColor; case 20: return AppColors.infoColor; case 50: diff --git a/lib/main.dart b/lib/main.dart index 79b600c..e15e8a7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -40,7 +40,7 @@ import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_v import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart'; import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart'; import 'package:hmg_patient_app_new/presentation/health_calculators_and_converts/health_calculator_view_model.dart'; -import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_view_model.dart'; +import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; diff --git a/lib/presentation/health_trackers/add_health_tracker_entry_page.dart b/lib/presentation/health_trackers/add_health_tracker_entry_page.dart index cf92c9b..702875d 100644 --- a/lib/presentation/health_trackers/add_health_tracker_entry_page.dart +++ b/lib/presentation/health_trackers/add_health_tracker_entry_page.dart @@ -10,7 +10,7 @@ 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/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_view_model.dart'; +import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; diff --git a/lib/presentation/health_trackers/health_tracker_detail_page.dart b/lib/presentation/health_trackers/health_tracker_detail_page.dart index 83b37f6..b5f41da 100644 --- a/lib/presentation/health_trackers/health_tracker_detail_page.dart +++ b/lib/presentation/health_trackers/health_tracker_detail_page.dart @@ -16,7 +16,7 @@ import 'package:hmg_patient_app_new/features/health_trackers/models/blood_sugar/ import 'package:hmg_patient_app_new/features/health_trackers/models/weight/week_weight_measurement_result_average.dart'; import 'package:hmg_patient_app_new/features/health_trackers/models/weight/year_weight_measurement_result_average.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_view_model.dart'; +import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart'; import 'package:hmg_patient_app_new/presentation/health_trackers/widgets/tracker_last_value_card.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/health_trackers/widgets/tracker_last_value_card.dart b/lib/presentation/health_trackers/widgets/tracker_last_value_card.dart index 570005b..7e4ac2c 100644 --- a/lib/presentation/health_trackers/widgets/tracker_last_value_card.dart +++ b/lib/presentation/health_trackers/widgets/tracker_last_value_card.dart @@ -6,7 +6,7 @@ import 'package:hmg_patient_app_new/core/enums.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/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/health_trackers/health_trackers_view_model.dart'; +import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.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:provider/provider.dart'; diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 770e953..ab0d247 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -654,299 +654,354 @@ class _LandingPageState extends State { ); } + // Main card selector based on index and priority Widget getIndexSwiperCard(int index) { + // Index 0: Priority cards (Queue > LiveCare > Upcoming Appointment > History) if (index == 0) { - if (myAppointmentsViewModel.isPatientHasQueueAppointment) { - return Container( + return _buildFirstCardSlot(); + } + // Index 1: Secondary cards based on first card type + if (index == 1) { + return _buildSecondCardSlot(); + } + // Index 2: Tertiary cards + if (index == 2) { + return _buildThirdCardSlot(); + } + return Container(); + } + + // First slot: Shows highest priority card + Widget _buildFirstCardSlot() { + if (myAppointmentsViewModel.isPatientHasQueueAppointment) { + return _buildQueueCard(); + } + + if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { + return _buildLiveCareRequestCard(); + } + + if (myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.isNotEmpty) { + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.first, + ); + } + + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList[0], + ); + } + + // Second slot: Shows appointment or ancillary orders + Widget _buildSecondCardSlot() { + final hasQueueOrLiveCare = myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest; + + if (hasQueueOrLiveCare) { + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList.first, + ); + } + + if (todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) { + return _buildAncillaryOrderCardWrapper( + todoSectionViewModel.patientAncillaryOrdersList.first, + ); + } + + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList[1], + ); + } + + // Third slot: Shows ancillary orders or appointment + Widget _buildThirdCardSlot() { + final hasQueueOrLiveCare = myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest; + final hasAncillaryOrders = todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty; + + if (hasQueueOrLiveCare && hasAncillaryOrders) { + return _buildAncillaryOrderCardWrapper( + todoSectionViewModel.patientAncillaryOrdersList.first, + ); + } + + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList[2], + ); + } + + // Queue Card Widget + Widget _buildQueueCard() { + final currentQueue = myAppointmentsViewModel.currentPatientQueueDetails; + final currentStatus = myAppointmentsViewModel.currentQueueStatus; + + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + side: BorderSide( + color: Utils.getCardBorderColor(currentStatus), + width: 2.w, + ), + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildQueueHeader(currentStatus), + SizedBox(height: 8.h), + _buildQueueGreeting(), + SizedBox(height: 2.h), + LocaleKeys.thankYouForPatience.tr().toText12( + fontWeight: FontWeight.w500, + color: AppColors.textColorLight, + ), + SizedBox(height: 8.h), + currentQueue.queueNo!.toText28(isBold: true), + SizedBox(height: 6.h), + _buildServingNowSection(), + SizedBox(height: 5.h), + _buildQueueActionButton(currentStatus, currentQueue.roomNo ?? ""), + ], + ), + ), + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute(page: AppointmentQueuePage()), + ); + }); + } + + // Queue Card: Header with status chip and icon + Widget _buildQueueHeader(int currentStatus) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppCustomChipWidget( + labelText: currentStatus == 0 ? LocaleKeys.inQueue.tr() : LocaleKeys.yourTurn.tr(), + backgroundColor: Utils.getCardBorderColor(currentStatus).withValues(alpha: 0.20), + textColor: Utils.getCardBorderColor(currentStatus), + ), + Utils.buildSvgWithAssets( + icon: AppAssets.waiting_icon, + width: 24.h, + height: 24.h, + ), + ], + ); + } + + // Queue Card: Greeting text + Widget _buildQueueGreeting() { + return LocaleKeys.halaFirstName.tr(namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}).toText16(isBold: true); + } + + // Queue Card: Currently serving section + Widget _buildServingNowSection() { + if (myAppointmentsViewModel.patientQueueDetailsList.isEmpty) { + return SizedBox(height: 12.h); + } + + final servingQueue = myAppointmentsViewModel.patientQueueDetailsList.first; + final isVitalCall = servingQueue.callType == 1; + + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + "${LocaleKeys.servingNow.tr()}: ".toText14(isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + servingQueue.queueNo!.toText12(isBold: true), + SizedBox(width: 8.w), + AppCustomChipWidget( + deleteIcon: isVitalCall ? AppAssets.call_for_vitals : AppAssets.call_for_doctor, + labelText: isVitalCall ? LocaleKeys.callForVitalSigns.tr() : LocaleKeys.callForDoctor.tr(), + iconColor: isVitalCall ? AppColors.primaryRedColor : AppColors.successColor, + textColor: isVitalCall ? AppColors.primaryRedColor : AppColors.successColor, + iconSize: 14.w, + backgroundColor: isVitalCall ? AppColors.primaryRedColor.withValues(alpha: 0.1) : AppColors.successColor.withValues(alpha: 0.1), + labelPadding: EdgeInsetsDirectional.only( + start: 8.h, + end: -2.h, + ), + ), + ], + ), + ], + ); + } + + // Queue Card: Action button + Widget _buildQueueActionButton(int currentStatus, String roomNo) { + return CustomButton( + text: Utils.getCardButtonText(currentStatus, roomNo), + onPressed: () {}, + backgroundColor: Utils.getCardButtonColor(currentStatus), + borderColor: Utils.getCardButtonColor(currentStatus).withValues(alpha: 0.01), + textColor: Utils.getCardButtonTextColor(currentStatus), + fontSize: 12.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 40.h, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ); + } + + // LiveCare Request Card Widget + Widget _buildLiveCareRequestCard() { + final liveCareData = immediateLiveCareViewModel.patientLiveCareHistoryList[0]; + + return Column( + children: [ + SizedBox(height: 12.h), + Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: false, - side: BorderSide(color: Utils.getCardBorderColor(myAppointmentsViewModel.currentQueueStatus), width: 2.w), + borderRadius: 20.r, + hasShadow: true, + side: BorderSide(color: AppColors.ratingColorYellow, width: 3.h), ), child: Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppCustomChipWidget( - labelText: myAppointmentsViewModel.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr() : LocaleKeys.yourTurn.tr(), - backgroundColor: Utils.getCardBorderColor(myAppointmentsViewModel.currentQueueStatus).withValues(alpha: 0.20), - textColor: Utils.getCardBorderColor(myAppointmentsViewModel.currentQueueStatus), - ), - Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), - ], - ), + LocaleKeys.immediateLiveCareRequest.tr(context: context).toText16(isBold: true), + SizedBox(height: 10.h), + _buildLiveCareHeader(liveCareData), + SizedBox(height: 10.h), + _buildLiveCareGreeting(), SizedBox(height: 8.h), - LocaleKeys.halaFirstName.tr(namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}).toText16(isBold: true), - SizedBox(height: 2.h), - LocaleKeys.thankYouForPatience.tr().toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + _buildLiveCareQueueInfo(liveCareData.patCount), SizedBox(height: 8.h), - myAppointmentsViewModel.currentPatientQueueDetails.queueNo!.toText28(isBold: true), - SizedBox(height: 6.h), - myAppointmentsViewModel.patientQueueDetailsList.isNotEmpty - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - "${LocaleKeys.servingNow.tr()}: ".toText14(isBold: true), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - myAppointmentsViewModel.patientQueueDetailsList.first.queueNo!.toText12(isBold: true), - SizedBox(width: 8.w), - AppCustomChipWidget( - deleteIcon: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 - ? AppAssets.call_for_vitals - : AppAssets.call_for_doctor, - labelText: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 - ? LocaleKeys.callForVitalSigns.tr() - : LocaleKeys.callForDoctor.tr(), - iconColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 - ? AppColors.primaryRedColor - : AppColors.successColor, - textColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 - ? AppColors.primaryRedColor - : AppColors.successColor, - iconSize: 14.w, - backgroundColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 - ? AppColors.primaryRedColor.withValues(alpha: 0.1) - : AppColors.successColor.withValues(alpha: 0.1), - labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h), - ), - ], - ), - ], - ) - : SizedBox(height: 12.h), - SizedBox(height: 5.h), - CustomButton( - text: Utils.getCardButtonText( - myAppointmentsViewModel.currentQueueStatus, myAppointmentsViewModel.currentPatientQueueDetails.roomNo ?? ""), - onPressed: () {}, - backgroundColor: Utils.getCardButtonColor(myAppointmentsViewModel.currentQueueStatus), - borderColor: Utils.getCardButtonColor(myAppointmentsViewModel.currentQueueStatus).withValues(alpha: 0.01), - textColor: Utils.getCardButtonTextColor(myAppointmentsViewModel.currentQueueStatus), - fontSize: 12.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 40.h, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ), + _buildLiveCareWaitingTime(), ], ), ), - ).onPress(() { + ).paddingSymmetrical(0.h, 0.h).onPress(() { Navigator.of(context).push( - CustomPageRoute( - page: AppointmentQueuePage(), - ), + CustomPageRoute(page: ImmediateLiveCarePendingRequestPage()), ); - }); - } else if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { - return Column( + }), + SizedBox(height: 12.h), + ], + ); + } + + // LiveCare Card: Header with status and date + Widget _buildLiveCareHeader(liveCareData) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( children: [ - SizedBox(height: 12.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: true, - side: BorderSide(color: AppColors.ratingColorYellow, width: 3.h), - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.immediateLiveCareRequest.tr(context: context).toText16(isBold: true), - SizedBox(height: 10.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppCustomChipWidget( - labelText: immediateLiveCareViewModel.patientLiveCareHistoryList[0].stringCallStatus, - backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.20), - textColor: AppColors.alertColor, - ), - SizedBox(width: 8.w), - AppCustomChipWidget( - icon: AppAssets.appointment_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(immediateLiveCareViewModel.patientLiveCareHistoryList[0].arrivalTime), false)), - ], - ), - Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), - // Lottie.asset(AppAnimations.pending_loading_animation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.cover), - ], - ), - SizedBox(height: 10.h), - LocaleKeys.halaFirstName - .tr(namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}, context: context).toText16(isBold: true), - SizedBox(height: 8.h), - LocaleKeys.yourTurnIsAfterPatients.tr( - namedArgs: {'count': immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount.toString()}, - context: context).toText14(isBold: true), - SizedBox(height: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "${LocaleKeys.waitingTime.tr()}: ".toText12(isBold: true), - SizedBox(height: 7.h), - ValueListenableBuilder( - valueListenable: immediateLiveCareViewModel.durationNotifier, - builder: (context, duration, child) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - buildTime(duration), - ], - ); - }, - ), - ], - ), - ], - ), + AppCustomChipWidget( + labelText: liveCareData.stringCallStatus, + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.20), + textColor: AppColors.alertColor, + ), + SizedBox(width: 8.w), + AppCustomChipWidget( + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate(liveCareData.arrivalTime), + false, ), - ).paddingSymmetrical(0.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ImmediateLiveCarePendingRequestPage())); - }), - SizedBox(height: 12.h), + ), ], - ); - } else if (myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.isNotEmpty) { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.first, - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ); - } else { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ); - } - } else if (index == 1) { - if (myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList.first, - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ); - } else if (todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) { - return AncillaryOrderCard( - order: todoSectionViewModel.patientAncillaryOrdersList.first, - isLoading: false, - isOrdersList: false, - onCheckIn: () { - log("Check-in for order: ${todoSectionViewModel.patientAncillaryOrdersList.first.orderNo}"); - }, - onViewDetails: () { - Navigator.of(context).push( - CustomPageRoute( - page: AncillaryOrderDetailsList( - appointmentNoVida: todoSectionViewModel.patientAncillaryOrdersList.first.appointmentNo ?? 0, - orderNo: todoSectionViewModel.patientAncillaryOrdersList.first.orderNo ?? 0, - projectID: todoSectionViewModel.patientAncillaryOrdersList.first.projectID ?? 0, - projectName: todoSectionViewModel.patientAncillaryOrdersList.first.projectName ?? "", - ), - ), - ); - }, - ); - } else { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ); - } - } else if (index == 2) { - if ((myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest) && - todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) { - return AncillaryOrderCard( - order: todoSectionViewModel.patientAncillaryOrdersList.first, - isLoading: false, - isOrdersList: false, - onCheckIn: () { - log("Check-in for order: ${todoSectionViewModel.patientAncillaryOrdersList.first.orderNo}"); - }, - onViewDetails: () { - Navigator.of(context).push( - CustomPageRoute( - page: AncillaryOrderDetailsList( - appointmentNoVida: todoSectionViewModel.patientAncillaryOrdersList.first.appointmentNo ?? 0, - orderNo: todoSectionViewModel.patientAncillaryOrdersList.first.orderNo ?? 0, - projectID: todoSectionViewModel.patientAncillaryOrdersList.first.projectID ?? 0, - projectName: todoSectionViewModel.patientAncillaryOrdersList.first.projectName ?? "", - ), - ), + ), + Utils.buildSvgWithAssets( + icon: AppAssets.waiting_icon, + width: 24.h, + height: 24.h, + ), + ], + ); + } + + // LiveCare Card: Greeting + Widget _buildLiveCareGreeting() { + return LocaleKeys.halaFirstName.tr( + namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}, + context: context, + ).toText16(isBold: true); + } + + // LiveCare Card: Queue position info + Widget _buildLiveCareQueueInfo(int? patCount) { + return LocaleKeys.yourTurnIsAfterPatients.tr( + namedArgs: {'count': (patCount ?? 0).toString()}, + context: context, + ).toText14(isBold: true); + } + + // LiveCare Card: Waiting time counter + Widget _buildLiveCareWaitingTime() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "${LocaleKeys.waitingTime.tr()}: ".toText12(isBold: true), + SizedBox(height: 7.h), + ValueListenableBuilder( + valueListenable: immediateLiveCareViewModel.durationNotifier, + builder: (context, duration, child) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + buildTime(duration), + ], ); }, - ); - } else { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, + ), + ], + ); + } + + // Appointment Card Wrapper (reusable) + Widget _buildAppointmentCardWrapper(appointment) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: appointment, + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: false, + isFromHomePage: true, + ), + ); + } + + // Ancillary Order Card Wrapper (reusable) + Widget _buildAncillaryOrderCardWrapper(order) { + return AncillaryOrderCard( + order: order, + isLoading: false, + isOrdersList: false, + onCheckIn: () { + log("Check-in for order: ${order.orderNo}"); + }, + onViewDetails: () { + Navigator.of(context).push( + CustomPageRoute( + page: AncillaryOrderDetailsList( + appointmentNoVida: order.appointmentNo ?? 0, + orderNo: order.orderNo ?? 0, + projectID: order.projectID ?? 0, + projectName: order.projectName ?? "", + ), ), ); - } - } - return Container(); + }, + ); } void showQuickLogin(BuildContext context) { diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 0725b1d..1ce1600 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -127,6 +127,7 @@ class HabibWalletCard extends StatelessWidget { borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 35.h, + // width: 35.w, ), ], ), diff --git a/lib/presentation/my_invoices/my_invoices_list.dart b/lib/presentation/my_invoices/my_invoices_list.dart index 9f969e8..177dde8 100644 --- a/lib/presentation/my_invoices/my_invoices_list.dart +++ b/lib/presentation/my_invoices/my_invoices_list.dart @@ -52,7 +52,7 @@ class _MyInvoicesListState extends State { children: [ SizedBox(height: 24.h), ListView.builder( - itemCount: myInvoicesVM.isInvoicesListLoading ? 4 : myInvoicesVM.allInvoicesList.length, + itemCount: myInvoicesVM.isInvoicesListLoading ? 4 : myInvoicesVM.allInvoicesList.isEmpty ? 1 : myInvoicesVM.allInvoicesList.length, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, padding: EdgeInsetsGeometry.zero, @@ -64,7 +64,7 @@ class _MyInvoicesListState extends State { index: index, isLoading: true, ) - : AnimationConfiguration.staggeredList( + : myInvoicesVM.allInvoicesList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( @@ -105,7 +105,7 @@ class _MyInvoicesListState extends State { ), ), ), - ); + ) : Utils.getNoDataWidget(context); }).paddingSymmetrical(24.w, 0.h), ], ); diff --git a/lib/presentation/symptoms_checker/user_info_selection.dart b/lib/presentation/symptoms_checker/user_info_selection.dart index 1d05c5a..c8d8cde 100644 --- a/lib/presentation/symptoms_checker/user_info_selection.dart +++ b/lib/presentation/symptoms_checker/user_info_selection.dart @@ -282,6 +282,7 @@ class _UserInfoSelectionPageState extends State { borderColor: Colors.transparent, textColor: AppColors.primaryRedColor, fontSize: 16.f, + iconSize: 20.w, ), ), SizedBox(width: 12.w), @@ -297,6 +298,7 @@ class _UserInfoSelectionPageState extends State { borderColor: hasEmptyFields ? AppColors.greyLightColor : AppColors.primaryRedColor, textColor: hasEmptyFields ? AppColors.greyTextColor : AppColors.whiteColor, fontSize: 16.f, + iconSize: 20.w, ), ), ], diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index a81f0eb..8500ce8 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -74,11 +74,9 @@ class CustomButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ if (icon != null) - Flexible( - child: Padding( - padding: text.isNotEmpty ? EdgeInsets.only(right: 4.w, left: 4.w) : EdgeInsets.zero, - child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconS, height: iconS), - ), + Padding( + padding: text.isNotEmpty ? EdgeInsets.only(right: 4.w, left: 4.w) : EdgeInsets.zero, + child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconS, height: iconS), ), if (text.isNotEmpty) Text(