diff --git a/lib/config/config.dart b/lib/config/config.dart index 7b816250..6349c249 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -21,14 +21,14 @@ var PACKAGES_ORDERS = '/api/orders'; var PACKAGES_ORDER_HISTORY = '/api/orders/items'; var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; // var BASE_URL = 'http://10.50.100.198:2018/'; - var BASE_URL = 'https://uat.hmgwebservices.com/'; + // var BASE_URL = 'https://uat.hmgwebservices.com/'; // var BASE_URL = 'https://hmgwebservices.com/'; // var BASE_URL = 'http://10.201.204.103/'; // var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidamergeuat.cloudsolutions.com.sa/'; -// var BASE_URL = 'https://webservices.hmg.com/'; +var BASE_URL = 'https://webservices.hmg.com/'; // var BASE_URL = 'http://10.50.100.198:4422/'; @@ -354,7 +354,7 @@ var CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/CanPayForWal var CHANNEL = 3; var GENERAL_ID = 'Cs2020@2016\$2958'; var IP_ADDRESS = '10.20.10.20'; -var VERSION_ID = 18.5; +var VERSION_ID = 19.0; var SETUP_ID = '91877'; var LANGUAGE = 2; // var PATIENT_OUT_SA = 0; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index ef2dc15b..d78c7194 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2326,4 +2326,7 @@ const Map localizedValues = { "liveCareTermsHeading16": {"en": "14. COMPLAINTS", "ar": "14. الشكاوى"}, "liveCareTermsConditions47": {"en": "Our Telehealth Services will be for specific medical specialties or follow-up or medication refill appointments.", "ar": "خدمات الرعاية الصحية عن بُعد الخاصة بنا سوف تكون لتخصصات طبية محددة أو لمواعيد المتابعة أو إعادة صرف الدواء. "}, "liveCareTermsConditions48": {"en": "If you have any complaints or concerns about the Application and or the Website, Our Services, or how we handle your personal information please contact us on: EServices.HMG@drsulaimanalhabib.com or call 011 525 9553", "ar": "إذا كانت لديك أي شكاوى أو مخاوف بشأن التطبيق و/أو موقع الويب أو خدماتنا أو كيفية تعاملنا مع معلوماتك الشخصية، فيرجى التواصل معنا على: EServices.HMG@drsulaimanalhabib.com أو الاتصال على الرقم: 9553 525 011"}, + "searchLabResult": {"en": "Search Lab Results", "ar": "نتائج البحث في المختبر"}, + "searchRadiology": {"en": "Search Radiology", "ar": "البحث في الأشعة"}, + }; diff --git a/lib/core/model/labs/patient_lab_orders.dart b/lib/core/model/labs/patient_lab_orders.dart index 2f3b1629..c843879d 100644 --- a/lib/core/model/labs/patient_lab_orders.dart +++ b/lib/core/model/labs/patient_lab_orders.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PatientLabOrders { @@ -39,6 +40,7 @@ class PatientLabOrders { bool? isLiveCareAppointment; int? status; String? statusDesc; + List? testDetails; PatientLabOrders( {this.actualDoctorRate, this.clinicDescription, @@ -77,7 +79,9 @@ class PatientLabOrders { this.speciality, this.isLiveCareAppointment, this.status, - this.statusDesc,}); + this.statusDesc, + this.testDetails + }); PatientLabOrders.fromJson(Map json) { actualDoctorRate = json['ActualDoctorRate']; @@ -117,6 +121,12 @@ class PatientLabOrders { isLiveCareAppointment = json['IsLiveCareAppointment']; status = json['Status']; statusDesc = json['StatusDesc']; + if (json['TestDetails'] != null) { + testDetails = []; + json['TestDetails'].forEach((v) { + testDetails!.add(new TestDetail.fromJson(v)); + }); + } // speciality = json['Speciality'].cast(); } @@ -159,6 +169,32 @@ class PatientLabOrders { data['invoiceNo_VP'] = this.invoiceNo_VP; data['Status'] = this.status; data['StatusDesc'] = this.statusDesc; + data['TestDetails'] = this.testDetails; + if (this.testDetails != null) { + data['TestDetails'] = this.testDetails!.map((v) => v.toJson()).toList(); + } + return data; + } + +} +class TestDetail { + String? description; + String? testCode; + String? testID; + + TestDetail({this.description, this.testCode, this.testID}); + + TestDetail.fromJson(Map json) { + description = json['Description']; + testCode = json['TestCode']; + testID = json['TestID']; + } + + Map toJson() { + final Map data = new Map(); + data['Description'] = this.description; + data['TestCode'] = this.testCode; + data['TestID'] = this.testID; return data; } } diff --git a/lib/core/model/radiology/final_radiology.dart b/lib/core/model/radiology/final_radiology.dart index 44a5883f..35b8f094 100644 --- a/lib/core/model/radiology/final_radiology.dart +++ b/lib/core/model/radiology/final_radiology.dart @@ -44,7 +44,7 @@ class FinalRadiology { bool? isCVI; bool? isRadMedicalReport; bool? isLiveCareAppointment; - + String? description; FinalRadiology( {this.setupID, this.projectID, @@ -88,7 +88,9 @@ class FinalRadiology { this.speciality, this.isCVI, this.isRadMedicalReport, - this.isLiveCareAppointment}); + this.isLiveCareAppointment, + this.description + }); FinalRadiology.fromJson(Map json) { try { @@ -135,6 +137,7 @@ class FinalRadiology { // speciality = json['Speciality'].cast(); isCVI = json['isCVI']; isRadMedicalReport = json['isRadMedicalReport']; + description = json['Description']; } catch (e) { print(e); } @@ -184,6 +187,7 @@ class FinalRadiology { data['Speciality'] = this.speciality; data['isCVI'] = this.isCVI; data['isRadMedicalReport'] = this.isRadMedicalReport; + data['Description'] =this.description; return data; } } diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 36afccdd..f5c91f74 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -196,10 +196,10 @@ class BaseAppClient { body.removeWhere((key, value) => key == null || value == null); - // if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { - // url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; - // body['TokenID'] = "@dm!n"; - // } + if (url == 'https://webservices.hmg.com/Services/Patients.svc/REST/GetPatientLabOrders' || url=='https://webservices.hmg.com/Services/Patients.svc/REST/GetPatientRadOrders') { + // url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; + body['VersionID'] = 50.0; + } // if (AppGlobal.isNetworkDebugEnabled) { debugPrint("URL : $url"); diff --git a/lib/core/viewModels/medical/labs_view_model.dart b/lib/core/viewModels/medical/labs_view_model.dart index ea45a312..773c4cf5 100644 --- a/lib/core/viewModels/medical/labs_view_model.dart +++ b/lib/core/viewModels/medical/labs_view_model.dart @@ -33,6 +33,10 @@ class LabsViewModel extends BaseViewModel { List get patientLabOrdersList => filterType == FilterType.Clinic ? _patientLabOrdersListClinic : _patientLabOrdersListHospital; + List tempPatientLabOrdersList = []; + List autoCompleteList = []; + bool _showSuggestions = false; + bool get showSuggestions => _showSuggestions; void getLabs() async { if (authenticatedUserObject.isLogin) { setState(ViewState.Busy); @@ -41,34 +45,48 @@ class LabsViewModel extends BaseViewModel { error = _labsService.error!; setState(ViewState.Error); } else { - _labsService.patientLabOrdersList.forEach((element) { - List patientLabOrdersClinic = _patientLabOrdersListClinic.where((elementClinic) => elementClinic.filterName == element.clinicDescription).toList(); + tempPatientLabOrdersList = List.from(_labsService.patientLabOrdersList); + tempPatientLabOrdersList.forEach((item1){ + item1.testDetails!.forEach((item2){ + if (!autoCompleteList.contains(item2.description)) { + autoCompleteList.add(item2.description!); + } + }); - if (patientLabOrdersClinic.length != 0) { - _patientLabOrdersListClinic[_patientLabOrdersListClinic.indexOf(patientLabOrdersClinic[0])].patientLabOrdersList.add(element); - } else { - _patientLabOrdersListClinic.add(PatientLabOrdersList(filterName: element.clinicDescription ?? element.projectName, patientDoctorAppointment: element)); - } - - // doctor list sort via project - List patientLabOrdersHospital = _patientLabOrdersListHospital - .where( - (elementClinic) => elementClinic.filterName == element.projectName, - ) - .toList(); - - if (patientLabOrdersHospital.length != 0) { - _patientLabOrdersListHospital[_patientLabOrdersListHospital.indexOf(patientLabOrdersHospital[0])].patientLabOrdersList.add(element); - } else { - _patientLabOrdersListHospital.add(PatientLabOrdersList(filterName: element.projectName ?? element.clinicDescription, patientDoctorAppointment: element)); - } }); - setState(ViewState.Idle); + runFilerTest(); } } } + runFilerTest() { + _labsService.patientLabOrdersList.forEach((element) { + List patientLabOrdersClinic = _patientLabOrdersListClinic.where((elementClinic) => elementClinic.filterName == element.clinicDescription).toList(); + + if (patientLabOrdersClinic.length != 0) { + _patientLabOrdersListClinic[_patientLabOrdersListClinic.indexOf(patientLabOrdersClinic[0])].patientLabOrdersList.add(element); + } else { + _patientLabOrdersListClinic.add(PatientLabOrdersList(filterName: element.clinicDescription ?? element.projectName, patientDoctorAppointment: element)); + } + + // doctor list sort via project + List patientLabOrdersHospital = _patientLabOrdersListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); + + if (patientLabOrdersHospital.length != 0) { + _patientLabOrdersListHospital[_patientLabOrdersListHospital.indexOf(patientLabOrdersHospital[0])].patientLabOrdersList.add(element); + } else { + _patientLabOrdersListHospital.add(PatientLabOrdersList(filterName: element.projectName ?? element.clinicDescription, patientDoctorAppointment: element)); + } + }); + + setState(ViewState.Idle); + } + setFilterType(FilterType filterType) { this.filterType = filterType; notifyListeners(); @@ -177,4 +195,43 @@ class LabsViewModel extends BaseViewModel { await file.writeAsBytes(bytes); return file.path; } + + searchLab(String searchParam, {bool isAutocomplete = false}) { + _showSuggestions = isAutocomplete; + if (searchParam.isEmpty) { + _showSuggestions =false; + _labsService.patientLabOrdersList = List.from(tempPatientLabOrdersList); + _patientLabOrdersListClinic.clear(); + _patientLabOrdersListHospital.clear(); + runFilerTest(); + notifyListeners(); + return; + } + if (isAutocomplete) { + notifyListeners(); + return; + } + filterList(searchParam); + } + List getFilteredSuggestions(String query) { + if (query.isEmpty) return []; + return autoCompleteList.where((suggestion) => + suggestion.toLowerCase().contains(query.toLowerCase()) + ).toList(); + } + filterList(String searchParam){ + final lowerCaseQuery = searchParam.toLowerCase(); + _labsService.patientLabOrdersList = tempPatientLabOrdersList.where((item) { + if (item.testDetails != null && item.testDetails!.isNotEmpty) { + return item.testDetails!.any((test) { + return test.description?.toLowerCase().contains(lowerCaseQuery) ?? false; + }); + } + return false; + }).toList(); + _patientLabOrdersListClinic.clear(); + _patientLabOrdersListHospital.clear(); + runFilerTest(); + notifyListeners(); + } } diff --git a/lib/core/viewModels/medical/radiology_view_model.dart b/lib/core/viewModels/medical/radiology_view_model.dart index 91988934..1cb8a426 100644 --- a/lib/core/viewModels/medical/radiology_view_model.dart +++ b/lib/core/viewModels/medical/radiology_view_model.dart @@ -19,9 +19,11 @@ class RadiologyViewModel extends BaseViewModel { List get finalRadiologyList => filterType == FilterType.Clinic ? _finalRadiologyListClinic : _finalRadiologyListHospital; bool _isRadiologyVIDAPlus = false; - + bool _showSuggestions = false; + bool get showSuggestions => _showSuggestions; bool get isRadiologyVIDAPlus => _isRadiologyVIDAPlus; - + List tempFinalRadiologyList =[]; + List autoCompleteList =[]; void getPatientRadOrders() async { setState(ViewState.Busy); await _radiologyService.getPatientRadOrders(); @@ -31,21 +33,28 @@ class RadiologyViewModel extends BaseViewModel { setState(ViewState.Error); } else { //Clinic Sorting - var clinicMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.clinicDescription); - clinicMap.forEach((key, value) { - _finalRadiologyListClinic.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); - }); - - //Hospital Sorting - var hospitalMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.projectName); - hospitalMap.forEach((key, value) { - _finalRadiologyListHospital.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); - }); - + filterRadiology(); + tempFinalRadiologyList = List.from(_radiologyService.finalRadiologyList); + // tempFinalRadiologyList.forEach((item) { + // if(!autoCompleteList.contains(item.description!)) { + // autoCompleteList.add(item.description!); + // }}); setState(ViewState.Idle); } } + filterRadiology(){ + var clinicMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.clinicDescription); + clinicMap.forEach((key, value) { + _finalRadiologyListClinic.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); + }); + + //Hospital Sorting + var hospitalMap = groupBy(_radiologyService.finalRadiologyList, (FinalRadiology obj) => obj.projectName); + hospitalMap.forEach((key, value) { + _finalRadiologyListHospital.add(FinalRadiologyList(filterName: key, finalRadiologyList: value.toList())); + }); + } String get radImageURL => _radiologyService.url; getRadImageURL({required int invoiceNo, String? invoiceType, required int lineItem, required int projectId, required bool isVidaPlus}) async { @@ -74,4 +83,37 @@ class RadiologyViewModel extends BaseViewModel { this.filterType = filterType; notifyListeners(); } + + searchRadiology(String searchParam, {bool isAutocomplete = false}){ + _showSuggestions = isAutocomplete; + if (searchParam.isEmpty) { + + _finalRadiologyListClinic.clear(); + _finalRadiologyListClinic.clear(); + _radiologyService.finalRadiologyList = List.from(tempFinalRadiologyList); + filterRadiology(); + notifyListeners(); + return; + } + if (isAutocomplete) { + notifyListeners(); + return; + } + final lowerCaseQuery = searchParam.toLowerCase(); + _finalRadiologyListClinic.clear(); + _finalRadiologyListClinic.clear(); + _radiologyService.finalRadiologyList = tempFinalRadiologyList.where((item) { + return item.description?.toLowerCase().contains(lowerCaseQuery) ?? false; + }).toList(); + filterRadiology(); + + + notifyListeners(); + } + List getFilteredSuggestions(String query) { + if (query.isEmpty) return []; + return autoCompleteList.where((suggestion) => + suggestion.toLowerCase().contains(query.toLowerCase()) + ).toList(); + } } diff --git a/lib/pages/medical/labs/labs_home_page.dart b/lib/pages/medical/labs/labs_home_page.dart index 5a163c10..98435fa8 100644 --- a/lib/pages/medical/labs/labs_home_page.dart +++ b/lib/pages/medical/labs/labs_home_page.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/input/input_widget.dart'; import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -16,15 +17,33 @@ import 'package:provider/provider.dart'; import 'laboratory_result_page.dart'; -class LabsHomePage extends StatelessWidget { +class LabsHomePage extends StatefulWidget { + LabsHomePage(); + + @override + _LabsHomePageState createState() => _LabsHomePageState(); +} + +class _LabsHomePageState extends State { List imagesInfo = []; + TextEditingController searchController = new TextEditingController(); + List tempList = []; + List originalList = []; + + @override + void initState() { + super.initState(); + } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-lab/ar/0.png')); return BaseView( - onModelReady: (model) => model.getLabs(), + onModelReady: (model) { + model.getLabs(); + originalList = model.patientLabOrdersList; + }, builder: (context, LabsViewModel model, widget) => AppScaffold( baseViewModel: model, isShowAppBar: true, @@ -46,6 +65,22 @@ class LabsHomePage extends StatelessWidget { }), ], ), + Container( + padding: EdgeInsets.only(bottom: 5, top: 14, left: 21, right: 21), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + inputWidget(TranslationBase.of(context).searchLabResult, '', searchController, + suffix: IconButton( + onPressed: () {}, + icon: Icon( + Icons.search, + size: 28, + )), onChanged: (String? searchParam) { + + model.searchLab(searchParam!, isAutocomplete: true); + + }) + ])), + if (model.showSuggestions) _buildSuggestionsList(model), Expanded( child: FractionallySizedBox( widthFactor: 1.0, @@ -62,40 +97,49 @@ class LabsHomePage extends StatelessWidget { }, itemBuilder: (context, index) { return AppExpandableNotifier( - title: model.patientLabOrdersList[index].filterName, - bodyWidget: ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), - itemBuilder: (context, _index) { - PatientLabOrders labOrder = model.patientLabOrdersList[index].patientLabOrdersList[_index]; - bool _isSortByClinic = model.filterType == FilterType.Clinic; - return DoctorCard( - onTap: () => Navigator.push( - context, - FadePage( - page: LaboratoryResultPage( - patientLabOrders: labOrder, - ), - ), - ), - isInOutPatient: labOrder.isInOutPatient, - name: TranslationBase.of(context).dr + " " + labOrder.doctorName!, - billNo: labOrder.invoiceNo, - profileUrl: labOrder.doctorImageURL, - subName: _isSortByClinic ? (labOrder.projectName ?? labOrder.clinicDescription) : (labOrder.clinicDescription ?? labOrder.projectName), - isLiveCareAppointment: labOrder.isLiveCareAppointment, - date: labOrder.orderDate, - isSortByClinic: _isSortByClinic, - isLabOrderResult: true, - resultStatus: labOrder.status!, - resultStatusDesc: labOrder.statusDesc!, - //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), - ); - }, - separatorBuilder: (context, index) => SizedBox(height: 14), - itemCount: model.patientLabOrdersList[index].patientLabOrdersList.length), - ); + isExpand: true, + title: model.patientLabOrdersList[index].filterName, + bodyWidget: + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Container( + // + // padding: EdgeInsets.only(left:21, right: 21), + // child: Text(model.patientLabOrdersList[index].filterName!, style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), )), + + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + PatientLabOrders labOrder = model.patientLabOrdersList[index].patientLabOrdersList[_index]; + bool _isSortByClinic = model.filterType == FilterType.Clinic; + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: LaboratoryResultPage( + patientLabOrders: labOrder, + ), + ), + ), + isInOutPatient: labOrder.isInOutPatient, + name: TranslationBase.of(context).dr + " " + labOrder.doctorName!, + billNo: labOrder.invoiceNo, + profileUrl: labOrder.doctorImageURL, + subName: _isSortByClinic ? (labOrder.projectName ?? labOrder.clinicDescription) : (labOrder.clinicDescription ?? labOrder.projectName), + isLiveCareAppointment: labOrder.isLiveCareAppointment, + date: labOrder.orderDate, + isSortByClinic: _isSortByClinic, + isLabOrderResult: true, + resultStatus: labOrder.status!, + resultStatusDesc: labOrder.statusDesc!, + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.patientLabOrdersList[index].patientLabOrdersList.length)); }, itemCount: model.patientLabOrdersList.length), ), @@ -105,4 +149,46 @@ class LabsHomePage extends StatelessWidget { ), ); } + + Widget _buildSuggestionsList(LabsViewModel model) { + final suggestions = model.getFilteredSuggestions(searchController.text); + return ConstrainedBox( + + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.4, + + ), + child: Container( + padding: EdgeInsets.only(bottom: 5, top: 0, left: 21, right: 21), + child: Material( + elevation: 4, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(8), + bottomRight: Radius.circular(8), + ), + child: ListView.builder( + shrinkWrap: true, + physics: ClampingScrollPhysics(), + itemCount: suggestions.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + searchController.text = suggestions[index]; + model.searchLab(suggestions[index]); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + border: Border( + bottom: index < suggestions.length - 1 ? BorderSide(color: Colors.grey.shade200) : BorderSide.none, + ), + ), + child: Text(suggestions[index]), + ), + ); + }, + ), + )), + ); + } } diff --git a/lib/pages/medical/radiology/radiology_home_page.dart b/lib/pages/medical/radiology/radiology_home_page.dart index fb60d5da..71aec44d 100644 --- a/lib/pages/medical/radiology/radiology_home_page.dart +++ b/lib/pages/medical/radiology/radiology_home_page.dart @@ -8,16 +8,33 @@ import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_p import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/input/input_widget.dart'; import 'package:diplomaticquarterapp/widgets/new_design/my_tab_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class RadiologyHomePage extends StatelessWidget { - List imagesInfo =[]; +class RadiologyHomePage extends StatefulWidget { + RadiologyHomePage(); + + @override + _RadiologyHomePageState createState() => _RadiologyHomePageState(); +} + +bool isExpand = false; + +class _RadiologyHomePageState extends State { + List imagesInfo = []; + TextEditingController searchController = new TextEditingController(); + + @override + void initState() { + super.initState(); + } @override Widget build(BuildContext context) { @@ -49,6 +66,25 @@ class RadiologyHomePage extends StatelessWidget { }), ], ), + Container( + padding: EdgeInsets.only(bottom: 5, top: 14, left: 21, right: 21), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + inputWidget(TranslationBase.of(context).searchRadiology, '', searchController, + suffix: IconButton( + onPressed: () {}, + icon: Icon( + Icons.search, + size: 28, + )), onChanged: (String? searchParam) { + // if (searchParam!.length > 2) { + model.searchRadiology(searchParam!, isAutocomplete: true); + // setState(() {}); + // } else { + // model.searchRadiology(searchParam!, isAutocomplete: false); + // } + }, onTap: () {}) + ])), + if (model.showSuggestions) _buildSuggestionsList(model), Expanded( child: FractionallySizedBox( @@ -65,40 +101,47 @@ class RadiologyHomePage extends StatelessWidget { ); }, itemBuilder: (context, index) { + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Container( + // padding: EdgeInsets.only(left:21, right: 21), + // child: Text(model.finalRadiologyList[index].filterName!, style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), )), return AppExpandableNotifier( - title: model.finalRadiologyList[index].filterName, - bodyWidget: ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), - itemBuilder: (context, _index) { - FinalRadiology radiology = model.finalRadiologyList[index].finalRadiologyList![_index]; - bool _isSortByClinic = model.filterType == FilterType.Clinic; - return DoctorCard( - onTap: () => Navigator.push( - context, - FadePage( - page: RadiologyDetailsPage( - finalRadiology: radiology, - isRadiologyVidaPlus: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!), + isExpand: true, + title: model.finalRadiologyList[index].filterName, + bodyWidget: ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(bottom: 14, top: 14, left: 21, right: 21), + itemBuilder: (context, _index) { + FinalRadiology radiology = model.finalRadiologyList[index].finalRadiologyList![_index]; + bool _isSortByClinic = model.filterType == FilterType.Clinic; + return DoctorCard( + onTap: () => Navigator.push( + context, + FadePage( + page: RadiologyDetailsPage( + finalRadiology: radiology, + isRadiologyVidaPlus: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!), + ), ), ), - ), - isInOutPatient: radiology.isInOutPatient, - name: TranslationBase.of(context).dr + " " + radiology.doctorName!, - billNo: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!) ? radiology.invoiceNo_VP.toString() : radiology.invoiceNo.toString(), - // billNo: radiology.invoiceNo_VP.toString(), - profileUrl: radiology.doctorImageURL, - subName: _isSortByClinic ? radiology.projectName : radiology.clinicDescription, - isLiveCareAppointment: radiology.isLiveCareAppointment, - date: radiology.orderDate, - isSortByClinic: _isSortByClinic, - //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), - ); - }, - separatorBuilder: (context, index) => SizedBox(height: 14), - itemCount: model.finalRadiologyList[index].finalRadiologyList!.length), - ); + isInOutPatient: radiology.isInOutPatient, + name: TranslationBase.of(context).dr + " " + radiology.doctorName!, + billNo: Utils.isVidaPlusProject(projectViewModel, radiology.projectID!) ? radiology.invoiceNo_VP.toString() : radiology.invoiceNo.toString(), + // billNo: radiology.invoiceNo_VP.toString(), + profileUrl: radiology.doctorImageURL, + subName: _isSortByClinic ? radiology.projectName : radiology.clinicDescription, + isLiveCareAppointment: radiology.isLiveCareAppointment, + date: radiology.orderDate, + isSortByClinic: _isSortByClinic, + //projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(labOrder.orderDate) : DateUtil.getMonthDayYearDateFormatted(labOrder.orderDate), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 14), + itemCount: model.finalRadiologyList[index].finalRadiologyList!.length)); + //); }, itemCount: model.finalRadiologyList.length), ), @@ -139,4 +182,43 @@ class RadiologyHomePage extends StatelessWidget { ), ); } + + Widget _buildSuggestionsList(RadiologyViewModel model) { + final suggestions = model.getFilteredSuggestions(searchController.text); + + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.4, + ), + child: Material( + elevation: 4, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(8), + bottomRight: Radius.circular(8), + ), + child: ListView.builder( + shrinkWrap: true, + physics: ClampingScrollPhysics(), + itemCount: suggestions.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + searchController.text = suggestions[index]; + model.searchRadiology(suggestions[index]); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + border: Border( + bottom: index < suggestions.length - 1 ? BorderSide(color: Colors.grey.shade200) : BorderSide.none, + ), + ), + child: Text(suggestions[index]), + ), + ); + }, + ), + ), + ); + } } diff --git a/lib/services/payfort_services/payfort_service.dart b/lib/services/payfort_services/payfort_service.dart index 9b2c4597..2d2ddd7d 100644 --- a/lib/services/payfort_services/payfort_service.dart +++ b/lib/services/payfort_services/payfort_service.dart @@ -168,7 +168,7 @@ class PayfortService extends BaseService { /// Step 4: Processing Payment [Don't multiply with 100] /// Amount value send always round ex. [100] not [100.00, 100.21] FortRequest request = FortRequest( - command: FortCommand.purchase, + // command: FortCommand.purchase, amount: orderAmount!, customerName: customerName!, customerEmail: customerEmail!, diff --git a/lib/uitl/app_toast.dart b/lib/uitl/app_toast.dart index bbeebe5d..651e92a3 100644 --- a/lib/uitl/app_toast.dart +++ b/lib/uitl/app_toast.dart @@ -70,7 +70,7 @@ class AppToast { child: toast, gravity: ToastGravity.TOP, toastDuration: Duration(seconds: timeInSeconds), - positionedToastBuilder: (context, child) { + positionedToastBuilder: (context, child, _) { return Positioned(top: 50, left: 10, right: 10, child: child); }); // Fluttertoast.showToast(msg: message, toastLength: toastLength, gravity: toastGravity, timeInSecForIosWeb: timeInSeconds, backgroundColor: Colors.red, textColor: textColor, fontSize: fontSize); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 3f4539c1..d7bab8c3 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -3473,6 +3473,9 @@ class TranslationBase { String get liveCareTermsHeading16 => localizedValues["liveCareTermsHeading16"][locale.languageCode]; String get liveCareTermsConditions47 => localizedValues["liveCareTermsConditions47"][locale.languageCode]; String get liveCareTermsConditions48 => localizedValues["liveCareTermsConditions48"][locale.languageCode]; + String get searchLabResult => localizedValues["searchLabResult"][locale.languageCode]; + String get searchRadiology => localizedValues["searchRadiology"][locale.languageCode]; + } diff --git a/lib/widgets/input/input_widget.dart b/lib/widgets/input/input_widget.dart new file mode 100644 index 00000000..a2a2d50c --- /dev/null +++ b/lib/widgets/input/input_widget.dart @@ -0,0 +1,89 @@ + +import 'package:flutter/material.dart'; + +Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String? prefix, bool isEnable = true, bool hasSelection = false, Widget? suffix, void Function(String)? onChanged,GestureTapCallback? onTap }) { + return Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 5, top: 5), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + + TextField( + enabled: isEnable, + onChanged: onChanged, + scrollPadding: EdgeInsets.zero, + onTap: onTap, + controller: _controller, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + + ), + ), + + + + ], + ), + ), + suffix ?? SizedBox() + ], + ), + ), + ); +} \ No newline at end of file