diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 91d5d4f..1b0abd3 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -782,8 +782,8 @@ "resultsPending": "النتائج معلقة", "resultsAvailable": "النتائج متاحة", "viewReport": "عرض التقرير", - "prescriptionDeliveryError": "هذه العيادة لا تدعم إعادة التعبئة والتسليم.", - "checkAvailability": "التحقق من التوفر", - "readInstructions": "قراءة التعليمات" + "readInstructions": "قراءة التعليمات", + "prescriptionDeliveryError": "هذه العيادة لا تدعم إعادة التعبئة والتسليم.", + "searchLabReport" : "ابحث عن تقرير المختبر" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index f91d98b..b276ed7 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -778,7 +778,8 @@ "resultsPending": "Results Pending", "resultsAvailable": "Results Available", "viewReport": "View Report", - "prescriptionDeliveryError": "This clinic doesn't support refill", "checkAvailability": "Check Availability", - "readInstructions": "Read Instructions" + "readInstructions": "Read Instructions", + "prescriptionDeliveryError": "This clinic doesn't support refill", + "searchLabReport" : "Search Lab Report" } \ No newline at end of file diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 530064e..2077440 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -79,6 +79,7 @@ class AppAssets { static const String myFilesBottom = '$svgBasePath/my_files_bottom.svg'; static const String toDoBottom = '$svgBasePath/todo_bottom.svg'; static const String servicesBottom = '$svgBasePath/services_bottom.svg'; + static const String closeBottomNav = '$svgBasePath/close_bottom_nav.svg'; // PNGS // static const String hmg_logo = '$pngBasePath/hmg_logo.png'; diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index 0b37082..6ad1835 100644 --- a/lib/core/utils/size_utils.dart +++ b/lib/core/utils/size_utils.dart @@ -11,6 +11,10 @@ extension ResponsiveExtension on num { double get h => ((this * _width) / FIGMA_DESIGN_WIDTH); double get fSize => ((this * _width) / FIGMA_DESIGN_WIDTH); + static double get screenHeight => SizeUtils.height; + + /// Full screen width + static double get screenWidth => SizeUtils.width; } extension FormatExtension on double { diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index acd87eb..115b28d 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -12,6 +12,10 @@ class LabViewModel extends ChangeNotifier { List patientLabOrders = []; + List labSuggestionsList =[]; + + get labSuggestions => labSuggestionsList; + LabViewModel({required this.labRepo, required this.errorHandlerService}); initLabProvider() { @@ -42,4 +46,8 @@ class LabViewModel extends ChangeNotifier { }, ); } + + filterSuggestions(){ + + } } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index cd59c15..d41773e 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -783,5 +783,6 @@ abstract class LocaleKeys { static const prescriptionDeliveryError = 'prescriptionDeliveryError'; static const checkAvailability = 'checkAvailability'; static const readInstructions = 'readInstructions'; + static const searchLabReport = 'searchLabReport'; } diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 8a0ce26..97e2216 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -5,14 +5,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_config.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/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/features/lab/lab_view_model.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/widgets/bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -25,7 +30,7 @@ class LabOrdersPage extends StatefulWidget { class _LabOrdersPageState extends State { late LabViewModel labProvider; - + List?> labSuggestions = []; int? expandedIndex; @override @@ -57,7 +62,17 @@ class _LabOrdersPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.labResults.tr(context: context).toText24(isBold: true), - Utils.buildSvgWithAssets(icon: AppAssets.search_icon), + Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(() { + if(model.isLabOrdersLoading){ + return; + }else { + labSuggestions = getLabSuggestions(model); + showCommonBottomSheet(context, child: SearchLabResultsContent(), + callBackFunc: () {}, + title: LocaleKeys.searchLabReport.tr(), + height: ResponsiveExtension.screenHeight, + isCloseButtonVisible: true); + } }), ], ), SizedBox(height: 16.h), @@ -262,4 +277,13 @@ class _LabOrdersPageState extends State { return ""; } } + getLabSuggestions(LabViewModel model) { + if(model.patientLabOrders.isEmpty){ + return []; + } + return model.patientLabOrders.map((m) => m.testDetails).toList(); + + + } + } diff --git a/lib/presentation/lab/search_lab_report.dart b/lib/presentation/lab/search_lab_report.dart new file mode 100644 index 0000000..1c05174 --- /dev/null +++ b/lib/presentation/lab/search_lab_report.dart @@ -0,0 +1,116 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:sizer/sizer.dart'; + +class SearchLabResultsContent extends StatelessWidget { + const SearchLabResultsContent({super.key}); + + final List _chipLabels = const [ + "Blood Test", + "X-Ray", + "MRI Scan", + "CT Scan", + "Ultrasound", + "Urine Test", + "Allergy Test", + "Cholesterol Test", + "Diabetes Test", + "Thyroid Test", + ]; + + @override + Widget build(BuildContext context) { + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextInputWidget( + labelText:"Search lab results", + hintText: "Type test name", + controller: TextEditingController(), + isEnable: true, + prefix: null, + autoFocus: true, + isBorderAllowed: false, + padding: EdgeInsets.symmetric(vertical:ResponsiveExtension(10).h, horizontal: ResponsiveExtension(15).h), + + ), + SizedBox(height: ResponsiveExtension(20).h), + "Suggestions".toText16(isBold: true), + const SizedBox(height: 12), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Wrap( + alignment: WrapAlignment.start, + spacing: 10, + runSpacing: 10, + children: _chipLabels + .map((label) => SuggestionChip( + label: label, + onTap: () {}, + )) + .toList(), + ), + ), + ), + Container( + color: Colors.white, + padding: EdgeInsets.all(ResponsiveExtension(20).h), + child: CustomButton( + text: LocaleKeys.search.tr(), + icon: AppAssets.search_icon, + iconColor: Colors.white, + onPressed: () => Navigator.pop(context), + ), + ), + ], + ); + } +} + +class SuggestionChip extends StatelessWidget { + final String label; + final bool isSelected; + final VoidCallback? onTap; + + const SuggestionChip({ + super.key, + required this.label, + this.isSelected = false, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, // optional tap callback + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), + decoration: BoxDecoration( + color: isSelected ? AppColors.primaryRedColor : AppColors.whiteColor, + borderRadius: BorderRadius.circular(8), + ), + child: label.toText12( + color: isSelected ? Colors.white : Colors.black87, + fontWeight: FontWeight.w500, + ), + ), + ); + } +} diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart new file mode 100644 index 0000000..3d72864 --- /dev/null +++ b/lib/widgets/common_bottom_sheet.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; + +void showCommonBottomSheet(BuildContext context, {required Widget child, required VoidCallback callBackFunc, String? title, required double height, bool isCloseButtonVisible = true}) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: AppColors.scaffoldBgColor, + builder: (BuildContext context) { + return Container( + height: height, + decoration: const BoxDecoration( + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + ), + child: ButtonSheetContent( + title: title!, + isCloseButtonVisible: isCloseButtonVisible, + child: child, + ), + ); + }).then((value) { + callBackFunc(); + }); +} + +class ButtonSheetContent extends StatelessWidget { + final Widget child; + final String title; + final bool isCloseButtonVisible; + + const ButtonSheetContent({super.key, required this.child, required this.isCloseButtonVisible, required this.title}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 20.h,), + Center( + child: Container( + margin: const EdgeInsets.only(top: 18, bottom: 12), + height: 4, + width: 40.h, + decoration: BoxDecoration( + color: Colors.grey[400], + borderRadius: BorderRadius.circular(2), + ), + ), + ), + + // Close button + isCloseButtonVisible + ? Padding( + padding: EdgeInsets.symmetric(horizontal: 16), child: Utils.buildSvgWithAssets( icon: AppAssets.closeBottomNav, + width: 32, + height: 32).onPress((){ + Navigator.of(context).pop(); + }), + ) + : SizedBox(), + + SizedBox(height: 20,), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Text( + title, + style: TextStyle(fontSize: 27.h, fontWeight: FontWeight.bold), + ), + ), + const SizedBox(height: 16), + + Expanded(child: child) + ], + ); + + } +}