From 5b04a5a3eaf277a298e094f448c9c7d7c5b25c5f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 9 Mar 2026 13:08:59 +0300 Subject: [PATCH 1/3] lab test description update --- lib/presentation/lab/lab_result_via_clinic/LabResultList.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/presentation/lab/lab_result_via_clinic/LabResultList.dart b/lib/presentation/lab/lab_result_via_clinic/LabResultList.dart index 6caa4a59..07b9fb65 100644 --- a/lib/presentation/lab/lab_result_via_clinic/LabResultList.dart +++ b/lib/presentation/lab/lab_result_via_clinic/LabResultList.dart @@ -27,7 +27,7 @@ class LabResultList extends StatelessWidget { shrinkWrap: true,itemCount: list.length,itemBuilder: (____, index) { var labItem = list[index]; return LabOrderResultItem(onTap: () { - model.getPatientLabResult(model.currentlySelectedPatientOrder!, labItem.description ?? "", labItem.packageShortDescription!, labItem.uOM ?? ""); + model.getPatientLabResult(model.currentlySelectedPatientOrder!, labItem.description ?? "", labItem.testShortDescription!, labItem.uOM ?? ""); }, tests: labItem, index: index, -- 2.30.2 From 29447cc9faf122a08b070589d2f5c0e61a4b2cf1 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 10 Mar 2026 15:33:38 +0300 Subject: [PATCH 2/3] updates --- lib/core/api/api_client.dart | 2 +- .../blood_donation/widgets/hospital_selection.dart | 2 +- lib/features/my_invoices/my_invoices_view_model.dart | 2 +- lib/presentation/authentication/login.dart | 8 ++++---- lib/presentation/authentication/saved_login_screen.dart | 5 +++-- .../book_appointment/review_appointment_page.dart | 2 +- lib/presentation/contact_us/live_chat_page.dart | 2 +- .../emergency_services/widgets/nearestERItem.dart | 4 ++-- lib/presentation/lab/lab_order_by_test.dart | 2 +- lib/presentation/lab/lab_orders_page.dart | 2 +- lib/presentation/lab/lab_results/lab_result_details.dart | 4 ++-- .../lab/lab_results/lab_result_list_item.dart | 2 +- lib/widgets/countdown_timer.dart | 4 ++-- lib/widgets/date_range_selector/date_range_calender.dart | 6 +++--- lib/widgets/datepicker_widget.dart | 4 ++-- lib/widgets/nfc/nfc_reader_sheet.dart | 6 +++--- lib/widgets/phone_number_input.dart | 2 +- 17 files changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index b17db626..192f6a4a 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -195,7 +195,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 4773715; + // body['PatientID'] = 2007395; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/features/blood_donation/widgets/hospital_selection.dart b/lib/features/blood_donation/widgets/hospital_selection.dart index 9889410c..f49b42d6 100644 --- a/lib/features/blood_donation/widgets/hospital_selection.dart +++ b/lib/features/blood_donation/widgets/hospital_selection.dart @@ -75,7 +75,7 @@ class HospitalBottomSheetBodySelection extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: AppAssets.hmg).paddingOnly(right: 10), Expanded( - child: Text(hospital.projectName ?? "", style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16, color: AppColors.blackColor)), + child: Text(hospital.projectName ?? "", style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16.f, color: AppColors.blackColor)), ) ], ); diff --git a/lib/features/my_invoices/my_invoices_view_model.dart b/lib/features/my_invoices/my_invoices_view_model.dart index a02d741d..20d7869f 100644 --- a/lib/features/my_invoices/my_invoices_view_model.dart +++ b/lib/features/my_invoices/my_invoices_view_model.dart @@ -43,7 +43,7 @@ class MyInvoicesViewModel extends ChangeNotifier { } else if (apiResponse.messageStatus == 1) { allInvoicesList = apiResponse.data!; isInvoicesListLoading = false; - + allInvoicesList.sort((a, b) => b.appointmentDate!.compareTo(a.appointmentDate!)); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index 28b47304..d68e933c 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -116,7 +116,7 @@ class LoginScreenState extends State { child: RichText( textAlign: TextAlign.center, text: TextSpan( - style: context.dynamicTextStyle(color: Colors.black, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500), + style: context.dynamicTextStyle(color: AppColors.textColor, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500), children: [ TextSpan(text: LocaleKeys.dontHaveAccount.tr(context: context), style: context.dynamicTextStyle()), TextSpan(text: " "), @@ -218,9 +218,9 @@ class LoginScreenState extends State { await authViewModel.checkUserAuthentication(otpTypeEnum: OTPTypeEnum.whatsapp); } }, - backgroundColor: Colors.white, - borderColor: AppColors.borderOnlyColor, - textColor: AppColors.whiteColor, + backgroundColor: AppColors.whiteColor, + borderColor: AppColors.textColor, + textColor: AppColors.textColor, icon: AppAssets.whatsapp, iconColor: null, applyThemeColor: false, diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index 231d7d14..98cbc37d 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -251,10 +251,11 @@ class _SavedLogin extends State { } }, backgroundColor: AppColors.whiteColor, - borderColor: Color(0xFF2E3039), - textColor: Color(0xFF2E3039), + borderColor: AppColors.textColor, + textColor: AppColors.textColor, borderWidth: 2.w, padding: EdgeInsets.fromLTRB(0, 14.h, 0, 14.h), + applyThemeColor: false, ), const Spacer(flex: 2), // OR divider diff --git a/lib/presentation/book_appointment/review_appointment_page.dart b/lib/presentation/book_appointment/review_appointment_page.dart index d75ab8be..794b821b 100644 --- a/lib/presentation/book_appointment/review_appointment_page.dart +++ b/lib/presentation/book_appointment/review_appointment_page.dart @@ -226,7 +226,7 @@ class _ReviewAppointmentPageState extends State { backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, textColor: Colors.white, - fontSize: 16, + fontSize: 16.f, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), diff --git a/lib/presentation/contact_us/live_chat_page.dart b/lib/presentation/contact_us/live_chat_page.dart index 5d09a64f..0350c316 100644 --- a/lib/presentation/contact_us/live_chat_page.dart +++ b/lib/presentation/contact_us/live_chat_page.dart @@ -236,7 +236,7 @@ class LiveChatPage extends StatelessWidget { backgroundColor: contactUsVM.selectedLiveChatProjectIndex == -1 ? AppColors.greyColor : AppColors.primaryRedColor, borderColor: contactUsVM.selectedLiveChatProjectIndex == -1 ? AppColors.greyColor : AppColors.primaryRedColor, textColor: Colors.white, - fontSize: 16, + fontSize: 16.f, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), diff --git a/lib/presentation/emergency_services/widgets/nearestERItem.dart b/lib/presentation/emergency_services/widgets/nearestERItem.dart index fae19a0a..0c4a5a6a 100644 --- a/lib/presentation/emergency_services/widgets/nearestERItem.dart +++ b/lib/presentation/emergency_services/widgets/nearestERItem.dart @@ -90,7 +90,7 @@ class NearestERItem extends StatelessWidget { Expanded( child: CustomButton( text: LocaleKeys.viewLocationGoogleMaps.tr(context: context), - iconSize: 18.h, + iconSize: 16.h, icon: AppAssets.location, onPressed: () { context.read().openDirections(destLat: double.parse(nearestERItem.latitude??"0.0"), destLng: double.parse(nearestERItem.longitude??"0.0") ); @@ -100,7 +100,7 @@ class NearestERItem extends StatelessWidget { textColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor, height: 40.h, - fontSize: 14, + fontSize: 14.f, fontWeight: FontWeight.w500, ).toShimmer2(isShow: isLoading), ), diff --git a/lib/presentation/lab/lab_order_by_test.dart b/lib/presentation/lab/lab_order_by_test.dart index 2e4a96b6..1b5db920 100644 --- a/lib/presentation/lab/lab_order_by_test.dart +++ b/lib/presentation/lab/lab_order_by_test.dart @@ -66,7 +66,7 @@ class LabOrderByTest extends StatelessWidget { backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, - fontSize: 14, + fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 0bcbc364..15461659 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.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/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.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/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr()), CustomTabBarModel(null, LocaleKeys.byTest.tr()), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { labViewModel.setIsSortByClinic(true); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { labViewModel.setIsSortByClinic(false); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: labViewModel.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( labViewModel.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr(context: context)}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex: 2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { labViewModel.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), // SizedBox(height: 12.h), // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), // SizedBox(height: 12.h), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, rangeViewModel: rangeViewModel, appState: _appState, ) ], )); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file +import 'dart:async'; import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.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/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.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/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr()), CustomTabBarModel(null, LocaleKeys.byTest.tr()), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { labViewModel.setIsSortByClinic(true); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12.f, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { labViewModel.setIsSortByClinic(false); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: labViewModel.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( labViewModel.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr(context: context)}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex: 2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { labViewModel.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), // SizedBox(height: 12.h), // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), // SizedBox(height: 12.h), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, rangeViewModel: rangeViewModel, appState: _appState, ) ], )); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index cab20aed..cff9764e 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -166,7 +166,7 @@ class LabResultDetails extends StatelessWidget { : (labmodel.filteredGraphValues.length < 3) ? (labmodel.filteredGraphValues.length * 64) + 80.h : 260.h, - padding: EdgeInsets.all(16.h), + padding: EdgeInsets.all(14.h), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -177,7 +177,7 @@ class LabResultDetails extends StatelessWidget { Text( labmodel.isGraphVisible ? LocaleKeys.historyFlowchart.tr(context: context) : LocaleKeys.history.tr(context: context), style: TextStyle( - fontSize: 16, + fontSize: 16.f, fontFamily: 'Poppins', fontWeight: FontWeight.w600, color: AppColors.textColor, diff --git a/lib/presentation/lab/lab_results/lab_result_list_item.dart b/lib/presentation/lab/lab_results/lab_result_list_item.dart index 6ccf7509..f2dc90e4 100644 --- a/lib/presentation/lab/lab_results/lab_result_list_item.dart +++ b/lib/presentation/lab/lab_results/lab_result_list_item.dart @@ -42,7 +42,7 @@ class LabHistoryItem extends StatelessWidget{ ), Transform.flip( flipY: shouldRotateIcon, - child: Utils.buildSvgWithAssets(icon: assetUrl,height: 18, width: 18) + child: Utils.buildSvgWithAssets(icon: assetUrl, height: 18, width: 18) ), ], ); diff --git a/lib/widgets/countdown_timer.dart b/lib/widgets/countdown_timer.dart index 7f8304e6..86249fc8 100644 --- a/lib/widgets/countdown_timer.dart +++ b/lib/widgets/countdown_timer.dart @@ -101,13 +101,13 @@ Widget buildLabel(String label) { } Widget buildTimeSeparator() { - return const Padding( + return Padding( padding: EdgeInsets.symmetric(horizontal: 2.0), child: Text( ":", style: TextStyle( color: Colors.black, - fontSize: 20, + fontSize: 20.f, ), ), ); diff --git a/lib/widgets/date_range_selector/date_range_calender.dart b/lib/widgets/date_range_selector/date_range_calender.dart index 0f6c9b99..d6e2eadf 100644 --- a/lib/widgets/date_range_selector/date_range_calender.dart +++ b/lib/widgets/date_range_selector/date_range_calender.dart @@ -74,7 +74,7 @@ class _DateRangeSelectorState extends State { LocaleKeys.to.tr(context: context), style: TextStyle( color: AppColors.calenderTextColor, - fontSize: 14.h, + fontSize: 14.f, fontWeight: FontWeight.w500, letterSpacing: -.2 ), @@ -247,7 +247,7 @@ class _DateRangeSelectorState extends State { label, style: TextStyle( color: AppColors.inputLabelTextColor, - fontSize: 12.h, + fontSize: 12.f, fontWeight: FontWeight.w500, ), ), @@ -255,7 +255,7 @@ class _DateRangeSelectorState extends State { date!, style: TextStyle( color: AppColors.textColor, - fontSize: 14.h, + fontSize: 14.f, fontWeight: FontWeight.w500, ), ) diff --git a/lib/widgets/datepicker_widget.dart b/lib/widgets/datepicker_widget.dart index e2891da4..f9d8ff73 100644 --- a/lib/widgets/datepicker_widget.dart +++ b/lib/widgets/datepicker_widget.dart @@ -53,7 +53,7 @@ class DatePickerWidget extends StatelessWidget { return Text( labelText, style: const TextStyle( - fontSize: 12, + fontSize: 12.f, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -0.2, @@ -99,7 +99,7 @@ class DatePickerWidget extends StatelessWidget { textAlign: TextAlign.left, textDirection: TextDirection.ltr, style: TextStyle( - fontSize: 14, + fontSize: 14.f, height: 21 / 14, fontWeight: FontWeight.w500, color: (selectedValue != null && selectedValue!.isNotEmpty) ? const Color(0xff2E3039) : const Color(0xffB0B0B0), diff --git a/lib/widgets/nfc/nfc_reader_sheet.dart b/lib/widgets/nfc/nfc_reader_sheet.dart index 10228a94..956f758b 100644 --- a/lib/widgets/nfc/nfc_reader_sheet.dart +++ b/lib/widgets/nfc/nfc_reader_sheet.dart @@ -87,7 +87,7 @@ class _NfcLayoutState extends State { "Ready To Scan", style: TextStyle( fontWeight: FontWeight.bold, - fontSize: 24, + fontSize: 24.f, ), ), SizedBox( @@ -103,7 +103,7 @@ class _NfcLayoutState extends State { Text( "Approach an NFC Tag", style: TextStyle( - fontSize: 18, + fontSize: 18.f, ), ), SizedBox( @@ -125,7 +125,7 @@ class _NfcLayoutState extends State { backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, textColor: AppColors.whiteColor, - fontSize: 14, + fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.h, height: 40.h, diff --git a/lib/widgets/phone_number_input.dart b/lib/widgets/phone_number_input.dart index 793c8062..6ea07141 100644 --- a/lib/widgets/phone_number_input.dart +++ b/lib/widgets/phone_number_input.dart @@ -100,7 +100,7 @@ class _PhoneNumberInputState extends State { ), ), style: const TextStyle( - fontSize: 18, + fontSize: 18.f, fontWeight: FontWeight.bold, letterSpacing: 2, color: Colors.black, -- 2.30.2 From 47b50e35a1a3a29f8d45c8c82e7f88f30ab56f31 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 11 Mar 2026 16:02:17 +0300 Subject: [PATCH 3/3] updates --- assets/images/svg/download.svg | 5 +- lib/core/api/api_client.dart | 20 +-- lib/features/radiology/radiology_repo.dart | 8 +- .../appointments/my_doctors_page.dart | 9 ++ .../book_appointment/doctor_profile_page.dart | 2 +- .../LabResultByClinic.dart | 148 ++++++++++-------- .../lab/lab_results/lab_result_details.dart | 124 +++++++++++---- lib/widgets/appbar/collapsing_list_view.dart | 6 + 8 files changed, 211 insertions(+), 111 deletions(-) diff --git a/assets/images/svg/download.svg b/assets/images/svg/download.svg index 37aef2bd..7bedc456 100644 --- a/assets/images/svg/download.svg +++ b/assets/images/svg/download.svg @@ -1,4 +1,3 @@ - - + + diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 192f6a4a..921e274b 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -195,7 +195,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 2007395; + // body['PatientID'] = 809289; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; @@ -301,14 +301,16 @@ class ApiClientImp implements ApiClient { } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); - } else if (parsed['IsAuthenticated'] == false) { - onFailure( - "User is not Authenticated", - statusCode, - failureType: - UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), - ); - } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { + } + // else if (parsed['IsAuthenticated'] == false) { + // onFailure( + // "User is not Authenticated", + // statusCode, + // failureType: + // UnAuthenticatedUserFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'] ?? "User is not Authenticated", url: url), + // ); + // } + else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); diff --git a/lib/features/radiology/radiology_repo.dart b/lib/features/radiology/radiology_repo.dart index 5847718d..3ad4e54f 100644 --- a/lib/features/radiology/radiology_repo.dart +++ b/lib/features/radiology/radiology_repo.dart @@ -188,14 +188,16 @@ class RadiologyRepoImp implements RadiologyRepo { failure = failureType; }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { - final radOrders; + List radOrders = []; try { if (response['FinalRadiologyList'] != null && response['FinalRadiologyList'].length != 0) { final list = response['FinalRadiologyList']; radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); } else { - final list = response['FinalRadiologyListAPI']; - radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); + if (response['FinalRadiologyListAPI'] != null && response['FinalRadiologyListAPI'].length != 0) { + final list = response['FinalRadiologyListAPI']; + radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast(); + } } apiResponse = GenericApiModel>( diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index fc7798f8..d1ea0e98 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -34,6 +36,13 @@ class _MyDoctorsPageState extends State { int? expandedIndex; final Map _groupKeys = {}; + @override + void initState() { + scheduleMicrotask(() { + myAppointmentsViewModel.getPatientMyDoctors(); + }); + super.initState(); + } @override Widget build(BuildContext context) { diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index 4b2d4dbb..549b8b0d 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -41,7 +41,7 @@ class DoctorProfilePage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 24.h), + // SizedBox(height: 24.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart index eed1eedb..af6c97f8 100644 --- a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart +++ b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart @@ -41,21 +41,54 @@ class LabResultByClinic extends StatelessWidget { Expanded( child: CollapsingListView( title: LocaleKeys.labResults.tr(), - aiOverview: () async { - final _dialogService = getIt.get(); - await _dialogService.showCommonBottomSheetWithoutH( - message: LocaleKeys.aiDisclaimer.tr(), - label: LocaleKeys.consent.tr(), - okLabel: LocaleKeys.acceptLbl.tr(), - cancelLabel: LocaleKeys.rejectView.tr(), - onOkPressed: () { - context.pop(); - labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - }, - onCancelPressed: () { - context.pop(); - }); + downloadReport: () async { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr(context: context)); + await labViewModel + .getLabResultReportPDF( + labOrder: labOrder, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }) + .then((val) async { + LoaderBottomSheet.hideLoader(); + if (labViewModel.patientLabResultReportPDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(labViewModel.patientLabResultReportPDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Cannot open file"), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + } + }); }, + // aiOverview: () async { + // final _dialogService = getIt.get(); + // await _dialogService.showCommonBottomSheetWithoutH( + // message: LocaleKeys.aiDisclaimer.tr(), + // label: LocaleKeys.consent.tr(), + // okLabel: LocaleKeys.acceptLbl.tr(), + // cancelLabel: LocaleKeys.rejectView.tr(), + // onOkPressed: () { + // context.pop(); + // labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + // }, + // onCancelPressed: () { + // context.pop(); + // }); + // }, child: SingleChildScrollView( child: Column( spacing: 8.h, @@ -109,53 +142,46 @@ class LabResultByClinic extends StatelessWidget { borderRadius: 24.h, hasShadow: true, ), - child: CustomButton( - text: LocaleKeys.downloadReport.tr(context: context), - onPressed: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.generatingReport.tr(context: context)); - await labViewModel - .getLabResultReportPDF( - labOrder: labOrder, - onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }) - .then((val) async { - LoaderBottomSheet.hideLoader(); - if (labViewModel.patientLabResultReportPDFBase64.isNotEmpty) { - String path = await Utils.createFileFromString(labViewModel.patientLabResultReportPDFBase64, "pdf"); - try { - OpenFilex.open(path); - } catch (ex) { - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: "Cannot open file"), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - } - } - }); - }, - backgroundColor: AppColors.successColor, - borderColor: AppColors.successColor, - textColor: Colors.white, - fontSize: 16.f, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 45.h, - icon: AppAssets.download, - iconColor: Colors.white, - iconSize: 20.h, - ).paddingSymmetrical(24.h, 24.h), + child: Container( + height: 56.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.236, 1.0], // 53.6% and 100% + colors: [ + Color(0xFF8A38F5), // Transparent + Color(0xFFE20BBB), // Solid #F8F8F8 + ], + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 4.w, left: 4.w), + child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + ), + LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + ], + ), + ).paddingSymmetrical(24.h, 24.h).onPress(() async { + final _dialogService = getIt.get(); + await _dialogService.showCommonBottomSheetWithoutH( + message: LocaleKeys.aiDisclaimer.tr(), + label: LocaleKeys.consent.tr(), + okLabel: LocaleKeys.acceptLbl.tr(), + cancelLabel: LocaleKeys.rejectView.tr(), + onOkPressed: () { + context.pop(); + labViewModel.getAiOverviewLabOrders(labOrder: labOrder, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + }, + onCancelPressed: () { + context.pop(); + }); + }), ), ], ), diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index cff9764e..d2c1b524 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -34,41 +34,97 @@ class LabResultDetails extends StatelessWidget { Widget build(BuildContext context) { LabViewModel labViewModel = Provider.of(context, listen: false); final appState = getIt.get(); - return CollapsingListView( - title: LocaleKeys.labResultDetails.tr(context: context), - aiOverview: () async { - final _dialogService = getIt.get(); - await _dialogService.showCommonBottomSheetWithoutH( - message: LocaleKeys.aiDisclaimer.tr(), - label: LocaleKeys.consent.tr(), - okLabel: LocaleKeys.acceptLbl.tr(), - cancelLabel: LocaleKeys.rejectView.tr(), - onOkPressed: () { - context.pop(); - labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - }, - onCancelPressed: () { - context.pop(); - }); - }, - child: SingleChildScrollView( - child: Column( - spacing: 16.h, - children: [ - LabNameAndStatus(context), - getLabDescription(context), - LabGraph(context), - Selector( - selector: (_, model) => model.labOrderResponseByAi, - builder: (_, aiData, __) { - if (aiData != null) { - return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); - } - return const SizedBox.shrink(); - }, + return Scaffold( + body: Column( + children: [ + Expanded( + child: CollapsingListView( + title: LocaleKeys.labResultDetails.tr(context: context), + // aiOverview: () async { + // final _dialogService = getIt.get(); + // await _dialogService.showCommonBottomSheetWithoutH( + // message: LocaleKeys.aiDisclaimer.tr(), + // label: LocaleKeys.consent.tr(), + // okLabel: LocaleKeys.acceptLbl.tr(), + // cancelLabel: LocaleKeys.rejectView.tr(), + // onOkPressed: () { + // context.pop(); + // labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + // }, + // onCancelPressed: () { + // context.pop(); + // }); + // }, + child: SingleChildScrollView( + child: Column( + spacing: 16.h, + children: [ + LabNameAndStatus(context), + getLabDescription(context), + LabGraph(context), + Selector( + selector: (_, model) => model.labOrderResponseByAi, + builder: (_, aiData, __) { + if (aiData != null) { + return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); + } + return const SizedBox.shrink(); + }, + ), + ], + ).paddingAll(24.h), + ), ), - ], - ).paddingAll(24.h), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + child: Container( + height: 56.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.236, 1.0], // 53.6% and 100% + colors: [ + Color(0xFF8A38F5), // Transparent + Color(0xFFE20BBB), // Solid #F8F8F8 + ], + ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 4.w, left: 4.w), + child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + ), + LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + ], + ), + ).paddingSymmetrical(24.h, 24.h).onPress(() async { + final _dialogService = getIt.get(); + await _dialogService.showCommonBottomSheetWithoutH( + message: LocaleKeys.aiDisclaimer.tr(), + label: LocaleKeys.consent.tr(), + okLabel: LocaleKeys.acceptLbl.tr(), + cancelLabel: LocaleKeys.rejectView.tr(), + onOkPressed: () { + context.pop(); + labViewModel.getAiOverviewSingleLabResult( + langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + }, + onCancelPressed: () { + context.pop(); + }); + }), + ), + ], ), ); } diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 25221962..0c32d87d 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -25,6 +25,7 @@ class CollapsingListView extends StatelessWidget { VoidCallback? requests; VoidCallback? sendEmail; VoidCallback? doctorResponse; + VoidCallback? downloadReport; Widget? bottomChild; Widget? trailing; bool isClose; @@ -47,6 +48,7 @@ class CollapsingListView extends StatelessWidget { this.requests, this.sendEmail, this.doctorResponse, + this.downloadReport, this.isLeading = true, this.trailing, this.leadingCallback, @@ -89,6 +91,7 @@ class CollapsingListView extends StatelessWidget { requests: requests, sendEmail: sendEmail, doctorResponse: doctorResponse, + downloadReport: downloadReport, bottomChild: bottomChild, trailing: trailing, aiOverview: aiOverview, @@ -200,6 +203,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget VoidCallback? requests; VoidCallback? sendEmail; VoidCallback? doctorResponse; + VoidCallback? downloadReport; Widget? bottomChild; Widget? trailing; @@ -217,6 +221,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget this.requests, this.sendEmail, this.doctorResponse, + this.downloadReport, this.bottomChild, this.trailing, }); @@ -295,6 +300,7 @@ class _ScrollAnimatedTitleState extends State { if (widget.doctorResponse != null) actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon).onPress(widget.doctorResponse!), if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!), if (widget.aiOverview != null) actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true).onPress(widget.aiOverview!), + if (widget.downloadReport != null) actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download).onPress(widget.downloadReport!), if (widget.trailing != null) widget.trailing!, ] ], -- 2.30.2