From 3e24278d89398ed3891082244fd11c218abb15c3 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 26 Apr 2021 14:59:37 +0300 Subject: [PATCH] in-patient re-design --- lib/config/config.dart | 3 + lib/config/localized_values.dart | 1 + lib/core/model/PatientSearchRequestModel.dart | 18 +- lib/core/service/patientInPatientService.dart | 36 ++++ .../viewModel/PatientSearchViewModel.dart | 53 ++++- lib/locator.dart | 2 + lib/screens/home/home_screen.dart | 26 ++- .../patients/PatientsInPatientScreen.dart | 189 ++++++++++++++++++ lib/util/translations_delegate_base.dart | 2 + .../shared/text_fields/text_fields_utils.dart | 4 +- 10 files changed, 312 insertions(+), 22 deletions(-) create mode 100644 lib/core/service/patientInPatientService.dart create mode 100644 lib/screens/patients/PatientsInPatientScreen.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 5c704152..e930aef9 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -152,6 +152,9 @@ const POST_PROCEDURE_LIST = 'Services/DoctorApplication.svc/REST/PostProcedure'; const GET_PATIENT_ARRIVAL_LIST = 'Services/DoctorApplication.svc/REST/PatientArrivalList'; +const GET_PATIENT_IN_PATIENT_LIST = + 'Services/DoctorApplication.svc/REST/GetMyInPatient'; + const Verify_Referral_Doctor_Remarks = 'Services/DoctorApplication.svc/REST/VerifyReferralDoctorRemarks'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index cfad087a..eec509a9 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -48,6 +48,7 @@ const Map> localizedValues = { 'service': {'en': 'Service', 'ar': 'خدمة'}, 'referral': {'en': 'Referral', 'ar': 'الإحالة'}, 'inPatient': {'en': 'My InPatients', 'ar': 'المريض الداخلي'}, + 'inPatientAll': {'en': 'All InPatients', 'ar': 'كل المرضى الداخليين'}, 'operations': {'en': 'Operations', 'ar': 'عمليات'}, 'patientServices': {'en': 'Patient Services', 'ar': 'خدمات المرضى'}, 'searchMedicine': {'en': 'Search Medicines', 'ar': 'بحث عن الدواء'}, diff --git a/lib/core/model/PatientSearchRequestModel.dart b/lib/core/model/PatientSearchRequestModel.dart index 72b1aa9e..e758d5e8 100644 --- a/lib/core/model/PatientSearchRequestModel.dart +++ b/lib/core/model/PatientSearchRequestModel.dart @@ -10,15 +10,15 @@ class PatientSearchRequestModel { String to; PatientSearchRequestModel( - {this.doctorID, - this.firstName, - this.middleName, - this.lastName, - this.patientMobileNumber, - this.patientIdentificationID, - this.patientID, - this.from, - this.to}); + {this.doctorID = 0, + this.firstName = "0", + this.middleName = "0", + this.lastName = "0", + this.patientMobileNumber = "0", + this.patientIdentificationID = "0", + this.patientID = 0, + this.from = "0", + this.to = "0"}); PatientSearchRequestModel.fromJson(Map json) { doctorID = json['DoctorID']; diff --git a/lib/core/service/patientInPatientService.dart b/lib/core/service/patientInPatientService.dart new file mode 100644 index 00000000..3e0ba4a4 --- /dev/null +++ b/lib/core/service/patientInPatientService.dart @@ -0,0 +1,36 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class PatientInPatientService extends BaseService { + List inPatientList = List(); + + Future getInPatientList( + PatientSearchRequestModel requestModel, bool isMyInpatient) async { + hasError = false; + await getDoctorProfile(); + + if (isMyInpatient) { + requestModel.doctorID = doctorProfile.doctorID; + }else { + requestModel.doctorID = 0; + } + + await baseAppClient.post( + GET_PATIENT_IN_PATIENT_LIST, + onSuccess: (dynamic response, int statusCode) { + inPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + inPatientList.add(PatiantInformtion.fromJson(v)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } +} diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index ea0e5cec..e2d675ca 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -1,5 +1,54 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/patientInPatientService.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +import '../../locator.dart'; import 'base_view_model.dart'; -class PatientSearchViewModel extends BaseViewModel{ +class PatientSearchViewModel extends BaseViewModel { + PatientInPatientService _inPatientService = + locator(); + + List get _inPatientList => _inPatientService.inPatientList; + List filteredInPatientItems = List(); + + Future getInPatientList(PatientSearchRequestModel requestModel, + {bool isMyInpatient = false}) async { + setState(ViewState.Busy); + await _inPatientService.getInPatientList(requestModel, isMyInpatient); + if (_inPatientService.hasError) { + error = _inPatientService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + filteredInPatientItems.clear(); + filteredInPatientItems.addAll(_inPatientList); + } + } + + void filterSearchResults(String query) { + var strExist = query.length > 0 ? true : false; + if (strExist) { + filteredInPatientItems = []; + for (var i = 0; i < _inPatientList.length; i++) { + String firstName = _inPatientList[i].firstName.toUpperCase(); + String lastName = _inPatientList[i].lastName.toUpperCase(); + String mobile = _inPatientList[i].mobileNumber.toUpperCase(); + String patientID = _inPatientList[i].patientId.toString(); + + if (firstName.contains(query.toUpperCase()) || + lastName.contains(query.toUpperCase()) || + mobile.contains(query) || + patientID.contains(query)) { + filteredInPatientItems.add(_inPatientList[i]); + } + } + notifyListeners(); + } else { + filteredInPatientItems = _inPatientList; + notifyListeners(); + } + } -} \ No newline at end of file +} diff --git a/lib/locator.dart b/lib/locator.dart index 3aabd46b..c6ddae3c 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -27,6 +27,7 @@ import 'core/service/patient-admission-request-service.dart'; import 'core/service/patient-doctor-referral-service.dart'; import 'core/service/patient-ucaf-service.dart'; import 'core/service/patient-vital-signs-service.dart'; +import 'core/service/patientInPatientService.dart'; import 'core/service/prescriptions_service.dart'; import 'core/service/radiology_service.dart'; import 'core/service/referral_patient_service.dart'; @@ -80,6 +81,7 @@ void setupLocator() { locator.registerLazySingleton(() => ReferralService()); locator.registerLazySingleton(() => MyReferralInPatientService()); locator.registerLazySingleton(() => DischargedPatientService()); + locator.registerLazySingleton(() => PatientInPatientService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 39fc7a8c..5b1574df 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -15,6 +15,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart'; import 'package:doctor_app_flutter/screens/medicine/search_medicine_patient_screen.dart'; import 'package:doctor_app_flutter/screens/patients/DischargedPatientPage.dart'; +import 'package:doctor_app_flutter/screens/patients/PatientsInPatientScreen.dart'; import 'package:doctor_app_flutter/screens/patients/ReferralDischargedPatientPage.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; @@ -30,6 +31,7 @@ import 'package:doctor_app_flutter/widgets/dashboard/swiper_rounded_pagination.d import 'package:doctor_app_flutter/widgets/patients/profile/profile-welcome-widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -494,15 +496,21 @@ class _HomeScreenState extends State { ), hasBorder: false, onTap: () { - getRequestHeader(true); - Navigator.of(context) - .pushNamed(PATIENTS, arguments: { - "patientSearchForm": - _patientSearchFormValues, - "selectedType": "1", - "arrivalType": "1", - "isInpatient": true - }); + Navigator.push( + context, + FadePage( + page: PatientInPatientScreen(), + ), + ); + // getRequestHeader(true); + // Navigator.of(context) + // .pushNamed(PATIENTS, arguments: { + // "patientSearchForm": + // _patientSearchFormValues, + // "selectedType": "1", + // "arrivalType": "1", + // "isInpatient": true + // }); }, ), HomePageCard( diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart new file mode 100644 index 00000000..e46055d5 --- /dev/null +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -0,0 +1,189 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; +import 'package:flutter/material.dart'; + +import '../../routes.dart'; + +class PatientInPatientScreen extends StatefulWidget { + @override + _PatientInPatientScreenState createState() => _PatientInPatientScreenState(); +} + +class _PatientInPatientScreenState extends State { + PatientSearchRequestModel requestModel = PatientSearchRequestModel(); + int _activeTab = 0; + + TextEditingController _searchController = TextEditingController(); + + @override + void dispose() { + _searchController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + + return BaseView( + onModelReady: (model) => model.getInPatientList(requestModel), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: false, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Row(children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Colors.black, //Colors.black, + onPressed: () => Navigator.pop(context), + ), + Expanded( + child: AppText( + TranslationBase.of(context).inPatient, + fontSize: SizeConfig.textMultiplier * 2.8, + fontWeight: FontWeight.bold, + color: Color(0xFF2B353E), + fontFamily: 'Poppins', + ), + ), + ]), + ), + ), + tabsBar(context, screenSize, model), + model.filteredInPatientItems.length > 0 + ? Expanded( + child: Container( + margin: EdgeInsets.all(16.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppTextFieldCustom( + hintText: TranslationBase.of(context) + .searchPatientName, + isTextFieldHasSuffix: true, + suffixIcon: IconButton( + icon: Icon( + Icons.search, + color: Colors.black, + ), + onPressed: () {}, + ), + controller: _searchController, + onChanged: (value) { + model.filterSearchResults(value); + }), + const SizedBox( + height: 16, + ), + ...model.filteredInPatientItems.map((item) { + return PatientCard( + patientInfo: item, + patientType: "1", + arrivalType: "1", + isInpatient: true, + onTap: () { + Navigator.of(context) + .pushNamed(PATIENTS_PROFILE, arguments: { + "patient": item, + "patientType": "1", + "from": "0", + "to": "0", + "isSearch": false, + "isInpatient": true, + "arrivalType": "1", + }); + }, + ); + }).toList(), + ], + ), + ), + ), + ) + : Container( + child: ErrorMessage( + error: TranslationBase.of(context).noDataAvailable)), + ], + ), + ), + ); + } + + Widget tabsBar( + BuildContext context, Size screenSize, PatientSearchViewModel model) { + List _tabs = [ + TranslationBase.of(context).inPatientAll.toUpperCase(), + TranslationBase.of(context).inPatient.toUpperCase(), + ]; + + return Container( + height: screenSize.height * 0.070, + decoration: TextFieldsUtils.containerBorderDecoration( + Color(0Xffffffff), Color(0xFFCCCCCC), + borderRadius: 4, borderWidth: 0), + child: Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: _tabs.map((item) { + bool _isActive = _tabs[_activeTab] == item ? true : false; + + return Expanded( + child: InkWell( + onTap: () async { + setState(() { + _activeTab = _tabs.indexOf(item); + }); + // GifLoaderDialogUtils.showMyDialog( + // context); + await model.getInPatientList(requestModel, + isMyInpatient: _activeTab == 1); + }, + child: Center( + child: Container( + height: screenSize.height * 0.070, + decoration: TextFieldsUtils.containerBorderDecoration( + _isActive + ? Color(0xFFD02127 /*B8382B*/) + : Color(0xFFEAEAEA), + _isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), + borderRadius: 4, + borderWidth: 0), + child: Center( + child: AppText( + item, + fontSize: SizeConfig.textMultiplier * 1.8, + color: _isActive ? Colors.white : Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ), + ); + }).toList(), + ), + ); + } +} diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 4645a5e0..3d431f9d 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -101,6 +101,8 @@ class TranslationBase { String get inPatient => localizedValues['inPatient'][locale.languageCode]; + String get inPatientAll => localizedValues['inPatientAll'][locale.languageCode]; + String get operations => localizedValues['operations'][locale.languageCode]; String get patientServices => diff --git a/lib/widgets/shared/text_fields/text_fields_utils.dart b/lib/widgets/shared/text_fields/text_fields_utils.dart index 660f7918..54c7e494 100644 --- a/lib/widgets/shared/text_fields/text_fields_utils.dart +++ b/lib/widgets/shared/text_fields/text_fields_utils.dart @@ -4,11 +4,11 @@ class TextFieldsUtils{ static BoxDecoration containerBorderDecoration( Color containerColor, Color borderColor, - {double borderWidth = -1}) { + {double borderWidth = -1, double borderRadius = 12}) { return BoxDecoration( color: containerColor, shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(12)), + borderRadius: BorderRadius.all(Radius.circular(borderRadius)), border: Border.fromBorderSide(BorderSide( color: borderColor, width: borderWidth == -1 ? 2.0 : borderWidth,