diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart index 1eb3d9f..2fbbd09 100644 --- a/lib/core/utils/date_util.dart +++ b/lib/core/utils/date_util.dart @@ -485,3 +485,11 @@ class DateUtil { return ""; } } + + +extension OnlyDate on DateTime{ + + DateTime provideDateOnly(){ + return DateTime(this.year, month, day); + } +} \ No newline at end of file diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index e7507b0..8a397e3 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -22,6 +22,8 @@ class LabViewModel extends ChangeNotifier { bool isLabResultsLoading = false; bool isLabResultByHospitalLoading = false; bool isSpecialResultsLoading = false; + bool isGraphVisible = true; + bool shouldShowGraph = true; LabRepo labRepo; ErrorHandlerService errorHandlerService; @@ -225,6 +227,7 @@ class LabViewModel extends ChangeNotifier { } catch (e) {} }); LabResult recentResult = recentThree.first; + checkIfGraphShouldBeDisplayed(recentResult); recentResult.verifiedOn = resultDate(DateUtil.convertStringToDate(recentResult.verifiedOnDateTime!)); // filteredGraphValues = [filteredGraphValues.first]; navigationService.push(MaterialPageRoute( @@ -237,6 +240,12 @@ class LabViewModel extends ChangeNotifier { ); } + void checkIfGraphShouldBeDisplayed(LabResult recentResult){ + shouldShowGraph = recentResult.checkIfGraphShouldBeDisplayed(); + isGraphVisible = shouldShowGraph; + notifyListeners(); + } + Future getPatientSpecialResult( PatientLabOrdersResponseModel laborder) async { isSpecialResultsLoading = true; @@ -551,4 +560,9 @@ class LabViewModel extends ChangeNotifier { return "normal"; } } + + alterGraphVisibility(){ + isGraphVisible = !isGraphVisible; + notifyListeners(); + } } diff --git a/lib/features/lab/models/resp_models/lab_result.dart b/lib/features/lab/models/resp_models/lab_result.dart index 3f14d54..a075be3 100644 --- a/lib/features/lab/models/resp_models/lab_result.dart +++ b/lib/features/lab/models/resp_models/lab_result.dart @@ -24,6 +24,7 @@ class LabResult { String? referenceHigh; String? criticalLow; String? referenceLow; + num? resultTypeID; String? packageShortDescription; LabResult( @@ -80,6 +81,7 @@ class LabResult { criticalLow = json['CriticalLow']; referenceLow = json['ReferenceLow']; packageShortDescription = json['PackageShortDescription']; + resultTypeID = json['ResultTypeID']; } Map toJson() { @@ -111,6 +113,21 @@ class LabResult { return data; } + bool checkIfGraphShouldBeDisplayed(){ + if (resultTypeID == null) return false; + if (resultTypeID == 6) return false; + if (referanceRange == null || referanceRange == "" || referanceRange == "\n") return false; + bool isDigit = RegExp(r"\\d+").hasMatch("$resultValue"); + if(isDigit) return true; + try { + num.parse(resultValue ?? ""); + } catch (e) { + return false; + } + + return true; + } + @override String toString() { return 'LabOrderResult(flag: $calculatedResultFlag, value: $resultValue, verifiedOn: $verifiedOnDateTime)'; diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 0c9509a..926f75d 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -50,6 +50,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { void onTabChange(int index) { previouslySelectedTab = selectedTabIndex; selectedTabIndex = index; + start = null; + end = null; notifyListeners(); } @@ -452,12 +454,12 @@ class MyAppointmentsViewModel extends ChangeNotifier { filteredAppointmentList.add(element); } }); - filteredAppointmentList.addAll(sourceList); } else { filteredAppointmentList.clear(); sourceList.forEach((element) { try { - var dateTime = DateUtil.convertStringToDate(element.appointmentDate); + var dateTime = DateUtil.convertStringToDate(element.appointmentDate).provideDateOnly(); + if (start != null && end == null) { if (dateTime.isAtSameMomentAs(start)) { if (isUnderFilter(element)) { @@ -465,7 +467,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } } } else if (start != null && end != null) { - if ((dateTime.isAfter(start)) && (dateTime.isBefore(end))) { + if ((dateTime.isAfter(start)) && ((dateTime.isBefore(end))||((dateTime.isAtSameMomentAs(end))))) { if (isUnderFilter(element)) { filteredAppointmentList.add(element); } diff --git a/lib/presentation/lab/lab_result_via_hospital/LabResultList.dart b/lib/presentation/lab/lab_result_via_hospital/LabResultList.dart index d7642c2..e94bb5c 100644 --- a/lib/presentation/lab/lab_result_via_hospital/LabResultList.dart +++ b/lib/presentation/lab/lab_result_via_hospital/LabResultList.dart @@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/extensions/string_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/lab_result.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_hospital/lab_order_result_item.dart'; -import 'package:provider/provider.dart' show Selector, Provider; +import 'package:provider/provider.dart' show Selector, Provider, ReadContext; class LabResultList extends StatelessWidget { late LabViewModel model; @@ -15,7 +15,7 @@ class LabResultList extends StatelessWidget { return Selector>( selector: (_, model) => model.mainLabResultsByHospitals, builder: (__, list, ___) { - if (list.isEmpty) { + if (list.isEmpty && context.read().labSpecialResult.isEmpty) { return Utils.getNoDataWidget(context, noDataText: "You don't have any lab results yet." .needTranslation); diff --git a/lib/presentation/lab/lab_result_via_hospital/lab_order_result_item.dart b/lib/presentation/lab/lab_result_via_hospital/lab_order_result_item.dart index 7dc4075..87fd790 100644 --- a/lib/presentation/lab/lab_result_via_hospital/lab_order_result_item.dart +++ b/lib/presentation/lab/lab_result_via_hospital/lab_order_result_item.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/utils/date_util.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' show LabViewModel; import 'package:hmg_patient_app_new/features/lab/models/resp_models/lab_result.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'; @@ -14,6 +15,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; +import 'package:provider/provider.dart'; class LabOrderResultItem extends StatelessWidget { final VoidCallback onTap; @@ -45,8 +47,49 @@ class LabOrderResultItem extends StatelessWidget { child: '${tests!.description}'.toText14(weight: FontWeight.w500), ), '${tests!.packageShortDescription}'.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), - // - SizedBox(height: 24.h), + SizedBox(height: 12.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: Text( + tests?.resultValue ?? "", + style: TextStyle( + fontSize: 24.fSize, + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + color: context.read().getColor( + tests?.calculatedResultFlag ?? "", + ), + letterSpacing: -2, + ), + overflow: TextOverflow.ellipsis, // prevent overflow + maxLines: 1, + softWrap: false, + ), + ), + SizedBox(width: 4.h,), + Expanded( + flex: 2, + child: Visibility( + visible: tests?.referanceRange != null, + child: Text( + "(Reference range ${tests?.referanceRange})".needTranslation, + style: TextStyle( + fontSize: 12.fSize, + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + color: AppColors.greyTextColor, + ), + // overflow: TextOverflow.ellipsis, + // maxLines: 2, + softWrap: true, + ), + ), + ), + ], + ), + SizedBox(height: 12.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index 89e86bb..30c1910 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -15,35 +15,38 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_results/lab_result_list import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/graph/custom_graph.dart'; -import 'package:provider/provider.dart' show Consumer, Provider; +import 'package:provider/provider.dart' show Consumer, Provider, ReadContext; import '../../../widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight; class LabResultDetails extends StatelessWidget { final LabResult recentLabResult; + final String? testDescription; - // final List graphPoint; - late LabViewModel model; - String? testDescription; - - LabResultDetails({super.key, required this.recentLabResult, required this.testDescription}); + const LabResultDetails( + {super.key, + required this.recentLabResult, + required this.testDescription}); @override Widget build(BuildContext context) { - model = Provider.of(context, listen: false); return CollapsingListView( title: 'Lab Result Details'.needTranslation, child: SingleChildScrollView( child: Column( spacing: 16.h, - children: [LabNameAndStatus, LabGraph(context)], + children: [ + LabNameAndStatus(context), + getLabDescription(context), + LabGraph(context) + ], ).paddingAll(24.h), ), ); } - Widget get LabNameAndStatus => Container( + Widget LabNameAndStatus(BuildContext context) => Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 24.h, @@ -80,11 +83,12 @@ class LabResultDetails extends StatelessWidget { //todo change the text color according to the provided test values Row( crossAxisAlignment: CrossAxisAlignment.center, + children: [ Expanded( child: Row( - spacing: 4.h, + mainAxisSize: MainAxisSize.max, children: [ Flexible( child: Text( @@ -93,8 +97,8 @@ class LabResultDetails extends StatelessWidget { fontSize: 24.fSize, fontWeight: FontWeight.w600, fontFamily: 'Poppins', - color: model.getColor( - recentLabResult.calculatedResultFlag ?? "", + color: context.read().getColor( + recentLabResult.calculatedResultFlag ?? "", ), letterSpacing: -2, ), @@ -103,30 +107,37 @@ class LabResultDetails extends StatelessWidget { softWrap: false, ), ), - Visibility( - visible: recentLabResult.referanceRange != null, - child: Text( - "(Reference range ${recentLabResult.referanceRange})".needTranslation, - style: TextStyle( - fontSize: 12.fSize, - fontWeight: FontWeight.w500, - fontFamily: 'Poppins', - color: AppColors.greyTextColor, + SizedBox(width: 4.h,), + Expanded( + flex: 2, + child: Visibility( + visible: recentLabResult.referanceRange != null, + child: Text( + "(Reference range ${recentLabResult.referanceRange})".needTranslation, + style: TextStyle( + fontSize: 12.fSize, + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + color: AppColors.greyTextColor, + ), + // overflow: TextOverflow.ellipsis, + // maxLines: 2, + softWrap: true, ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - softWrap: false, ), ), ], ), ), - Utils.buildSvgWithAssets( - icon: AppAssets.lab_result_indicator, + SizedBox( width: 21, - height: 23, - iconColor: model.getColor( - recentLabResult.calculatedResultFlag ?? "", + child: Utils.buildSvgWithAssets( + icon: AppAssets.lab_result_indicator, + width: 21, + height: 23, + iconColor: context.read().getColor( + recentLabResult.calculatedResultFlag ?? "", + ), ), ), ], @@ -135,73 +146,80 @@ class LabResultDetails extends StatelessWidget { ], )); - Widget LabGraph(BuildContext context) => Consumer( - builder: (_, model, ___) => Consumer( - builder: (_, labmodel, ___) => Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: true, - ), - height: model.isGraphVisible?260.h:(labmodel.filteredGraphValues.length<3)?(labmodel.filteredGraphValues.length*64)+80.h:260.h, - padding: EdgeInsets.all(16.h), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, + Widget LabGraph(BuildContext context) => Consumer( + builder: (_, labmodel, ___) => Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + height: labmodel.isGraphVisible + ? 260.h + : (labmodel.filteredGraphValues.length < 3) + ? (labmodel.filteredGraphValues.length * 64) + 80.h + : 260.h, + padding: EdgeInsets.all(16.h), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + //title and filter icon + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - //title and filter icon + Text( + labmodel.isGraphVisible + ? LocaleKeys.historyFlowchart.tr() + : LocaleKeys.history.tr(), + style: TextStyle( + fontSize: 16, + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + color: AppColors.textColor, + ), + ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + spacing: 16.h, children: [ - Text( - model.isGraphVisible?LocaleKeys.historyFlowchart.tr(): LocaleKeys.history.tr(), - style: TextStyle( - fontSize: 16, - fontFamily: 'Poppins', - - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), - ), - Row( - spacing: 16.h, - children: [ - //todo handle when the graph icon is being displayed - Utils.buildSvgWithAssets( - icon: model.isGraphVisible?AppAssets.ic_list:AppAssets.ic_graph, - width: 24.h, - height: 24.h) - .onPress(() { - model.alterGraphVisibility(); - }), - Utils.buildSvgWithAssets( - icon: AppAssets.ic_date_filter, - width: 24, - height: 24) - .onPress(() { - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.setTheDateRange.tr(), - context, - child: DateRangeSelector( - onRangeSelected: (start, end) { - - // if (start != null) { - labmodel.getSelectedDateRange(start, end); - // } - }, - ), - isFullScreen: false, - isCloseButtonVisible: true, - callBackFunc: () {}, - ); - }), - ], - ) + //todo handle when the graph icon is being displayed + Utils.buildSvgWithAssets( + icon: labmodel.isGraphVisible + ? AppAssets.ic_list + : AppAssets.ic_graph, + width: 24.h, + height: 24.h) + .onPress(() { + if (labmodel.shouldShowGraph) { + labmodel.alterGraphVisibility(); + } + }), + Utils.buildSvgWithAssets( + icon: AppAssets.ic_date_filter, + width: 24, + height: 24) + .onPress(() { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.setTheDateRange.tr(), + context, + child: DateRangeSelector( + onRangeSelected: (start, end) { + // if (start != null) { + labmodel.getSelectedDateRange(start, end); + // } + }, + ), + isFullScreen: false, + isCloseButtonVisible: true, + callBackFunc: () {}, + ); + }), ], - ).paddingOnly(bottom: model.isGraphVisible? 16.h :24.h), - historyBody(model, labmodel) + ) ], - )), - )); + ).paddingOnly(bottom: labmodel.isGraphVisible ? 16.h : 24.h), + historyBody(labmodel) + ], + )), + ); Widget leftLabels(String value) { return Text( @@ -229,17 +247,15 @@ class LabResultDetails extends StatelessWidget { ); } - Widget historyBody(DateRangeSelectorRangeViewModel model, LabViewModel labmodel) { - if(model.isGraphVisible){ + Widget historyBody(LabViewModel labmodel) { + if (labmodel.isGraphVisible && labmodel.shouldShowGraph) { var graphColor = labmodel.getColor(recentLabResult.calculatedResultFlag??"N"); return CustomGraph( dataPoints: labmodel.filteredGraphValues, - // maxY: 100, - makeGraphBasedOnActualValue: true, leftLabelReservedSize: 40, leftLabelInterval: getInterval(labmodel), - maxY: (labmodel.maxY)+(getInterval(labmodel)??0)/5, + maxY: (labmodel.maxY)+(getInterval(labmodel)??0)/2, maxX: labmodel.filteredGraphValues.length.toDouble()-.75, leftLabelFormatter: (value) { return leftLabels(value.toStringAsFixed(2).tr()); @@ -279,11 +295,11 @@ class LabResultDetails extends StatelessWidget { scrollDirection: Axis.horizontal, height: 180.h); }else { - return labHistoryList(model, labmodel); + return labHistoryList(labmodel); } } - Widget labHistoryList(DateRangeSelectorRangeViewModel model, LabViewModel labmodel) { + Widget labHistoryList(LabViewModel labmodel) { return SizedBox( height: labmodel.filteredGraphValues.length<3?labmodel.filteredGraphValues.length*64:180.h, child: ListView.separated( @@ -315,4 +331,27 @@ class LabResultDetails extends StatelessWidget { if(maxX >100 && maxX < 200) return 30; return 50; } + + Widget getLabDescription(BuildContext context) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + height: 98.h, + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8.h, + children: [ + "What is this result?" + .needTranslation + .toText16(weight: FontWeight.w600, color: AppColors.textColor), + testDescription?.toText12( + fontWeight: FontWeight.w500, color: AppColors.textColorLight) ?? + SizedBox.shrink() + ], + )); + } } diff --git a/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart b/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart index 42f222b..d295987 100644 --- a/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart +++ b/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart @@ -1,5 +1,6 @@ import 'package:dartz/dartz.dart'; import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/features/lab/models/Range.dart'; class DateRangeSelectorRangeViewModel extends ChangeNotifier { @@ -17,7 +18,7 @@ class DateRangeSelectorRangeViewModel extends ChangeNotifier { 'Nov', 'Dec' ]; - bool isGraphVisible = true; + Range? _currentlySelectedRange; Range? get currentlySelectedRange => _currentlySelectedRange; @@ -50,7 +51,7 @@ class DateRangeSelectorRangeViewModel extends ChangeNotifier { get getCurrentYear => DateTime.now().year; calculateDatesFromRange() { - _toDate = DateTime.now(); + _toDate = DateTime.now().provideDateOnly(); switch (_currentlySelectedRange) { case Range.WEEKLY: _fromDate = _toDate!.subtract(Duration(days: 7)); @@ -77,7 +78,6 @@ class DateRangeSelectorRangeViewModel extends ChangeNotifier { toDate = null; fromDate = null; currentlySelectedRange = null; - isGraphVisible = true; notifyListeners(); } @@ -86,8 +86,4 @@ class DateRangeSelectorRangeViewModel extends ChangeNotifier { notifyListeners(); } - alterGraphVisibility(){ - isGraphVisible = !isGraphVisible; - notifyListeners(); - } }