From 663d2a942f339ef41f839bbc564cf5c1797d8981 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 3 May 2021 16:18:00 +0300 Subject: [PATCH 001/241] first step from refactoring auth part --- .../get_hospitals_request_model.dart | 48 ++ .../get_hospitals_response_model.dart | 0 lib/core/service/auth_service.dart | 14 - .../service/hospitals/hospitals_service.dart | 23 + lib/core/viewModel/auth_view_model.dart | 72 +-- lib/core/viewModel/hospital_view_model.dart | 32 -- lib/core/viewModel/hospitals_view_model.dart | 27 ++ lib/core/viewModel/imei_view_model.dart | 20 +- lib/locator.dart | 4 + lib/main.dart | 6 +- lib/screens/auth/change_password_screen.dart | 29 -- lib/screens/auth/login_screen.dart | 430 +++++++++++++++++- .../auth/verification_methods_screen.dart | 19 +- lib/screens/home/home_screen.dart | 2 +- .../medicine/medicine_search_screen.dart | 4 +- lib/util/helpers.dart | 1 + lib/widgets/auth/auth_header.dart | 85 ---- lib/widgets/auth/change_password.dart | 159 ------- lib/widgets/auth/known_user_login.dart | 328 ------------- lib/widgets/auth/login_form.dart | 312 ------------- lib/widgets/auth/show_timer_text.dart | 105 ----- lib/widgets/auth/verfiy_account.dart | 386 ---------------- lib/widgets/auth/verification_methods.dart | 47 +- 23 files changed, 562 insertions(+), 1591 deletions(-) create mode 100644 lib/core/model/hospitals/get_hospitals_request_model.dart create mode 100644 lib/core/model/hospitals/get_hospitals_response_model.dart create mode 100644 lib/core/service/hospitals/hospitals_service.dart delete mode 100644 lib/core/viewModel/hospital_view_model.dart create mode 100644 lib/core/viewModel/hospitals_view_model.dart delete mode 100644 lib/screens/auth/change_password_screen.dart delete mode 100644 lib/widgets/auth/change_password.dart delete mode 100644 lib/widgets/auth/known_user_login.dart delete mode 100644 lib/widgets/auth/login_form.dart delete mode 100644 lib/widgets/auth/show_timer_text.dart delete mode 100644 lib/widgets/auth/verfiy_account.dart diff --git a/lib/core/model/hospitals/get_hospitals_request_model.dart b/lib/core/model/hospitals/get_hospitals_request_model.dart new file mode 100644 index 00000000..8a5f1bc1 --- /dev/null +++ b/lib/core/model/hospitals/get_hospitals_request_model.dart @@ -0,0 +1,48 @@ +class GetHospitalsRequestModel { + int languageID; + String stamp; + String iPAdress; + double versionID; + int channel; + String tokenID; + String sessionID; + bool isLoginForDoctorApp; + String memberID; + + GetHospitalsRequestModel( + {this.languageID, + this.stamp, + this.iPAdress, + this.versionID, + this.channel, + this.tokenID, + this.sessionID, + this.isLoginForDoctorApp, + this.memberID}); + + GetHospitalsRequestModel.fromJson(Map json) { + languageID = json['LanguageID']; + stamp = json['stamp']; + iPAdress = json['IPAdress']; + versionID = json['VersionID']; + channel = json['Channel']; + tokenID = json['TokenID']; + sessionID = json['SessionID']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + memberID = json['MemberID']; + } + + Map toJson() { + final Map data = new Map(); + data['LanguageID'] = this.languageID; + data['stamp'] = this.stamp; + data['IPAdress'] = this.iPAdress; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['TokenID'] = this.tokenID; + data['SessionID'] = this.sessionID; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['MemberID'] = this.memberID; + return data; + } +} diff --git a/lib/core/model/hospitals/get_hospitals_response_model.dart b/lib/core/model/hospitals/get_hospitals_response_model.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/core/service/auth_service.dart b/lib/core/service/auth_service.dart index adb2d646..ec56bed7 100644 --- a/lib/core/service/auth_service.dart +++ b/lib/core/service/auth_service.dart @@ -44,19 +44,5 @@ class AuthService extends BaseService { super.error = error; } - // await baseAppClient.post(SELECT_DEVICE_IMEI, - // onSuccess: (dynamic response, int statusCode) { - // _imeiDetails = []; - // response['List_DoctorDeviceDetails'].forEach((v) { - // _imeiDetails.add(GetIMEIDetailsModel.fromJson(v)); - // }); - // }, onFailure: (String error, int statusCode) { - // hasError = true; - // super.error = error; - // }, body: {}); - // } catch (error) { - // hasError = true; - // super.error = error; - // } } } diff --git a/lib/core/service/hospitals/hospitals_service.dart b/lib/core/service/hospitals/hospitals_service.dart new file mode 100644 index 00000000..2c670e09 --- /dev/null +++ b/lib/core/service/hospitals/hospitals_service.dart @@ -0,0 +1,23 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; + +class HospitalsService extends BaseService { + +List hospitals; + + Future getHospitals(GetHospitalsRequestModel getHospitalsRequestModel) async { + hasError = false; + await baseAppClient.post( + GET_PROJECTS, + onSuccess: (dynamic response, int statusCode) { + hospitals = response['ProjectInfo']; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: getHospitalsRequestModel.toJson(), + ); + } +} diff --git a/lib/core/viewModel/auth_view_model.dart b/lib/core/viewModel/auth_view_model.dart index 4e40fe31..48f4661d 100644 --- a/lib/core/viewModel/auth_view_model.dart +++ b/lib/core/viewModel/auth_view_model.dart @@ -56,23 +56,23 @@ class AuthViewModel extends BaseViewModel { } } - Future login(UserModel userInfo) async { - try { - dynamic localRes; - - await baseAppClient.post(LOGIN_URL, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: userInfo.toJson()); - - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } + // Future login(UserModel userInfo) async { + // try { + // dynamic localRes; + // + // await baseAppClient.post(LOGIN_URL, + // onSuccess: (dynamic response, int statusCode) { + // localRes = response; + // }, onFailure: (String error, int statusCode) { + // throw error; + // }, body: userInfo.toJson()); + // + // return Future.value(localRes); + // } catch (error) { + // print(error); + // throw error; + // } + // } Future insertDeviceImei(request) async { var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); @@ -112,22 +112,6 @@ class AuthViewModel extends BaseViewModel { } } - Future sendActivationCodeByOtpNotificationType(activationCodeModel) async { - try { - var localRes; - await baseAppClient.post(SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: activationCodeModel); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } - Future sendActivationCodeForDoctorApp( ActivationCodeModel activationCodeModel) async { try { @@ -145,28 +129,6 @@ class AuthViewModel extends BaseViewModel { } } - Future memberCheckActivationCodeNew(activationCodeModel) async { - try { - dynamic localRes; - await baseAppClient.post(MEMBER_CHECK_ACTIVATION_CODE_NEW, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - selectedClinicName = - ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; - - response['List_DoctorsClinic'].forEach((v) { - doctorsClinicList.add(new ClinicModel.fromJson(v)); - }); - }, onFailure: (String error, int statusCode) { - throw error; - }, body: activationCodeModel); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } - Future checkActivationCodeForDoctorApp( CheckActivationCodeRequestModel checkActivationCodeRequestModel) async { try { diff --git a/lib/core/viewModel/hospital_view_model.dart b/lib/core/viewModel/hospital_view_model.dart deleted file mode 100644 index a49b85e5..00000000 --- a/lib/core/viewModel/hospital_view_model.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:doctor_app_flutter/client/base_app_client.dart'; -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:flutter/cupertino.dart'; - -// TODO change it when change login -class HospitalViewModel with ChangeNotifier { - BaseAppClient baseAppClient = BaseAppClient(); - - Future getProjectsList(memberID) async { - const url = GET_PROJECTS; - // TODO create model or remove it if no info need - var info = { - "LanguageID": 1, - "stamp": "2020-02-26T13:51:44.111Z", - "IPAdress": "11.11.11.11", - "VersionID": 5.8, - "Channel": 9, - "TokenID": "", - "SessionID": "i1UJwCTSqt", - "IsLoginForDoctorApp": true, - "MemberID": memberID - }; - dynamic localRes; - - await baseAppClient.post(url, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: info); - return Future.value(localRes); - } -} diff --git a/lib/core/viewModel/hospitals_view_model.dart b/lib/core/viewModel/hospitals_view_model.dart new file mode 100644 index 00000000..c0ce1bc4 --- /dev/null +++ b/lib/core/viewModel/hospitals_view_model.dart @@ -0,0 +1,27 @@ +import 'package:doctor_app_flutter/client/base_app_client.dart'; +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; +import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; +import 'package:flutter/cupertino.dart'; + +import '../../locator.dart'; +import 'base_view_model.dart'; + + +class HospitalViewModel extends BaseViewModel { + HospitalsService _hospitalsService = locator(); + // List get imeiDetails => _authService.dashboardItemsList; + // get loginInfo => _authService.loginInfo; + Future getHospitalsList(memberID) async { + GetHospitalsRequestModel getHospitalsRequestModel =GetHospitalsRequestModel(); + getHospitalsRequestModel.memberID = memberID; + setState(ViewState.Busy); + await _hospitalsService.getHospitals(getHospitalsRequestModel); + if (_hospitalsService.hasError) { + error = _hospitalsService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/core/viewModel/imei_view_model.dart b/lib/core/viewModel/imei_view_model.dart index c2d16206..ba462553 100644 --- a/lib/core/viewModel/imei_view_model.dart +++ b/lib/core/viewModel/imei_view_model.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/service/auth_service.dart'; +import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; @@ -8,7 +10,10 @@ import 'package:doctor_app_flutter/util/helpers.dart'; class IMEIViewModel extends BaseViewModel { AuthService _authService = locator(); + HospitalsService _hospitalsService = locator(); + List get imeiDetails => _authService.dashboardItemsList; + List get hospitals => _hospitalsService.hospitals; get loginInfo => _authService.loginInfo; Future selectDeviceImei(imei) async { setState(ViewState.Busy); @@ -21,13 +26,24 @@ class IMEIViewModel extends BaseViewModel { } Future login(UserModel userInfo) async { - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _authService.login(userInfo); if (_authService.hasError) { error = _authService.error; - Helpers.showErrorToast(error); setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } + + Future getHospitalsList(memberID) async { + GetHospitalsRequestModel getHospitalsRequestModel =GetHospitalsRequestModel(); + getHospitalsRequestModel.memberID = memberID; + // setState(ViewState.Busy); + await _hospitalsService.getHospitals(getHospitalsRequestModel); + if (_hospitalsService.hasError) { + error = _hospitalsService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } } diff --git a/lib/locator.dart b/lib/locator.dart index 13b51d95..d0d76ea3 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -6,6 +6,7 @@ import 'package:doctor_app_flutter/core/service/prescription_service.dart'; import 'package:doctor_app_flutter/core/service/procedure_service.dart'; import 'package:doctor_app_flutter/core/service/sickleave_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; @@ -21,6 +22,7 @@ import 'core/service/PatientMuseService.dart'; import 'core/service/ReferralService.dart'; import 'core/service/SOAP_service.dart'; import 'core/service/doctor_reply_service.dart'; +import 'core/service/hospitals/hospitals_service.dart'; import 'core/service/labs_service.dart'; import 'core/service/medicine_service.dart'; import 'core/service/patient-admission-request-service.dart'; @@ -84,6 +86,7 @@ void setupLocator() { locator.registerLazySingleton(() => DischargedPatientService()); locator.registerLazySingleton(() => PatientInPatientService()); locator.registerLazySingleton(() => OutPatientService()); + locator.registerLazySingleton(() => HospitalsService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -110,4 +113,5 @@ void setupLocator() { locator.registerFactory(() => PrescriptionsViewModel()); locator.registerFactory(() => DischargedPatientViewModel()); locator.registerFactory(() => PatientSearchViewModel()); + locator.registerFactory(() => HospitalViewModel()); } diff --git a/lib/main.dart b/lib/main.dart index 4e140920..83c2a450 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,7 +12,7 @@ import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; import 'core/viewModel/auth_view_model.dart'; -import 'core/viewModel/hospital_view_model.dart'; +import 'core/viewModel/hospitals_view_model.dart'; import 'locator.dart'; void main() async { @@ -35,8 +35,8 @@ class MyApp extends StatelessWidget { providers: [ ChangeNotifierProvider( create: (context) => AuthViewModel()), - ChangeNotifierProvider( - create: (context) => HospitalViewModel()), + // ChangeNotifierProvider( + // create: (context) => HospitalViewModel()), ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), diff --git a/lib/screens/auth/change_password_screen.dart b/lib/screens/auth/change_password_screen.dart deleted file mode 100644 index 1a502b68..00000000 --- a/lib/screens/auth/change_password_screen.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:doctor_app_flutter/lookups/auth_lookup.dart'; -import 'package:doctor_app_flutter/widgets/auth/auth_header.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:flutter/material.dart'; - -import '../../widgets/auth/change_password.dart'; - -class ChangePasswordScreen extends StatelessWidget { - @override - Widget build(BuildContext context) { - - return AppScaffold( - isShowAppBar: false, - body: SafeArea( - child: ListView(children: [ - Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 0, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AuthHeader(loginType.changePassword), - ChangePassword(), - ], - ), - ), - ]), - )); - } -} diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index fbba6360..b49b492f 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -3,22 +3,30 @@ import 'dart:io'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/auth_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import '../../lookups/auth_lookup.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../widgets/auth/auth_header.dart'; -import '../../widgets/auth/login_form.dart'; import '../../widgets/shared/app_scaffold_widget.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); @@ -29,14 +37,22 @@ class Loginsreen extends StatefulWidget { } class _LoginsreenState extends State { - Future _prefs = SharedPreferences.getInstance(); String platformImei; - // Future platformImeiFuture; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); bool _isLoading = true; ProjectViewModel projectViewModel; AuthService authService = AuthService(); + + //TODO change AppTextFormField to AppTextFormFieldCustom + final loginFormKey = GlobalKey(); + var projectIdController = TextEditingController(); + var projectsList = []; + FocusNode focusPass = FocusNode(); + FocusNode focusProject = FocusNode(); + // HospitalViewModel hospitalViewModel; + var userInfo = UserModel(); + @override void initState() { super.initState(); @@ -49,7 +65,7 @@ class _LoginsreenState extends State { _firebaseMessaging.getToken().then((String token) async { if (DEVICE_TOKEN == "" && projectViewModel.isLogin == false) { DEVICE_TOKEN = token; - changeLoadingStata(true); + changeLoadingState(true); authService.selectDeviceImei(DEVICE_TOKEN).then((value) { print(authService.dashboardItemsList); @@ -61,30 +77,18 @@ class _LoginsreenState extends State { password: null, ))); } else { - changeLoadingStata(false); + changeLoadingState(false); } - //changeLoadingStata(false); }); } else { - changeLoadingStata(false); + changeLoadingState(false); } - - // else if (projectViewModel.isLogin) { - // getNotificationCount(token); - // } }).catchError((err) { print(err); }); } -/* - *@author: Elham Rababah - *@Date:19/4/2020 - *@param: isLoading - *@return: - *@desc: Change Isloading attribute in order to show or hide loader - */ - void changeLoadingStata(isLoading) { + void changeLoadingState(isLoading) { setState(() { _isLoading = isLoading; }); @@ -94,9 +98,11 @@ class _LoginsreenState extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); + return BaseView( onModelReady: (model) => {}, - builder: (_, model, w) => AppScaffold( + builder: (_, model, w) => + AppScaffold( baseViewModel: model, isShowAppBar: false, backgroundColor: HexColor('#F8F8F8'), @@ -118,15 +124,389 @@ class _LoginsreenState extends State { SizedBox( height: 40, ), - LoginForm( - model: model, - ), + Form( + key: loginFormKey, + child: Column( + mainAxisAlignment: MainAxisAlignment + .spaceBetween, + children: [ + Container( + width: SizeConfig + .realScreenWidth * 0.90, + height: SizeConfig + .realScreenHeight * 0.65, + child: + Column( + crossAxisAlignment: CrossAxisAlignment + .start, children: [ + buildSizedBox(), + Padding( + child: AppText( + TranslationBase + .of(context) + .enterCredentials, + fontSize: 18, + fontWeight: FontWeight + .bold, + ), + padding: EdgeInsets.only( + top: 10, bottom: 10)), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .enterId, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + labelText: '', + borderColor: Colors + .white, + textInputAction: TextInputAction + .next, + + validator: (value) { + if (value != + null && value + .isEmpty) { + return TranslationBase + .of(context) + .pleaseEnterYourID; + } + return null; + }, + onSaved: (value) { + if (value != + null) setState(() { + userInfo + .userID = + value + .trim(); + }); + }, + onChanged: (value) { + if (value != null) + setState(() { + userInfo + .userID = + value + .trim(); + }); + }, + onFieldSubmitted: ( + _) { + focusPass + .nextFocus(); + }, + ) + ])), + buildSizedBox(), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .enterPassword, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + focusNode: focusPass, + obscureText: true, + borderColor: Colors + .white, + textInputAction: TextInputAction + .next, + validator: (value) { + if (value != + null && value + .isEmpty) { + return TranslationBase + .of(context) + .pleaseEnterPassword; + } + return null; + }, + onSaved: (value) { + setState(() { + userInfo + .password = + value; + }); + + }, + onChanged: (value){ + setState(() { + userInfo + .password = + value; + }); + }, + onFieldSubmitted: ( + _) { + focusPass + .nextFocus(); + Helpers + .showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject); + }, + onTap: () { + this.getProjects( + userInfo + .userID, model); + }, + ) + ])), + buildSizedBox(), + projectsList.length > 0 + ? Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .selectYourProject, + fontWeight: FontWeight + .w600, + )), + AppTextFormField( + focusNode: focusProject, + controller: projectIdController, + borderColor: Colors + .white, + suffixIcon: Icons + .arrow_drop_down, + onTap: () { + Helpers + .showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject); + }, + validator: ( + value) { + if (value != + null && + value + .isEmpty) { + return TranslationBase + .of( + context) + .pleaseEnterYourProject; + } + return null; + }) + ])) + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .selectYourProject, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + readOnly: true, + borderColor: Colors + .white, + prefix: IconButton( + icon: Icon(Icons + .arrow_drop_down), + iconSize: 30, + padding: EdgeInsets + .only( + bottom: 30), + ), + ) + ])), + ]), + ), + Row( + mainAxisAlignment: MainAxisAlignment + .end, + children: [ + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .login, + color: HexColor( + '#D02127'), + disabled: userInfo + .userID == null || + userInfo.password == + null, + fontWeight: FontWeight + .bold, + onPressed: () { + login(context, model); + }, + )), + ], + ) + ], + ), + ) ], ) ])) - ]) + ]) : Center(child: AppLoaderWidget()), ), )); } + + SizedBox buildSizedBox() { + return SizedBox( + height: 20, + ); + } + + login(context, + IMEIViewModel model,) async { + if (loginFormKey.currentState.validate()) { + loginFormKey.currentState.save(); + GifLoaderDialogUtils.showMyDialog(context); + sharedPref.setInt(PROJECT_ID, userInfo.projectID); + await model.login(userInfo); + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + } else { + if (model.loginInfo['MessageStatus'] == 1) { + saveObjToString(LOGGED_IN_USER, model.loginInfo); + sharedPref.remove(LAST_LOGIN_USER); + sharedPref.setString(TOKEN, model.loginInfo['LogInTokenID']); + Navigator.of(AppGlobal.CONTEX).pushReplacement(MaterialPageRoute( + builder: (BuildContext context) => + VerificationMethodsScreen( + password: userInfo.password, + ))); + } + } + GifLoaderDialogUtils.hideDialog(context); + } + } + + Future setSharedPref(key, value) async { + sharedPref.setString(key, value).then((success) { + print("sharedPref.setString" + success.toString()); + }); + } + + + saveObjToString(String key, value) async { + sharedPref.setObj(key, value); + } + + onSelectProject(index) { + setState(() { + userInfo.projectID = projectsList[index]["facilityId"]; + projectIdController.text = projectsList[index]['facilityName']; + }); + + primaryFocus.unfocus(); + } + + getProjects(memberID, IMEIViewModel model) { + if (memberID != null && memberID != '') { + if (projectsList.length == 0) { + model.getHospitalsList(memberID).then((res) { + if (res['MessageStatus'] == 1) { + projectsList = res['ProjectInfo']; + setState(() { + userInfo.projectID = projectsList[0]["facilityId"]; + projectIdController.text = projectsList[0]['facilityName']; + }); + } else { + print(res); + } + }); + } + } + } } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 0ad71b76..7503a70e 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -4,13 +4,6 @@ import 'package:hexcolor/hexcolor.dart'; import '../../widgets/auth/verification_methods.dart'; -/* - *@author: Elham Rababah - *@Date:4/7/2020 - *@param: - *@return: - *@desc: Verification Methods screen - */ class VerificationMethodsScreen extends StatefulWidget { const VerificationMethodsScreen({Key key, this.password}) : super(key: key); @@ -24,14 +17,7 @@ class VerificationMethodsScreen extends StatefulWidget { class _VerificationMethodsScreenState extends State { bool _isLoading = false; - /* - *@author: Elham Rababah - *@Date:19/4/2020 - *@param: isLoading - *@return: - *@desc: Change Isloading attribute in order to show or hide loader - */ - void changeLoadingStata(isLoading) { + void changeLoadingState(isLoading) { setState(() { _isLoading = isLoading; }); @@ -50,13 +36,12 @@ class _VerificationMethodsScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // AuthHeader(loginType.verificationMethods), SizedBox( height: 50, ), VerificationMethods( password: widget.password, - changeLoadingStata: changeLoadingStata, + changeLoadingState: changeLoadingState, ), ], ), diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index fdc4e3df..284fa1ed 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -6,7 +6,7 @@ import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/hospital_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; diff --git a/lib/screens/medicine/medicine_search_screen.dart b/lib/screens/medicine/medicine_search_screen.dart index 3ce5c1be..f1bb4c7b 100644 --- a/lib/screens/medicine/medicine_search_screen.dart +++ b/lib/screens/medicine/medicine_search_screen.dart @@ -29,9 +29,9 @@ import '../../util/extenstions.dart'; DrAppSharedPreferances sharedPref = DrAppSharedPreferances(); class MedicineSearchScreen extends StatefulWidget with DrAppToastMsg { - MedicineSearchScreen({this.changeLoadingStata}); + MedicineSearchScreen({this.changeLoadingState}); - final Function changeLoadingStata; + final Function changeLoadingState; @override _MedicineSearchState createState() => _MedicineSearchState(); diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 13b7b2ae..625a31c6 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -128,6 +128,7 @@ class Helpers { } static generateContactAdminMsg([err = null]) { + //TODO: Add translation String localMsg = 'Something wrong happened, please contact the admin'; if (err != null) { localMsg = localMsg + '\n \n' + err.toString(); diff --git a/lib/widgets/auth/auth_header.dart b/lib/widgets/auth/auth_header.dart index f84e9425..47e128be 100644 --- a/lib/widgets/auth/auth_header.dart +++ b/lib/widgets/auth/auth_header.dart @@ -24,18 +24,9 @@ class AuthHeader extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Container( - // margin: SizeConfig.isMobile - // ? EdgeInsetsDirectional.fromSTEB( - // 0, SizeConfig.realScreenHeight * 0.03, 0, 0) - // : EdgeInsetsDirectional.fromSTEB( - // SizeConfig.realScreenWidth * 0.13, 0, 0, 0), - // child: buildImageLogo(), - // ), SizedBox( height: 30, ), - //buildTextUnderLogo(context), ], ), Column( @@ -67,78 +58,6 @@ class AuthHeader extends StatelessWidget { return screen; } - Image buildImageLogo() { - String img = 'assets/images/dr_app_logo.png'; - return Image.asset( - img, - fit: BoxFit.cover, - height: SizeConfig.isMobile ? null : SizeConfig.realScreenWidth * 0.09, - ); - } - - Widget buildTextUnderLogo(context) { - Widget finalWid; - double textFontSize = - SizeConfig.isMobile ? 30 : SizeConfig.textMultiplier * 3; - EdgeInsetsDirectional containerMargin; - if (userType == loginType.knownUser || userType == loginType.unknownUser) { - finalWid = Text( - TranslationBase.of(context).login, - style: TextStyle(fontSize: textFontSize, fontWeight: FontWeight.w800), - ); - } else { - String text1; - String text2; - if (userType == loginType.changePassword) { - text1 = 'Change '; - text2 = 'Password!'; - } - if (userType == loginType.verifyPassword) { - text1 = TranslationBase.of(context).verify1; - text2 = TranslationBase.of(context).yourAccount; - } - if (userType == loginType.verificationMethods) { - text1 = TranslationBase.of(context).choose; - text2 = TranslationBase.of(context).verification; - } - List childrens = [ - Text( - text1, - style: TextStyle(fontSize: textFontSize, fontWeight: FontWeight.w800), - ), - Text( - text2, - style: TextStyle( - color: HexColor('#B8382C'), - fontSize: textFontSize, - fontWeight: FontWeight.w800), - ) - ]; - - if (!SizeConfig.isMobile) { - finalWid = Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: childrens, - ); - } else { - finalWid = Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: childrens, - ); - } - } - if (!SizeConfig.isMobile) { - double start = SizeConfig.realScreenWidth * 0.13; - if (loginType.verifyPassword == userType || - loginType.changePassword == userType || - userType == loginType.verificationMethods) { - start = 0; - } - containerMargin = EdgeInsetsDirectional.fromSTEB(start, 0, 0, 0); - } - - return Container(margin: containerMargin, child: finalWid); - } Container buildDrAppContainer(BuildContext context) { if (userType == loginType.changePassword || @@ -147,10 +66,6 @@ class AuthHeader extends StatelessWidget { return Container(); } return Container( - // margin: SizeConfig.isMobile - // ? null - // : EdgeInsetsDirectional.fromSTEB( - // SizeConfig.realScreenWidth * 0.13, 0, 0, 0), child: Text( "Doctor App", style: TextStyle( diff --git a/lib/widgets/auth/change_password.dart b/lib/widgets/auth/change_password.dart deleted file mode 100644 index 3eb9b975..00000000 --- a/lib/widgets/auth/change_password.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -class ChangePassword extends StatelessWidget { - final changePassFormKey = GlobalKey(); - var changePassFormValues = { - 'currentPass': null, - 'newPass': null, - 'repeatedPass': null - }; - - @override - Widget build(BuildContext context) { - return Form( - key: changePassFormKey, - child: Container( - width: SizeConfig.realScreenWidth * 0.90, - child: - Column(crossAxisAlignment: CrossAxisAlignment.start, children: < - Widget>[ - buildSizedBox(), - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - // ts/images/password_icon.png - prefixIcon: Image.asset('assets/images/password_icon.png'), - hintText: 'Current Password', - hintStyle: - TextStyle(fontSize: 2 * SizeConfig.textMultiplier), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(20)), - borderSide: BorderSide(color: HexColor('#CCCCCC')), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: - BorderSide(color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), - validator: (value) { - if (value.isEmpty) { - return 'Please enter your Current Password'; - } - return null; - }, - onSaved: (value) { - // changePassFormValues. = value; - }, - ), - buildSizedBox(40), - // buildSizedBox(), - Text( - "New Password", - style: TextStyle( - fontSize: 2.8 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w800), - ), - buildSizedBox(10.0), - // Text() - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - // ts/images/password_icon.png - prefixIcon: Image.asset('assets/images/password_icon.png'), - hintText: 'New Password', - hintStyle: - TextStyle(fontSize: 2 * SizeConfig.textMultiplier), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(20)), - borderSide: BorderSide(color: HexColor('#CCCCCC')), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: - BorderSide(color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), - validator: (value) { - if (value.isEmpty) { - return 'Please enter your New Password'; - } - return null; - }, - onSaved: (value) { - // userInfo.UserID = value; - }, - ), - buildSizedBox(), - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - prefixIcon: Image.asset('assets/images/password_icon.png'), - hintText: 'Repeat Password', - hintStyle: - TextStyle(fontSize: 2 * SizeConfig.textMultiplier), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(20)), - borderSide: BorderSide(color: HexColor('#CCCCCC')), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: - BorderSide(color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), - validator: (value) { - if (value.isEmpty) { - return 'Please enter your Repeat Password'; - } - return null; - }, - onSaved: (value) { - // userInfo.UserID = value; - }, - ), - buildSizedBox(), - RaisedButton( - onPressed:changePass, - elevation: 0.0, - child: Container( - width: double.infinity, - height: 50, - child: Center( - child: Text( - 'Change Password' - .toUpperCase(), - // textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: 2.5 * SizeConfig.textMultiplier), - ), - ), - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(width: 0.5, color: HexColor('#CCCCCC'))), - ), - SizedBox( - height: 10, - ), - ]))); - } - - SizedBox buildSizedBox([double height = 20]) { - return SizedBox( - height: height, - ); - } - changePass(){ - if(changePassFormKey.currentState.validate()){ - changePassFormKey.currentState.save(); - // call Api - } - } -} diff --git a/lib/widgets/auth/known_user_login.dart b/lib/widgets/auth/known_user_login.dart deleted file mode 100644 index cbf3c71a..00000000 --- a/lib/widgets/auth/known_user_login.dart +++ /dev/null @@ -1,328 +0,0 @@ -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:local_auth/error_codes.dart' as auth_error; -import 'package:local_auth/local_auth.dart'; -import 'package:provider/provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -import '../../config/size_config.dart'; -import '../../core/viewModel/auth_view_model.dart'; -import '../../routes.dart'; -import '../../util/dr_app_shared_pref.dart'; -import '../../util/dr_app_toast_msg.dart'; -import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart'; - -DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - -class KnownUserLogin extends StatefulWidget { - @override - _KnownUserLoginState createState() => _KnownUserLoginState(); -} - -class _KnownUserLoginState extends State { - Future _prefs = SharedPreferences.getInstance(); - final LocalAuthentication auth = LocalAuthentication(); - - String _authorized = "not Authorized"; - bool _isAuthenticating = false; - Future _loggedUserFuture; - var _loggedUser; - int _loginType = 1; - String _platformImei; - Future _loginTypeFuture; - - Map _loginTypeMap = { - 1: { - "name": "SMS", - 'imageUrl': 'assets/images/verification_sms_lg_icon.png', - }, - 2: { - "name": "FingerPrint", - 'imageUrl': 'assets/images/verification_fingerprint_lg_icon.png' - }, - 3: { - "name": "Face", - 'imageUrl': 'assets/images/verification_faceid_lg_icon.png' - }, - 4: { - "name": "WhatsApp", - 'imageUrl': 'assets/images/verification_whatsapp_lg_icon.png' - } - }; - - Future getSharedPref() async { - sharedPref.getObj(LOGGED_IN_USER).then((userInfo) { - _loggedUser = userInfo; - }); - sharedPref.getString('platformImei').then((imei) { - _platformImei = imei; - }); - } - - @override - void initState() { - super.initState(); - _loggedUserFuture = getSharedPref(); - } - - @override - Widget build(BuildContext context) { - AuthViewModel authProv = Provider.of(context); - // var imeiModel = {'IMEI': _platformImei}; - // _loginTypeFuture = authProv.selectDeviceImei(imeiModel); - return FutureBuilder( - future: Future.wait([_loggedUserFuture, _loginTypeFuture]), - builder: (BuildContext context, AsyncSnapshot snapshot) { - _loginTypeFuture.then((res) { - _loginType = - 2; //res['SELECTDeviceIMEIbyIMEI_List'][0]['LogInType']; - }).catchError((err) { - print('${err}'); - DrAppToastMsg.showErrorToast(err); - }); - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return DrAppCircularProgressIndeicator(); - default: - if (snapshot.hasError) { - DrAppToastMsg.showErrorToast('Error: ${snapshot.error}'); - return Text('Error: ${snapshot.error}'); - } else { - return Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Stack(children: [ - Container( - decoration: BoxDecoration( - border: Border.all( - color: HexColor('#CCCCCC'), - ), - borderRadius: BorderRadius.circular(50)), - margin: const EdgeInsets.fromLTRB(0, 20.0, 30, 0), - child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - height: 100, - width: 100, - decoration: new BoxDecoration( - // color: Colors.green, // border color - shape: BoxShape.circle, - border: - Border.all(color: HexColor('#CCCCCC'))), - child: CircleAvatar( - child: Image.asset( - 'assets/images/dr_avatar.png', - fit: BoxFit.cover, - ), - )), - Container( - margin: EdgeInsets.symmetric( - vertical: 3, horizontal: 15), - child: Column( - // mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _loggedUser['List_MemberInformation'][0] - ['MemberName'], - style: TextStyle( - color: HexColor('515A5D'), - fontSize: - 2.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w800), - ), - Text( - 'ENT Spec', - style: TextStyle( - color: HexColor('515A5D'), - fontSize: - 1.5 * SizeConfig.textMultiplier), - ) - ], - ), - ) - ], - ), - ), - Positioned( - top: 7, - right: 70, - child: Image.asset( - 'assets/images/close_icon.png', - fit: BoxFit.cover, - )) - ]), - buildVerificationTypeImageContainer(), - buildButtonsContainer(context) - ], - ); - } - } - }); - } - - Container buildVerificationTypeImageContainer() { - print('${_loginTypeMap[_loginType]}'); - return Container( - height: 200, - width: 200, - child: Center( - child: Image.asset( - _loginTypeMap[_loginType]['imageUrl'], - fit: BoxFit.cover, - ), - )); - } - - // - Container buildButtonsContainer(BuildContext context) { - return Container( - margin: EdgeInsetsDirectional.fromSTEB(0, 0, 30, 0), - width: double.infinity, - child: Column( - children: [ - RaisedButton( - onPressed: _authenticate, - elevation: 0.0, - child: Container( - width: double.infinity, - height: 50, - child: Center( - child: Text( - "Verify using ${_loginTypeMap[_loginType]['name']}" - .toUpperCase(), - // textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: 2.5 * SizeConfig.textMultiplier), - ), - ), - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide(width: 0.5, color: HexColor('#CCCCCC'))), - ), - SizedBox( - height: 10, - ), - Container( - width: double.infinity, - height: 50, - child: FlatButton( - onPressed: () { - navigateToMoreOption(); - }, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide( - width: 1, color: Theme.of(context).primaryColor)), - child: Text( - "More verification Options".toUpperCase(), - style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 2.5 * SizeConfig.textMultiplier), - )), - ), - SizedBox( - height: 20, - ), - ], - ), - ); - } - - navigateToMoreOption() { - Navigator.of(context).pushNamed(VERIFICATION_METHODS); - } - - _authenticate() { - if (_loginType == 1) { - _authenticateBySMS(); - } - if (_loginType == 2) { - _authenticateByFingerPrint(); - } - if (_loginType == 3) { - _authenticateByFace(); - } - if (_loginType == 4) { - _authenticateByWhatsApp(); - } - } - - Future _authenticateByFingerPrint() async { - _getAvailableBiometrics(); - bool authenticated = false; - try { - setState(() { - _isAuthenticating = true; - _authorized = 'Authenticating'; - }); - authenticated = await auth.authenticateWithBiometrics( - localizedReason: 'Scan your fingerprint to authenticate', - useErrorDialogs: true, - stickyAuth: false); - setState(() { - _isAuthenticating = false; - _authorized = 'Authenticating'; - }); - } on PlatformException catch (e) { - print(e); - } - if (!mounted) return; - - final String message = authenticated ? 'Authorized' : 'Not Authorized'; - if (message == 'Authorized') { - navigateToHome(); - } - setState(() { - print('_authorized' + _authorized); - _authorized = message; - print('_authorized' + _authorized); - }); - } - - Future _authenticateBySMS() { - print('_authenticateBySMS'); - } - - Future _authenticateByFace() { - print('_authenticateByFace'); - } - - Future _authenticateByWhatsApp() { - print('_authenticateByWhatsApp'); - } - - Future _getAvailableBiometrics() async { - List availableBiometrics; - try { - availableBiometrics = await auth.getAvailableBiometrics(); - } on PlatformException catch (e) { - print(e); - if (e.code == auth_error.notAvailable) { - showErorrMsg("Auth Methods Not Available"); - } else if (e.code == auth_error.passcodeNotSet) { - showErorrMsg("Auth Methods Not passcodeNotSet"); - } else if (e.code == auth_error.permanentlyLockedOut) { - showErorrMsg("Auth Methods Not permanentlyLockedOut"); - } - } - if (!mounted) return; - - setState(() { - print('availableBiometrics $availableBiometrics'); - }); - } - - navigateToHome() { - Navigator.of(context).pushReplacementNamed(HOME); - } - - showErorrMsg(localMsg) { - DrAppToastMsg.showErrorToast(localMsg); - } -} diff --git a/lib/widgets/auth/login_form.dart b/lib/widgets/auth/login_form.dart deleted file mode 100644 index a2c200cb..00000000 --- a/lib/widgets/auth/login_form.dart +++ /dev/null @@ -1,312 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; -import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; - -import '../../config/shared_pref_kay.dart'; -import '../../config/size_config.dart'; -import '../../core/viewModel/hospital_view_model.dart'; -import '../../models/doctor/user_model.dart'; -import '../../util/dr_app_shared_pref.dart'; -import '../../util/dr_app_toast_msg.dart'; -import '../../util/helpers.dart'; - -DrAppSharedPreferances sharedPref = DrAppSharedPreferances(); -DrAppToastMsg toastMsg = DrAppToastMsg(); -Helpers helpers = Helpers(); - -class LoginForm extends StatefulWidget with DrAppToastMsg { - LoginForm({this.model}); - - final IMEIViewModel model; - - @override - _LoginFormState createState() => _LoginFormState(); -} - -class _LoginFormState extends State { - final loginFormKey = GlobalKey(); - var projectIdController = TextEditingController(); - var projectsList = []; - FocusNode focusPass = FocusNode(); - FocusNode focusProject = FocusNode(); - HospitalViewModel projectsProv; - var userInfo = UserModel(); - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - projectsProv = Provider.of(context); - return Form( - key: loginFormKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: SizeConfig.realScreenWidth * 0.90, - height: SizeConfig.realScreenHeight * 0.65, - child: - Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - buildSizedBox(), - Padding( - child: AppText( - TranslationBase.of(context).enterCredentials, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - padding: EdgeInsets.only(top: 10, bottom: 10)), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 10, top: 10), - child: AppText( - TranslationBase.of(context).enterId, - fontWeight: FontWeight.w800, - fontSize: 14, - )), - AppTextFormField( - labelText: '', - borderColor: Colors.white, - // keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - - validator: (value) { - if (value != null && value.isEmpty) { - return TranslationBase.of(context) - .pleaseEnterYourID; - } - return null; - }, - onSaved: (value) { - if (value != null) userInfo.userID = value.trim(); - }, - onChanged: (value) { - if (value != null) userInfo.userID = value.trim(); - }, - onFieldSubmitted: (_) { - focusPass.nextFocus(); - }, - ) - ])), - buildSizedBox(), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 10, top: 10), - child: AppText( - TranslationBase.of(context).enterPassword, - fontWeight: FontWeight.w800, - fontSize: 14, - )), - AppTextFormField( - focusNode: focusPass, - obscureText: true, - borderColor: Colors.white, - textInputAction: TextInputAction.next, - validator: (value) { - if (value != null && value.isEmpty) { - return TranslationBase.of(context) - .pleaseEnterPassword; - } - return null; - }, - onSaved: (value) { - userInfo.password = value; - }, - onFieldSubmitted: (_) { - focusPass.nextFocus(); - Helpers.showCupertinoPicker(context, projectsList, - 'facilityName', onSelectProject); - }, - onTap: () { - this.getProjects(userInfo.userID); - }, - ) - ])), - buildSizedBox(), - projectsList.length > 0 - ? Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 10, top: 10), - child: AppText( - TranslationBase.of(context).selectYourProject, - fontWeight: FontWeight.w600, - )), - AppTextFormField( - focusNode: focusProject, - controller: projectIdController, - borderColor: Colors.white, - suffixIcon: Icons.arrow_drop_down, - onTap: () { - Helpers.showCupertinoPicker( - context, - projectsList, - 'facilityName', - onSelectProject); - }, - validator: (value) { - if (value != null && value.isEmpty) { - return TranslationBase.of(context) - .pleaseEnterYourProject; - } - return null; - }) - ])) - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 10, top: 10), - child: AppText( - TranslationBase.of(context).selectYourProject, - fontWeight: FontWeight.w800, - fontSize: 14, - )), - AppTextFormField( - readOnly: true, - borderColor: Colors.white, - prefix: IconButton( - icon: Icon(Icons.arrow_drop_down), - iconSize: 30, - padding: EdgeInsets.only(bottom: 30), - ), - ) - ])), - ]), - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).login, - color: HexColor('#D02127'), - fontWeight: FontWeight.bold, - onPressed: () { - login(context, this.widget.model); - }, - )), - ], - ) - ], - ), - ); - //)); - } - - SizedBox buildSizedBox() { - return SizedBox( - height: 20, - ); - } - - login( - context, - model, - ) { - if (loginFormKey.currentState.validate()) { - loginFormKey.currentState.save(); - sharedPref.setInt(PROJECT_ID, userInfo.projectID); - model.login(userInfo).then((res) { - if (model.loginInfo['MessageStatus'] == 1) { - saveObjToString(LOGGED_IN_USER, model.loginInfo); - sharedPref.remove(LAST_LOGIN_USER); - sharedPref.setString(TOKEN, model.loginInfo['LogInTokenID']); - Navigator.of(AppGlobal.CONTEX).pushReplacement(MaterialPageRoute( - builder: (BuildContext context) => VerificationMethodsScreen( - password: userInfo.password, - ))); - } - }); - } - } - - Future setSharedPref(key, value) async { - sharedPref.setString(key, value).then((success) { - print("sharedPref.setString" + success.toString()); - }); - } - - getProjectsList(memberID) { - projectsProv.getProjectsList(memberID).then((res) { - if (res['MessageStatus'] == 1) { - projectsList = res['ProjectInfo']; - setState(() { - userInfo.projectID = projectsList[0]["facilityId"]; - projectIdController.text = projectsList[0]['facilityName']; - }); - } else { - print(res); - } - }); - } - - saveObjToString(String key, value) async { - sharedPref.setObj(key, value); - } - - onSelectProject(index) { - setState(() { - userInfo.projectID = projectsList[index]["facilityId"]; - projectIdController.text = projectsList[index]['facilityName']; - }); - - primaryFocus.unfocus(); - } - - getProjects(value) { - if (value != null && value != '') { - if (projectsList.length == 0) { - getProjectsList(value); - } - } - } -} diff --git a/lib/widgets/auth/show_timer_text.dart b/lib/widgets/auth/show_timer_text.dart deleted file mode 100644 index a418e1b5..00000000 --- a/lib/widgets/auth/show_timer_text.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'dart:async'; - -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; -import 'package:doctor_app_flutter/routes.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; -Helpers helpers = Helpers(); - -class ShowTimerText extends StatefulWidget { - ShowTimerText({Key key, this.model}); - final model; - - @override - _ShowTimerTextState createState() => _ShowTimerTextState(); -} - -class _ShowTimerTextState extends State { - String timerText = (TIMER_MIN - 1).toString() + ':59'; - int min = TIMER_MIN - 1; - int sec = 59; - Timer _timer; - - AuthViewModel authProv; - - resendCode() { - min = TIMER_MIN - 1; - sec = 59; - _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) { - if (min <= 0 && sec <= 0) { - timer.cancel(); - } else { - setState(() { - sec = sec - 1; - if (sec == 0 && min == 0) { - Navigator.of(context).pushNamed(LOGIN); - - min = 0; - sec = 0; - } else if (sec == 0) { - min = min - 1; - sec = 59; - } - timerText = min.toString() + ':' + sec.toString(); - }); - } - }); - } - - @override - void initState() { - super.initState(); - resendCode(); - } - - @override - void dispose() { - _timer.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - authProv = Provider.of(context); - return Center( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InkWell( - onTap: min != 0 || sec != 0 - ? null - : () { - resendActivatioinCode(); - }, - child: Text( - timerText, - style: TextStyle( - fontSize: 3.0 * SizeConfig.textMultiplier, - color: HexColor('#B8382C'), - fontWeight: FontWeight.bold), - ), - ), - ], - ), - ); - } - - resendActivatioinCode() { - authProv - .sendActivationCodeByOtpNotificationType(widget.model) - .then((res) => { - // print('$value') - if (res['MessageStatus'] == 1) - {resendCode()} - else - {Helpers.showErrorToast(res['ErrorEndUserMessage'])} - }) - .catchError((err) { - Helpers.showErrorToast(); - }); - } -} diff --git a/lib/widgets/auth/verfiy_account.dart b/lib/widgets/auth/verfiy_account.dart deleted file mode 100644 index 1574d3d4..00000000 --- a/lib/widgets/auth/verfiy_account.dart +++ /dev/null @@ -1,386 +0,0 @@ -import 'dart:async'; - -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; -import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/auth/show_timer_text.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; - -import '../../config/size_config.dart'; -import '../../core/viewModel/auth_view_model.dart'; -import '../../routes.dart'; -import '../../util/dr_app_shared_pref.dart'; -import '../../util/dr_app_toast_msg.dart'; -import '../../util/helpers.dart'; -import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart'; - -DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); -Helpers helpers = Helpers(); - -class VerifyAccount extends StatefulWidget { - VerifyAccount({this.changeLoadingStata}); - - final Function changeLoadingStata; - - @override - _VerifyAccountState createState() => _VerifyAccountState(); -} - -class _VerifyAccountState extends State { - final verifyAccountForm = GlobalKey(); - Map verifyAccountFormValue = { - 'digit1': null, - 'digit2': null, - 'digit3': null, - 'digit4': null, - }; - Future _loggedUserFuture; - var _loggedUser; - AuthViewModel authProv; - bool _isInit = true; - var model; - TextEditingController digit1 = TextEditingController(text: ""); - TextEditingController digit2 = TextEditingController(text: ""); - TextEditingController digit3 = TextEditingController(text: ""); - TextEditingController digit4 = TextEditingController(text: ""); - - @override - void initState() { - super.initState(); - _loggedUserFuture = getSharedPref(); - } - - Future getSharedPref() async { - sharedPref.getObj(LOGGED_IN_USER).then((userInfo) { - _loggedUser = userInfo; - }); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - if (_isInit) { - authProv = Provider.of(context); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - model = routeArgs['model']; - } - _isInit = false; - } - - @override - Widget build(BuildContext context) { - authProv = Provider.of(context); - final focusD1 = FocusNode(); - final focusD2 = FocusNode(); - final focusD3 = FocusNode(); - final focusD4 = FocusNode(); - return FutureBuilder( - future: Future.wait([_loggedUserFuture]), - builder: (BuildContext context, AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return DrAppCircularProgressIndeicator(); - default: - if (snapshot.hasError) { - DrAppToastMsg.showErrorToast('Error: ${snapshot.error}'); - return Text('Error: ${snapshot.error}'); - } else { - return Form( - key: verifyAccountForm, - child: Container( - width: SizeConfig.realScreenWidth * 0.95, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildSizedBox(30), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: [ - Container( - width: SizeConfig.realScreenWidth * 0.20, - child: TextFormField( - textInputAction: TextInputAction.next, - style: buildTextStyle(), - autofocus: true, - maxLength: 1, - controller: digit1, - textAlign: TextAlign.center, - keyboardType: TextInputType.number, - decoration: buildInputDecoration(context), - onSaved: (val) { - verifyAccountFormValue['digit1'] = val; - }, - validator: validateCodeDigit, - onFieldSubmitted: (_) { - FocusScope.of(context) - .requestFocus(focusD2); - }, - onChanged: (val) { - if (val.length == 1) { - FocusScope.of(context) - .requestFocus(focusD2); - } - }, - ), - ), - Container( - width: SizeConfig.realScreenWidth * 0.20, - child: TextFormField( - focusNode: focusD2, - controller: digit2, - textInputAction: TextInputAction.next, - maxLength: 1, - textAlign: TextAlign.center, - style: buildTextStyle(), - keyboardType: TextInputType.number, - decoration: - buildInputDecoration(context), - onSaved: (val) { - verifyAccountFormValue['digit2'] = - val; - }, - onFieldSubmitted: (_) { - FocusScope.of(context) - .requestFocus(focusD3); - }, - onChanged: (val) { - if (val.length == 1) { - FocusScope.of(context) - .requestFocus(focusD3); - } - }, - validator: validateCodeDigit), - ), - Container( - width: SizeConfig.realScreenWidth * 0.20, - child: TextFormField( - focusNode: focusD3, - controller: digit3, - textInputAction: TextInputAction.next, - maxLength: 1, - textAlign: TextAlign.center, - style: buildTextStyle(), - keyboardType: TextInputType.number, - decoration: - buildInputDecoration(context), - onSaved: (val) { - verifyAccountFormValue['digit3'] = - val; - }, - onFieldSubmitted: (_) { - FocusScope.of(context) - .requestFocus(focusD4); - }, - onChanged: (val) { - if (val.length == 1) { - FocusScope.of(context) - .requestFocus(focusD4); - } - }, - validator: validateCodeDigit)), - Container( - width: SizeConfig.realScreenWidth * 0.20, - child: TextFormField( - focusNode: focusD4, - controller: digit4, - maxLength: 1, - textAlign: TextAlign.center, - style: buildTextStyle(), - keyboardType: TextInputType.number, - decoration: - buildInputDecoration(context), - onSaved: (val) { - verifyAccountFormValue['digit4'] = - val; - }, - validator: validateCodeDigit)) - ], - ), - buildSizedBox(20), - buildText(), - buildSizedBox(40), - RaisedButton( - onPressed: () { - verifyAccount( - authProv, widget.changeLoadingStata); - }, - elevation: 0.0, - child: Container( - width: double.infinity, - height: 50, - child: Center( - child: Text( - TranslationBase.of(context).verify, - style: TextStyle( - color: Colors.white, - fontSize: - 3 * SizeConfig.textMultiplier), - ), - ), - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: BorderSide( - width: 0.5, - color: HexColor('#CCCCCC'))), - ), - buildSizedBox(20), - ShowTimerText(model: model), - buildSizedBox(10), - ]))); - } - } - }); - } - - TextStyle buildTextStyle() { - return TextStyle( - fontSize: SizeConfig.textMultiplier * 3, - ); - } - - String validateCodeDigit(value) { - if (value.isEmpty) { - return 'Please enter your Password'; - } - - return null; - } - - InputDecoration buildInputDecoration(BuildContext context) { - return InputDecoration( - contentPadding: EdgeInsets.only(top: 30, bottom: 30), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10)), - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).primaryColor), - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).errorColor), - ), - ); - } - - RichText buildText() { - String medthodName; - switch (model['OTP_SendType']) { - case 1: - medthodName = TranslationBase.of(context).smsBy; - break; - case 2: - medthodName = TranslationBase.of(context).whatsAppBy; - break; - default: - } - var text = RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 3.0 * SizeConfig.textMultiplier, color: Colors.black), - children: [ - new TextSpan(text: TranslationBase.of(context).youWillReceiveA), - new TextSpan( - text: TranslationBase.of(context).loginCode, - style: TextStyle(fontWeight: FontWeight.w700)), - new TextSpan(text: ' ${medthodName},'), - TextSpan(text: TranslationBase.of(context).pleaseEnterTheCode) - ])); - return text; - } - - SizedBox buildSizedBox([double height = 20]) { - return SizedBox( - height: height, - ); - } - - verifyAccount(AuthViewModel authProv, Function changeLoadingStata) async { - if (verifyAccountForm.currentState.validate()) { - changeLoadingStata(true); - - verifyAccountForm.currentState.save(); - final activationCode = verifyAccountFormValue['digit1'] + - verifyAccountFormValue['digit2'] + - verifyAccountFormValue['digit3'] + - verifyAccountFormValue['digit4']; - - CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = - new CheckActivationCodeRequestModel( - zipCode: _loggedUser['ZipCode'], - mobileNumber: _loggedUser['MobileNumber'], - projectID: await sharedPref.getInt(PROJECT_ID), - logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), - activationCode: activationCode, - generalid: "Cs2020@2016\$2958"); - - authProv - .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp) - .then((res) async { - if (res['MessageStatus'] == 1) { - sharedPref.setString(TOKEN, res['AuthenticationTokenID']); - if (res['List_DoctorProfile'] != null) { - loginProcessCompleted( - res['List_DoctorProfile'][0], changeLoadingStata); - } else { - ClinicModel clinic = - ClinicModel.fromJson(res['List_DoctorsClinic'][0]); - getDocProfiles(clinic, changeLoadingStata); - } - } else { - changeLoadingStata(false); - Helpers.showErrorToast(res['ErrorEndUserMessage']); - } - }).catchError((err) { - changeLoadingStata(false); - Helpers.showErrorToast(err); - }); - } - } - - loginProcessCompleted( - Map profile, Function changeLoadingStata) { - var doctor = DoctorProfileModel.fromJson(profile); - authProv.setDoctorProfile(doctor); - sharedPref.setObj(DOCTOR_PROFILE, profile); - this.getDashboard(doctor, changeLoadingStata); - } - - getDashboard(doctor, Function changeLoadingStata) { - changeLoadingStata(false); - Navigator.of(context).pushReplacementNamed(HOME); - } - - getDocProfiles(ClinicModel clinicInfo, Function changeLoadingStata) { - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: clinicInfo.doctorID, - clinicID: clinicInfo.clinicID, - license: true, - projectID: clinicInfo.projectID, - tokenID: '', - languageID: 2); - authProv.getDocProfiles(docInfo.toJson()).then((res) { - if (res['MessageStatus'] == 1) { - loginProcessCompleted(res['DoctorProfileList'][0], changeLoadingStata); - } else { - changeLoadingStata(false); - Helpers.showErrorToast(res['ErrorEndUserMessage']); - } - }).catchError((err) { - changeLoadingStata(false); - Helpers.showErrorToast(err); - }); - } -} diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 48d93f54..91d80a71 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -34,18 +34,11 @@ import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); -/* - *@author: Elham Rababah - *@Date:4/7/2020 - *@param: - *@return: - *@desc: Verification Methods widget - */ class VerificationMethods extends StatefulWidget { - VerificationMethods({this.changeLoadingStata, this.password}); + VerificationMethods({this.changeLoadingState, this.password}); final password; - final Function changeLoadingStata; + final Function changeLoadingState; @override _VerificationMethodsState createState() => _VerificationMethodsState(); @@ -62,7 +55,6 @@ class _VerificationMethodsState extends State { ProjectViewModel projectsProvider; var isMoreOption = false; var onlySMSBox = false; - static BuildContext _context; var loginTokenID; bool authenticated; @@ -254,11 +246,6 @@ class _VerificationMethodsState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ - // Expanded( - // child: - // getButton(3, authProv)), - // Expanded( - // child: getButton(4, authProv)) Expanded( child: InkWell( onTap: () => { @@ -343,7 +330,7 @@ class _VerificationMethodsState extends State { oTPSendType, AuthViewModel authProv) async { // TODO : build enum for verfication method if (oTPSendType == 1 || oTPSendType == 2) { - widget.changeLoadingStata(true); + widget.changeLoadingState(true); int projectID = await sharedPref.getInt(PROJECT_ID); ActivationCodeModel activationCodeModel = ActivationCodeModel( facilityId: projectID, @@ -371,7 +358,7 @@ class _VerificationMethodsState extends State { } }).catchError((err) { print('$err'); - widget.changeLoadingStata(false); + widget.changeLoadingState(false); Helpers.showErrorToast(); }); @@ -393,9 +380,7 @@ class _VerificationMethodsState extends State { sendActivationCodeVerificationScreen( oTPSendType, AuthViewModel authProv) async { - // TODO : build enum for verfication method - //if (oTPSendType == 1 || oTPSendType == 2) { - widget.changeLoadingStata(true); + widget.changeLoadingState(true); ActivationCodeModel2 activationCodeModel = ActivationCodeModel2( iMEI: user.iMEI, facilityId: user.projectID, @@ -418,7 +403,7 @@ class _VerificationMethodsState extends State { VIDA_REFRESH_TOKEN_ID, res["VidaRefreshTokenID"]); sharedPref.setString(LOGIN_TOKEN_ID, res["LogInTokenID"]); if (oTPSendType == 1 || oTPSendType == 2) { - widget.changeLoadingStata(false); + widget.changeLoadingState(false); this.startSMSService(oTPSendType, authProv); } else { checkActivationCode(authProv); @@ -429,7 +414,7 @@ class _VerificationMethodsState extends State { } }).catchError((err) { print('$err'); - widget.changeLoadingStata(false); + widget.changeLoadingState(false); Helpers.showErrorToast(); }); @@ -557,12 +542,6 @@ class _VerificationMethodsState extends State { } }, child: - // RoundedContainer( - // backgroundColor: checkIfBiometricAvailable(BiometricType.face) - // ? Colors.white - // : Colors.white.withOpacity(.7), - // borderColor: Colors.grey, - // showBorder: false, Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), @@ -601,9 +580,6 @@ class _VerificationMethodsState extends State { }) }, child: Container( - // backgroundColor: Colors.white, - // borderColor: Colors.grey, - // showBorder: false, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.white, @@ -630,7 +606,6 @@ class _VerificationMethodsState extends State { TranslationBase.of(context).moreVerification, fontSize: 14, fontWeight: FontWeight.w600, - // textAlign: TextAlign.center, ) ], ), @@ -743,7 +718,7 @@ class _VerificationMethodsState extends State { this.checkActivationCode(authProv, value: value); }, () => { - widget.changeLoadingStata(false), + widget.changeLoadingState(false), print('Faild..'), }, ).displayDialog(context); @@ -798,7 +773,7 @@ class _VerificationMethodsState extends State { authProv .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp) .then((res) async { - widget.changeLoadingStata(false); + widget.changeLoadingState(false); if (res['MessageStatus'] == 1) { sharedPref.setString(TOKEN, res['AuthenticationTokenID']); if (res['List_DoctorProfile'] != null) { @@ -846,11 +821,11 @@ class _VerificationMethodsState extends State { if (res['MessageStatus'] == 1) { loginProcessCompleted(res['DoctorProfileList'][0], authProv); } else { - // changeLoadingStata(false); + // changeLoadingState(false); Helpers.showErrorToast(res['ErrorEndUserMessage']); } }).catchError((err) { - // changeLoadingStata(false); + // changeLoadingState(false); Helpers.showErrorToast(err); }); } From c72ef3f58569cefd27cb685a076c847c9065c82c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 3 May 2021 17:16:29 +0300 Subject: [PATCH 002/241] finish refactoring login --- lib/screens/auth/login_screen.dart | 31 ++++++++++++++++-------------- lib/screens/home/home_screen.dart | 2 -- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index b49b492f..1d27e31e 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -270,6 +270,8 @@ class _LoginsreenState extends State { return null; }, onSaved: (value) { + if (value != + null) setState(() { userInfo .password = @@ -278,6 +280,8 @@ class _LoginsreenState extends State { }, onChanged: (value){ + if (value != + null) setState(() { userInfo .password = @@ -456,19 +460,21 @@ class _LoginsreenState extends State { await model.login(userInfo); if (model.state == ViewState.ErrorLocal) { Helpers.showErrorToast(model.error); + } else { if (model.loginInfo['MessageStatus'] == 1) { saveObjToString(LOGGED_IN_USER, model.loginInfo); sharedPref.remove(LAST_LOGIN_USER); sharedPref.setString(TOKEN, model.loginInfo['LogInTokenID']); - Navigator.of(AppGlobal.CONTEX).pushReplacement(MaterialPageRoute( + GifLoaderDialogUtils.hideDialog(context); + + Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (BuildContext context) => VerificationMethodsScreen( password: userInfo.password, ))); } } - GifLoaderDialogUtils.hideDialog(context); } } @@ -492,20 +498,17 @@ class _LoginsreenState extends State { primaryFocus.unfocus(); } - getProjects(memberID, IMEIViewModel model) { + getProjects(memberID, IMEIViewModel model)async { if (memberID != null && memberID != '') { if (projectsList.length == 0) { - model.getHospitalsList(memberID).then((res) { - if (res['MessageStatus'] == 1) { - projectsList = res['ProjectInfo']; - setState(() { - userInfo.projectID = projectsList[0]["facilityId"]; - projectIdController.text = projectsList[0]['facilityName']; - }); - } else { - print(res); - } - }); + await model.getHospitalsList(memberID); + if(model.state == ViewState.Idle) { + projectsList = model.hospitals; + setState(() { + userInfo.projectID = projectsList[0]["facilityId"]; + projectIdController.text = projectsList[0]['facilityName']; + }); + } } } } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 1ecbe637..1fc4c795 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -61,7 +61,6 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); - HospitalViewModel hospitalProvider; AuthViewModel authProvider; bool isLoading = false; ProjectViewModel projectsProvider; @@ -108,7 +107,6 @@ class _HomeScreenState extends State { @override Widget build(BuildContext context) { myContext = context; - hospitalProvider = Provider.of(context); authProvider = Provider.of(context); projectsProvider = Provider.of(context); FocusScopeNode currentFocus = FocusScope.of(context); From 916c1266caaf9815d9328e2814a65469ca1bf59e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 4 May 2021 11:40:14 +0300 Subject: [PATCH 003/241] refactoring home screen --- lib/core/viewModel/dashboard_view_model.dart | 28 +++- .../home/dashboard_slider-item-widget.dart | 37 +++++ lib/screens/home/home_screen.dart | 157 +++--------------- 3 files changed, 83 insertions(+), 139 deletions(-) create mode 100644 lib/screens/home/dashboard_slider-item-widget.dart diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index fede0793..7c6748a5 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -1,12 +1,18 @@ +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/dasboard_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import '../../locator.dart'; import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { DashboardService _dashboardService = locator(); - get dashboardItemsList => _dashboardService.dashboardItemsList; + + List get dashboardItemsList => + _dashboardService.dashboardItemsList; Future getDashboard() async { setState(ViewState.Busy); @@ -17,4 +23,24 @@ class DashboardViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future changeClinic(int clinicId, AuthViewModel authProvider) async { + setState(ViewState.BusyLocal); + await getDoctorProfile(); + ProfileReqModel docInfo = new ProfileReqModel( + doctorID: doctorProfile.doctorID, + clinicID: clinicId, + license: true, + projectID: doctorProfile.projectID, + tokenID: '', + languageID: 2); + + await authProvider.getDocProfiles(docInfo.toJson()).then((res) async { + sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); + setState(ViewState.Idle); + }).catchError((err) { + error = err; + setState(ViewState.ErrorLocal); + }); + } } diff --git a/lib/screens/home/dashboard_slider-item-widget.dart b/lib/screens/home/dashboard_slider-item-widget.dart new file mode 100644 index 00000000..9a42b4b6 --- /dev/null +++ b/lib/screens/home/dashboard_slider-item-widget.dart @@ -0,0 +1,37 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/activity_button.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class DashboardSliderItemWidget extends StatelessWidget { + final DashboardModel item; + + DashboardSliderItemWidget(this.item); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + item.kPIName, + fontSize: SizeConfig.textMultiplier * 2.2, + fontWeight: FontWeight.bold, + ), + ], + ), + new Container( + height: 130, + child: new ListView( + scrollDirection: Axis.horizontal, + children: + new List.generate(item.summaryoptions.length, (int index) { + return GetActivityButton(item.summaryoptions[index]); + }))) + ], + ); + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 76dba1cf..a858660b 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; @@ -14,6 +15,7 @@ import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/DischargedPatientPage.dart'; import 'package:doctor_app_flutter/screens/patients/PatientsInPatientScreen.dart'; @@ -24,6 +26,7 @@ import 'package:doctor_app_flutter/screens/patients/patient_search/patient_searc import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/dashboard/activity_button.dart'; @@ -34,6 +37,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/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; @@ -47,7 +51,6 @@ import '../../widgets/shared/rounded_container_widget.dart'; import 'home_page_card.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); -Helpers helpers = Helpers(); class HomeScreen extends StatefulWidget { HomeScreen({Key key, this.title}) : super(key: key); @@ -72,7 +75,6 @@ class _HomeScreenState extends State { var clinicName = []; int sliderActiveIndex = 0; var clinicId; - var _patientSearchFormValues; void didChangeDependencies() async { super.didChangeDependencies(); @@ -105,6 +107,7 @@ class _HomeScreenState extends State { } BuildContext myContext; + @override Widget build(BuildContext context) { myContext = context; @@ -143,7 +146,6 @@ class _HomeScreenState extends State { children: [ Container( width: MediaQuery.of(context).size.width * .6, - // // height: 100, child: projectsProvider.doctorClinicsList.length > 0 ? Stack( @@ -210,10 +212,15 @@ class _HomeScreenState extends State { ); }).toList(); }, - onChanged: (newValue) { + onChanged: (newValue) async { clinicId = newValue; - changeClinic( - newValue, context, model); + GifLoaderDialogUtils.showMyDialog( + context); + await model.changeClinic(newValue, authProvider); + GifLoaderDialogUtils + .hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error);} }, items: projectsProvider .doctorClinicsList @@ -309,111 +316,13 @@ class _HomeScreenState extends State { height: 10, ), sliderActiveIndex == 1 - ? Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - model.dashboardItemsList[3] - .kPIName, - fontSize: - SizeConfig.textMultiplier * - 2.2, - fontWeight: FontWeight.bold, - ), - ], - ), - new Container( - height: 130, - child: new ListView( - scrollDirection: - Axis.horizontal, - children: new List.generate( - model - .dashboardItemsList[3] - .summaryoptions - .length, (int index) { - return GetActivityButton(model - .dashboardItemsList[3] - .summaryoptions[index]); - }))) - ], - ) + ? DashboardSliderItemWidget( + model.dashboardItemsList[3]) : sliderActiveIndex == 0 - ? Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - model.dashboardItemsList[6] - .kPIName, - fontSize: SizeConfig - .textMultiplier * - 2.2, - fontWeight: FontWeight.bold, - ), - ], - ), - new Container( - height: 130, - child: new ListView( - scrollDirection: Axis - .horizontal, - children: new List - .generate( - model - .dashboardItemsList[ - 6] - .summaryoptions - .length, - (int index) { - return GetActivityButton(model - .dashboardItemsList[ - 6] - .summaryoptions[index]); - }))) - ], - ) - : Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - model.dashboardItemsList[4] - .kPIName, - fontSize: SizeConfig - .textMultiplier * - 2.2, - fontWeight: FontWeight.bold, - ), - ], - ), - new Container( - height: 130, - child: new ListView( - scrollDirection: Axis - .horizontal, - children: new List - .generate( - model - .dashboardItemsList[ - 4] - .summaryoptions - .length, - (int index) { - return GetActivityButton(model - .dashboardItemsList[ - 4] - .summaryoptions[index]); - }))) - ], - ), + ? DashboardSliderItemWidget( + model.dashboardItemsList[6]) + : DashboardSliderItemWidget( + model.dashboardItemsList[4]), ]))) : SizedBox(), FractionallySizedBox( @@ -810,7 +719,6 @@ class _HomeScreenState extends State { } changeClinic(clinicId, BuildContext context, model) async { - // Navigator.pop(context); changeIsLoading(true); Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); @@ -960,31 +868,4 @@ class _HomeScreenState extends State { ])), ]; } - - getRequestHeader(isInpatient) { - _patientSearchFormValues = PatientModel( - FirstName: "0", - MiddleName: "0", - LastName: "0", - PatientMobileNumber: "0", - PatientIdentificationID: "0", - PatientID: 0, - From: isInpatient == true - ? '0' - : DateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd') - .toString(), - To: isInpatient == true - ? '0' - : DateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd') - .toString(), - LanguageID: 2, - stamp: "2020-03-02T13:56:39.170Z", - IPAdress: "11.11.11.11", - VersionID: 1.2, - Channel: 9, - TokenID: "2Fi7HoIHB0eDyekVa6tCJg==", - SessionID: "5G0yXn0Jnq", - IsLoginForDoctorApp: true, - PatientOutSA: false); - } } From b20d936933c5249dffaec464276cf0a3c9b1202f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 4 May 2021 13:09:48 +0300 Subject: [PATCH 004/241] fix hospitals_service --- .../get_hospitals_response_model.dart | 22 +++++++++++++++++++ .../service/hospitals/hospitals_service.dart | 8 +++++-- lib/core/viewModel/auth_view_model.dart | 17 -------------- lib/core/viewModel/imei_view_model.dart | 16 ++++++++++++-- lib/screens/auth/login_screen.dart | 12 +++++----- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/lib/core/model/hospitals/get_hospitals_response_model.dart b/lib/core/model/hospitals/get_hospitals_response_model.dart index e69de29b..edbc3fe5 100644 --- a/lib/core/model/hospitals/get_hospitals_response_model.dart +++ b/lib/core/model/hospitals/get_hospitals_response_model.dart @@ -0,0 +1,22 @@ +class GetHospitalsResponseModel { + String facilityGroupId; + int facilityId; + String facilityName; + + GetHospitalsResponseModel( + {this.facilityGroupId, this.facilityId, this.facilityName}); + + GetHospitalsResponseModel.fromJson(Map json) { + facilityGroupId = json['facilityGroupId']; + facilityId = json['facilityId']; + facilityName = json['facilityName']; + } + + Map toJson() { + final Map data = new Map(); + data['facilityGroupId'] = this.facilityGroupId; + data['facilityId'] = this.facilityId; + data['facilityName'] = this.facilityName; + return data; + } +} diff --git a/lib/core/service/hospitals/hospitals_service.dart b/lib/core/service/hospitals/hospitals_service.dart index 2c670e09..f8a7579d 100644 --- a/lib/core/service/hospitals/hospitals_service.dart +++ b/lib/core/service/hospitals/hospitals_service.dart @@ -1,17 +1,21 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; class HospitalsService extends BaseService { -List hospitals; +List hospitals =List(); Future getHospitals(GetHospitalsRequestModel getHospitalsRequestModel) async { hasError = false; await baseAppClient.post( GET_PROJECTS, onSuccess: (dynamic response, int statusCode) { - hospitals = response['ProjectInfo']; + hospitals.clear(); + response['ProjectInfo'].forEach((hospital) { + hospitals.add(GetHospitalsResponseModel.fromJson(hospital)); + }); }, onFailure: (String error, int statusCode) { hasError = true; diff --git a/lib/core/viewModel/auth_view_model.dart b/lib/core/viewModel/auth_view_model.dart index 48f4661d..c1410fe6 100644 --- a/lib/core/viewModel/auth_view_model.dart +++ b/lib/core/viewModel/auth_view_model.dart @@ -56,23 +56,6 @@ class AuthViewModel extends BaseViewModel { } } - // Future login(UserModel userInfo) async { - // try { - // dynamic localRes; - // - // await baseAppClient.post(LOGIN_URL, - // onSuccess: (dynamic response, int statusCode) { - // localRes = response; - // }, onFailure: (String error, int statusCode) { - // throw error; - // }, body: userInfo.toJson()); - // - // return Future.value(localRes); - // } catch (error) { - // print(error); - // throw error; - // } - // } Future insertDeviceImei(request) async { var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); diff --git a/lib/core/viewModel/imei_view_model.dart b/lib/core/viewModel/imei_view_model.dart index ba462553..6499cfac 100644 --- a/lib/core/viewModel/imei_view_model.dart +++ b/lib/core/viewModel/imei_view_model.dart @@ -1,10 +1,12 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/service/auth_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; +import 'package:doctor_app_flutter/models/auth/send_activation_code_model2.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -13,7 +15,7 @@ class IMEIViewModel extends BaseViewModel { HospitalsService _hospitalsService = locator(); List get imeiDetails => _authService.dashboardItemsList; - List get hospitals => _hospitalsService.hospitals; + List get hospitals => _hospitalsService.hospitals; get loginInfo => _authService.loginInfo; Future selectDeviceImei(imei) async { setState(ViewState.Busy); @@ -35,10 +37,20 @@ class IMEIViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future sendActivationCodeVerificationScreen(ActivationCodeModel2 activationCodeModel) async { + setState(ViewState.BusyLocal); + // await _authService.sendActivationCodeVerificationScreen(userInfo); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future getHospitalsList(memberID) async { GetHospitalsRequestModel getHospitalsRequestModel =GetHospitalsRequestModel(); getHospitalsRequestModel.memberID = memberID; - // setState(ViewState.Busy); await _hospitalsService.getHospitals(getHospitalsRequestModel); if (_hospitalsService.hasError) { error = _hospitalsService.error; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 1d27e31e..d7784881 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -5,8 +5,8 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/service/auth_service.dart'; -import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; @@ -47,7 +47,7 @@ class _LoginsreenState extends State { //TODO change AppTextFormField to AppTextFormFieldCustom final loginFormKey = GlobalKey(); var projectIdController = TextEditingController(); - var projectsList = []; + List projectsList = []; FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); // HospitalViewModel hospitalViewModel; @@ -491,8 +491,8 @@ class _LoginsreenState extends State { onSelectProject(index) { setState(() { - userInfo.projectID = projectsList[index]["facilityId"]; - projectIdController.text = projectsList[index]['facilityName']; + userInfo.projectID = projectsList[index].facilityId; + projectIdController.text = projectsList[index].facilityName; }); primaryFocus.unfocus(); @@ -505,8 +505,8 @@ class _LoginsreenState extends State { if(model.state == ViewState.Idle) { projectsList = model.hospitals; setState(() { - userInfo.projectID = projectsList[0]["facilityId"]; - projectIdController.text = projectsList[0]['facilityName']; + userInfo.projectID = projectsList[0].facilityId; + projectIdController.text = projectsList[0].facilityName; }); } } From 9f1f06f2fc1cc4c2ba707579d46052f8973169bd Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 4 May 2021 16:02:04 +0300 Subject: [PATCH 005/241] refactor verification methods services --- lib/core/service/auth_service.dart | 78 ++++++++ lib/core/viewModel/auth_view_model.dart | 59 +----- lib/core/viewModel/imei_view_model.dart | 38 +++- ...n_code_for_verification_screen_model.dart} | 6 +- lib/screens/auth/login_screen.dart | 1 + .../auth/verification_methods_screen.dart | 49 ++--- lib/widgets/auth/verification_methods.dart | 168 +++++++++--------- 7 files changed, 227 insertions(+), 172 deletions(-) rename lib/models/auth/{send_activation_code_model2.dart => activation_code_for_verification_screen_model.dart} (91%) diff --git a/lib/core/service/auth_service.dart b/lib/core/service/auth_service.dart index ec56bed7..bdc500d0 100644 --- a/lib/core/service/auth_service.dart +++ b/lib/core/service/auth_service.dart @@ -1,13 +1,30 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:provider/provider.dart'; class AuthService extends BaseService { List _imeiDetails = []; List get dashboardItemsList => _imeiDetails; + //TODO Change this to models Map _loginInfo = {}; Map get loginInfo => _loginInfo; + Map _activationCodeVerificationScreenRes = {}; + + Map get activationCodeVerificationScreenRes => _activationCodeVerificationScreenRes; + + Map _activationCodeForDoctorAppRes = {}; + + Map get activationCodeForDoctorAppRes => _activationCodeForDoctorAppRes; + Map _checkActivationCodeForDoctorAppRes = {}; + + Map get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; Future selectDeviceImei(imei) async { try { // dynamic localRes; @@ -45,4 +62,65 @@ class AuthService extends BaseService { } } + + Future sendActivationCodeVerificationScreen(ActivationCodeForVerificationScreenModel activationCodeModel) async { + hasError = false; + _activationCodeVerificationScreenRes = {}; + try { + await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_VERIFICATION_SCREEN, + onSuccess: (dynamic response, int statusCode) { + _activationCodeVerificationScreenRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: activationCodeModel.toJson()); + } catch (error) { + hasError = true; + super.error = error; + } + + } + + Future sendActivationCodeForDoctorApp(ActivationCodeModel activationCodeModel)async { + hasError = false; + _activationCodeForDoctorAppRes = {}; + try { + await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_DOCTOR_APP, + onSuccess: (dynamic response, int statusCode) { + _activationCodeForDoctorAppRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: activationCodeModel.toJson()); + } catch (error) { + hasError = true; + super.error = error; + } + } + + Future checkActivationCodeForDoctorApp(CheckActivationCodeRequestModel checkActivationCodeRequestModel)async { + hasError = false; + _checkActivationCodeForDoctorAppRes = {}; + try { + await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, + onSuccess: (dynamic response, int statusCode) { + // TODO improve the logic here + Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.clear(); + _checkActivationCodeForDoctorAppRes = response; + Provider.of(AppGlobal.CONTEX, listen: false).selectedClinicName = + ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; + + response['List_DoctorsClinic'].forEach((v) { + Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.add(new ClinicModel.fromJson(v)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: checkActivationCodeRequestModel.toJson()); + } catch (error) { + hasError = true; + super.error = error; + } + + } } diff --git a/lib/core/viewModel/auth_view_model.dart b/lib/core/viewModel/auth_view_model.dart index c1410fe6..add5db86 100644 --- a/lib/core/viewModel/auth_view_model.dart +++ b/lib/core/viewModel/auth_view_model.dart @@ -6,7 +6,7 @@ import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/auth/send_activation_code_model2.dart'; +import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; @@ -95,46 +95,6 @@ class AuthViewModel extends BaseViewModel { } } - Future sendActivationCodeForDoctorApp( - ActivationCodeModel activationCodeModel) async { - try { - var localRes; - await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_DOCTOR_APP, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: activationCodeModel.toJson()); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } - - Future checkActivationCodeForDoctorApp( - CheckActivationCodeRequestModel checkActivationCodeRequestModel) async { - try { - dynamic localRes; - await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - selectedClinicName = - ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; - - response['List_DoctorsClinic'].forEach((v) { - doctorsClinicList.add(new ClinicModel.fromJson(v)); - }); - }, onFailure: (String error, int statusCode) { - throw error; - }, body: checkActivationCodeRequestModel.toJson()); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } - Future getDocProfiles(docInfo, {bool allowChangeProfile = true}) async { try { @@ -158,21 +118,4 @@ class AuthViewModel extends BaseViewModel { throw error; } } - - Future sendActivationCodeVerificationScreen( - ActivationCodeModel2 activationCodeModel) async { - try { - var localRes; - await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_VERIFICATION_SCREEN, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: activationCodeModel.toJson()); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } } diff --git a/lib/core/viewModel/imei_view_model.dart b/lib/core/viewModel/imei_view_model.dart index 6499cfac..09bfe8b3 100644 --- a/lib/core/viewModel/imei_view_model.dart +++ b/lib/core/viewModel/imei_view_model.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; @@ -6,9 +7,14 @@ import 'package:doctor_app_flutter/core/service/auth_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; -import 'package:doctor_app_flutter/models/auth/send_activation_code_model2.dart'; +import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:provider/provider.dart'; + +import 'auth_view_model.dart'; class IMEIViewModel extends BaseViewModel { AuthService _authService = locator(); @@ -17,6 +23,10 @@ class IMEIViewModel extends BaseViewModel { List get imeiDetails => _authService.dashboardItemsList; List get hospitals => _hospitalsService.hospitals; get loginInfo => _authService.loginInfo; + get activationCodeVerificationScreenRes => _authService.activationCodeVerificationScreenRes; + get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; + get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; + Future selectDeviceImei(imei) async { setState(ViewState.Busy); await _authService.selectDeviceImei(imei); @@ -37,9 +47,19 @@ class IMEIViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future sendActivationCodeVerificationScreen(ActivationCodeModel2 activationCodeModel) async { + Future sendActivationCodeVerificationScreen(ActivationCodeForVerificationScreenModel activationCodeModel) async { + setState(ViewState.BusyLocal); + await _authService.sendActivationCodeVerificationScreen(activationCodeModel); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future sendActivationCodeForDoctorApp(ActivationCodeModel activationCodeModel) async { setState(ViewState.BusyLocal); - // await _authService.sendActivationCodeVerificationScreen(userInfo); + await _authService.sendActivationCodeForDoctorApp(activationCodeModel); if (_authService.hasError) { error = _authService.error; setState(ViewState.ErrorLocal); @@ -47,6 +67,18 @@ class IMEIViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future checkActivationCodeForDoctorApp(CheckActivationCodeRequestModel checkActivationCodeRequestModel) async { + setState(ViewState.BusyLocal); + await _authService.checkActivationCodeForDoctorApp(checkActivationCodeRequestModel); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + + } + } + Future getHospitalsList(memberID) async { GetHospitalsRequestModel getHospitalsRequestModel =GetHospitalsRequestModel(); diff --git a/lib/models/auth/send_activation_code_model2.dart b/lib/models/auth/activation_code_for_verification_screen_model.dart similarity index 91% rename from lib/models/auth/send_activation_code_model2.dart rename to lib/models/auth/activation_code_for_verification_screen_model.dart index 68a90c85..28cc58db 100644 --- a/lib/models/auth/send_activation_code_model2.dart +++ b/lib/models/auth/activation_code_for_verification_screen_model.dart @@ -1,4 +1,4 @@ -class ActivationCodeModel2 { +class ActivationCodeForVerificationScreenModel { int oTPSendType; String mobileNumber; String zipCode; @@ -12,7 +12,7 @@ class ActivationCodeModel2 { String vidaAuthTokenID; String vidaRefreshTokenID; String iMEI; - ActivationCodeModel2( + ActivationCodeForVerificationScreenModel( {this.oTPSendType, this.mobileNumber, this.zipCode, @@ -27,7 +27,7 @@ class ActivationCodeModel2 { this.vidaRefreshTokenID, this.iMEI}); - ActivationCodeModel2.fromJson(Map json) { + ActivationCodeForVerificationScreenModel.fromJson(Map json) { oTPSendType = json['OTP_SendType']; mobileNumber = json['MobileNumber']; zipCode = json['ZipCode']; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index d7784881..5e069a2a 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -459,6 +459,7 @@ class _LoginsreenState extends State { sharedPref.setInt(PROJECT_ID, userInfo.projectID); await model.login(userInfo); if (model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 7503a70e..a83db25c 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -1,3 +1,5 @@ +import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -25,27 +27,30 @@ class _VerificationMethodsScreenState extends State { @override Widget build(BuildContext context) { - return AppScaffold( - isLoading: _isLoading, - isShowAppBar: false, - isHomeIcon: false, - backgroundColor: HexColor('#F8F8F8'), - body: ListView(children: [ - Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - ), - VerificationMethods( - password: widget.password, - changeLoadingState: changeLoadingState, - ), - ], - ), - ), - ])); + return BaseView( + onModelReady: (model) async {}, + builder: (_, model, w) => AppScaffold( + isLoading: _isLoading, + isShowAppBar: false, + isHomeIcon: false, + backgroundColor: HexColor('#F8F8F8'), + body: ListView(children: [ + Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + ), + VerificationMethods( + password: widget.password, + changeLoadingState: changeLoadingState, + model:model + ), + ], + ), + ), + ]))); } } diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 91d80a71..dc95f6dd 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -1,11 +1,13 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; +import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/auth/send_activation_code_model2.dart'; +import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; @@ -15,6 +17,7 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/otp/sms-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -35,10 +38,11 @@ DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); class VerificationMethods extends StatefulWidget { - VerificationMethods({this.changeLoadingState, this.password}); + VerificationMethods({this.changeLoadingState, this.password, this.model}); final password; final Function changeLoadingState; + final IMEIViewModel model; @override _VerificationMethodsState createState() => _VerificationMethodsState(); @@ -330,8 +334,10 @@ class _VerificationMethodsState extends State { oTPSendType, AuthViewModel authProv) async { // TODO : build enum for verfication method if (oTPSendType == 1 || oTPSendType == 2) { - widget.changeLoadingState(true); + GifLoaderDialogUtils.showMyDialog(context); + int projectID = await sharedPref.getInt(PROJECT_ID); + // TODO create model for _loggedUser; ActivationCodeModel activationCodeModel = ActivationCodeModel( facilityId: projectID, memberID: _loggedUser['List_MemberInformation'][0]['MemberID'], @@ -339,49 +345,34 @@ class _VerificationMethodsState extends State { mobileNumber: _loggedUser['MobileNumber'], otpSendType: oTPSendType.toString(), password: widget.password); - - try { - authProv - .sendActivationCodeForDoctorApp(activationCodeModel) - .then((res) { - if (res['MessageStatus'] == 1) { - print("VerificationCode : " + res["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, res["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, res["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, res["LogInTokenID"]); - sharedPref.setString(PASSWORD, widget.password); - this.startSMSService(oTPSendType, authProv); - } else { - print(res['ErrorEndUserMessage']); - Helpers.showErrorToast(res['ErrorEndUserMessage']); - } - }).catchError((err) { - print('$err'); - widget.changeLoadingState(false); - - Helpers.showErrorToast(); - }); - } catch (e) {} + await widget.model + .sendActivationCodeForDoctorApp(activationCodeModel); + if(widget.model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.model.error); + GifLoaderDialogUtils.hideDialog(context); + }else{ + print("VerificationCode : " + widget.model.activationCodeForDoctorAppRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); + sharedPref.setString( + VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["LogInTokenID"]); + sharedPref.setString(PASSWORD, widget.password); + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(oTPSendType, authProv); + } } else { // TODO route to this page with parameters to inicate we should present 2 option if (Platform.isAndroid && oTPSendType == 3) { Helpers.showErrorToast('Your device not support this feature'); } else { - // Navigator.of(context).push(MaterialPageRoute( - // builder: (BuildContext context) => - // VerificationMethodsScreen(password: widget.password,))); - - // Navigator.of(context).pushNamed(VERIFICATION_METHODS, - // arguments: {'verificationMethod': oTPSendType}); } } } sendActivationCodeVerificationScreen( oTPSendType, AuthViewModel authProv) async { - widget.changeLoadingState(true); - ActivationCodeModel2 activationCodeModel = ActivationCodeModel2( + GifLoaderDialogUtils.showMyDialog(context); + ActivationCodeForVerificationScreenModel activationCodeModel = ActivationCodeForVerificationScreenModel( iMEI: user.iMEI, facilityId: user.projectID, memberID: user.doctorID, @@ -392,37 +383,25 @@ class _VerificationMethodsState extends State { vidaAuthTokenID: user.vidaAuthTokenID, vidaRefreshTokenID: user.vidaRefreshTokenID); - try { - authProv - .sendActivationCodeVerificationScreen(activationCodeModel) - .then((res) { - if (res['MessageStatus'] == 1) { - print("VerificationCode : " + res["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, res["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, res["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, res["LogInTokenID"]); - if (oTPSendType == 1 || oTPSendType == 2) { - widget.changeLoadingState(false); - this.startSMSService(oTPSendType, authProv); - } else { - checkActivationCode(authProv); - } + await widget.model + .sendActivationCodeVerificationScreen(activationCodeModel); + + if(widget.model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); + Helpers.showErrorToast(widget.model.error); + } else { + print("VerificationCode : " + widget.model.activationCodeVerificationScreenRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); + sharedPref.setString( + VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["LogInTokenID"]); + if (oTPSendType == 1 || oTPSendType == 2) { + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(oTPSendType, authProv); } else { - print(res['ErrorEndUserMessage']); - Helpers.showErrorToast(res['ErrorEndUserMessage']); + checkActivationCode(authProv); } - }).catchError((err) { - print('$err'); - widget.changeLoadingState(false); - - Helpers.showErrorToast(); - }); - } catch (e) {} - // } - // else { - // checkActivationCode(authProv); - // } + } } Widget getButton(flag, authProv) { @@ -741,7 +720,7 @@ class _VerificationMethodsState extends State { stickyAuth: true, iOSAuthStrings: iosStrings); } on PlatformException catch (e) { - DrAppToastMsg.showErrorToast(e); + DrAppToastMsg.showErrorToast(e.toString()); } if (!mounted) return; if (user != null && (user.logInTypeID == 3 || user.logInTypeID == 4)) { @@ -769,30 +748,47 @@ class _VerificationMethodsState extends State { activationCode: value ?? '0000', oTPSendType: await sharedPref.getInt(OTP_TYPE), generalid: "Cs2020@2016\$2958"); + await widget.model.checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); - authProv - .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp) - .then((res) async { - widget.changeLoadingState(false); - if (res['MessageStatus'] == 1) { - sharedPref.setString(TOKEN, res['AuthenticationTokenID']); - if (res['List_DoctorProfile'] != null) { - loginProcessCompleted(res['List_DoctorProfile'][0], authProv); - sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); - } else { - sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); - ClinicModel clinic = - ClinicModel.fromJson(res['List_DoctorsClinic'][0]); - getDocProfiles(clinic, authProv); - } + if(widget.model.state == ViewState.ErrorLocal){ + Navigator.pop(context); + Helpers.showErrorToast(widget.model.error); + } else { + sharedPref.setString(TOKEN, widget.model.checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); + if (widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != null) { + loginProcessCompleted(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0], authProv); + sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); } else { - Navigator.pop(context); - Helpers.showErrorToast(res['ErrorEndUserMessage']); + sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + ClinicModel clinic = + ClinicModel.fromJson(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); + getDocProfiles(clinic, authProv); } - }).catchError((err) { - Navigator.pop(context); - Helpers.showErrorToast(err); - }); + } + + // authProv + // .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp) + // .then((res) async { + // widget.changeLoadingState(false); + // if (res['MessageStatus'] == 1) { + // sharedPref.setString(TOKEN, res['AuthenticationTokenID']); + // if (res['List_DoctorProfile'] != null) { + // loginProcessCompleted(res['List_DoctorProfile'][0], authProv); + // sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); + // } else { + // sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); + // ClinicModel clinic = + // ClinicModel.fromJson(res['List_DoctorsClinic'][0]); + // getDocProfiles(clinic, authProv); + // } + // } else { + // Navigator.pop(context); + // Helpers.showErrorToast(res['ErrorEndUserMessage']); + // } + // }).catchError((err) { + // Navigator.pop(context); + // Helpers.showErrorToast(err); + // }); } loginProcessCompleted(Map profile, authProv) { From 0d867592452375d67b57908d0572507e6d1b7fc4 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 4 May 2021 16:11:48 +0300 Subject: [PATCH 006/241] working on dashboard re-factoring --- lib/core/viewModel/dashboard_view_model.dart | 34 ++ lib/screens/home/dashboard_swipe_widget.dart | 234 +++++++++++ lib/screens/home/home_screen.dart | 404 +++---------------- lib/widgets/dashboard/out_patient_stack.dart | 10 +- lib/widgets/dashboard/row_count.dart | 35 +- lib/widgets/shared/app_texts_widget.dart | 14 +- 6 files changed, 369 insertions(+), 362 deletions(-) create mode 100644 lib/screens/home/dashboard_swipe_widget.dart diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 7c6748a5..a12f3a87 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -1,19 +1,46 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/dasboard_service.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import '../../locator.dart'; import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { + + final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); DashboardService _dashboardService = locator(); List get dashboardItemsList => _dashboardService.dashboardItemsList; + Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthViewModel authProvider) async{ + await projectsProvider.getDoctorClinicsList(); + + // _firebaseMessaging.setAutoInitEnabled(true); + _firebaseMessaging.requestNotificationPermissions( + const IosNotificationSettings( + sound: true, badge: true, alert: true, provisional: true)); + _firebaseMessaging.onIosSettingsRegistered + .listen((IosNotificationSettings settings) { + print("Settings registered: $settings"); + }); + + _firebaseMessaging.getToken().then((String token) async { + if (token != '') { + DEVICE_TOKEN = token; + var request = await sharedPref.getObj(DOCTOR_PROFILE); + authProvider.insertDeviceImei(request).then((value) { + }); + } + }); + } + Future getDashboard() async { setState(ViewState.Busy); await _dashboardService.getDashboard(); @@ -43,4 +70,11 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); }); } + + getPatientCount(DashboardModel inPatientCount) { + int value = 0; + inPatientCount.summaryoptions.forEach((result) => {value += result.value}); + + return value.toString(); + } } diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart new file mode 100644 index 00000000..8f8077d8 --- /dev/null +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -0,0 +1,234 @@ +import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/guage_chart.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/out_patient_stack.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/row_count.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/swiper_rounded_pagination.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_swiper/flutter_swiper.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + +class DashboardSwipeWidget extends StatefulWidget { + final List dashboardItemList; + final DashboardViewModel model; + final Function(int) sliderChange; + + DashboardSwipeWidget(this.dashboardItemList, this.model, this.sliderChange); + + @override + _DashboardSwipeWidgetState createState() => _DashboardSwipeWidgetState(); +} + +class _DashboardSwipeWidgetState extends State { + int sliderActiveIndex = 0; + + @override + Widget build(BuildContext context) { + return Swiper( + onIndexChanged: (index) { + if (mounted) { + setState(() { + sliderActiveIndex = index; + widget.sliderChange(index); + }); + } + }, + itemBuilder: (BuildContext context, int index) { + return getSwipeWidget(widget.dashboardItemList, index); + }, + itemCount: 3, + itemHeight: 300, + pagination: new SwiperCustomPagination( + builder: (BuildContext context, SwiperPluginConfig config) { + return new Stack( + alignment: Alignment.bottomCenter, + children: [ + Positioned( + bottom: 0, + child: Center( + child: InkWell( + onTap: () {}, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + config.activeIndex == 0 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + config.activeIndex == 1 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + config.activeIndex == 2 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + ], + ), + ), + ), + ), + ) + ], + ); + }), + viewportFraction: 0.9, + // scale: 0.9, + // control: new SwiperControl(), + ); + } + + Widget getSwipeWidget(List dashboardItemList, int index) { + if (index == 1) + return RoundedContainer( + height: MediaQuery.of(context).size.height * 0.35, + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + child: Padding( + padding: const EdgeInsets.all(5.0), + child: GetOutPatientStack(dashboardItemList[1]))); + if (index == 0) + return RoundedContainer( + height: MediaQuery.of(context).size.height * 0.35, + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + child: Padding( + padding: const EdgeInsets.all(5.0), + child: GetOutPatientStack(dashboardItemList[0]))); + if (index == 2) + return RoundedContainer( + height: MediaQuery.of(context).size.height * 0.35, + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + child: + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Expanded( + flex: 1, + child: Row( + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: Padding( + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText(TranslationBase.of(context) + .patients, + fontSize: 12, + fontWeight: FontWeight.bold, + fontHeight: 0.5,), + AppText(TranslationBase.of(context) + .referral, + fontSize: 22, + fontWeight: FontWeight.bold, + ), + ], + ))), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RowCounts( + dashboardItemList[2] + .summaryoptions[0] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[0] + .value, + Colors.black), + RowCounts( + dashboardItemList[2] + .summaryoptions[1] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[1] + .value, + Colors.grey), + RowCounts( + dashboardItemList[2] + .summaryoptions[2] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[2] + .value, + Colors.red), + ], + ), + ) + ], + )), + ), + Expanded( + flex: 3, + child: Stack(children: [ + Container( + child: GaugeChart( + _createReferralData(widget.dashboardItemList))), + Positioned( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + AppText( + widget.model + .getPatientCount(dashboardItemList[2]) + .toString(), + fontSize: 30, + fontWeight: FontWeight.bold, + ) + ], + ), + top: MediaQuery.of(context).size.height * 0.12, + left: 0, + right: 0) + ]), + ), + ], + )), + ])); + return Container(); + } + + static List> _createReferralData( + List dashboardItemList) { + final data = [ + new GaugeSegment( + dashboardItemList[2].summaryoptions[0].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[0].value), + charts.MaterialPalette.black), + new GaugeSegment( + dashboardItemList[2].summaryoptions[1].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[1].value), + charts.MaterialPalette.gray.shadeDefault), + new GaugeSegment( + dashboardItemList[2].summaryoptions[2].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[2].value), + charts.MaterialPalette.red.shadeDefault), + ]; + + return [ + new charts.Series( + id: 'Segments', + domainFn: (GaugeSegment segment, _) => segment.segment, + measureFn: (GaugeSegment segment, _) => segment.size, + data: data, + colorFn: (GaugeSegment segment, _) => segment.color, + ) + ]; + } + + static int getValue(value) { + return value == 0 ? 1 : value; + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index a858660b..dcf2980d 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -1,57 +1,33 @@ -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/hospital_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; -import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; -import 'package:doctor_app_flutter/models/patient/patient_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; +import 'package:doctor_app_flutter/screens/home/dashboard_swipe_widget.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_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/out_patient/out_patient_screen.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_screen.dart'; -import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_result_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/activity_button.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/guage_chart.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/out_patient_stack.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/row_count.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/swiper_rounded_pagination.dart'; 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/shared/loader/gif_loader_dialog_utils.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'; -import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:provider/provider.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; import '../../widgets/shared/app_texts_widget.dart'; -import '../../widgets/shared/rounded_container_widget.dart'; import 'home_page_card.dart'; -DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - class HomeScreen extends StatefulWidget { HomeScreen({Key key, this.title}) : super(key: key); @@ -63,65 +39,25 @@ class HomeScreen extends StatefulWidget { } class _HomeScreenState extends State { - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); - HospitalViewModel hospitalProvider; - AuthViewModel authProvider; - bool isLoading = false; - ProjectViewModel projectsProvider; - var _isInit = true; - DoctorProfileModel profile; bool isExpanded = false; bool isInpatient = false; - var clinicName = []; int sliderActiveIndex = 0; var clinicId; - void didChangeDependencies() async { - super.didChangeDependencies(); - if (_isInit) { - projectsProvider = Provider.of(context); - projectsProvider.getDoctorClinicsList(); - - // _firebaseMessaging.setAutoInitEnabled(true); - _firebaseMessaging.requestNotificationPermissions( - const IosNotificationSettings( - sound: true, badge: true, alert: true, provisional: true)); - _firebaseMessaging.onIosSettingsRegistered - .listen((IosNotificationSettings settings) { - print("Settings registered: $settings"); - }); - clinicName = await sharedPref.getObj(CLINIC_NAME); - print(clinicName); - _firebaseMessaging.getToken().then((String token) async { - if (token != '') { - DEVICE_TOKEN = token; - var request = await sharedPref.getObj(DOCTOR_PROFILE); - authProvider.insertDeviceImei(request).then((value) { - // print(value); - changeIsLoading(false); - }); - } - }); - } - _isInit = false; - } - - BuildContext myContext; - @override Widget build(BuildContext context) { - myContext = context; - hospitalProvider = Provider.of(context); - authProvider = Provider.of(context); - projectsProvider = Provider.of(context); + ProjectViewModel projectsProvider = Provider.of(context); + AuthViewModel authProvider = Provider.of(context); FocusScopeNode currentFocus = FocusScope.of(context); - if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } return BaseView( - onModelReady: (model) => model.getDashboard(), + onModelReady: (model) async { + await model.setFirebaseNotification(projectsProvider, authProvider); + await model.getDashboard(); + }, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -171,36 +107,49 @@ class _HomeScreenState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ - Container( - padding: EdgeInsets.all(2), - margin: EdgeInsets.all(2), - decoration: - new BoxDecoration( - color: Colors.red[800], - borderRadius: - BorderRadius.circular( - 20), - ), - constraints: BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: new Text( - projectsProvider - .doctorClinicsList - .length - .toString(), - style: new TextStyle( - color: Colors.white, - fontSize: - projectsProvider - .isArabic - ? 10 - : 11, - ), - textAlign: - TextAlign.center, - ), + Column( + mainAxisAlignment: + MainAxisAlignment + .center, + children: [ + Container( + padding: + EdgeInsets.all(2), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: + Colors.red[800], + borderRadius: + BorderRadius + .circular( + 20), + ), + constraints: + BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Center( + child: AppText( + projectsProvider + .doctorClinicsList + .length + .toString(), + color: + Colors.white, + fontSize: + projectsProvider + .isArabic + ? 10 + : 11, + textAlign: + TextAlign + .center, + ), + )), + ], ), AppText(item.clinicName, fontSize: 12, @@ -216,11 +165,15 @@ class _HomeScreenState extends State { clinicId = newValue; GifLoaderDialogUtils.showMyDialog( context); - await model.changeClinic(newValue, authProvider); - GifLoaderDialogUtils - .hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error);} + await model.changeClinic( + newValue, authProvider); + GifLoaderDialogUtils.hideDialog( + context); + if (model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + model.error); + } }, items: projectsProvider .doctorClinicsList @@ -251,58 +204,14 @@ class _HomeScreenState extends State { Container( height: MediaQuery.of(context).size.height * 0.35, child: model.dashboardItemsList.length > 0 - ? new Swiper( - onIndexChanged: (index) { - if (mounted) { - setState(() { - sliderActiveIndex = index; - }); - } - }, - itemBuilder: (BuildContext context, int index) { - return getSwipeWidget(model)[index]; + ? DashboardSwipeWidget( + model.dashboardItemsList, + model, + (sliderIndex) { + setState(() { + sliderActiveIndex = sliderIndex; + }); }, - itemCount: 3, - itemHeight: 300, - pagination: new SwiperCustomPagination(builder: - (BuildContext context, - SwiperPluginConfig config) { - return new Stack( - alignment: Alignment.bottomCenter, - children: [ - Positioned( - bottom: 0, - child: Center( - child: InkWell( - onTap: () {}, - child: Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - config.activeIndex == 0 - ? SwiperRoundedPagination( - true) - : SwiperRoundedPagination( - false), - config.activeIndex == 1 - ? SwiperRoundedPagination( - true) - : SwiperRoundedPagination( - false), - config.activeIndex == 2 - ? SwiperRoundedPagination( - true) - : SwiperRoundedPagination( - false), - ], - ))))) - ]); - }), - viewportFraction: 0.9, - // scale: 0.9, - // control: new SwiperControl(), ) : SizedBox()), model.dashboardItemsList.length > 0 @@ -687,185 +596,4 @@ class _HomeScreenState extends State { ); } - static List> _createReferralData(model) { - final data = [ - new GaugeSegment( - model.dashboardItemsList[2].summaryoptions[0].kPIParameter, - getValue(model.dashboardItemsList[1].summaryoptions[0].value), - charts.MaterialPalette.black), - new GaugeSegment( - model.dashboardItemsList[2].summaryoptions[1].kPIParameter, - getValue(model.dashboardItemsList[1].summaryoptions[1].value), - charts.MaterialPalette.gray.shadeDefault), - new GaugeSegment( - model.dashboardItemsList[2].summaryoptions[2].kPIParameter, - getValue(model.dashboardItemsList[1].summaryoptions[2].value), - charts.MaterialPalette.red.shadeDefault), - ]; - - return [ - new charts.Series( - id: 'Segments', - domainFn: (GaugeSegment segment, _) => segment.segment, - measureFn: (GaugeSegment segment, _) => segment.size, - data: data, - colorFn: (GaugeSegment segment, _) => segment.color, - ) - ]; - } - - static int getValue(value) { - return value == 0 ? 1 : value; - } - - changeClinic(clinicId, BuildContext context, model) async { - changeIsLoading(true); - Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: doctorProfile.doctorID, - clinicID: clinicId, - license: true, - projectID: doctorProfile.projectID, - tokenID: '', - languageID: 2); - authProvider.getDocProfiles(docInfo.toJson()).then((res) async { - changeIsLoading(false); - sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); - }).catchError((err) { - changeIsLoading(false); - Helpers.showErrorToast(err); - }); - } - - changeIsLoading(bool val) { - setState(() { - this.isLoading = val; - }); - } - - getPatientCount(DashboardModel inPatientCount) { - int value = 0; - inPatientCount.summaryoptions.forEach((result) => {value += result.value}); - - return value.toString(); - } - - List getSwipeWidget(model) { - return [ - RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), - child: Padding( - padding: const EdgeInsets.all(5.0), - child: GetOutPatientStack(model.dashboardItemsList[1]))), - RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), - child: Padding( - padding: const EdgeInsets.all(5.0), - child: GetOutPatientStack(model.dashboardItemsList[0]))), - RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), - child: - Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - flex: 1, - child: Row( - children: [ - Expanded( - flex: 4, - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 1, - child: Padding( - padding: EdgeInsets.all(8), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context) - .patients, - style: TextStyle( - fontSize: 12, - height: .5, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins'), - ), - Text( - TranslationBase.of(context) - .referral, - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins'), - ), - ], - ))), - Expanded( - flex: 2, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - RowCounts( - model.dashboardItemsList[2] - .summaryoptions[0].kPIParameter, - model.dashboardItemsList[2] - .summaryoptions[0].value, - Colors.black), - RowCounts( - model.dashboardItemsList[2] - .summaryoptions[1].kPIParameter, - model.dashboardItemsList[2] - .summaryoptions[1].value, - Colors.grey), - RowCounts( - model.dashboardItemsList[2] - .summaryoptions[2].kPIParameter, - model.dashboardItemsList[2] - .summaryoptions[2].value, - Colors.red), - ], - ), - ) - ], - ))), - Expanded( - flex: 3, - child: Stack(children: [ - Container( - child: GaugeChart(_createReferralData(model))), - Positioned( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - AppText( - getPatientCount(model.dashboardItemsList[2]) - .toString(), - fontSize: 30, - fontWeight: FontWeight.bold, - ) - ], - ), - top: MediaQuery.of(context).size.height * 0.12, - left: 0, - right: 0) - ]), - ), - ], - )), - ])), - ]; - } } diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index d5da97c6..c09e2757 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -31,7 +31,7 @@ class GetOutPatientStack extends StatelessWidget { Container( height: 150, margin: EdgeInsets.all(5), - width: 40, + width: 35, child: SizedBox(), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.red[50]), @@ -43,7 +43,7 @@ class GetOutPatientStack extends StatelessWidget { margin: EdgeInsets.all(5), padding: EdgeInsets.all(10), height: max != 0 ? (150 * value.value) / max : 0, - width: 40, + width: 35, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.red[300]))), @@ -55,12 +55,14 @@ class GetOutPatientStack extends StatelessWidget { quarterTurns: 1, child: Center( child: Align( - child: AppText( + child: FittedBox( + child: AppText( value.kPIParameter + ' (' + value.value.toString() + ') ', fontSize: 10, textAlign: TextAlign.center, fontWeight: FontWeight.bold, - )), + ), + )), ), )) ]); diff --git a/lib/widgets/dashboard/row_count.dart b/lib/widgets/dashboard/row_count.dart index c56613da..a42cccdf 100644 --- a/lib/widgets/dashboard/row_count.dart +++ b/lib/widgets/dashboard/row_count.dart @@ -8,31 +8,38 @@ class RowCounts extends StatelessWidget { RowCounts(this.name, this.count, this.c); @override Widget build(BuildContext context) { - return Row( - children: [ - dot(c), - Padding( - padding: EdgeInsets.only(top: 5, bottom: 5), + return Container( + padding: EdgeInsets.only(top: 5, bottom: 5), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + dot(c), + Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ - AppText( - name, - color: Colors.black, - textAlign: TextAlign.center, - fontSize: 12, - textOverflow: TextOverflow.ellipsis, + Expanded( + child: AppText( + name, + color: Colors.black, + textAlign: TextAlign.start, // from TextAlign.center + fontSize: 12, + textOverflow: TextOverflow.ellipsis, + ), ), AppText( ' (' + count.toString() + ')', color: Colors.black, textAlign: TextAlign.center, - fontSize: 14, + fontSize: 13, fontWeight: FontWeight.bold, ) ], - )), - ], + ), + ), + ], + ), ); } diff --git a/lib/widgets/shared/app_texts_widget.dart b/lib/widgets/shared/app_texts_widget.dart index 74acff8a..48661a32 100644 --- a/lib/widgets/shared/app_texts_widget.dart +++ b/lib/widgets/shared/app_texts_widget.dart @@ -9,6 +9,7 @@ class AppText extends StatefulWidget { final Color color; final FontWeight fontWeight; final double fontSize; + final double fontHeight; final String fontFamily; final int maxLength; final bool italic; @@ -35,6 +36,7 @@ class AppText extends StatefulWidget { this.fontWeight, this.variant, this.fontSize, + this.fontHeight, this.fontFamily = 'Poppins', this.italic = false, this.maxLength = 60, @@ -121,20 +123,20 @@ class _AppTextState extends State { style: widget.style != null ? _getFontStyle().copyWith( fontStyle: widget.italic ? FontStyle.italic : null, - color: widget.color , + color: widget.color, fontWeight: widget.fontWeight ?? _getFontWeight(), - ) + height: widget.fontHeight) : TextStyle( fontStyle: widget.italic ? FontStyle.italic : null, - color: widget.color != null - ? widget.color - : Colors.black, + color: + widget.color != null ? widget.color : Colors.black, fontSize: widget.fontSize ?? _getFontSize(), letterSpacing: widget.variant == "overline" ? 1.5 : null, fontWeight: widget.fontWeight ?? _getFontWeight(), fontFamily: widget.fontFamily ?? 'Poppins', - decoration: widget.textDecoration), + decoration: widget.textDecoration, + height: widget.fontHeight), ), if (widget.readMore && text.length > widget.maxLength && hidden) Positioned( From 15bead5164209dab1a707ea965541293cc01c547 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 4 May 2021 16:48:39 +0300 Subject: [PATCH 007/241] add insert IMEI service --- lib/core/service/auth_service.dart | 22 ++++++++++++ lib/core/viewModel/auth_view_model.dart | 39 --------------------- lib/core/viewModel/imei_view_model.dart | 45 ++++++++++++++++++++++--- lib/screens/home/home_screen.dart | 13 ++++--- 4 files changed, 71 insertions(+), 48 deletions(-) diff --git a/lib/core/service/auth_service.dart b/lib/core/service/auth_service.dart index bdc500d0..f4d0e096 100644 --- a/lib/core/service/auth_service.dart +++ b/lib/core/service/auth_service.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; +import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; @@ -25,6 +26,9 @@ class AuthService extends BaseService { Map _checkActivationCodeForDoctorAppRes = {}; Map get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; + Map _insertDeviceImeiRes = {}; + + Map get insertDeviceImeiRes => _insertDeviceImeiRes; Future selectDeviceImei(imei) async { try { // dynamic localRes; @@ -123,4 +127,22 @@ class AuthService extends BaseService { } } + + + Future insertDeviceImei(InsertIMEIDetailsModel insertIMEIDetailsModel)async { + hasError = false; + _insertDeviceImeiRes = {}; + try { + await baseAppClient.post(INSERT_DEVICE_IMEI, + onSuccess: (dynamic response, int statusCode) { + _insertDeviceImeiRes = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: insertIMEIDetailsModel.toJson()); + } catch (error) { + hasError = true; + super.error = error; + } + } } diff --git a/lib/core/viewModel/auth_view_model.dart b/lib/core/viewModel/auth_view_model.dart index add5db86..6eb85ebb 100644 --- a/lib/core/viewModel/auth_view_model.dart +++ b/lib/core/viewModel/auth_view_model.dart @@ -56,45 +56,6 @@ class AuthViewModel extends BaseViewModel { } } - - Future insertDeviceImei(request) async { - var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); - var user = await sharedPref.getObj(LAST_LOGIN_USER); - if (user != null) { - user = GetIMEIDetailsModel.fromJson(user); - } - request['IMEI'] = DEVICE_TOKEN; - request['LogInTypeID'] = await sharedPref.getInt(OTP_TYPE); - request['BioMetricEnabled'] = true; - request['MobileNo'] = - loggedIn != null ? loggedIn['MobileNumber'] : user.mobile; - InsertIMEIDetailsModel nRequest = InsertIMEIDetailsModel.fromJson(request); - nRequest.genderDescription = request['Gender_Description']; - nRequest.genderDescriptionN = request['Gender_DescriptionN']; - nRequest.genderDescriptionN = request['Gender_DescriptionN']; - nRequest.titleDescription = request['Title_Description']; - nRequest.titleDescriptionN = request['Title_DescriptionN']; - nRequest.projectID = await sharedPref.getInt(PROJECT_ID); - nRequest.doctorID = loggedIn != null - ? loggedIn['List_MemberInformation'][0]['MemberID'] - : user.doctorID; - nRequest.outSA = loggedIn != null ? loggedIn['PatientOutSA'] : user.outSA; - nRequest.vidaAuthTokenID = await sharedPref.getString(VIDA_AUTH_TOKEN_ID); - nRequest.vidaRefreshTokenID = - await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); - nRequest.password = await sharedPref.getString(PASSWORD); - try { - var localRes; - await baseAppClient.post(INSERT_DEVICE_IMEI, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - }, onFailure: (String error, int statusCode) {}, body: nRequest.toJson()); - return Future.value(localRes); - } catch (error) { - throw error; - } - } - Future getDocProfiles(docInfo, {bool allowChangeProfile = true}) async { try { diff --git a/lib/core/viewModel/imei_view_model.dart b/lib/core/viewModel/imei_view_model.dart index 09bfe8b3..90fb3578 100644 --- a/lib/core/viewModel/imei_view_model.dart +++ b/lib/core/viewModel/imei_view_model.dart @@ -1,8 +1,10 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; +import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/service/auth_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; @@ -11,10 +13,6 @@ import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:provider/provider.dart'; - -import 'auth_view_model.dart'; class IMEIViewModel extends BaseViewModel { AuthService _authService = locator(); @@ -37,6 +35,45 @@ class IMEIViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future insertDeviceImei() async { + + var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); + var user = await sharedPref.getObj(LAST_LOGIN_USER); + if (user != null) { + user = GetIMEIDetailsModel.fromJson(user); + } + + var profileInfo = await sharedPref.getObj(DOCTOR_PROFILE); + + profileInfo['IMEI'] = DEVICE_TOKEN; + profileInfo['LogInTypeID'] = await sharedPref.getInt(OTP_TYPE); + profileInfo['BioMetricEnabled'] = true; + profileInfo['MobileNo'] = + loggedIn != null ? loggedIn['MobileNumber'] : user.mobile; + InsertIMEIDetailsModel insertIMEIDetailsModel = InsertIMEIDetailsModel.fromJson(profileInfo); + insertIMEIDetailsModel.genderDescription = profileInfo['Gender_Description']; + insertIMEIDetailsModel.genderDescriptionN = profileInfo['Gender_DescriptionN']; + insertIMEIDetailsModel.genderDescriptionN = profileInfo['Gender_DescriptionN']; + insertIMEIDetailsModel.titleDescription = profileInfo['Title_Description']; + insertIMEIDetailsModel.titleDescriptionN = profileInfo['Title_DescriptionN']; + insertIMEIDetailsModel.projectID = await sharedPref.getInt(PROJECT_ID); + insertIMEIDetailsModel.doctorID = loggedIn != null + ? loggedIn['List_MemberInformation'][0]['MemberID'] + : user.doctorID; + insertIMEIDetailsModel.outSA = loggedIn != null ? loggedIn['PatientOutSA'] : user.outSA; + insertIMEIDetailsModel.vidaAuthTokenID = await sharedPref.getString(VIDA_AUTH_TOKEN_ID); + insertIMEIDetailsModel.vidaRefreshTokenID = + await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); + insertIMEIDetailsModel.password = await sharedPref.getString(PASSWORD); + + await _authService.insertDeviceImei(insertIMEIDetailsModel); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + Future login(UserModel userInfo) async { setState(ViewState.BusyLocal); await _authService.login(userInfo); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 1fc4c795..f2d72b83 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -7,6 +7,7 @@ import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; @@ -42,6 +43,7 @@ import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:provider/provider.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; +import '../../locator.dart'; import '../../widgets/shared/app_texts_widget.dart'; import '../../widgets/shared/rounded_container_widget.dart'; import 'home_page_card.dart'; @@ -73,6 +75,9 @@ class _HomeScreenState extends State { var clinicId; var _patientSearchFormValues; + IMEIViewModel _IMEIViewModel = locator(); + + void didChangeDependencies() async { super.didChangeDependencies(); if (_isInit) { @@ -92,11 +97,9 @@ class _HomeScreenState extends State { _firebaseMessaging.getToken().then((String token) async { if (token != '') { DEVICE_TOKEN = token; - var request = await sharedPref.getObj(DOCTOR_PROFILE); - authProvider.insertDeviceImei(request).then((value) { - // print(value); - changeIsLoading(false); - }); + await _IMEIViewModel.insertDeviceImei(); + changeIsLoading(false); + } }); } From 4ce9a3c5bffb4c660ff3a0bd102392dcadbb3822 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 5 May 2021 12:32:16 +0300 Subject: [PATCH 008/241] finish home-refactoring --- .../home/dashboard_slider-item-widget.dart | 2 +- lib/screens/home/home_page_card.dart | 6 +- lib/screens/home/home_patient_card.dart | 83 +++++ lib/screens/home/home_screen.dart | 323 ++++-------------- lib/widgets/dashboard/activity_button.dart | 8 +- 5 files changed, 149 insertions(+), 273 deletions(-) create mode 100644 lib/screens/home/home_patient_card.dart diff --git a/lib/screens/home/dashboard_slider-item-widget.dart b/lib/screens/home/dashboard_slider-item-widget.dart index 9a42b4b6..4ee67daf 100644 --- a/lib/screens/home/dashboard_slider-item-widget.dart +++ b/lib/screens/home/dashboard_slider-item-widget.dart @@ -28,7 +28,7 @@ class DashboardSliderItemWidget extends StatelessWidget { child: new ListView( scrollDirection: Axis.horizontal, children: - new List.generate(item.summaryoptions.length, (int index) { + List.generate(item.summaryoptions.length, (int index) { return GetActivityButton(item.summaryoptions[index]); }))) ], diff --git a/lib/screens/home/home_page_card.dart b/lib/screens/home/home_page_card.dart index 2f85ff89..64b870b4 100644 --- a/lib/screens/home/home_page_card.dart +++ b/lib/screens/home/home_page_card.dart @@ -26,8 +26,8 @@ class HomePageCard extends StatelessWidget { child: Container( width: 100, height: MediaQuery.of(context).orientation == Orientation.portrait - ? 130 - : 250, + ? 100 + : 200, margin: this.margin, decoration: BoxDecoration( color: !hasBorder @@ -41,7 +41,7 @@ class HomePageCard extends StatelessWidget { : Border.all(width: 0.0, color: Colors.transparent), image: imageName != null ? DecorationImage( - image: AssetImage('assets/images/dashboard/${imageName}'), + image: AssetImage('assets/images/dashboard/$imageName'), fit: BoxFit.cover, colorFilter: new ColorFilter.mode( Colors.black.withOpacity(0.2), BlendMode.dstIn), diff --git a/lib/screens/home/home_patient_card.dart b/lib/screens/home/home_patient_card.dart new file mode 100644 index 00000000..c604fdd7 --- /dev/null +++ b/lib/screens/home/home_patient_card.dart @@ -0,0 +1,83 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/screens/home/home_page_card.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class HomePatientCard extends StatelessWidget { + final Color backgroundColor; + final IconData cardIcon; + final Color backgroundIconColor; + final String text; + final Color textColor; + final Function onTap; + + HomePatientCard({ + @required this.backgroundColor, + @required this.backgroundIconColor, + @required this.cardIcon, + @required this.text, + @required this.textColor, + @required this.onTap, + }); + + @override + Widget build(BuildContext context) { + return HomePageCard( + color: backgroundColor, + margin: EdgeInsets.all(4), + child: Container( + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Stack( + children: [ + Positioned( + bottom: 0.1, + right: 0.5, + width: 23.0, + height: 25.0, + child: Icon( + cardIcon, + size: 60, + color: backgroundIconColor, + ), + ), + Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + cardIcon, + size: 30, + color: textColor, + ), + SizedBox( + height: 4, + ), + ], + ), + ), + ], + ), + ), + Expanded( + child: Container( + child: AppText( + text, + color: textColor, + textAlign: TextAlign.start, + fontSize: SizeConfig.textMultiplier * 1.6, + ), + ), + ), + ], + ), + ), + hasBorder: false, + onTap: onTap, + ); + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index dcf2980d..49f83a66 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -7,6 +7,7 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_swipe_widget.dart'; +import 'package:doctor_app_flutter/screens/home/home_patient_card.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/PatientsInPatientScreen.dart'; import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_screen.dart'; @@ -246,90 +247,44 @@ class _HomeScreenState extends State { margin: EdgeInsets.only(top: 10), child: Column( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 10, ), - Row( - children: [ - Container( - width: 150, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).patients, - style: TextStyle( - fontSize: 12, - height: .5, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins'), - ), - Text( - TranslationBase.of(context).services, - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins'), - ), - ], - )), + Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).patients, + fontSize: 12, + fontWeight: FontWeight.bold, + fontHeight: .5, + ), + AppText( + TranslationBase.of(context).services, + fontSize: 22, + fontWeight: FontWeight.bold, + ), ], - ), + )), SizedBox( height: 10, ), - new Container( - height: 130, - child: new ListView( + Container( + height: 100, + child: ListView( scrollDirection: Axis.horizontal, children: [ - HomePageCard( - color: Color(0xffD02127), - margin: EdgeInsets.all(5), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - top: 10, left: 10, right: 0), - child: Stack( - children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, - child: Icon( - DoctorApp.inpatient, - size: 65, - color: Colors.white12, - ), - ), - Icon( - DoctorApp.inpatient, - size: 32, - color: Colors.white, - ), - ], - )), - Container( - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context) - .inPatient, - color: Colors.white, - textAlign: TextAlign.start, - fontSize: 15, - )) - ], - ), - hasBorder: false, + HomePatientCard( + backgroundColor: Color(0xffD02127), + backgroundIconColor: Colors.white12, + cardIcon: DoctorApp.inpatient, + textColor: Colors.white, + text: + TranslationBase.of(context).inPatient, onTap: () { Navigator.push( context, @@ -339,51 +294,13 @@ class _HomeScreenState extends State { ); }, ), - HomePageCard( - color: Colors.grey[300], - margin: EdgeInsets.all(5), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - top: 10, left: 10, right: 0), - child: Stack( - children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, - child: Icon( - DoctorApp - .arrival_patients, - size: 65, - color: Colors.white38, - ), - ), - Icon( - DoctorApp.arrival_patients, - size: 35, - color: Colors.black, - ), - ], - )), - Container( - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context) - .myOutPatient, - color: Colors.black, - textAlign: TextAlign.start, - fontSize: 15, - )) - ], - ), - hasBorder: false, + HomePatientCard( + backgroundColor: Colors.grey[300], + backgroundIconColor: Colors.white38, + cardIcon: DoctorApp.arrival_patients, + textColor: Colors.black, + text: TranslationBase.of(context) + .myOutPatient, onTap: () { String date = DateUtils.convertDateToFormat( @@ -407,106 +324,30 @@ class _HomeScreenState extends State { )); }, ), - HomePageCard( - color: Color(0xff2B353E), - margin: EdgeInsets.all(5), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - top: 10, left: 10, right: 0), - child: Stack( - children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, - child: Icon( - DoctorApp.referral_1, - size: 65, - color: Colors.white10 - .withOpacity(0.1), - ), - ), - Icon( - DoctorApp.referral_1, - size: 35, - color: Colors.white, - ), - ], - )), - Container( - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context) - .patientsreferral, - color: Colors.white, - textAlign: TextAlign.start, - fontSize: 15, - )) - ], - ), - hasBorder: false, + HomePatientCard( + backgroundColor: Color(0xff2B353E), + backgroundIconColor: Colors.white10, + cardIcon: DoctorApp.referral_1, + textColor: Colors.white, + text: TranslationBase.of(context) + .patientsreferral, onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => PatientReferralScreen(), - // MyReferredPatient(), ), ); }, ), - HomePageCard( - color: Color(0xffD02127), - margin: EdgeInsets.all(5), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - top: 10, left: 10, right: 0), - child: Stack( - children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, - child: Icon( - DoctorApp.search, - size: 65, - color: Colors.white10, - ), - ), - Icon( - DoctorApp.search, - size: 35, - color: Colors.white, - ), - ], - )), - Container( - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context) - .searchPatient, - color: Colors.white, - textAlign: TextAlign.start, - fontSize: 13, - )) - ], - ), - hasBorder: false, + HomePatientCard( + backgroundColor: Color(0xffD02127), + backgroundIconColor: Colors.white10, + cardIcon: DoctorApp.search, + textColor: Colors.white, + text: TranslationBase.of(context) + .searchPatient, onTap: () { Navigator.push( context, @@ -516,51 +357,13 @@ class _HomeScreenState extends State { )); }, ), - HomePageCard( - color: Color(0xffC9C9C9), - margin: EdgeInsets.all(5), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - top: 10, left: 10, right: 0), - child: Stack( - children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, - child: Icon( - DoctorApp - .search_medicines, - color: Colors.black12, - size: 65, - ), - ), - Icon( - DoctorApp.search_medicines, - size: 40, - color: Color(0xff2B353E), - ), - ], - )), - Container( - padding: EdgeInsets.all(10), - child: AppText( - TranslationBase.of(context) - .searchMedicine, - color: Color(0xff2B353E), - textAlign: TextAlign.start, - fontSize: 13, - )) - ], - ), - hasBorder: false, + HomePatientCard( + backgroundColor: Color(0xffC9C9C9), + backgroundIconColor: Colors.black12, + cardIcon: DoctorApp.search_medicines, + textColor: Color(0xff2B353E), + text: TranslationBase.of(context) + .searchMedicine, onTap: () { Navigator.push( context, @@ -569,17 +372,8 @@ class _HomeScreenState extends State { MedicineSearchScreen(), )); }, - ) + ), ])), - Row( - // mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: 8, - ), - ], - ), SizedBox( height: 20, ), @@ -595,5 +389,4 @@ class _HomeScreenState extends State { ), ); } - } diff --git a/lib/widgets/dashboard/activity_button.dart b/lib/widgets/dashboard/activity_button.dart index 8258a1df..b925870f 100644 --- a/lib/widgets/dashboard/activity_button.dart +++ b/lib/widgets/dashboard/activity_button.dart @@ -17,17 +17,17 @@ class GetActivityButton extends StatelessWidget { ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( - padding: EdgeInsets.all(10), + padding: EdgeInsets.all(8), child: AppText(value.value.toString(), - fontSize: 32, fontWeight: FontWeight.bold)), + fontSize: 28, fontWeight: FontWeight.bold)), Expanded( child: AppText( value.kPIParameter, textOverflow: TextOverflow.clip, - fontSize: 12, + fontSize: 10, textAlign: TextAlign.center, fontWeight: FontWeight.w600, ), From a5120b473f40f9571cf0debb48c37e472e1a1df9 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 5 May 2021 12:44:38 +0300 Subject: [PATCH 009/241] rename Auth view model to Doctor Profile View Model --- lib/core/service/auth_service.dart | 8 ++++---- ..._model.dart => doctor_profile_view_model.dart} | 15 ++++----------- lib/core/viewModel/project_view_model.dart | 4 ++-- lib/main.dart | 6 +++--- lib/root_page.dart | 4 ++-- lib/screens/home/home_screen.dart | 4 ++-- .../patients/out_patient/out_patient_screen.dart | 4 ++-- .../patient_search_result_screen.dart | 4 ++-- .../patient_search/patient_search_screen.dart | 4 ++-- .../profile/note/progress_note_screen.dart | 4 ++-- .../referral/my-referral-detail-screen.dart | 4 ++-- .../referral/my-referral-patient-screen.dart | 4 ++-- .../assessment/add_assessment_details.dart | 2 +- lib/widgets/auth/verification_methods.dart | 10 +++++----- .../patients/profile/profile-welcome-widget.dart | 4 ++-- lib/widgets/shared/app_drawer_widget.dart | 4 ++-- 16 files changed, 39 insertions(+), 46 deletions(-) rename lib/core/viewModel/{auth_view_model.dart => doctor_profile_view_model.dart} (78%) diff --git a/lib/core/service/auth_service.dart b/lib/core/service/auth_service.dart index f4d0e096..ec7c2615 100644 --- a/lib/core/service/auth_service.dart +++ b/lib/core/service/auth_service.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; @@ -109,13 +109,13 @@ class AuthService extends BaseService { await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, onSuccess: (dynamic response, int statusCode) { // TODO improve the logic here - Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.clear(); + Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.clear(); _checkActivationCodeForDoctorAppRes = response; - Provider.of(AppGlobal.CONTEX, listen: false).selectedClinicName = + Provider.of(AppGlobal.CONTEX, listen: false).selectedClinicName = ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; response['List_DoctorsClinic'].forEach((v) { - Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.add(new ClinicModel.fromJson(v)); + Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.add(new ClinicModel.fromJson(v)); }); }, onFailure: (String error, int statusCode) { hasError = true; diff --git a/lib/core/viewModel/auth_view_model.dart b/lib/core/viewModel/doctor_profile_view_model.dart similarity index 78% rename from lib/core/viewModel/auth_view_model.dart rename to lib/core/viewModel/doctor_profile_view_model.dart index 6eb85ebb..24f53e5b 100644 --- a/lib/core/viewModel/auth_view_model.dart +++ b/lib/core/viewModel/doctor_profile_view_model.dart @@ -1,20 +1,13 @@ import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/core/model/imei_details.dart'; -import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import '../../models/doctor/user_model.dart'; - enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } -class AuthViewModel extends BaseViewModel { +class DoctorProfileViewModel extends BaseViewModel { List doctorsClinicList = []; String selectedClinicName; @@ -27,11 +20,11 @@ class AuthViewModel extends BaseViewModel { notifyListeners(); } - AuthViewModel() { - getUserAuthentication(); + DoctorProfileViewModel() { + getUserProfile(); } - getUserAuthentication() async { + getUserProfile() async { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); if (profile != null) { doctorProfile = new DoctorProfileModel.fromJson(profile); diff --git a/lib/core/viewModel/project_view_model.dart b/lib/core/viewModel/project_view_model.dart index 97974a04..0bf0c844 100644 --- a/lib/core/viewModel/project_view_model.dart +++ b/lib/core/viewModel/project_view_model.dart @@ -4,7 +4,7 @@ import 'package:connectivity/connectivity.dart'; import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; @@ -123,7 +123,7 @@ class ProjectViewModel with ChangeNotifier { projectID: doctorProfile.projectID, ); - Provider.of(AppGlobal.CONTEX, listen: false) + Provider.of(AppGlobal.CONTEX, listen: false) .getDocProfiles(docInfo.toJson()) .then((res) async { sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); diff --git a/lib/main.dart b/lib/main.dart index 83c2a450..7c70061c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,7 +11,7 @@ import 'package:provider/provider.dart'; import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; -import 'core/viewModel/auth_view_model.dart'; +import 'core/viewModel/doctor_profile_view_model.dart'; import 'core/viewModel/hospitals_view_model.dart'; import 'locator.dart'; @@ -33,8 +33,8 @@ class MyApp extends StatelessWidget { SizeConfig().init(constraints, orientation); return MultiProvider( providers: [ - ChangeNotifierProvider( - create: (context) => AuthViewModel()), + ChangeNotifierProvider( + create: (context) => DoctorProfileViewModel()), // ChangeNotifierProvider( // create: (context) => HospitalViewModel()), ChangeNotifierProvider( diff --git a/lib/root_page.dart b/lib/root_page.dart index 3bd24a81..7df1b7cb 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; import 'package:doctor_app_flutter/widgets/shared/dr_app_circular_progress_Indeicator.dart'; import 'package:flutter/cupertino.dart'; @@ -10,7 +10,7 @@ import 'landing_page.dart'; class RootPage extends StatelessWidget { @override Widget build(BuildContext context) { - AuthViewModel authProvider = Provider.of(context); + DoctorProfileViewModel authProvider = Provider.of(context); Widget buildRoot() { switch (authProvider.stutas) { case APP_STATUS.LOADING: diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f2d72b83..b3f79761 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; @@ -63,7 +63,7 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); - AuthViewModel authProvider; + DoctorProfileViewModel authProvider; bool isLoading = false; ProjectViewModel projectsProvider; var _isInit = true; diff --git a/lib/screens/patients/out_patient/out_patient_screen.dart b/lib/screens/patients/out_patient/out_patient_screen.dart index c8d197de..c6549568 100644 --- a/lib/screens/patients/out_patient/out_patient_screen.dart +++ b/lib/screens/patients/out_patient/out_patient_screen.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; @@ -60,7 +60,7 @@ class OutPatientsScreen extends StatefulWidget { class _OutPatientsScreenState extends State { int clinicId; - AuthViewModel authProvider; + DoctorProfileViewModel authProvider; List _times = []; //['All', 'Today', 'Tomorrow', 'Next Week']; diff --git a/lib/screens/patients/patient_search/patient_search_result_screen.dart b/lib/screens/patients/patient_search/patient_search_result_screen.dart index 0f536fcd..05de14db 100644 --- a/lib/screens/patients/patient_search/patient_search_result_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_result_screen.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; @@ -48,7 +48,7 @@ class PatientsSearchResultScreen extends StatefulWidget { class _PatientsSearchResultScreenState extends State { int clinicId; - AuthViewModel authProvider; + DoctorProfileViewModel authProvider; String patientType; diff --git a/lib/screens/patients/patient_search/patient_search_screen.dart b/lib/screens/patients/patient_search/patient_search_screen.dart index dc6d3587..192a37c9 100644 --- a/lib/screens/patients/patient_search/patient_search_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_screen.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_result_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; @@ -29,7 +29,7 @@ class _PatientSearchScreenState extends State { TextEditingController middleNameInfoController = TextEditingController(); TextEditingController lastNameFileInfoController = TextEditingController(); PatientType selectedPatientType = PatientType.inPatient; - AuthViewModel authProvider; + DoctorProfileViewModel authProvider; @override Widget build(BuildContext context) { diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 173115f9..38b4edad 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -42,7 +42,7 @@ class _ProgressNoteState extends State { final _controller = TextEditingController(); var _isInit = true; bool isDischargedPatient = false; - AuthViewModel authProvider; + DoctorProfileViewModel authProvider; ProjectViewModel projectViewModel; getProgressNoteList(BuildContext context, PatientViewModel model, diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 71edabb6..8eea6c34 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/my_referral/PendingReferral.dart'; @@ -24,7 +24,7 @@ class MyReferralDetailScreen extends StatelessWidget { Widget build(BuildContext context) { final gridHeight = (MediaQuery.of(context).size.width * 0.3) * 1.8; - AuthViewModel authProvider = Provider.of(context); + DoctorProfileViewModel authProvider = Provider.of(context); final routeArgs = ModalRoute.of(context).settings.arguments as Map; pendingReferral = routeArgs['referral']; diff --git a/lib/screens/patients/profile/referral/my-referral-patient-screen.dart b/lib/screens/patients/profile/referral/my-referral-patient-screen.dart index b2953cca..1482db74 100644 --- a/lib/screens/patients/profile/referral/my-referral-patient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-patient-screen.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -15,7 +15,7 @@ class MyReferralPatientScreen extends StatelessWidget { // previous design page is: MyReferralPatient @override Widget build(BuildContext context) { - AuthViewModel authProvider = Provider.of(context); + DoctorProfileViewModel authProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.getPendingReferralPatients(), diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index 47d639ad..57e2e53f 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -3,7 +3,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -// import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +// import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PatchAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index dc95f6dd..67252c6b 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -27,7 +27,7 @@ import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; import '../../config/size_config.dart'; -import '../../core/viewModel/auth_view_model.dart'; +import '../../core/viewModel/doctor_profile_view_model.dart'; import '../../landing_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; @@ -97,7 +97,7 @@ class _VerificationMethodsState extends State { @override Widget build(BuildContext context) { - AuthViewModel authProv = Provider.of(context); + DoctorProfileViewModel authProv = Provider.of(context); projectsProvider = Provider.of(context); return FutureBuilder( future: Future.wait([_loggedUserFuture]), @@ -331,7 +331,7 @@ class _VerificationMethodsState extends State { } sendActivationCodeByOtpNotificationType( - oTPSendType, AuthViewModel authProv) async { + oTPSendType, DoctorProfileViewModel authProv) async { // TODO : build enum for verfication method if (oTPSendType == 1 || oTPSendType == 2) { GifLoaderDialogUtils.showMyDialog(context); @@ -370,7 +370,7 @@ class _VerificationMethodsState extends State { } sendActivationCodeVerificationScreen( - oTPSendType, AuthViewModel authProv) async { + oTPSendType, DoctorProfileViewModel authProv) async { GifLoaderDialogUtils.showMyDialog(context); ActivationCodeForVerificationScreenModel activationCodeModel = ActivationCodeForVerificationScreenModel( iMEI: user.iMEI, @@ -734,7 +734,7 @@ class _VerificationMethodsState extends State { } } - checkActivationCode(AuthViewModel authProv, {value}) async { + checkActivationCode(DoctorProfileViewModel authProv, {value}) async { CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = new CheckActivationCodeRequestModel( zipCode: diff --git a/lib/widgets/patients/profile/profile-welcome-widget.dart b/lib/widgets/patients/profile/profile-welcome-widget.dart index 10586552..577d94bd 100644 --- a/lib/widgets/patients/profile/profile-welcome-widget.dart +++ b/lib/widgets/patients/profile/profile-welcome-widget.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -11,7 +11,7 @@ class ProfileWelcomeWidget extends StatelessWidget { @override Widget build(BuildContext context) { - AuthViewModel authProvider = Provider.of(context); + DoctorProfileViewModel authProvider = Provider.of(context); return Container( height: height, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index ebb49e6f..5ca6bf84 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/reschedule-leaves/add-rescheduleleave.dart'; @@ -28,7 +28,7 @@ class _AppDrawerState extends State { @override Widget build(BuildContext context) { - AuthViewModel authProvider = Provider.of(context); + DoctorProfileViewModel authProvider = Provider.of(context); projectsProvider = Provider.of(context); return RoundedContainer( child: Container( From 53791f1028fb43dd179ce80f39620c6998feb62a Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 5 May 2021 12:48:36 +0300 Subject: [PATCH 010/241] change imei to authentication --- ...auth_service.dart => authentication_service.dart} | 2 +- ...iew_model.dart => authentication_view_model.dart} | 6 +++--- lib/locator.dart | 8 ++++---- lib/screens/auth/login_screen.dart | 12 ++++++------ lib/screens/auth/verification_methods_screen.dart | 4 ++-- lib/screens/home/home_screen.dart | 4 ++-- lib/widgets/auth/verification_methods.dart | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) rename lib/core/service/{auth_service.dart => authentication_service.dart} (99%) rename lib/core/viewModel/{imei_view_model.dart => authentication_view_model.dart} (96%) diff --git a/lib/core/service/auth_service.dart b/lib/core/service/authentication_service.dart similarity index 99% rename from lib/core/service/auth_service.dart rename to lib/core/service/authentication_service.dart index ec7c2615..59d8e34a 100644 --- a/lib/core/service/auth_service.dart +++ b/lib/core/service/authentication_service.dart @@ -10,7 +10,7 @@ import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:provider/provider.dart'; -class AuthService extends BaseService { +class AuthenticationService extends BaseService { List _imeiDetails = []; List get dashboardItemsList => _imeiDetails; //TODO Change this to models diff --git a/lib/core/viewModel/imei_view_model.dart b/lib/core/viewModel/authentication_view_model.dart similarity index 96% rename from lib/core/viewModel/imei_view_model.dart rename to lib/core/viewModel/authentication_view_model.dart index 90fb3578..54a06c04 100644 --- a/lib/core/viewModel/imei_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -5,7 +5,7 @@ import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_mo import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; -import 'package:doctor_app_flutter/core/service/auth_service.dart'; +import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; @@ -14,8 +14,8 @@ import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_ import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; -class IMEIViewModel extends BaseViewModel { - AuthService _authService = locator(); +class AuthenticationViewModel extends BaseViewModel { + AuthenticationService _authService = locator(); HospitalsService _hospitalsService = locator(); List get imeiDetails => _authService.dashboardItemsList; diff --git a/lib/locator.dart b/lib/locator.dart index d0d76ea3..3032c49d 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/service/auth_service.dart'; +import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/service/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/medical_file_service.dart'; import 'package:doctor_app_flutter/core/service/patient_service.dart'; @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/core/service/procedure_service.dart'; import 'package:doctor_app_flutter/core/service/sickleave_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; @@ -75,7 +75,7 @@ void setupLocator() { locator.registerLazySingleton(() => MedicalFileService()); locator.registerLazySingleton(() => AdmissionRequestService()); locator.registerLazySingleton(() => UcafService()); - locator.registerLazySingleton(() => AuthService()); + locator.registerLazySingleton(() => AuthenticationService()); locator.registerLazySingleton(() => PatientMuseService()); locator.registerLazySingleton(() => LabsService()); locator.registerLazySingleton(() => InsuranceCardService()); @@ -90,7 +90,7 @@ void setupLocator() { /// View Model locator.registerFactory(() => DoctorReplayViewModel()); - locator.registerFactory(() => IMEIViewModel()); + locator.registerFactory(() => AuthenticationViewModel()); locator.registerFactory(() => ScheduleViewModel()); locator.registerFactory(() => ReferralPatientViewModel()); locator.registerFactory(() => ReferredPatientViewModel()); diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 5e069a2a..707e178c 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -6,8 +6,8 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; -import 'package:doctor_app_flutter/core/service/auth_service.dart'; -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/core/service/authentication_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; @@ -42,7 +42,7 @@ class _LoginsreenState extends State { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); bool _isLoading = true; ProjectViewModel projectViewModel; - AuthService authService = AuthService(); + AuthenticationService authService = AuthenticationService(); //TODO change AppTextFormField to AppTextFormFieldCustom final loginFormKey = GlobalKey(); @@ -99,7 +99,7 @@ class _LoginsreenState extends State { projectViewModel = Provider.of(context); - return BaseView( + return BaseView( onModelReady: (model) => {}, builder: (_, model, w) => AppScaffold( @@ -452,7 +452,7 @@ class _LoginsreenState extends State { } login(context, - IMEIViewModel model,) async { + AuthenticationViewModel model,) async { if (loginFormKey.currentState.validate()) { loginFormKey.currentState.save(); GifLoaderDialogUtils.showMyDialog(context); @@ -499,7 +499,7 @@ class _LoginsreenState extends State { primaryFocus.unfocus(); } - getProjects(memberID, IMEIViewModel model)async { + getProjects(memberID, AuthenticationViewModel model)async { if (memberID != null && memberID != '') { if (projectsList.length == 0) { await model.getHospitalsList(memberID); diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index a83db25c..3d44d726 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; @@ -27,7 +27,7 @@ class _VerificationMethodsScreenState extends State { @override Widget build(BuildContext context) { - return BaseView( + return BaseView( onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( isLoading: _isLoading, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index b3f79761..dad2460d 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -7,7 +7,7 @@ import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; @@ -75,7 +75,7 @@ class _HomeScreenState extends State { var clinicId; var _patientSearchFormValues; - IMEIViewModel _IMEIViewModel = locator(); + AuthenticationViewModel _IMEIViewModel = locator(); void didChangeDependencies() async { diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 67252c6b..7e268b06 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -3,7 +3,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; -import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; @@ -42,7 +42,7 @@ class VerificationMethods extends StatefulWidget { final password; final Function changeLoadingState; - final IMEIViewModel model; + final AuthenticationViewModel model; @override _VerificationMethodsState createState() => _VerificationMethodsState(); From 4f817810c2c28b25322e20888027922d91fb835e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 5 May 2021 13:24:17 +0300 Subject: [PATCH 011/241] hot fix --- lib/config/localized_values.dart | 1 + lib/screens/home/home_screen.dart | 2 +- lib/util/translations_delegate_base.dart | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d09d33f4..fb01bfb1 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': 'InPatients', 'ar': 'مرضاي'}, + 'myInPatient': {'en': 'My InPatients', 'ar': 'مرضاي'}, 'inPatientLabel': {'en': 'InPatients', 'ar': 'المريض الداخلي'}, 'inPatientAll': {'en': 'All InPatients', 'ar': 'كل المرضى'}, 'operations': {'en': 'Operations', 'ar': 'عمليات'}, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 49f83a66..3a048f52 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -284,7 +284,7 @@ class _HomeScreenState extends State { cardIcon: DoctorApp.inpatient, textColor: Colors.white, text: - TranslationBase.of(context).inPatient, + TranslationBase.of(context).myInPatient, onTap: () { Navigator.push( context, diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index ba69e104..bd9c68d9 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -100,6 +100,7 @@ class TranslationBase { String get referral => localizedValues['referral'][locale.languageCode]; String get inPatient => localizedValues['inPatient'][locale.languageCode]; + String get myInPatient => localizedValues['myInPatient'][locale.languageCode]; String get inPatientLabel => localizedValues['inPatientLabel'][locale.languageCode]; From 06706ad9a6cb332c056feaae239436485872f8d8 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 5 May 2021 13:32:47 +0300 Subject: [PATCH 012/241] Fix prescription item --- .../prescription_item_in_patient_page.dart | 182 ------------------ .../prescription/prescription_items_page.dart | 21 +- 2 files changed, 15 insertions(+), 188 deletions(-) diff --git a/lib/screens/prescription/prescription_item_in_patient_page.dart b/lib/screens/prescription/prescription_item_in_patient_page.dart index b29a2169..e79c1d8e 100644 --- a/lib/screens/prescription/prescription_item_in_patient_page.dart +++ b/lib/screens/prescription/prescription_item_in_patient_page.dart @@ -50,160 +50,6 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { child: Container( child: Column( children: [ - // if (!prescriptions.isInOutPatient) - // ...List.generate( - // model.prescriptionReportList.length, - // (index) => Container( - // decoration: BoxDecoration( - // borderRadius: BorderRadius.circular(12), - // color: Colors.white, - // ), - // margin: EdgeInsets.all(12), - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Container( - // margin: - // EdgeInsets.only(left: 18, right: 18), - // child: AppText( - // model.prescriptionReportList[index] - // .itemDescription.isNotEmpty - // ? model - // .prescriptionReportList[index] - // .itemDescription - // : model - // .prescriptionReportList[index] - // .itemDescriptionN, - // bold: true, - // )), - // SizedBox( - // height: 12, - // ), - // Row( - // children: [ - // SizedBox( - // width: 18, - // ), - // Container( - // decoration: BoxDecoration( - // shape: BoxShape.circle, - // border: Border.all( - // width: 0.5, - // color: Colors.grey)), - // height: 55, - // width: 55, - // child: InkWell( - // onTap: () { - // showDialog( - // context: context, - // child: ShowImageDialog( - // imageUrl: model - // .prescriptionReportEnhList[ - // index] - // .imageSRCUrl, - // )); - // }, - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // child: Image.network( - // model - // .prescriptionReportList[index] - // .imageSRCUrl, - // fit: BoxFit.cover, - // ), - // ), - // ), - // ), - // SizedBox( - // width: 10, - // ), - // Expanded( - // child: Column( - // crossAxisAlignment: - // CrossAxisAlignment.start, - // children: [ - // Row( - // children: [ - // AppText( - // TranslationBase.of(context) - // .route, - // color: Colors.grey, - // ), - // Expanded( - // child: AppText(" " + - // model - // .prescriptionReportList[ - // index] - // .routeN)), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context) - // .frequency, - // color: Colors.grey, - // ), - // AppText(" " + - // model - // .prescriptionReportList[ - // index] - // .frequencyN ?? - // ''), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context) - // .dailyDoses, - // color: Colors.grey, - // ), - // AppText(" " + - // model - // .prescriptionReportList[ - // index] - // .doseDailyQuantity ?? - // ''), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context) - // .duration, - // color: Colors.grey, - // ), - // AppText(" " + - // model - // .prescriptionReportList[ - // index] - // .days - // .toString() ?? - // ''), - // ], - // ), - // SizedBox( - // height: 12, - // ), - // AppText(model - // .prescriptionReportList[ - // index] - // .remarks ?? - // ''), - // ], - // ), - // ) - // ], - // ) - // ], - // ), - // ), - // )) - // else - Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), @@ -233,34 +79,6 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { SizedBox( width: 18, ), - // Container( - // decoration: BoxDecoration( - // shape: BoxShape.circle, - // border: Border.all( - // width: 0.5, color: Colors.grey)), - // height: 55, - // width: 55, - // child: InkWell( - // onTap: () { - // showDialog( - // context: context, - // // child: ShowImageDialog( - // // imageUrl: model - // // .inPatientPrescription[index] - // // .imageSRCUrl, - // // ), - // ); - // }, - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // // child: Image.network( - // // model.prescriptionReportEnhList[index] - // // .imageSRCUrl, - // // fit: BoxFit.cover, - // // ), - // ), - // ), - // ), SizedBox( width: 10, ), diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index 06d9634c..832c583d 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -8,6 +8,7 @@ import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_head 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/dialogs/ShowImageDialog.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -169,13 +170,21 @@ class PrescriptionItemsPage extends StatelessWidget { ) ); }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Image.network( - model.prescriptionReportEnhList[index].imageSRCUrl, - fit: BoxFit.cover, + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Image.network( + model.prescriptionReportEnhList[index].imageSRCUrl, + fit: BoxFit.cover, - ), + ), + ), + Positioned( + top: 10, + right: 10, + child: Icon(EvaIcons.search,color: Colors.grey,size: 35,)) + ], ), ), ), From f0039b491ee68249c133d760741e06fb1cf0e0df Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 5 May 2021 13:51:57 +0300 Subject: [PATCH 013/241] fix home page --- lib/core/viewModel/dashboard_view_model.dart | 1 + lib/screens/home/home_page_card.dart | 2 +- lib/screens/home/home_screen.dart | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index a12f3a87..faebd0c0 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -20,6 +20,7 @@ class DashboardViewModel extends BaseViewModel { _dashboardService.dashboardItemsList; Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthViewModel authProvider) async{ + setState(ViewState.Busy); await projectsProvider.getDoctorClinicsList(); // _firebaseMessaging.setAutoInitEnabled(true); diff --git a/lib/screens/home/home_page_card.dart b/lib/screens/home/home_page_card.dart index 64b870b4..55919c25 100644 --- a/lib/screens/home/home_page_card.dart +++ b/lib/screens/home/home_page_card.dart @@ -24,7 +24,7 @@ class HomePageCard extends StatelessWidget { return InkWell( onTap: onTap, child: Container( - width: 100, + width: 120, height: MediaQuery.of(context).orientation == Orientation.portrait ? 100 : 200, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 3a048f52..acfa36b1 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -274,7 +274,7 @@ class _HomeScreenState extends State { height: 10, ), Container( - height: 100, + height: 120, child: ListView( scrollDirection: Axis.horizontal, children: [ From fa194f5e0050f8ef13a3f65cda6e7dd153763833 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 5 May 2021 14:11:26 +0300 Subject: [PATCH 014/241] hot fix --- lib/config/localized_values.dart | 2 +- lib/screens/home/home_page_card.dart | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index fb01bfb1..8a1c2e01 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -48,7 +48,7 @@ const Map> localizedValues = { 'service': {'en': 'Service', 'ar': 'خدمة'}, 'referral': {'en': 'Referral', 'ar': 'الإحالة'}, 'inPatient': {'en': 'InPatients', 'ar': 'مرضاي'}, - 'myInPatient': {'en': 'My InPatients', 'ar': 'مرضاي'}, + 'myInPatient': {'en': 'My\nInPatients', 'ar': 'مرضاي'}, 'inPatientLabel': {'en': 'InPatients', 'ar': 'المريض الداخلي'}, 'inPatientAll': {'en': 'All InPatients', 'ar': 'كل المرضى'}, 'operations': {'en': 'Operations', 'ar': 'عمليات'}, diff --git a/lib/screens/home/home_page_card.dart b/lib/screens/home/home_page_card.dart index 64b870b4..a2200fad 100644 --- a/lib/screens/home/home_page_card.dart +++ b/lib/screens/home/home_page_card.dart @@ -48,9 +48,7 @@ class HomePageCard extends StatelessWidget { ) : null, ), - child: Center( - child: child, - ), + child: child, ), ); } From aab7808468a7bc5d128af84ef0db1994328bd12b Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 5 May 2021 14:48:22 +0300 Subject: [PATCH 015/241] add medical report page design --- .../medical_report/MedicalReportPage.dart | 125 +++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index f31c754e..6b85fa80 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -1,8 +1,131 @@ +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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/card_with_bg_widget.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class MedicalReportPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Container(); + final routeArgs = ModalRoute.of(context).settings.arguments as Map; + PatiantInformtion patient = routeArgs['patient']; + String patientType = routeArgs['patientType']; + bool isInpatient = routeArgs['isInpatient']; + ProjectViewModel projectViewModel = Provider.of(context); + //TODO Jammal + return AppScaffold( + appBar: PatientProfileHeaderNewDesignAppBar( + patient, + patient.patientType.toString() ?? '0', + patientType, + isInpatient: isInpatient, + ), + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox( + height: 12, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + "Medical", + style: "caption2", + color: Colors.black, + fontSize: 13, + ), + AppText( + "Report", + bold: true, + fontSize: 22, + ), + ], + ), + ), + AddNewOrder( + onTap: () { + + }, + label: "Create New Medical Report", + ), + ...List.generate( + /*model.patientLabOrdersList.length,*/1, + (index) => CardWithBgWidget( + hasBorder: false, + bgColor: 0==0? Colors.red[700]:Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText('On Hold',color: Colors.red,), + AppText( + "Jammal" ?? "", + fontSize: 15, + bold: true, + ), + ], + )), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + AppText( + '${DateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 14, + ), + AppText( + '${DateUtils.getHour(DateTime.now())}', + fontWeight: FontWeight.w600, + color: Colors.grey[700], + fontSize: 14, + ), + ], + ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: LargeAvatar( + name: "Jammal", + url: null, + ), + width: 55, + height: 55, + ), + Expanded(child: AppText("")), + Icon( + EvaIcons.eye, + ) + ], + ), + ], + ), + ), + ) + ], + ), + ), + ); } } From a3caf023e2f7a533f4c99a8dd306d061be0b9b48 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 5 May 2021 14:54:36 +0300 Subject: [PATCH 016/241] Add enum to verification_methods --- lib/core/enum/auth_method_types.dart | 24 +++ lib/widgets/{otp => auth}/sms-popup.dart | 5 +- lib/widgets/auth/verification_methods.dart | 190 ++++++++------------- 3 files changed, 101 insertions(+), 118 deletions(-) create mode 100644 lib/core/enum/auth_method_types.dart rename lib/widgets/{otp => auth}/sms-popup.dart (99%) diff --git a/lib/core/enum/auth_method_types.dart b/lib/core/enum/auth_method_types.dart new file mode 100644 index 00000000..3faff89c --- /dev/null +++ b/lib/core/enum/auth_method_types.dart @@ -0,0 +1,24 @@ +enum AuthMethodTypes { SMS, WhatsApp, Fingerprint,FaceID,MoreOptions } +extension SelectedAuthMethodTypesService on AuthMethodTypes { + // ignore: missing_return + int getTypeIdService() { + switch (this) { + case AuthMethodTypes.SMS: + return 1; + break; + case AuthMethodTypes.WhatsApp: + return 2; + break; + case AuthMethodTypes.Fingerprint: + return 3; + break; + case AuthMethodTypes.FaceID: + return 4; + break; + case AuthMethodTypes.MoreOptions: + return 5; + break; + + } + } +} \ No newline at end of file diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/auth/sms-popup.dart similarity index 99% rename from lib/widgets/otp/sms-popup.dart rename to lib/widgets/auth/sms-popup.dart index fca0d689..50674138 100644 --- a/lib/widgets/otp/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -9,7 +10,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class SMSOTP { - final type; + final AuthMethodTypes type; final mobileNo; final Function onSuccess; final Function onFailure; @@ -81,7 +82,7 @@ class SMSOTP { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - type == 1 + type == AuthMethodTypes.SMS ? Padding( child: Icon( DoctorApp.verify_sms_1, diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 7e268b06..6c7142c4 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -1,6 +1,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; @@ -14,7 +15,7 @@ import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/otp/sms-popup.dart'; +import 'package:doctor_app_flutter/widgets/auth/sms-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; @@ -57,15 +58,16 @@ class _VerificationMethodsState extends State { final LocalAuthentication auth = LocalAuthentication(); var _availableBiometrics; ProjectViewModel projectsProvider; - var isMoreOption = false; - var onlySMSBox = false; + bool isMoreOption = false; + bool onlySMSBox = false; var loginTokenID; + DoctorProfileViewModel doctorProfileViewModel; bool authenticated; - var fingrePrintBefore; + AuthMethodTypes fingrePrintBefore; - var selectedOption; + AuthMethodTypes selectedOption; @override void initState() { @@ -97,7 +99,7 @@ class _VerificationMethodsState extends State { @override Widget build(BuildContext context) { - DoctorProfileViewModel authProv = Provider.of(context); + doctorProfileViewModel = Provider.of(context); projectsProvider = Provider.of(context); return FutureBuilder( future: Future.wait([_loggedUserFuture]), @@ -112,7 +114,7 @@ class _VerificationMethodsState extends State { } else { return SingleChildScrollView( child: Container( - height: SizeConfig.realScreenHeight * .9, + height: SizeConfig.realScreenHeight * .87, width: SizeConfig.realScreenWidth, child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -253,14 +255,16 @@ class _VerificationMethodsState extends State { Expanded( child: InkWell( onTap: () => { - authenticateUser(3, - true, authProv) + // TODO check this logic it seem it will create bug to us + + authenticateUser(AuthMethodTypes.Fingerprint, + true) }, - child: getButton( - user.logInTypeID, - authProv))), + child: methodCard( + user.logInTypeID == 4 ?AuthMethodTypes.FaceID:user.logInTypeID == 2?AuthMethodTypes.WhatsApp:user.logInTypeID ==3? AuthMethodTypes.Fingerprint:AuthMethodTypes.SMS + ))), Expanded( - child: getButton(5, authProv)) + child: methodCard(AuthMethodTypes.MoreOptions)) ]), ]) : Column( @@ -274,11 +278,11 @@ class _VerificationMethodsState extends State { MainAxisAlignment.center, children: [ Expanded( - child: getButton( - 3, authProv)), + child: methodCard( + AuthMethodTypes.Fingerprint)), Expanded( - child: getButton( - 4, authProv)) + child: methodCard( + AuthMethodTypes.FaceID)) ], ) : SizedBox(), @@ -287,9 +291,9 @@ class _VerificationMethodsState extends State { MainAxisAlignment.center, children: [ Expanded( - child: getButton(1, authProv)), + child: methodCard(AuthMethodTypes.SMS)), Expanded( - child: getButton(2, authProv)) + child: methodCard(AuthMethodTypes.WhatsApp)) ], ), ]), @@ -325,15 +329,10 @@ class _VerificationMethodsState extends State { } }); } - - bool hideSilentMethods() { - return verificationMethod == 4 || verificationMethod == 3 ? true : false; - } - + sendActivationCodeByOtpNotificationType( - oTPSendType, DoctorProfileViewModel authProv) async { - // TODO : build enum for verfication method - if (oTPSendType == 1 || oTPSendType == 2) { + AuthMethodTypes authMethodType) async { + if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.showMyDialog(context); int projectID = await sharedPref.getInt(PROJECT_ID); @@ -343,7 +342,7 @@ class _VerificationMethodsState extends State { memberID: _loggedUser['List_MemberInformation'][0]['MemberID'], zipCode: _loggedUser['ZipCode'], mobileNumber: _loggedUser['MobileNumber'], - otpSendType: oTPSendType.toString(), + otpSendType: authMethodType.getTypeIdService().toString(), password: widget.password); await widget.model .sendActivationCodeForDoctorApp(activationCodeModel); @@ -358,11 +357,11 @@ class _VerificationMethodsState extends State { sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["LogInTokenID"]); sharedPref.setString(PASSWORD, widget.password); GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(oTPSendType, authProv); + this.startSMSService(authMethodType); } } else { // TODO route to this page with parameters to inicate we should present 2 option - if (Platform.isAndroid && oTPSendType == 3) { + if (Platform.isAndroid && authMethodType == AuthMethodTypes.Fingerprint) { Helpers.showErrorToast('Your device not support this feature'); } else { } @@ -370,7 +369,7 @@ class _VerificationMethodsState extends State { } sendActivationCodeVerificationScreen( - oTPSendType, DoctorProfileViewModel authProv) async { + AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); ActivationCodeForVerificationScreenModel activationCodeModel = ActivationCodeForVerificationScreenModel( iMEI: user.iMEI, @@ -378,7 +377,7 @@ class _VerificationMethodsState extends State { memberID: user.doctorID, zipCode: user.outSA == true ? '971' : '966', mobileNumber: user.mobile, - oTPSendType: oTPSendType, + oTPSendType: authMethodType ==AuthMethodTypes.FaceID?4:authMethodType ==AuthMethodTypes.Fingerprint?3:authMethodType ==AuthMethodTypes.WhatsApp?2:1, isMobileFingerPrint: 1, vidaAuthTokenID: user.vidaAuthTokenID, vidaRefreshTokenID: user.vidaRefreshTokenID); @@ -395,20 +394,20 @@ class _VerificationMethodsState extends State { sharedPref.setString( VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["LogInTokenID"]); - if (oTPSendType == 1 || oTPSendType == 2) { + if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(oTPSendType, authProv); + this.startSMSService(authMethodType); } else { - checkActivationCode(authProv); + checkActivationCode(); } } } - Widget getButton(flag, authProv) { - switch (flag) { - case 2: + Widget methodCard(AuthMethodTypes authMethodType) { + switch (authMethodType) { + case AuthMethodTypes.WhatsApp: return InkWell( - onTap: () => {authenticateUser(2, true, authProv)}, + onTap: () => {authenticateUser(AuthMethodTypes.WhatsApp, true)}, child: Container( margin: EdgeInsets.all(10), decoration: BoxDecoration( @@ -442,9 +441,9 @@ class _VerificationMethodsState extends State { ), ))); break; - case 1: + case AuthMethodTypes.SMS: return InkWell( - onTap: () => {authenticateUser(1, true, authProv)}, + onTap: () => {authenticateUser(AuthMethodTypes.SMS, true)}, child: Container( margin: EdgeInsets.all(10), decoration: BoxDecoration( @@ -462,11 +461,7 @@ class _VerificationMethodsState extends State { height: 60, width: 60, ), - projectsProvider.isArabic - ? SizedBox( - height: 20, - ) - : SizedBox( + SizedBox( height: 20, ), AppText( @@ -478,11 +473,11 @@ class _VerificationMethodsState extends State { ), ))); break; - case 3: + case AuthMethodTypes.Fingerprint: return InkWell( onTap: () => { if (checkIfBiometricAvailable(BiometricType.fingerprint)) - {authenticateUser(3, true, authProv)} + {authenticateUser(AuthMethodTypes.Fingerprint, true)} }, child: Container( margin: EdgeInsets.all(10), @@ -513,11 +508,11 @@ class _VerificationMethodsState extends State { ), ))); break; - case 4: + case AuthMethodTypes.FaceID: return InkWell( onTap: () { if (checkIfBiometricAvailable(BiometricType.face)) { - authenticateUser(4, true, authProv); + authenticateUser(AuthMethodTypes.FaceID, true); } }, child: @@ -622,41 +617,32 @@ class _VerificationMethodsState extends State { return isAvailable; } - formatDate(date) { - return DateFormat('MMM dd, yyy, kk:mm').format(date); - } - authenticateUser(type, isActive, authProv) { - //GifLoaderDialogUtils.showMyDialog(context); - if (type == 3 || type == 4) { - fingrePrintBefore = type; + authenticateUser( AuthMethodTypes authMethodType, isActive) { + if (authMethodType == AuthMethodTypes.Fingerprint || authMethodType == AuthMethodTypes.FaceID) { + fingrePrintBefore = authMethodType; } - this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; + this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : authMethodType; - switch (type) { - case 1: - this.loginWithSMS(1, isActive, authProv); + switch (authMethodType) { + case AuthMethodTypes.SMS: + sendActivationCode(authMethodType); break; - case 2: - this.loginWithSMS(2, isActive, authProv); - + case AuthMethodTypes.WhatsApp: + sendActivationCode(authMethodType); break; - case 3: - this.loginWithFingurePrintFace(3, isActive, authProv); + case AuthMethodTypes.Fingerprint: + this.loginWithFingerPrintOrFaceID(AuthMethodTypes.Fingerprint, isActive); break; - case 4: - this.loginWithFingurePrintFace(4, isActive, authProv); + case AuthMethodTypes.FaceID: + this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); break; default: break; } - sharedPref.setInt(OTP_TYPE, selectedOption); - // sharedPref.setInt(LAST_LOGIN), + sharedPref.setInt(OTP_TYPE, selectedOption.getTypeIdService()); } - loginWithSMS(type, isActive, authProv) { - this.sendActivationCode(type, authProv); - } Future _getAvailableBiometrics() async { var availableBiometrics; @@ -672,15 +658,15 @@ class _VerificationMethodsState extends State { }); } - sendActivationCode(type, authProv) async { + sendActivationCode(AuthMethodTypes authMethodType) async { if (user != null) { - sendActivationCodeVerificationScreen(type, authProv); + sendActivationCodeVerificationScreen(authMethodType); } else { - sendActivationCodeByOtpNotificationType(type, authProv); + sendActivationCodeByOtpNotificationType(authMethodType); } } - startSMSService(type, authProv) { + startSMSService(AuthMethodTypes type) { new SMSOTP( context, type, @@ -694,7 +680,7 @@ class _VerificationMethodsState extends State { ); }); - this.checkActivationCode(authProv, value: value); + this.checkActivationCode(value: value); }, () => { widget.changeLoadingState(false), @@ -703,10 +689,8 @@ class _VerificationMethodsState extends State { ).displayDialog(context); } - loginWithFingurePrintFace(type, isActive, authProv) async { + loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { if (isActive) { - // this.startBiometricLoginIfAvailable(); - const iosStrings = const IOSAuthMessages( cancelButton: 'cancel', goToSettingsButton: 'settings', @@ -724,8 +708,7 @@ class _VerificationMethodsState extends State { } if (!mounted) return; if (user != null && (user.logInTypeID == 3 || user.logInTypeID == 4)) { - this.sendActivationCode(type, authProv); - // this.checkActivationCode(authProv); + this.sendActivationCode(authMethodTypes); } else { setState(() { this.onlySMSBox = true; @@ -734,7 +717,7 @@ class _VerificationMethodsState extends State { } } - checkActivationCode(DoctorProfileViewModel authProv, {value}) async { + checkActivationCode( {value}) async { CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = new CheckActivationCodeRequestModel( zipCode: @@ -756,44 +739,20 @@ class _VerificationMethodsState extends State { } else { sharedPref.setString(TOKEN, widget.model.checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); if (widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != null) { - loginProcessCompleted(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0], authProv); + loginProcessCompleted(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); } else { sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); ClinicModel clinic = ClinicModel.fromJson(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); - getDocProfiles(clinic, authProv); + getDocProfiles(clinic); } } - - // authProv - // .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp) - // .then((res) async { - // widget.changeLoadingState(false); - // if (res['MessageStatus'] == 1) { - // sharedPref.setString(TOKEN, res['AuthenticationTokenID']); - // if (res['List_DoctorProfile'] != null) { - // loginProcessCompleted(res['List_DoctorProfile'][0], authProv); - // sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); - // } else { - // sharedPref.setObj(CLINIC_NAME, res['List_DoctorsClinic']); - // ClinicModel clinic = - // ClinicModel.fromJson(res['List_DoctorsClinic'][0]); - // getDocProfiles(clinic, authProv); - // } - // } else { - // Navigator.pop(context); - // Helpers.showErrorToast(res['ErrorEndUserMessage']); - // } - // }).catchError((err) { - // Navigator.pop(context); - // Helpers.showErrorToast(err); - // }); } - loginProcessCompleted(Map profile, authProv) { + loginProcessCompleted(Map profile) { var doctor = DoctorProfileModel.fromJson(profile); - authProv.setDoctorProfile(doctor); + doctorProfileViewModel.setDoctorProfile(doctor); sharedPref.setObj(DOCTOR_PROFILE, profile); projectsProvider.isLogin = true; @@ -805,7 +764,7 @@ class _VerificationMethodsState extends State { (r) => false); } - getDocProfiles(ClinicModel clinicInfo, authProv) { + getDocProfiles(ClinicModel clinicInfo) { ProfileReqModel docInfo = new ProfileReqModel( doctorID: clinicInfo.doctorID, clinicID: clinicInfo.clinicID, @@ -813,15 +772,14 @@ class _VerificationMethodsState extends State { projectID: clinicInfo.projectID, tokenID: '', languageID: 2); - authProv.getDocProfiles(docInfo.toJson()).then((res) { + doctorProfileViewModel.getDocProfiles(docInfo.toJson()).then((res) { if (res['MessageStatus'] == 1) { - loginProcessCompleted(res['DoctorProfileList'][0], authProv); + loginProcessCompleted(res['DoctorProfileList'][0]); } else { // changeLoadingState(false); Helpers.showErrorToast(res['ErrorEndUserMessage']); } }).catchError((err) { - // changeLoadingState(false); Helpers.showErrorToast(err); }); } From 2cf77bac85eec59e452c8ff79cfb509161db7955 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 5 May 2021 16:37:03 +0300 Subject: [PATCH 017/241] fit dashboard design --- lib/config/config.dart | 2 +- lib/widgets/dashboard/out_patient_stack.dart | 70 +++++++++++--------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index b21ee8ed..ec8efe26 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -337,7 +337,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 5.9; +const VERSION_ID = 6.0; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index c09e2757..ad79b106 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -4,7 +4,9 @@ import 'package:flutter/material.dart'; class GetOutPatientStack extends StatelessWidget { final value; + GetOutPatientStack(this.value); + @override Widget build(BuildContext context) { value.summaryoptions @@ -27,44 +29,48 @@ class GetOutPatientStack extends StatelessWidget { } getStack(Summaryoptions value, max) { - return Stack(children: [ - Container( - height: 150, - margin: EdgeInsets.all(5), - width: 35, - child: SizedBox(), + return Expanded( + child: Container( + margin: EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), color: Colors.red[50]), - ), - Positioned( - bottom: 0, - child: Container( + borderRadius: BorderRadius.circular(6), + color: Colors.red[50], + ), + child: Stack(children: [ + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( child: SizedBox(), - margin: EdgeInsets.all(5), padding: EdgeInsets.all(10), height: max != 0 ? (150 * value.value) / max : 0, - width: 35, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.red[300]))), - Container( - height: 150, - margin: EdgeInsets.only(left: 5, top: 5), - padding: EdgeInsets.all(10), - child: RotatedBox( - quarterTurns: 1, - child: Center( - child: Align( - child: FittedBox( - child: AppText( - value.kPIParameter + ' (' + value.value.toString() + ') ', - fontSize: 10, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, + borderRadius: BorderRadius.circular(6), + color: Color(0x63D02127), ), - )), ), - )) - ]); + ), + Container( + height: 150, + margin: EdgeInsets.only(left: 5, top: 5), + padding: EdgeInsets.all(10), + child: RotatedBox( + quarterTurns: 3, + child: Center( + child: Align( + child: FittedBox( + child: AppText( + value.kPIParameter + ' (' + value.value.toString() + ') ', + fontSize: 10, + textAlign: TextAlign.center, + fontWeight: FontWeight.bold, + ), + )), + ), + )) + ]), + ), + ); } } From 3ca4ac3632c93725e36695cf066189b97f3e44e6 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 5 May 2021 16:59:11 +0300 Subject: [PATCH 018/241] create method card and remove future builder from verification method widget --- lib/config/config.dart | 2 +- .../viewModel/authentication_view_model.dart | 56 + .../auth/verification_methods_screen.dart | 24 +- lib/widgets/auth/method_card.dart | 242 +++++ lib/widgets/auth/sms-popup.dart | 3 - lib/widgets/auth/verification_methods.dart | 959 +++++++----------- 6 files changed, 694 insertions(+), 592 deletions(-) create mode 100644 lib/widgets/auth/method_card.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index b21ee8ed..ec8efe26 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -337,7 +337,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 5.9; +const VERSION_ID = 6.0; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 54a06c04..474b91fe 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -13,6 +13,8 @@ import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:intl/intl.dart'; class AuthenticationViewModel extends BaseViewModel { AuthenticationService _authService = locator(); @@ -25,6 +27,8 @@ class AuthenticationViewModel extends BaseViewModel { get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; + var loggedUser; + GetIMEIDetailsModel user; Future selectDeviceImei(imei) async { setState(ViewState.Busy); await _authService.selectDeviceImei(imei); @@ -127,4 +131,56 @@ class AuthenticationViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + + + getDate(DateTime date) { + final DateFormat formatter = DateFormat('dd MMM yyyy'); + + return formatter.format(date); + } + + getTime(DateTime date) { + final DateFormat formatter = DateFormat('HH:mm a'); + + return formatter.format(date); + } + + + getType(type, context) { + switch (type) { + case 1: + return TranslationBase + .of(context) + .verifySMS; + break; + case 3: + return TranslationBase + .of(context) + .verifyFingerprint; + break; + case 4: + return TranslationBase + .of(context) + .verifyFaceID; + break; + case 2: + return TranslationBase.of(context).verifyWhatsApp; + break; + default: + return TranslationBase.of(context).verifySMS; + break; + } + } + + getInitUserInfo()async{ + setState(ViewState.Busy); + loggedUser = await sharedPref.getObj(LOGGED_IN_USER); + var lastLogin = await sharedPref.getObj(LAST_LOGIN_USER); + if (lastLogin != null) { + user = GetIMEIDetailsModel.fromJson(lastLogin); + } + setState(ViewState.Idle); + + } } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 3d44d726..e4d2603d 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -28,29 +28,15 @@ class _VerificationMethodsScreenState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( isLoading: _isLoading, isShowAppBar: false, isHomeIcon: false, backgroundColor: HexColor('#F8F8F8'), - body: ListView(children: [ - Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - ), - VerificationMethods( - password: widget.password, - changeLoadingState: changeLoadingState, - model:model - ), - ], - ), - ), - ]))); + body:VerificationMethods( + password: widget.password, + changeLoadingState: changeLoadingState, + // model:model + ))); } } diff --git a/lib/widgets/auth/method_card.dart b/lib/widgets/auth/method_card.dart new file mode 100644 index 00000000..94bd261b --- /dev/null +++ b/lib/widgets/auth/method_card.dart @@ -0,0 +1,242 @@ +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; + +class MethodCard extends StatefulWidget { + final AuthMethodTypes authMethodType; + final Function ( AuthMethodTypes type, bool isActive) authenticateUser; + final Function onShowMore; + + const MethodCard({Key key, this.authMethodType, this.authenticateUser, this.onShowMore}) : super(key: key); + + @override + _MethodCardState createState() => _MethodCardState(); +} + +class _MethodCardState extends State { + + var _availableBiometrics; + + final LocalAuthentication auth = LocalAuthentication(); + ProjectViewModel projectsProvider; + + + + @override + void initState() { + super.initState(); + _getAvailableBiometrics(); + } + + + bool checkIfBiometricAvailable(BiometricType biometricType) { + bool isAvailable = false; + if (_availableBiometrics != null) { + for (var i = 0; i < _availableBiometrics.length; i++) { + if (biometricType == _availableBiometrics[i]) isAvailable = true; + } + } + return isAvailable; + } + + Future _getAvailableBiometrics() async { + var availableBiometrics; + try { + availableBiometrics = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + print(e); + } + if (!mounted) return; + + setState(() { + _availableBiometrics = availableBiometrics; + }); + } + @override + Widget build(BuildContext context) { + projectsProvider = Provider.of(context); + + switch (widget.authMethodType) { + case AuthMethodTypes.WhatsApp: + return InkWell( + onTap: () => {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + 'assets/images/verify-whtsapp.png', + height: 60, + width: 60, + ), + ], + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyWhatsApp, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.SMS: + return InkWell( + onTap: () => {widget.authenticateUser(AuthMethodTypes.SMS, true)}, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verify-sms.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifySMS, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.Fingerprint: + return InkWell( + onTap: () => { + if (checkIfBiometricAvailable(BiometricType.fingerprint)) + {widget.authenticateUser(AuthMethodTypes.Fingerprint, true)} + }, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verification_fingerprint_icon.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyFingerprint, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.FaceID: + return InkWell( + onTap: () { + if (checkIfBiometricAvailable(BiometricType.face)) { + widget.authenticateUser(AuthMethodTypes.FaceID, true); + } + }, + child: + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + margin: EdgeInsets.all(10), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verification_faceid_icon.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyFaceID, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + + default: + return InkWell( + onTap: widget.onShowMore, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/login/more_icon.png', + height: 60, + width: 60, + ), + projectsProvider.isArabic + ? SizedBox( + height: 20, + ) + : SizedBox( + height: 10, + ), + AppText( + TranslationBase.of(context).moreVerification, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + }; + } +} diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 50674138..61329758 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -61,9 +61,6 @@ class SMSOTP { projectProvider = Provider.of(context); return AlertDialog( contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 0.0, 24.0), - - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.all(Radius.circular(10.0))), content: StatefulBuilder(builder: (context, setState) { if (displayTime == '') { startTimer(setState); diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 6c7142c4..faadbf9e 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -7,22 +7,23 @@ import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.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/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:intl/intl.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; import 'package:provider/provider.dart'; @@ -33,30 +34,23 @@ import '../../landing_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../util/helpers.dart'; -import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart'; +import 'method_card.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); class VerificationMethods extends StatefulWidget { - VerificationMethods({this.changeLoadingState, this.password, this.model}); + VerificationMethods({this.changeLoadingState, this.password}); final password; final Function changeLoadingState; - final AuthenticationViewModel model; @override _VerificationMethodsState createState() => _VerificationMethodsState(); } class _VerificationMethodsState extends State { - MainAxisAlignment spaceBetweenMethods = MainAxisAlignment.spaceBetween; - Future _loggedUserFuture; - var _loggedUser; - var verificationMethod; - GetIMEIDetailsModel user; - final LocalAuthentication auth = LocalAuthentication(); - var _availableBiometrics; + ProjectViewModel projectsProvider; bool isMoreOption = false; bool onlySMSBox = false; @@ -65,564 +59,404 @@ class _VerificationMethodsState extends State { bool authenticated; - AuthMethodTypes fingrePrintBefore; + AuthMethodTypes fingerPrintBefore; AuthMethodTypes selectedOption; + AuthenticationViewModel model; + + final LocalAuthentication auth = LocalAuthentication(); @override void initState() { super.initState(); - _loggedUserFuture = getSharedPref(); - _getAvailableBiometrics(); - } - - Future getSharedPref() async { - sharedPref.getObj(LOGGED_IN_USER).then((userInfo) { - _loggedUser = userInfo; - }); - sharedPref.getObj(LAST_LOGIN_USER).then((lastLogin) { - if (lastLogin != null) { - user = GetIMEIDetailsModel.fromJson(lastLogin); - } - }); - - print(user); } + @override - void didChangeDependencies() { + void didChangeDependencies() async{ super.didChangeDependencies(); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - verificationMethod = - routeArgs != null ? routeArgs['verificationMethod'] : null; + } @override Widget build(BuildContext context) { doctorProfileViewModel = Provider.of(context); projectsProvider = Provider.of(context); - return FutureBuilder( - future: Future.wait([_loggedUserFuture]), - builder: (BuildContext context, AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return DrAppCircularProgressIndeicator(); - default: - if (snapshot.hasError) { - Helpers.showErrorToast('Error: ${snapshot.error}'); - return Text('Error: ${snapshot.error}'); - } else { - return SingleChildScrollView( - child: Container( - height: SizeConfig.realScreenHeight * .87, - width: SizeConfig.realScreenWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - child: Column( - children: [ - user != null && isMoreOption == false - ? Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText(TranslationBase.of(context) - .welcomeBack), - AppText( - Helpers.capitalize(user.doctorName), - fontSize: - SizeConfig.textMultiplier * 3.5, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).accountInfo, - fontSize: - SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 20, - ), - Card( - color: Colors.white, - child: Row( - children: [ - Flexible( - flex: 3, - child: ListTile( - title: Text( - TranslationBase.of( - context) - .lastLoginAt, - overflow: TextOverflow - .ellipsis, - style: TextStyle( - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w800, - fontSize: 14), - ), - subtitle: AppText( - getType( - user.logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - user.editedOn != null - ? getDate(DateUtils + return BaseView( + onModelReady: (model) async { + this.model = model; + await model.getInitUserInfo(); + }, + builder: (_, model, w) => AppScaffold( + isShowAppBar: false, + baseViewModel: model, + body: SingleChildScrollView( + child: Center( + child: FractionallySizedBox( + // widthFactor: 0.9, + child: Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), + + height: SizeConfig.realScreenHeight * .95, + width: SizeConfig.realScreenWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: Column( + + children: [ + SizedBox( + height: 100, + ), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).welcomeBack), + AppText( + Helpers.capitalize(model.user.doctorName), + fontSize: SizeConfig.textMultiplier * 3.5, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).accountInfo, + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.w600, + ), + SizedBox( + height: 20, + ), + Card( + color: Colors.white, + child: Row( + children: [ + Flexible( + flex: 3, + child: ListTile( + title: Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontWeight: + FontWeight.w800, + fontSize: 14), + ), + subtitle: AppText( + model.getType( + model.user.logInTypeID, + context), + fontSize: 14, + ))), + Flexible( + flex: 2, + child: ListTile( + title: AppText( + model.user.editedOn != null + ? model.getDate( + DateUtils .convertStringToDate( - user + model.user .editedOn)) - : user.createdOn != - null - ? getDate(DateUtils + : model.user.createdOn != null + ? model + .getDate(DateUtils .convertStringToDate( - user.createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - fontWeight: - FontWeight.w800, - ), - subtitle: AppText( - user.editedOn != null - ? getTime(DateUtils + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + fontWeight: FontWeight.w800, + ), + subtitle: AppText( + model.user.editedOn != null + ? model.getTime( + DateUtils .convertStringToDate( - user + model.user .editedOn)) - : user.createdOn != - null - ? getTime(DateUtils + : model.user.createdOn != null + ? model + .getTime(DateUtils .convertStringToDate( - user.createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - ), - )) - ], - )), - ], - ) - : Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - this.onlySMSBox == false - ? AppText( - TranslationBase.of(context) - .verifyLoginWith, - fontSize: - SizeConfig.textMultiplier * - 3.5, - textAlign: TextAlign.left, - ) - : AppText( - TranslationBase.of(context) - .verifyFingerprint2, - fontSize: - SizeConfig.textMultiplier * - 2.5, - textAlign: TextAlign.start, - ), - ]), - user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + ), + )) + ], + )), + ], + ) + : Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + this.onlySMSBox == false + ? AppText( + TranslationBase.of(context) + .verifyLoginWith, + fontSize: + SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: + SizeConfig.textMultiplier * 2.5, + textAlign: TextAlign.start, + ), + ]), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => { + // TODO check this logic it seem it will create bug to us + + authenticateUser( + AuthMethodTypes + .Fingerprint, + true) + }, + child: MethodCard( + authMethodType: model.user + .logInTypeID == + 4 + ? AuthMethodTypes.FaceID + : model.user.logInTypeID == 2 + ? AuthMethodTypes + .WhatsApp + : model.user.logInTypeID == + 3 + ? AuthMethodTypes + .Fingerprint + : AuthMethodTypes + .SMS, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + ), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.MoreOptions, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) + ]), + ]) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + onlySMSBox == false + ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( - child: InkWell( - onTap: () => { - // TODO check this logic it seem it will create bug to us - - authenticateUser(AuthMethodTypes.Fingerprint, - true) - }, - child: methodCard( - user.logInTypeID == 4 ?AuthMethodTypes.FaceID:user.logInTypeID == 2?AuthMethodTypes.WhatsApp:user.logInTypeID ==3? AuthMethodTypes.Fingerprint:AuthMethodTypes.SMS - ))), + child: MethodCard( + authMethodType: + AuthMethodTypes.Fingerprint, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), Expanded( - child: methodCard(AuthMethodTypes.MoreOptions)) - ]), - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: methodCard( - AuthMethodTypes.Fingerprint)), - Expanded( - child: methodCard( - AuthMethodTypes.FaceID)) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: methodCard(AuthMethodTypes.SMS)), - Expanded( - child: methodCard(AuthMethodTypes.WhatsApp)) - ], - ), - ]), - - // ) - ], - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - user != null - ? Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context) - .useAnotherAccount, - color: Colors.red[700], - onPressed: () { - Navigator.of(context).pushNamed(LOGIN); - }, - )), - ], - ) - : SizedBox(), - ], - ), + child: MethodCard( + authMethodType: + AuthMethodTypes.FaceID, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )) + ], + ) + : SizedBox(), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: MethodCard( + authMethodType: AuthMethodTypes.SMS, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.WhatsApp, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )) + ], + ), + ]), + + // ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + model.user != null + ? Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context) + .useAnotherAccount, + color: Colors.red[700], + onPressed: () { + Navigator.of(context).pushNamed(LOGIN); + }, + )), + ], + ) + : SizedBox(), ], ), - )); - } - } - }); + ], + ), + ), + ), + ), + ), + )); } - + sendActivationCodeByOtpNotificationType( AuthMethodTypes authMethodType) async { - if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.showMyDialog(context); int projectID = await sharedPref.getInt(PROJECT_ID); - // TODO create model for _loggedUser; + // TODO create model for model.loggedUser; ActivationCodeModel activationCodeModel = ActivationCodeModel( facilityId: projectID, - memberID: _loggedUser['List_MemberInformation'][0]['MemberID'], - zipCode: _loggedUser['ZipCode'], - mobileNumber: _loggedUser['MobileNumber'], + memberID: model.loggedUser['List_MemberInformation'][0]['MemberID'], + zipCode: model.loggedUser['ZipCode'], + mobileNumber: model.loggedUser['MobileNumber'], otpSendType: authMethodType.getTypeIdService().toString(), password: widget.password); - await widget.model - .sendActivationCodeForDoctorApp(activationCodeModel); - if(widget.model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(widget.model.error); - GifLoaderDialogUtils.hideDialog(context); - }else{ - print("VerificationCode : " + widget.model.activationCodeForDoctorAppRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["LogInTokenID"]); - sharedPref.setString(PASSWORD, widget.password); - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } + await model.sendActivationCodeForDoctorApp(activationCodeModel); + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + GifLoaderDialogUtils.hideDialog(context); + } else { + print("VerificationCode : " + + model.activationCodeForDoctorAppRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); + sharedPref.setString(VIDA_REFRESH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeForDoctorAppRes["LogInTokenID"]); + sharedPref.setString(PASSWORD, widget.password); + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(authMethodType); + } } else { // TODO route to this page with parameters to inicate we should present 2 option if (Platform.isAndroid && authMethodType == AuthMethodTypes.Fingerprint) { Helpers.showErrorToast('Your device not support this feature'); - } else { - } + } else {} } } - sendActivationCodeVerificationScreen( - AuthMethodTypes authMethodType) async { + sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); - ActivationCodeForVerificationScreenModel activationCodeModel = ActivationCodeForVerificationScreenModel( - iMEI: user.iMEI, - facilityId: user.projectID, - memberID: user.doctorID, - zipCode: user.outSA == true ? '971' : '966', - mobileNumber: user.mobile, - oTPSendType: authMethodType ==AuthMethodTypes.FaceID?4:authMethodType ==AuthMethodTypes.Fingerprint?3:authMethodType ==AuthMethodTypes.WhatsApp?2:1, + ActivationCodeForVerificationScreenModel activationCodeModel = + ActivationCodeForVerificationScreenModel( + iMEI: model.user.iMEI, + facilityId: model.user.projectID, + memberID: model.user.doctorID, + zipCode: model.user.outSA == true ? '971' : '966', + mobileNumber: model.user.mobile, + oTPSendType: authMethodType.getTypeIdService(), isMobileFingerPrint: 1, - vidaAuthTokenID: user.vidaAuthTokenID, - vidaRefreshTokenID: user.vidaRefreshTokenID); + vidaAuthTokenID: model.user.vidaAuthTokenID, + vidaRefreshTokenID: model.user.vidaRefreshTokenID); - await widget.model + await model .sendActivationCodeVerificationScreen(activationCodeModel); - if(widget.model.state == ViewState.ErrorLocal) { + if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(widget.model.error); + Helpers.showErrorToast(model.error); } else { - print("VerificationCode : " + widget.model.activationCodeVerificationScreenRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["LogInTokenID"]); - if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } else { - checkActivationCode(); - } - } - } - - Widget methodCard(AuthMethodTypes authMethodType) { - switch (authMethodType) { - case AuthMethodTypes.WhatsApp: - return InkWell( - onTap: () => {authenticateUser(AuthMethodTypes.WhatsApp, true)}, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - 'assets/images/verify-whtsapp.png', - height: 60, - width: 60, - ), - ], - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyWhatsApp, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.SMS: - return InkWell( - onTap: () => {authenticateUser(AuthMethodTypes.SMS, true)}, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verify-sms.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifySMS, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.Fingerprint: - return InkWell( - onTap: () => { - if (checkIfBiometricAvailable(BiometricType.fingerprint)) - {authenticateUser(AuthMethodTypes.Fingerprint, true)} - }, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_fingerprint_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFingerprint, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.FaceID: - return InkWell( - onTap: () { - if (checkIfBiometricAvailable(BiometricType.face)) { - authenticateUser(AuthMethodTypes.FaceID, true); - } - }, - child: - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - margin: EdgeInsets.all(10), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_faceid_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFaceID, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - - default: - return InkWell( - onTap: () => { - setState(() { - isMoreOption = true; - }) - }, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/login/more_icon.png', - height: 60, - width: 60, - ), - projectsProvider.isArabic - ? SizedBox( - height: 20, - ) - : SizedBox( - height: 10, - ), - AppText( - TranslationBase.of(context).moreVerification, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - } - } - - getType(type, context) { - switch (type) { - case 1: - return TranslationBase.of(context).verifySMS; - break; - case 3: - return TranslationBase.of(context).verifyFingerprint; - break; - case 4: - return TranslationBase.of(context).verifyFaceID; - break; - case 2: - return TranslationBase.of(context).verifyWhatsApp; - break; - default: - return TranslationBase.of(context).verifySMS; - break; - } - } - - bool checkIfBiometricAvailable(BiometricType biometricType) { - bool isAvailable = false; - if (_availableBiometrics != null) { - for (var i = 0; i < _availableBiometrics.length; i++) { - if (biometricType == _availableBiometrics[i]) isAvailable = true; + print("VerificationCode : " + + model.activationCodeVerificationScreenRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); + sharedPref.setString( + VIDA_REFRESH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeVerificationScreenRes["LogInTokenID"]); + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(authMethodType); + } else { + checkActivationCode(); } } - return isAvailable; } - - authenticateUser( AuthMethodTypes authMethodType, isActive) { - if (authMethodType == AuthMethodTypes.Fingerprint || authMethodType == AuthMethodTypes.FaceID) { - fingrePrintBefore = authMethodType; + authenticateUser(AuthMethodTypes authMethodType, isActive) { + if (authMethodType == AuthMethodTypes.Fingerprint || + authMethodType == AuthMethodTypes.FaceID) { + fingerPrintBefore = authMethodType; } - this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : authMethodType; + this.selectedOption = + fingerPrintBefore != null ? fingerPrintBefore : authMethodType; switch (authMethodType) { case AuthMethodTypes.SMS: @@ -632,7 +466,8 @@ class _VerificationMethodsState extends State { sendActivationCode(authMethodType); break; case AuthMethodTypes.Fingerprint: - this.loginWithFingerPrintOrFaceID(AuthMethodTypes.Fingerprint, isActive); + this.loginWithFingerPrintOrFaceID( + AuthMethodTypes.Fingerprint, isActive); break; case AuthMethodTypes.FaceID: this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); @@ -643,23 +478,8 @@ class _VerificationMethodsState extends State { sharedPref.setInt(OTP_TYPE, selectedOption.getTypeIdService()); } - - Future _getAvailableBiometrics() async { - var availableBiometrics; - try { - availableBiometrics = await auth.getAvailableBiometrics(); - } on PlatformException catch (e) { - print(e); - } - if (!mounted) return; - - setState(() { - _availableBiometrics = availableBiometrics; - }); - } - sendActivationCode(AuthMethodTypes authMethodType) async { - if (user != null) { + if (model.user != null) { sendActivationCodeVerificationScreen(authMethodType); } else { sendActivationCodeByOtpNotificationType(authMethodType); @@ -667,10 +487,11 @@ class _VerificationMethodsState extends State { } startSMSService(AuthMethodTypes type) { + // TODO improve this logic new SMSOTP( context, type, - _loggedUser != null ? _loggedUser['MobileNumber'] : user.mobile, + model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, (value) { showDialog( context: context, @@ -682,14 +503,16 @@ class _VerificationMethodsState extends State { this.checkActivationCode(value: value); }, - () => { + () => + { widget.changeLoadingState(false), print('Faild..'), }, ).displayDialog(context); } - loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { + loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, + isActive) async { if (isActive) { const iosStrings = const IOSAuthMessages( cancelButton: 'cancel', @@ -707,7 +530,7 @@ class _VerificationMethodsState extends State { DrAppToastMsg.showErrorToast(e.toString()); } if (!mounted) return; - if (user != null && (user.logInTypeID == 3 || user.logInTypeID == 4)) { + if (model.user != null && (model.user.logInTypeID == 3 || model.user.logInTypeID == 4)) { this.sendActivationCode(authMethodTypes); } else { setState(() { @@ -717,34 +540,44 @@ class _VerificationMethodsState extends State { } } - checkActivationCode( {value}) async { + checkActivationCode({value}) async { CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = - new CheckActivationCodeRequestModel( - zipCode: - _loggedUser != null ? _loggedUser['ZipCode'] : user.zipCode, - mobileNumber: - _loggedUser != null ? _loggedUser['MobileNumber'] : user.mobile, - projectID: await sharedPref.getInt(PROJECT_ID) != null - ? await sharedPref.getInt(PROJECT_ID) - : user.projectID, - logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), - activationCode: value ?? '0000', - oTPSendType: await sharedPref.getInt(OTP_TYPE), - generalid: "Cs2020@2016\$2958"); - await widget.model.checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); - - if(widget.model.state == ViewState.ErrorLocal){ + new CheckActivationCodeRequestModel( + zipCode: + model.loggedUser != null ? model.loggedUser['ZipCode'] : model.user.zipCode, + mobileNumber: + model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, + projectID: await sharedPref.getInt(PROJECT_ID) != null + ? await sharedPref.getInt(PROJECT_ID) + : model.user.projectID, + logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), + activationCode: value ?? '0000', + oTPSendType: await sharedPref.getInt(OTP_TYPE), + generalid: "Cs2020@2016\$2958"); + await model + .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); + + if (model.state == ViewState.ErrorLocal) { Navigator.pop(context); - Helpers.showErrorToast(widget.model.error); + Helpers.showErrorToast(model.error); } else { - sharedPref.setString(TOKEN, widget.model.checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); - if (widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != null) { - loginProcessCompleted(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); - sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + sharedPref.setString( + TOKEN, + model + .checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); + if (model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != + null) { + loginProcessCompleted(model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); } else { - sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); - ClinicModel clinic = - ClinicModel.fromJson(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); getDocProfiles(clinic); } } @@ -783,16 +616,4 @@ class _VerificationMethodsState extends State { Helpers.showErrorToast(err); }); } - - getDate(DateTime date) { - final DateFormat formatter = DateFormat('dd MMM yyyy'); - - return formatter.format(date); - } - - getTime(DateTime date) { - final DateFormat formatter = DateFormat('HH:mm a'); - - return formatter.format(date); - } } From 32d26c3c4b4445c2eff8618ef25bb4c2e9a039e3 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 5 May 2021 17:53:53 +0300 Subject: [PATCH 019/241] remove Verification Methods page and move some code to model --- .../viewModel/authentication_view_model.dart | 41 +- lib/routes.dart | 2 +- lib/screens/auth/login_screen.dart | 2 +- .../auth/verification_methods_screen.dart | 591 ++++++++++++++++- lib/widgets/auth/verification_methods.dart | 619 ------------------ 5 files changed, 609 insertions(+), 646 deletions(-) delete mode 100644 lib/widgets/auth/verification_methods.dart diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 474b91fe..a8dda45f 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; @@ -88,8 +89,19 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future sendActivationCodeVerificationScreen(ActivationCodeForVerificationScreenModel activationCodeModel) async { + Future sendActivationCodeVerificationScreen( AuthMethodTypes authMethodType) async { setState(ViewState.BusyLocal); + ActivationCodeForVerificationScreenModel activationCodeModel = + ActivationCodeForVerificationScreenModel( + iMEI: user.iMEI, + facilityId: user.projectID, + memberID: user.doctorID, + zipCode: user.outSA == true ? '971' : '966', + mobileNumber: user.mobile, + oTPSendType: authMethodType.getTypeIdService(), + isMobileFingerPrint: 1, + vidaAuthTokenID: user.vidaAuthTokenID, + vidaRefreshTokenID: user.vidaRefreshTokenID); await _authService.sendActivationCodeVerificationScreen(activationCodeModel); if (_authService.hasError) { error = _authService.error; @@ -98,8 +110,16 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future sendActivationCodeForDoctorApp(ActivationCodeModel activationCodeModel) async { + Future sendActivationCodeForDoctorApp({AuthMethodTypes authMethodType, String password }) async { setState(ViewState.BusyLocal); + int projectID = await sharedPref.getInt(PROJECT_ID); + ActivationCodeModel activationCodeModel = ActivationCodeModel( + facilityId: projectID, + memberID: loggedUser['List_MemberInformation'][0]['MemberID'], + zipCode: loggedUser['ZipCode'], + mobileNumber: loggedUser['MobileNumber'], + otpSendType: authMethodType.getTypeIdService().toString(), + password: password); await _authService.sendActivationCodeForDoctorApp(activationCodeModel); if (_authService.hasError) { error = _authService.error; @@ -108,9 +128,22 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future checkActivationCodeForDoctorApp(CheckActivationCodeRequestModel checkActivationCodeRequestModel) async { + Future checkActivationCodeForDoctorApp({String activationCode}) async { setState(ViewState.BusyLocal); - await _authService.checkActivationCodeForDoctorApp(checkActivationCodeRequestModel); + CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = + new CheckActivationCodeRequestModel( + zipCode: + loggedUser != null ? loggedUser['ZipCode'] :user.zipCode, + mobileNumber: + loggedUser != null ? loggedUser['MobileNumber'] : user.mobile, + projectID: await sharedPref.getInt(PROJECT_ID) != null + ? await sharedPref.getInt(PROJECT_ID) + : user.projectID, + logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), + activationCode: activationCode ?? '0000', + oTPSendType: await sharedPref.getInt(OTP_TYPE), + generalid: "Cs2020@2016\$2958"); + await _authService.checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); if (_authService.hasError) { error = _authService.error; setState(ViewState.ErrorLocal); diff --git a/lib/routes.dart b/lib/routes.dart index 2684cd82..90e061b8 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -14,9 +14,9 @@ import 'package:doctor_app_flutter/screens/prescription/prescriptions_page.dart' import 'package:doctor_app_flutter/screens/procedures/procedure_screen.dart'; import 'package:doctor_app_flutter/screens/sick-leave/add-sickleave.dart'; import 'package:doctor_app_flutter/screens/sick-leave/show-sickleave.dart'; +import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import './screens/auth/login_screen.dart'; -import './screens/auth/verification_methods_screen.dart'; import 'screens/patients/profile/profile_screen/patient_profile_screen.dart'; import './screens/patients/profile/vital_sign/vital_sign_details_screen.dart'; import 'landing_page.dart'; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 707e178c..0048b10c 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -10,10 +10,10 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; -import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index e4d2603d..2b906588 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -1,42 +1,591 @@ +import 'dart:io' show Platform; + +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/imei_details.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/auth/sms-popup.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/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth/auth_strings.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; -import '../../widgets/auth/verification_methods.dart'; +import '../../config/size_config.dart'; +import '../../core/viewModel/doctor_profile_view_model.dart'; +import '../../landing_page.dart'; +import '../../routes.dart'; +import '../../util/dr_app_shared_pref.dart'; +import '../../util/helpers.dart'; +import '../../widgets/auth/method_card.dart'; -class VerificationMethodsScreen extends StatefulWidget { - const VerificationMethodsScreen({Key key, this.password}) : super(key: key); +DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); +Helpers helpers = Helpers(); - @override - _VerificationMethodsScreenState createState() => - _VerificationMethodsScreenState(); +class VerificationMethodsScreen extends StatefulWidget { + VerificationMethodsScreen({this.changeLoadingState, this.password}); final password; + final Function changeLoadingState; + + @override + _VerificationMethodsScreenState createState() => _VerificationMethodsScreenState(); } class _VerificationMethodsScreenState extends State { - bool _isLoading = false; + + ProjectViewModel projectsProvider; + bool isMoreOption = false; + bool onlySMSBox = false; + var loginTokenID; + DoctorProfileViewModel doctorProfileViewModel; - void changeLoadingState(isLoading) { - setState(() { - _isLoading = isLoading; - }); + bool authenticated; + + AuthMethodTypes fingerPrintBefore; + + AuthMethodTypes selectedOption; + AuthenticationViewModel model; + + final LocalAuthentication auth = LocalAuthentication(); + + @override + void initState() { + super.initState(); + } + + + @override + void didChangeDependencies() async{ + super.didChangeDependencies(); + } @override Widget build(BuildContext context) { + doctorProfileViewModel = Provider.of(context); + projectsProvider = Provider.of(context); return BaseView( + onModelReady: (model) async { + this.model = model; + await model.getInitUserInfo(); + }, builder: (_, model, w) => AppScaffold( - isLoading: _isLoading, - isShowAppBar: false, - isHomeIcon: false, - backgroundColor: HexColor('#F8F8F8'), - body:VerificationMethods( - password: widget.password, - changeLoadingState: changeLoadingState, - // model:model - ))); + isShowAppBar: false, + baseViewModel: model, + body: SingleChildScrollView( + child: Center( + child: FractionallySizedBox( + // widthFactor: 0.9, + child: Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), + + height: SizeConfig.realScreenHeight * .95, + width: SizeConfig.realScreenWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: Column( + + children: [ + SizedBox( + height: 100, + ), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).welcomeBack), + AppText( + Helpers.capitalize(model.user.doctorName), + fontSize: SizeConfig.textMultiplier * 3.5, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).accountInfo, + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.w600, + ), + SizedBox( + height: 20, + ), + Card( + color: Colors.white, + child: Row( + children: [ + Flexible( + flex: 3, + child: ListTile( + title: Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontWeight: + FontWeight.w800, + fontSize: 14), + ), + subtitle: AppText( + model.getType( + model.user.logInTypeID, + context), + fontSize: 14, + ))), + Flexible( + flex: 2, + child: ListTile( + title: AppText( + model.user.editedOn != null + ? model.getDate( + DateUtils + .convertStringToDate( + model.user + .editedOn)) + : model.user.createdOn != null + ? model + .getDate(DateUtils + .convertStringToDate( + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + fontWeight: FontWeight.w800, + ), + subtitle: AppText( + model.user.editedOn != null + ? model.getTime( + DateUtils + .convertStringToDate( + model.user + .editedOn)) + : model.user.createdOn != null + ? model + .getTime(DateUtils + .convertStringToDate( + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + ), + )) + ], + )), + ], + ) + : Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + this.onlySMSBox == false + ? AppText( + TranslationBase.of(context) + .verifyLoginWith, + fontSize: + SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: + SizeConfig.textMultiplier * 2.5, + textAlign: TextAlign.start, + ), + ]), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => { + // TODO check this logic it seem it will create bug to us + + authenticateUser( + AuthMethodTypes + .Fingerprint, + true) + }, + child: MethodCard( + authMethodType: model.user + .logInTypeID == + 4 + ? AuthMethodTypes.FaceID + : model.user.logInTypeID == 2 + ? AuthMethodTypes + .WhatsApp + : model.user.logInTypeID == + 3 + ? AuthMethodTypes + .Fingerprint + : AuthMethodTypes + .SMS, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + ), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.MoreOptions, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) + ]), + ]) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + onlySMSBox == false + ? Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.Fingerprint, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.FaceID, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )) + ], + ) + : SizedBox(), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: MethodCard( + authMethodType: AuthMethodTypes.SMS, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.WhatsApp, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )) + ], + ), + ]), + + // ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + model.user != null + ? Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context) + .useAnotherAccount, + color: Colors.red[700], + onPressed: () { + Navigator.of(context).pushNamed(LOGIN); + }, + )), + ], + ) + : SizedBox(), + ], + ), + ], + ), + ), + ), + ), + ), + )); + } + + sendActivationCodeByOtpNotificationType( + AuthMethodTypes authMethodType) async { + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { + GifLoaderDialogUtils.showMyDialog(context); + + + await model.sendActivationCodeForDoctorApp(authMethodType:authMethodType, password: widget.password ); + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + GifLoaderDialogUtils.hideDialog(context); + } else { + // TODO move it model + print("VerificationCode : " + + model.activationCodeForDoctorAppRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); + sharedPref.setString(VIDA_REFRESH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeForDoctorAppRes["LogInTokenID"]); + sharedPref.setString(PASSWORD, widget.password); + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(authMethodType); + } + } else { + // TODO route to this page with parameters to inicate we should present 2 option + if (Platform.isAndroid && authMethodType == AuthMethodTypes.Fingerprint) { + Helpers.showErrorToast('Your device not support this feature'); + } else {} + } + } + + sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { + GifLoaderDialogUtils.showMyDialog(context); + + + await model + .sendActivationCodeVerificationScreen(authMethodType); + + if (model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); + Helpers.showErrorToast(model.error); + } else { + //TODO Move it to view model + print("VerificationCode : " + + model.activationCodeVerificationScreenRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); + sharedPref.setString( + VIDA_REFRESH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeVerificationScreenRes["LogInTokenID"]); + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(authMethodType); + } else { + checkActivationCode(); + } + } + } + + authenticateUser(AuthMethodTypes authMethodType, isActive) { + if (authMethodType == AuthMethodTypes.Fingerprint || + authMethodType == AuthMethodTypes.FaceID) { + fingerPrintBefore = authMethodType; + } + this.selectedOption = + fingerPrintBefore != null ? fingerPrintBefore : authMethodType; + + switch (authMethodType) { + case AuthMethodTypes.SMS: + sendActivationCode(authMethodType); + break; + case AuthMethodTypes.WhatsApp: + sendActivationCode(authMethodType); + break; + case AuthMethodTypes.Fingerprint: + this.loginWithFingerPrintOrFaceID( + AuthMethodTypes.Fingerprint, isActive); + break; + case AuthMethodTypes.FaceID: + this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); + break; + default: + break; + } + sharedPref.setInt(OTP_TYPE, selectedOption.getTypeIdService()); + } + + sendActivationCode(AuthMethodTypes authMethodType) async { + if (model.user != null) { + sendActivationCodeVerificationScreen(authMethodType); + } else { + sendActivationCodeByOtpNotificationType(authMethodType); + } + } + + startSMSService(AuthMethodTypes type) { + // TODO improve this logic + new SMSOTP( + context, + type, + model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, + (value) { + showDialog( + context: context, + builder: (BuildContext context) { + return Center( + child: CircularProgressIndicator(), + ); + }); + + this.checkActivationCode(value: value); + }, + () => + { + widget.changeLoadingState(false), + print('Faild..'), + }, + ).displayDialog(context); + } + + loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, + isActive) async { + if (isActive) { + const iosStrings = const IOSAuthMessages( + cancelButton: 'cancel', + goToSettingsButton: 'settings', + goToSettingsDescription: 'Please set up your Touch ID.', + lockOut: 'Please reenable your Touch ID'); + + try { + authenticated = await auth.authenticateWithBiometrics( + localizedReason: 'Scan your fingerprint to authenticate', + useErrorDialogs: true, + stickyAuth: true, + iOSAuthStrings: iosStrings); + } on PlatformException catch (e) { + DrAppToastMsg.showErrorToast(e.toString()); + } + if (!mounted) return; + if (model.user != null && (model.user.logInTypeID == 3 || model.user.logInTypeID == 4)) { + this.sendActivationCode(authMethodTypes); + } else { + setState(() { + this.onlySMSBox = true; + }); + } + } + } + + checkActivationCode({value}) async { + + await model + .checkActivationCodeForDoctorApp(activationCode:value ); + + if (model.state == ViewState.ErrorLocal) { + Navigator.pop(context); + Helpers.showErrorToast(model.error); + } else { + sharedPref.setString( + TOKEN, + model + .checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); + if (model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != + null) { + loginProcessCompleted(model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + } else { + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); + getDocProfiles(clinic); + } + } + } + + loginProcessCompleted(Map profile) { + var doctor = DoctorProfileModel.fromJson(profile); + doctorProfileViewModel.setDoctorProfile(doctor); + sharedPref.setObj(DOCTOR_PROFILE, profile); + projectsProvider.isLogin = true; + + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false); + } + + getDocProfiles(ClinicModel clinicInfo) { + ProfileReqModel docInfo = new ProfileReqModel( + doctorID: clinicInfo.doctorID, + clinicID: clinicInfo.clinicID, + license: true, + projectID: clinicInfo.projectID, + tokenID: '', + languageID: 2); + doctorProfileViewModel.getDocProfiles(docInfo.toJson()).then((res) { + if (res['MessageStatus'] == 1) { + loginProcessCompleted(res['DoctorProfileList'][0]); + } else { + // changeLoadingState(false); + Helpers.showErrorToast(res['ErrorEndUserMessage']); + } + }).catchError((err) { + Helpers.showErrorToast(err); + }); } } diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart deleted file mode 100644 index faadbf9e..00000000 --- a/lib/widgets/auth/verification_methods.dart +++ /dev/null @@ -1,619 +0,0 @@ -import 'dart:io' show Platform; - -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/imei_details.dart'; -import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; -import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/auth/sms-popup.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; -import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:local_auth/auth_strings.dart'; -import 'package:local_auth/local_auth.dart'; -import 'package:provider/provider.dart'; - -import '../../config/size_config.dart'; -import '../../core/viewModel/doctor_profile_view_model.dart'; -import '../../landing_page.dart'; -import '../../routes.dart'; -import '../../util/dr_app_shared_pref.dart'; -import '../../util/helpers.dart'; -import 'method_card.dart'; - -DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); -Helpers helpers = Helpers(); - -class VerificationMethods extends StatefulWidget { - VerificationMethods({this.changeLoadingState, this.password}); - - final password; - final Function changeLoadingState; - - @override - _VerificationMethodsState createState() => _VerificationMethodsState(); -} - -class _VerificationMethodsState extends State { - - ProjectViewModel projectsProvider; - bool isMoreOption = false; - bool onlySMSBox = false; - var loginTokenID; - DoctorProfileViewModel doctorProfileViewModel; - - bool authenticated; - - AuthMethodTypes fingerPrintBefore; - - AuthMethodTypes selectedOption; - AuthenticationViewModel model; - - final LocalAuthentication auth = LocalAuthentication(); - - @override - void initState() { - super.initState(); - } - - - @override - void didChangeDependencies() async{ - super.didChangeDependencies(); - - } - - @override - Widget build(BuildContext context) { - doctorProfileViewModel = Provider.of(context); - projectsProvider = Provider.of(context); - return BaseView( - onModelReady: (model) async { - this.model = model; - await model.getInitUserInfo(); - }, - builder: (_, model, w) => AppScaffold( - isShowAppBar: false, - baseViewModel: model, - body: SingleChildScrollView( - child: Center( - child: FractionallySizedBox( - // widthFactor: 0.9, - child: Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - - height: SizeConfig.realScreenHeight * .95, - width: SizeConfig.realScreenWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - child: Column( - - children: [ - SizedBox( - height: 100, - ), - model.user != null && isMoreOption == false - ? Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).welcomeBack), - AppText( - Helpers.capitalize(model.user.doctorName), - fontSize: SizeConfig.textMultiplier * 3.5, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).accountInfo, - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 20, - ), - Card( - color: Colors.white, - child: Row( - children: [ - Flexible( - flex: 3, - child: ListTile( - title: Text( - TranslationBase.of(context) - .lastLoginAt, - overflow: - TextOverflow.ellipsis, - style: TextStyle( - fontFamily: 'Poppins', - fontWeight: - FontWeight.w800, - fontSize: 14), - ), - subtitle: AppText( - model.getType( - model.user.logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - model.user.editedOn != null - ? model.getDate( - DateUtils - .convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != null - ? model - .getDate(DateUtils - .convertStringToDate( - model.user.createdOn)) - : '--', - textAlign: TextAlign.right, - fontSize: 14, - fontWeight: FontWeight.w800, - ), - subtitle: AppText( - model.user.editedOn != null - ? model.getTime( - DateUtils - .convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != null - ? model - .getTime(DateUtils - .convertStringToDate( - model.user.createdOn)) - : '--', - textAlign: TextAlign.right, - fontSize: 14, - ), - )) - ], - )), - ], - ) - : Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - this.onlySMSBox == false - ? AppText( - TranslationBase.of(context) - .verifyLoginWith, - fontSize: - SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ) - : AppText( - TranslationBase.of(context) - .verifyFingerprint2, - fontSize: - SizeConfig.textMultiplier * 2.5, - textAlign: TextAlign.start, - ), - ]), - model.user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => { - // TODO check this logic it seem it will create bug to us - - authenticateUser( - AuthMethodTypes - .Fingerprint, - true) - }, - child: MethodCard( - authMethodType: model.user - .logInTypeID == - 4 - ? AuthMethodTypes.FaceID - : model.user.logInTypeID == 2 - ? AuthMethodTypes - .WhatsApp - : model.user.logInTypeID == - 3 - ? AuthMethodTypes - .Fingerprint - : AuthMethodTypes - .SMS, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )), - ), - Expanded( - child: MethodCard( - authMethodType: - AuthMethodTypes.MoreOptions, - onShowMore: () { - setState(() { - isMoreOption = true; - }); - }, - )) - ]), - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: MethodCard( - authMethodType: - AuthMethodTypes.Fingerprint, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )), - Expanded( - child: MethodCard( - authMethodType: - AuthMethodTypes.FaceID, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: MethodCard( - authMethodType: AuthMethodTypes.SMS, - authenticateUser: - (AuthMethodTypes authMethodType, - isActive) => - authenticateUser( - authMethodType, isActive), - )), - Expanded( - child: MethodCard( - authMethodType: - AuthMethodTypes.WhatsApp, - authenticateUser: - (AuthMethodTypes authMethodType, - isActive) => - authenticateUser( - authMethodType, isActive), - )) - ], - ), - ]), - - // ) - ], - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - model.user != null - ? Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context) - .useAnotherAccount, - color: Colors.red[700], - onPressed: () { - Navigator.of(context).pushNamed(LOGIN); - }, - )), - ], - ) - : SizedBox(), - ], - ), - ], - ), - ), - ), - ), - ), - )); - } - - sendActivationCodeByOtpNotificationType( - AuthMethodTypes authMethodType) async { - if (authMethodType == AuthMethodTypes.SMS || - authMethodType == AuthMethodTypes.WhatsApp) { - GifLoaderDialogUtils.showMyDialog(context); - - int projectID = await sharedPref.getInt(PROJECT_ID); - // TODO create model for model.loggedUser; - ActivationCodeModel activationCodeModel = ActivationCodeModel( - facilityId: projectID, - memberID: model.loggedUser['List_MemberInformation'][0]['MemberID'], - zipCode: model.loggedUser['ZipCode'], - mobileNumber: model.loggedUser['MobileNumber'], - otpSendType: authMethodType.getTypeIdService().toString(), - password: widget.password); - await model.sendActivationCodeForDoctorApp(activationCodeModel); - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - GifLoaderDialogUtils.hideDialog(context); - } else { - print("VerificationCode : " + - model.activationCodeForDoctorAppRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, - model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); - sharedPref.setString(VIDA_REFRESH_TOKEN_ID, - model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, - model.activationCodeForDoctorAppRes["LogInTokenID"]); - sharedPref.setString(PASSWORD, widget.password); - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } - } else { - // TODO route to this page with parameters to inicate we should present 2 option - if (Platform.isAndroid && authMethodType == AuthMethodTypes.Fingerprint) { - Helpers.showErrorToast('Your device not support this feature'); - } else {} - } - } - - sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { - GifLoaderDialogUtils.showMyDialog(context); - ActivationCodeForVerificationScreenModel activationCodeModel = - ActivationCodeForVerificationScreenModel( - iMEI: model.user.iMEI, - facilityId: model.user.projectID, - memberID: model.user.doctorID, - zipCode: model.user.outSA == true ? '971' : '966', - mobileNumber: model.user.mobile, - oTPSendType: authMethodType.getTypeIdService(), - isMobileFingerPrint: 1, - vidaAuthTokenID: model.user.vidaAuthTokenID, - vidaRefreshTokenID: model.user.vidaRefreshTokenID); - - await model - .sendActivationCodeVerificationScreen(activationCodeModel); - - if (model.state == ViewState.ErrorLocal) { - GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(model.error); - } else { - print("VerificationCode : " + - model.activationCodeVerificationScreenRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, - model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, - model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, - model.activationCodeVerificationScreenRes["LogInTokenID"]); - if (authMethodType == AuthMethodTypes.SMS || - authMethodType == AuthMethodTypes.WhatsApp) { - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } else { - checkActivationCode(); - } - } - } - - authenticateUser(AuthMethodTypes authMethodType, isActive) { - if (authMethodType == AuthMethodTypes.Fingerprint || - authMethodType == AuthMethodTypes.FaceID) { - fingerPrintBefore = authMethodType; - } - this.selectedOption = - fingerPrintBefore != null ? fingerPrintBefore : authMethodType; - - switch (authMethodType) { - case AuthMethodTypes.SMS: - sendActivationCode(authMethodType); - break; - case AuthMethodTypes.WhatsApp: - sendActivationCode(authMethodType); - break; - case AuthMethodTypes.Fingerprint: - this.loginWithFingerPrintOrFaceID( - AuthMethodTypes.Fingerprint, isActive); - break; - case AuthMethodTypes.FaceID: - this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); - break; - default: - break; - } - sharedPref.setInt(OTP_TYPE, selectedOption.getTypeIdService()); - } - - sendActivationCode(AuthMethodTypes authMethodType) async { - if (model.user != null) { - sendActivationCodeVerificationScreen(authMethodType); - } else { - sendActivationCodeByOtpNotificationType(authMethodType); - } - } - - startSMSService(AuthMethodTypes type) { - // TODO improve this logic - new SMSOTP( - context, - type, - model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, - (value) { - showDialog( - context: context, - builder: (BuildContext context) { - return Center( - child: CircularProgressIndicator(), - ); - }); - - this.checkActivationCode(value: value); - }, - () => - { - widget.changeLoadingState(false), - print('Faild..'), - }, - ).displayDialog(context); - } - - loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, - isActive) async { - if (isActive) { - const iosStrings = const IOSAuthMessages( - cancelButton: 'cancel', - goToSettingsButton: 'settings', - goToSettingsDescription: 'Please set up your Touch ID.', - lockOut: 'Please reenable your Touch ID'); - - try { - authenticated = await auth.authenticateWithBiometrics( - localizedReason: 'Scan your fingerprint to authenticate', - useErrorDialogs: true, - stickyAuth: true, - iOSAuthStrings: iosStrings); - } on PlatformException catch (e) { - DrAppToastMsg.showErrorToast(e.toString()); - } - if (!mounted) return; - if (model.user != null && (model.user.logInTypeID == 3 || model.user.logInTypeID == 4)) { - this.sendActivationCode(authMethodTypes); - } else { - setState(() { - this.onlySMSBox = true; - }); - } - } - } - - checkActivationCode({value}) async { - CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = - new CheckActivationCodeRequestModel( - zipCode: - model.loggedUser != null ? model.loggedUser['ZipCode'] : model.user.zipCode, - mobileNumber: - model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, - projectID: await sharedPref.getInt(PROJECT_ID) != null - ? await sharedPref.getInt(PROJECT_ID) - : model.user.projectID, - logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), - activationCode: value ?? '0000', - oTPSendType: await sharedPref.getInt(OTP_TYPE), - generalid: "Cs2020@2016\$2958"); - await model - .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); - - if (model.state == ViewState.ErrorLocal) { - Navigator.pop(context); - Helpers.showErrorToast(model.error); - } else { - sharedPref.setString( - TOKEN, - model - .checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); - if (model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != - null) { - loginProcessCompleted(model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); - sharedPref.setObj( - CLINIC_NAME, - model - .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); - } else { - sharedPref.setObj( - CLINIC_NAME, - model - .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); - ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); - getDocProfiles(clinic); - } - } - } - - loginProcessCompleted(Map profile) { - var doctor = DoctorProfileModel.fromJson(profile); - doctorProfileViewModel.setDoctorProfile(doctor); - sharedPref.setObj(DOCTOR_PROFILE, profile); - projectsProvider.isLogin = true; - - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: LandingPage(), - ), - (r) => false); - } - - getDocProfiles(ClinicModel clinicInfo) { - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: clinicInfo.doctorID, - clinicID: clinicInfo.clinicID, - license: true, - projectID: clinicInfo.projectID, - tokenID: '', - languageID: 2); - doctorProfileViewModel.getDocProfiles(docInfo.toJson()).then((res) { - if (res['MessageStatus'] == 1) { - loginProcessCompleted(res['DoctorProfileList'][0]); - } else { - // changeLoadingState(false); - Helpers.showErrorToast(res['ErrorEndUserMessage']); - } - }).catchError((err) { - Helpers.showErrorToast(err); - }); - } -} From 333d1e3f50d8e3c4b397ff9a8cd9a8dd200005cf Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 6 May 2021 13:45:25 +0300 Subject: [PATCH 020/241] first step from models --- ios/Podfile.lock | 2 +- .../auth/activation_Code_req_model.dart | 0 ...on_code_for_verification_screen_model.dart | 0 .../check_activation_code_request_model.dart | 0 lib/core/model/{ => auth}/imei_details.dart | 0 .../model/{ => auth}/insert_imei_model.dart | 0 .../new_login_information_response_model.dart | 113 ++++++++++++++++++ ...on_code_for_doctor_app_response_model.dart | 29 +++++ lib/core/service/authentication_service.dart | 30 ++--- .../viewModel/authentication_view_model.dart | 34 +++--- lib/screens/auth/login_screen.dart | 25 ++-- .../auth/verification_methods_screen.dart | 18 ++- 12 files changed, 198 insertions(+), 53 deletions(-) rename lib/{models => core/model}/auth/activation_Code_req_model.dart (100%) rename lib/{models => core/model}/auth/activation_code_for_verification_screen_model.dart (100%) rename lib/{models => core/model}/auth/check_activation_code_request_model.dart (100%) rename lib/core/model/{ => auth}/imei_details.dart (100%) rename lib/core/model/{ => auth}/insert_imei_model.dart (100%) create mode 100644 lib/core/model/auth/new_login_information_response_model.dart create mode 100644 lib/core/model/auth/send_activation_code_for_doctor_app_response_model.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 878a1850..2f4607e0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/models/auth/activation_Code_req_model.dart b/lib/core/model/auth/activation_Code_req_model.dart similarity index 100% rename from lib/models/auth/activation_Code_req_model.dart rename to lib/core/model/auth/activation_Code_req_model.dart diff --git a/lib/models/auth/activation_code_for_verification_screen_model.dart b/lib/core/model/auth/activation_code_for_verification_screen_model.dart similarity index 100% rename from lib/models/auth/activation_code_for_verification_screen_model.dart rename to lib/core/model/auth/activation_code_for_verification_screen_model.dart diff --git a/lib/models/auth/check_activation_code_request_model.dart b/lib/core/model/auth/check_activation_code_request_model.dart similarity index 100% rename from lib/models/auth/check_activation_code_request_model.dart rename to lib/core/model/auth/check_activation_code_request_model.dart diff --git a/lib/core/model/imei_details.dart b/lib/core/model/auth/imei_details.dart similarity index 100% rename from lib/core/model/imei_details.dart rename to lib/core/model/auth/imei_details.dart diff --git a/lib/core/model/insert_imei_model.dart b/lib/core/model/auth/insert_imei_model.dart similarity index 100% rename from lib/core/model/insert_imei_model.dart rename to lib/core/model/auth/insert_imei_model.dart diff --git a/lib/core/model/auth/new_login_information_response_model.dart b/lib/core/model/auth/new_login_information_response_model.dart new file mode 100644 index 00000000..117060e4 --- /dev/null +++ b/lib/core/model/auth/new_login_information_response_model.dart @@ -0,0 +1,113 @@ +class NewLoginInformationModel { + int doctorID; + List listMemberInformation; + String logInTokenID; + String mobileNumber; + Null sELECTDeviceIMEIbyIMEIList; + int userID; + String zipCode; + bool isActiveCode; + bool isSMSSent; + + NewLoginInformationModel( + {this.doctorID, + this.listMemberInformation, + this.logInTokenID, + this.mobileNumber, + this.sELECTDeviceIMEIbyIMEIList, + this.userID, + this.zipCode, + this.isActiveCode, + this.isSMSSent}); + + NewLoginInformationModel.fromJson(Map json) { + doctorID = json['DoctorID']; + if (json['List_MemberInformation'] != null) { + listMemberInformation = new List(); + json['List_MemberInformation'].forEach((v) { + listMemberInformation.add(new ListMemberInformation.fromJson(v)); + }); + } + logInTokenID = json['LogInTokenID']; + mobileNumber = json['MobileNumber']; + sELECTDeviceIMEIbyIMEIList = json['SELECTDeviceIMEIbyIMEI_List']; + userID = json['UserID']; + zipCode = json['ZipCode']; + isActiveCode = json['isActiveCode']; + isSMSSent = json['isSMSSent']; + } + + Map toJson() { + final Map data = new Map(); + data['DoctorID'] = this.doctorID; + if (this.listMemberInformation != null) { + data['List_MemberInformation'] = + this.listMemberInformation.map((v) => v.toJson()).toList(); + } + data['LogInTokenID'] = this.logInTokenID; + data['MobileNumber'] = this.mobileNumber; + data['SELECTDeviceIMEIbyIMEI_List'] = this.sELECTDeviceIMEIbyIMEIList; + data['UserID'] = this.userID; + data['ZipCode'] = this.zipCode; + data['isActiveCode'] = this.isActiveCode; + data['isSMSSent'] = this.isSMSSent; + return data; + } +} + +class ListMemberInformation { + Null setupID; + int memberID; + String memberName; + Null memberNameN; + String preferredLang; + String pIN; + String saltHash; + int referenceID; + int employeeID; + int roleID; + int projectid; + + ListMemberInformation( + {this.setupID, + this.memberID, + this.memberName, + this.memberNameN, + this.preferredLang, + this.pIN, + this.saltHash, + this.referenceID, + this.employeeID, + this.roleID, + this.projectid}); + + ListMemberInformation.fromJson(Map json) { + setupID = json['SetupID']; + memberID = json['MemberID']; + memberName = json['MemberName']; + memberNameN = json['MemberNameN']; + preferredLang = json['PreferredLang']; + pIN = json['PIN']; + saltHash = json['SaltHash']; + referenceID = json['ReferenceID']; + employeeID = json['EmployeeID']; + roleID = json['RoleID']; + projectid = json['projectid']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['MemberID'] = this.memberID; + data['MemberName'] = this.memberName; + data['MemberNameN'] = this.memberNameN; + data['PreferredLang'] = this.preferredLang; + data['PIN'] = this.pIN; + data['SaltHash'] = this.saltHash; + data['ReferenceID'] = this.referenceID; + data['EmployeeID'] = this.employeeID; + data['RoleID'] = this.roleID; + data['projectid'] = this.projectid; + return data; + } +} diff --git a/lib/core/model/auth/send_activation_code_for_doctor_app_response_model.dart b/lib/core/model/auth/send_activation_code_for_doctor_app_response_model.dart new file mode 100644 index 00000000..ceaf4c65 --- /dev/null +++ b/lib/core/model/auth/send_activation_code_for_doctor_app_response_model.dart @@ -0,0 +1,29 @@ +class SendActivationCodeForDoctorAppResponseModel { + String logInTokenID; + String verificationCode; + String vidaAuthTokenID; + String vidaRefreshTokenID; + + SendActivationCodeForDoctorAppResponseModel( + {this.logInTokenID, + this.verificationCode, + this.vidaAuthTokenID, + this.vidaRefreshTokenID}); + + SendActivationCodeForDoctorAppResponseModel.fromJson( + Map json) { + logInTokenID = json['LogInTokenID']; + verificationCode = json['VerificationCode']; + vidaAuthTokenID = json['VidaAuthTokenID']; + vidaRefreshTokenID = json['VidaRefreshTokenID']; + } + + Map toJson() { + final Map data = new Map(); + data['LogInTokenID'] = this.logInTokenID; + data['VerificationCode'] = this.verificationCode; + data['VidaAuthTokenID'] = this.vidaAuthTokenID; + data['VidaRefreshTokenID'] = this.vidaRefreshTokenID; + return data; + } +} diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index 59d8e34a..18624d58 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -1,11 +1,13 @@ import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/core/model/imei_details.dart'; -import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; +import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/send_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:provider/provider.dart'; @@ -14,15 +16,15 @@ class AuthenticationService extends BaseService { List _imeiDetails = []; List get dashboardItemsList => _imeiDetails; //TODO Change this to models - Map _loginInfo = {}; - Map get loginInfo => _loginInfo; + NewLoginInformationModel _loginInfo = NewLoginInformationModel(); + NewLoginInformationModel get loginInfo => _loginInfo; Map _activationCodeVerificationScreenRes = {}; Map get activationCodeVerificationScreenRes => _activationCodeVerificationScreenRes; - Map _activationCodeForDoctorAppRes = {}; + SendActivationCodeForDoctorAppResponseModel _activationCodeForDoctorAppRes = SendActivationCodeForDoctorAppResponseModel(); - Map get activationCodeForDoctorAppRes => _activationCodeForDoctorAppRes; + SendActivationCodeForDoctorAppResponseModel get activationCodeForDoctorAppRes => _activationCodeForDoctorAppRes; Map _checkActivationCodeForDoctorAppRes = {}; Map get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; @@ -31,7 +33,6 @@ class AuthenticationService extends BaseService { Map get insertDeviceImeiRes => _insertDeviceImeiRes; Future selectDeviceImei(imei) async { try { - // dynamic localRes; await baseAppClient.post(SELECT_DEVICE_IMEI, onSuccess: (dynamic response, int statusCode) { _imeiDetails = []; @@ -42,7 +43,6 @@ class AuthenticationService extends BaseService { hasError = true; super.error = error; }, body: {"IMEI": imei, "TokenID": "@dm!n"}); - //return Future.value(localRes); } catch (error) { hasError = true; super.error = error; @@ -51,11 +51,11 @@ class AuthenticationService extends BaseService { Future login(UserModel userInfo) async { hasError = false; - _loginInfo = {}; + _loginInfo = NewLoginInformationModel(); try { await baseAppClient.post(LOGIN_URL, onSuccess: (dynamic response, int statusCode) { - _loginInfo = response; + _loginInfo = NewLoginInformationModel.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -87,11 +87,11 @@ class AuthenticationService extends BaseService { Future sendActivationCodeForDoctorApp(ActivationCodeModel activationCodeModel)async { hasError = false; - _activationCodeForDoctorAppRes = {}; + _activationCodeForDoctorAppRes = SendActivationCodeForDoctorAppResponseModel(); try { await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_DOCTOR_APP, onSuccess: (dynamic response, int statusCode) { - _activationCodeForDoctorAppRes = response; + _activationCodeForDoctorAppRes = SendActivationCodeForDoctorAppResponseModel.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a8dda45f..a9986cec 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -2,17 +2,19 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/send_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; -import 'package:doctor_app_flutter/core/model/imei_details.dart'; -import 'package:doctor_app_flutter/core/model/insert_imei_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; -import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:intl/intl.dart'; @@ -23,12 +25,12 @@ class AuthenticationViewModel extends BaseViewModel { List get imeiDetails => _authService.dashboardItemsList; List get hospitals => _hospitalsService.hospitals; - get loginInfo => _authService.loginInfo; + NewLoginInformationModel get loginInfo => _authService.loginInfo; get activationCodeVerificationScreenRes => _authService.activationCodeVerificationScreenRes; - get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; + SendActivationCodeForDoctorAppResponseModel get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; - var loggedUser; + NewLoginInformationModel loggedUser; GetIMEIDetailsModel user; Future selectDeviceImei(imei) async { setState(ViewState.Busy); @@ -115,9 +117,9 @@ class AuthenticationViewModel extends BaseViewModel { int projectID = await sharedPref.getInt(PROJECT_ID); ActivationCodeModel activationCodeModel = ActivationCodeModel( facilityId: projectID, - memberID: loggedUser['List_MemberInformation'][0]['MemberID'], - zipCode: loggedUser['ZipCode'], - mobileNumber: loggedUser['MobileNumber'], + memberID: loggedUser.listMemberInformation[0].memberID, + zipCode: loggedUser.zipCode, + mobileNumber: loggedUser.mobileNumber, otpSendType: authMethodType.getTypeIdService().toString(), password: password); await _authService.sendActivationCodeForDoctorApp(activationCodeModel); @@ -133,9 +135,9 @@ class AuthenticationViewModel extends BaseViewModel { CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = new CheckActivationCodeRequestModel( zipCode: - loggedUser != null ? loggedUser['ZipCode'] :user.zipCode, + loggedUser != null ? loggedUser.zipCode :user.zipCode, mobileNumber: - loggedUser != null ? loggedUser['MobileNumber'] : user.mobile, + loggedUser != null ? loggedUser.mobileNumber : user.mobile, projectID: await sharedPref.getInt(PROJECT_ID) != null ? await sharedPref.getInt(PROJECT_ID) : user.projectID, @@ -208,7 +210,11 @@ class AuthenticationViewModel extends BaseViewModel { getInitUserInfo()async{ setState(ViewState.Busy); - loggedUser = await sharedPref.getObj(LOGGED_IN_USER); + var localLoggedUser = await sharedPref.getObj(LOGGED_IN_USER); + if(localLoggedUser!= null) { + loggedUser = NewLoginInformationModel.fromJson(localLoggedUser); + + } var lastLogin = await sharedPref.getObj(LAST_LOGIN_USER); if (lastLogin != null) { user = GetIMEIDetailsModel.fromJson(lastLogin); diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 0048b10c..a6eab35b 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -10,10 +10,10 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -463,25 +463,24 @@ class _LoginsreenState extends State { Helpers.showErrorToast(model.error); } else { - if (model.loginInfo['MessageStatus'] == 1) { - saveObjToString(LOGGED_IN_USER, model.loginInfo); - sharedPref.remove(LAST_LOGIN_USER); - sharedPref.setString(TOKEN, model.loginInfo['LogInTokenID']); - GifLoaderDialogUtils.hideDialog(context); + saveObjToString(LOGGED_IN_USER, model.loginInfo); + sharedPref.remove(LAST_LOGIN_USER); + sharedPref.setString(TOKEN, model.loginInfo.logInTokenID); + GifLoaderDialogUtils.hideDialog(context); - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (BuildContext context) => - VerificationMethodsScreen( - password: userInfo.password, - ))); - } + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => VerificationMethodsScreen( + password: userInfo.password, + ), + ), + ); } } } Future setSharedPref(key, value) async { sharedPref.setString(key, value).then((success) { - print("sharedPref.setString" + success.toString()); }); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 2b906588..ce783901 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -3,12 +3,11 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/imei_details.dart'; +import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; @@ -384,13 +383,13 @@ class _VerificationMethodsScreenState extends State { } else { // TODO move it model print("VerificationCode : " + - model.activationCodeForDoctorAppRes["VerificationCode"]); + model.activationCodeForDoctorAppRes.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, - model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); + model.activationCodeForDoctorAppRes.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, - model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); + model.activationCodeForDoctorAppRes.vidaRefreshTokenID); sharedPref.setString(LOGIN_TOKEN_ID, - model.activationCodeForDoctorAppRes["LogInTokenID"]); + model.activationCodeForDoctorAppRes.logInTokenID); sharedPref.setString(PASSWORD, widget.password); GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); @@ -475,7 +474,7 @@ class _VerificationMethodsScreenState extends State { new SMSOTP( context, type, - model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, + model.loggedUser != null ? model.loggedUser.mobileNumber : model.user.mobile, (value) { showDialog( context: context, @@ -581,7 +580,6 @@ class _VerificationMethodsScreenState extends State { if (res['MessageStatus'] == 1) { loginProcessCompleted(res['DoctorProfileList'][0]); } else { - // changeLoadingState(false); Helpers.showErrorToast(res['ErrorEndUserMessage']); } }).catchError((err) { From 745545ffc3afb722c0d4ffc1da4e04d094569704 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 6 May 2021 14:57:11 +0300 Subject: [PATCH 021/241] add models --- ...on_code_for_doctor_app_response_model.dart | 181 ++++++++++++++++++ lib/core/service/authentication_service.dart | 19 +- .../viewModel/authentication_view_model.dart | 16 +- .../auth/verification_methods_screen.dart | 38 +--- 4 files changed, 213 insertions(+), 41 deletions(-) create mode 100644 lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart diff --git a/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart b/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart new file mode 100644 index 00000000..283e617f --- /dev/null +++ b/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart @@ -0,0 +1,181 @@ +class CheckActivationCodeForDoctorAppResponseModel { + String authenticationTokenID; + List listDoctorsClinic; + List list_DoctorProfile; + MemberInformation memberInformation; + + CheckActivationCodeForDoctorAppResponseModel( + {this.authenticationTokenID, + this.listDoctorsClinic, + this.memberInformation}); + + CheckActivationCodeForDoctorAppResponseModel.fromJson( + Map json) { + authenticationTokenID = json['AuthenticationTokenID']; + list_DoctorProfile = json['List_DoctorProfile']; + if (json['List_DoctorsClinic'] != null) { + listDoctorsClinic = new List(); + json['List_DoctorsClinic'].forEach((v) { + listDoctorsClinic.add(new ListDoctorsClinic.fromJson(v)); + }); + } + memberInformation = json['memberInformation'] != null + ? new MemberInformation.fromJson(json['memberInformation']) + : null; + } + + Map toJson() { + final Map data = new Map(); + data['AuthenticationTokenID'] = this.authenticationTokenID; + data['List_DoctorProfile'] = this.list_DoctorProfile; + if (this.listDoctorsClinic != null) { + data['List_DoctorsClinic'] = + this.listDoctorsClinic.map((v) => v.toJson()).toList(); + } + if (this.memberInformation != null) { + data['memberInformation'] = this.memberInformation.toJson(); + } + return data; + } +} + +class ListDoctorsClinic { + Null setupID; + int projectID; + int doctorID; + int clinicID; + bool isActive; + String clinicName; + + ListDoctorsClinic( + {this.setupID, + this.projectID, + this.doctorID, + this.clinicID, + this.isActive, + this.clinicName}); + + ListDoctorsClinic.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + doctorID = json['DoctorID']; + clinicID = json['ClinicID']; + isActive = json['IsActive']; + clinicName = json['ClinicName']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['DoctorID'] = this.doctorID; + data['ClinicID'] = this.clinicID; + data['IsActive'] = this.isActive; + data['ClinicName'] = this.clinicName; + return data; + } +} + +class MemberInformation { + List clinics; + int doctorId; + String email; + int employeeId; + int memberId; + Null memberName; + Null memberNameArabic; + String preferredLanguage; + List roles; + + MemberInformation( + {this.clinics, + this.doctorId, + this.email, + this.employeeId, + this.memberId, + this.memberName, + this.memberNameArabic, + this.preferredLanguage, + this.roles}); + + MemberInformation.fromJson(Map json) { + if (json['clinics'] != null) { + clinics = new List(); + json['clinics'].forEach((v) { + clinics.add(new Clinics.fromJson(v)); + }); + } + doctorId = json['doctorId']; + email = json['email']; + employeeId = json['employeeId']; + memberId = json['memberId']; + memberName = json['memberName']; + memberNameArabic = json['memberNameArabic']; + preferredLanguage = json['preferredLanguage']; + if (json['roles'] != null) { + roles = new List(); + json['roles'].forEach((v) { + roles.add(new Roles.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.clinics != null) { + data['clinics'] = this.clinics.map((v) => v.toJson()).toList(); + } + data['doctorId'] = this.doctorId; + data['email'] = this.email; + data['employeeId'] = this.employeeId; + data['memberId'] = this.memberId; + data['memberName'] = this.memberName; + data['memberNameArabic'] = this.memberNameArabic; + data['preferredLanguage'] = this.preferredLanguage; + if (this.roles != null) { + data['roles'] = this.roles.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Clinics { + bool defaultClinic; + int id; + String name; + + Clinics({this.defaultClinic, this.id, this.name}); + + Clinics.fromJson(Map json) { + defaultClinic = json['defaultClinic']; + id = json['id']; + name = json['name']; + } + + Map toJson() { + final Map data = new Map(); + data['defaultClinic'] = this.defaultClinic; + data['id'] = this.id; + data['name'] = this.name; + return data; + } +} + +class Roles { + String name; + int roleId; + + Roles({this.name, this.roleId}); + + Roles.fromJson(Map json) { + name = json['name']; + roleId = json['roleId']; + } + + Map toJson() { + final Map data = new Map(); + data['name'] = this.name; + data['roleId'] = this.roleId; + return data; + } +} diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index 18624d58..9f67a3b8 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; @@ -15,22 +16,20 @@ import 'package:provider/provider.dart'; class AuthenticationService extends BaseService { List _imeiDetails = []; List get dashboardItemsList => _imeiDetails; - //TODO Change this to models NewLoginInformationModel _loginInfo = NewLoginInformationModel(); NewLoginInformationModel get loginInfo => _loginInfo; - Map _activationCodeVerificationScreenRes = {}; + SendActivationCodeForDoctorAppResponseModel _activationCodeVerificationScreenRes = SendActivationCodeForDoctorAppResponseModel(); - Map get activationCodeVerificationScreenRes => _activationCodeVerificationScreenRes; + SendActivationCodeForDoctorAppResponseModel get activationCodeVerificationScreenRes => _activationCodeVerificationScreenRes; SendActivationCodeForDoctorAppResponseModel _activationCodeForDoctorAppRes = SendActivationCodeForDoctorAppResponseModel(); SendActivationCodeForDoctorAppResponseModel get activationCodeForDoctorAppRes => _activationCodeForDoctorAppRes; - Map _checkActivationCodeForDoctorAppRes = {}; + CheckActivationCodeForDoctorAppResponseModel _checkActivationCodeForDoctorAppRes = CheckActivationCodeForDoctorAppResponseModel(); - Map get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; + CheckActivationCodeForDoctorAppResponseModel get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; Map _insertDeviceImeiRes = {}; - Map get insertDeviceImeiRes => _insertDeviceImeiRes; Future selectDeviceImei(imei) async { try { await baseAppClient.post(SELECT_DEVICE_IMEI, @@ -69,11 +68,11 @@ class AuthenticationService extends BaseService { Future sendActivationCodeVerificationScreen(ActivationCodeForVerificationScreenModel activationCodeModel) async { hasError = false; - _activationCodeVerificationScreenRes = {}; + _activationCodeVerificationScreenRes = SendActivationCodeForDoctorAppResponseModel(); try { await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_VERIFICATION_SCREEN, onSuccess: (dynamic response, int statusCode) { - _activationCodeVerificationScreenRes = response; + _activationCodeVerificationScreenRes = SendActivationCodeForDoctorAppResponseModel.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -104,13 +103,13 @@ class AuthenticationService extends BaseService { Future checkActivationCodeForDoctorApp(CheckActivationCodeRequestModel checkActivationCodeRequestModel)async { hasError = false; - _checkActivationCodeForDoctorAppRes = {}; + _checkActivationCodeForDoctorAppRes = CheckActivationCodeForDoctorAppResponseModel(); try { await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, onSuccess: (dynamic response, int statusCode) { // TODO improve the logic here Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.clear(); - _checkActivationCodeForDoctorAppRes = response; + _checkActivationCodeForDoctorAppRes = CheckActivationCodeForDoctorAppResponseModel.fromJson(response); Provider.of(AppGlobal.CONTEX, listen: false).selectedClinicName = ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a9986cec..f33ec782 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; import 'package:doctor_app_flutter/core/model/auth/send_activation_code_for_doctor_app_response_model.dart'; @@ -26,9 +27,9 @@ class AuthenticationViewModel extends BaseViewModel { List get imeiDetails => _authService.dashboardItemsList; List get hospitals => _hospitalsService.hospitals; NewLoginInformationModel get loginInfo => _authService.loginInfo; - get activationCodeVerificationScreenRes => _authService.activationCodeVerificationScreenRes; + SendActivationCodeForDoctorAppResponseModel get activationCodeVerificationScreenRes => _authService.activationCodeVerificationScreenRes; SendActivationCodeForDoctorAppResponseModel get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; - get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; + CheckActivationCodeForDoctorAppResponseModel get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; NewLoginInformationModel loggedUser; GetIMEIDetailsModel user; @@ -222,4 +223,15 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + + setDataAfterSendActivationSuccsess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel){ + print("VerificationCode : " + + sendActivationCodeForDoctorAppResponseModel.verificationCode); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); + sharedPref.setString(VIDA_REFRESH_TOKEN_ID, + sendActivationCodeForDoctorAppResponseModel.vidaRefreshTokenID); + sharedPref.setString(LOGIN_TOKEN_ID, + sendActivationCodeForDoctorAppResponseModel.logInTokenID); + } } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index ce783901..29188194 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -3,11 +3,8 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; @@ -381,15 +378,7 @@ class _VerificationMethodsScreenState extends State { Helpers.showErrorToast(model.error); GifLoaderDialogUtils.hideDialog(context); } else { - // TODO move it model - print("VerificationCode : " + - model.activationCodeForDoctorAppRes.verificationCode); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, - model.activationCodeForDoctorAppRes.vidaAuthTokenID); - sharedPref.setString(VIDA_REFRESH_TOKEN_ID, - model.activationCodeForDoctorAppRes.vidaRefreshTokenID); - sharedPref.setString(LOGIN_TOKEN_ID, - model.activationCodeForDoctorAppRes.logInTokenID); + model.setDataAfterSendActivationSuccsess(model.activationCodeForDoctorAppRes); sharedPref.setString(PASSWORD, widget.password); GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); @@ -413,16 +402,7 @@ class _VerificationMethodsScreenState extends State { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { - //TODO Move it to view model - print("VerificationCode : " + - model.activationCodeVerificationScreenRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, - model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, - model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, - model.activationCodeVerificationScreenRes["LogInTokenID"]); + model.setDataAfterSendActivationSuccsess(model.activationCodeVerificationScreenRes); if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.hideDialog(context); @@ -535,20 +515,19 @@ class _VerificationMethodsScreenState extends State { sharedPref.setString( TOKEN, model - .checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); - if (model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != - null) { - loginProcessCompleted(model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); + .checkActivationCodeForDoctorAppRes.authenticationTokenID); + if (model.checkActivationCodeForDoctorAppRes.listDoctorsClinic.isNotEmpty) { + loginProcessCompleted(model.checkActivationCodeForDoctorAppRes.list_DoctorProfile[0]); sharedPref.setObj( CLINIC_NAME, model - .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + .checkActivationCodeForDoctorAppRes.listDoctorsClinic); } else { sharedPref.setObj( CLINIC_NAME, model - .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); - ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); + .checkActivationCodeForDoctorAppRes.listDoctorsClinic); + ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes.listDoctorsClinic[0].toJson()); getDocProfiles(clinic); } } @@ -586,4 +565,5 @@ class _VerificationMethodsScreenState extends State { Helpers.showErrorToast(err); }); } + } From 95a6893b59bfe61657fa8507bb09e6976441e605 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 6 May 2021 15:19:42 +0300 Subject: [PATCH 022/241] home design --- lib/screens/home/dashboard_swipe_widget.dart | 33 +++++++------ lib/widgets/dashboard/activity_button.dart | 46 ++++++++++++------- lib/widgets/dashboard/out_patient_stack.dart | 30 ++++++++---- .../shared/rounded_container_widget.dart | 4 -- 4 files changed, 68 insertions(+), 45 deletions(-) diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart index 8f8077d8..faca68f8 100644 --- a/lib/screens/home/dashboard_swipe_widget.dart +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -40,7 +40,7 @@ class _DashboardSwipeWidgetState extends State { return getSwipeWidget(widget.dashboardItemList, index); }, itemCount: 3, - itemHeight: 300, + // itemHeight: 300, pagination: new SwiperCustomPagination( builder: (BuildContext context, SwiperPluginConfig config) { return new Stack( @@ -82,22 +82,22 @@ class _DashboardSwipeWidgetState extends State { Widget getSwipeWidget(List dashboardItemList, int index) { if (index == 1) return RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + raduis: 16, + margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[1]))); if (index == 0) return RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + raduis: 16, + margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[0]))); if (index == 2) return RoundedContainer( - height: MediaQuery.of(context).size.height * 0.35, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + raduis: 16, + margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( @@ -122,16 +122,19 @@ class _DashboardSwipeWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppText(TranslationBase.of(context) - .patients, - fontSize: 12, - fontWeight: FontWeight.bold, - fontHeight: 0.5,), - AppText(TranslationBase.of(context) - .referral, + AppText( + TranslationBase.of(context) + .patients, + fontSize: 12, + fontWeight: FontWeight.bold, + fontHeight: 0.5, + ), + AppText( + TranslationBase.of(context) + .referral, fontSize: 22, fontWeight: FontWeight.bold, - ), + ), ], ))), Expanded( diff --git a/lib/widgets/dashboard/activity_button.dart b/lib/widgets/dashboard/activity_button.dart index e9001e41..b8f390dd 100644 --- a/lib/widgets/dashboard/activity_button.dart +++ b/lib/widgets/dashboard/activity_button.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; class GetActivityButton extends StatelessWidget { final value; + GetActivityButton(this.value); + @override Widget build(BuildContext context) { return Container( @@ -15,24 +17,34 @@ class GetActivityButton extends StatelessWidget { color: Colors.white, borderRadius: BorderRadius.circular(20), ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(8), - child: AppText(value.value.toString(), - fontSize: 30, fontWeight: FontWeight.bold)), - Expanded( - child: AppText( - value.kPIParameter, - textOverflow: TextOverflow.clip, - fontSize: 10, - textAlign: TextAlign.center, - fontWeight: FontWeight.w600, + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + value.value.toString(), + fontSize: 30, + fontWeight: FontWeight.bold, + color: Color(0xFF2B353E), + ), + Expanded( + child: Column( + children: [ + AppText( + value.kPIParameter, + textOverflow: TextOverflow.clip, + fontSize: 10, + color: Color(0xFF2B353E), + textAlign: TextAlign.start, + fontWeight: FontWeight.w700, + ), + ], + ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index ad79b106..b3b7ed8c 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -33,7 +33,7 @@ class GetOutPatientStack extends StatelessWidget { child: Container( margin: EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), + borderRadius: BorderRadius.circular(8), color: Colors.red[50], ), child: Stack(children: [ @@ -46,7 +46,7 @@ class GetOutPatientStack extends StatelessWidget { padding: EdgeInsets.all(10), height: max != 0 ? (150 * value.value) / max : 0, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), + borderRadius: BorderRadius.circular(8), color: Color(0x63D02127), ), ), @@ -60,13 +60,25 @@ class GetOutPatientStack extends StatelessWidget { child: Center( child: Align( child: FittedBox( - child: AppText( - value.kPIParameter + ' (' + value.value.toString() + ') ', - fontSize: 10, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - )), + child: Row( + children: [ + AppText( + value.kPIParameter, + fontSize: 10, + textAlign: TextAlign.center, + color: Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + AppText( + ' (' + value.value.toString() + ') ', + fontSize: 12, + textAlign: TextAlign.center, + color: Color(0xFF2B353E), + fontWeight: FontWeight.bold, + ), + ], + ), + )), ), )) ]), diff --git a/lib/widgets/shared/rounded_container_widget.dart b/lib/widgets/shared/rounded_container_widget.dart index e86c85aa..4cfe7b08 100644 --- a/lib/widgets/shared/rounded_container_widget.dart +++ b/lib/widgets/shared/rounded_container_widget.dart @@ -1,9 +1,5 @@ import 'package:flutter/material.dart'; -// OWNER : Ibrahim albitar -// DATE : 05-04-2020 -// DESCRIPTION : Custom widget for rounded container and custom decoration - class RoundedContainer extends StatefulWidget { final double width; final double height; From 081bfe3f61b0f17b0b38f70a1a2b631187109ab2 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 6 May 2021 15:51:58 +0300 Subject: [PATCH 023/241] add TODO to Elham --- ios/Podfile.lock | 2 +- .../viewModel/authentication_view_model.dart | 4 +-- .../viewModel/doctor_profile_view_model.dart | 2 +- lib/screens/auth/login_screen.dart | 15 +++++++---- .../auth/verification_methods_screen.dart | 25 ++++++++----------- lib/widgets/auth/auth_header.dart | 2 +- lib/widgets/auth/method_card.dart | 2 ++ lib/widgets/auth/sms-popup.dart | 2 +- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2f4607e0..878a1850 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.1 diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index f33ec782..228a63e7 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -169,13 +169,13 @@ class AuthenticationViewModel extends BaseViewModel { } - + //TODO Elham remove it getDate(DateTime date) { final DateFormat formatter = DateFormat('dd MMM yyyy'); return formatter.format(date); } - + //TODO Elham remove it getTime(DateTime date) { final DateFormat formatter = DateFormat('HH:mm a'); diff --git a/lib/core/viewModel/doctor_profile_view_model.dart b/lib/core/viewModel/doctor_profile_view_model.dart index 24f53e5b..d336dd8d 100644 --- a/lib/core/viewModel/doctor_profile_view_model.dart +++ b/lib/core/viewModel/doctor_profile_view_model.dart @@ -36,7 +36,7 @@ class DoctorProfileViewModel extends BaseViewModel { } notifyListeners(); } - +//TODO Elham move it auth view model APP_STATUS get stutas { if (isLoading) { return APP_STATUS.LOADING; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index a6eab35b..91af7a2f 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -28,9 +28,9 @@ import '../../lookups/auth_lookup.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../widgets/auth/auth_header.dart'; import '../../widgets/shared/app_scaffold_widget.dart'; - +//TODO Elham remove it DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - +//TODO Elham change the name class Loginsreen extends StatefulWidget { @override _LoginsreenState createState() => _LoginsreenState(); @@ -51,12 +51,13 @@ class _LoginsreenState extends State { FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); // HospitalViewModel hospitalViewModel; + //TODO Elham to change it ti UserModel var userInfo = UserModel(); @override void initState() { super.initState(); - + //TODO Elham move it root page and the logic in the view model _firebaseMessaging.setAutoInitEnabled(true); if (Platform.isIOS) { _firebaseMessaging.requestNotificationPermissions(); @@ -88,6 +89,7 @@ class _LoginsreenState extends State { }); } + //TODO Elham change it to GIF void changeLoadingState(isLoading) { setState(() { _isLoading = isLoading; @@ -100,6 +102,7 @@ class _LoginsreenState extends State { return BaseView( + //TODO Elham remove it onModelReady: (model) => {}, builder: (_, model, w) => AppScaffold( @@ -457,6 +460,7 @@ class _LoginsreenState extends State { loginFormKey.currentState.save(); GifLoaderDialogUtils.showMyDialog(context); sharedPref.setInt(PROJECT_ID, userInfo.projectID); + //TODO Elham move the sharedPref to view model await model.login(userInfo); if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); @@ -466,6 +470,7 @@ class _LoginsreenState extends State { saveObjToString(LOGGED_IN_USER, model.loginInfo); sharedPref.remove(LAST_LOGIN_USER); sharedPref.setString(TOKEN, model.loginInfo.logInTokenID); + //TODO Elham move the sharedPref to view model GifLoaderDialogUtils.hideDialog(context); Navigator.of(context).pushReplacement( @@ -478,13 +483,13 @@ class _LoginsreenState extends State { } } } - + //TODO Elham to it view model Future setSharedPref(key, value) async { sharedPref.setString(key, value).then((success) { }); } - +//TODO Elham to it view model saveObjToString(String key, value) async { sharedPref.setObj(key, value); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 29188194..521dd5f6 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -39,6 +39,7 @@ class VerificationMethodsScreen extends StatefulWidget { VerificationMethodsScreen({this.changeLoadingState, this.password}); final password; + //TODO Elham remove this fun final Function changeLoadingState; @override @@ -62,12 +63,13 @@ class _VerificationMethodsScreenState extends State { final LocalAuthentication auth = LocalAuthentication(); + //TODO Elham remove this fun @override void initState() { super.initState(); } - +//TODO Elham remove this fun @override void didChangeDependencies() async{ super.didChangeDependencies(); @@ -229,11 +231,7 @@ class _VerificationMethodsScreenState extends State { child: InkWell( onTap: () => { // TODO check this logic it seem it will create bug to us - - authenticateUser( - AuthMethodTypes - .Fingerprint, - true) + authenticateUser(AuthMethodTypes.Fingerprint, true) }, child: MethodCard( authMethodType: model.user @@ -337,6 +335,7 @@ class _VerificationMethodsScreenState extends State { ], ), ), + //TODO Elham move it to bottom sheet Column( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -473,7 +472,7 @@ class _VerificationMethodsScreenState extends State { }, ).displayDialog(context); } - +//TODO Elham move it to view model loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { if (isActive) { @@ -505,17 +504,15 @@ class _VerificationMethodsScreenState extends State { checkActivationCode({value}) async { - await model - .checkActivationCodeForDoctorApp(activationCode:value ); + await model.checkActivationCodeForDoctorApp(activationCode:value ); if (model.state == ViewState.ErrorLocal) { Navigator.pop(context); Helpers.showErrorToast(model.error); } else { sharedPref.setString( - TOKEN, - model - .checkActivationCodeForDoctorAppRes.authenticationTokenID); + TOKEN, model.checkActivationCodeForDoctorAppRes.authenticationTokenID); + //TODO Elham check the logic if (model.checkActivationCodeForDoctorAppRes.listDoctorsClinic.isNotEmpty) { loginProcessCompleted(model.checkActivationCodeForDoctorAppRes.list_DoctorProfile[0]); sharedPref.setObj( @@ -532,7 +529,7 @@ class _VerificationMethodsScreenState extends State { } } } - + //TODO Elham move it to view model loginProcessCompleted(Map profile) { var doctor = DoctorProfileModel.fromJson(profile); doctorProfileViewModel.setDoctorProfile(doctor); @@ -546,7 +543,7 @@ class _VerificationMethodsScreenState extends State { ), (r) => false); } - +//TODO Elham move it to view model getDocProfiles(ClinicModel clinicInfo) { ProfileReqModel docInfo = new ProfileReqModel( doctorID: clinicInfo.doctorID, diff --git a/lib/widgets/auth/auth_header.dart b/lib/widgets/auth/auth_header.dart index 47e128be..27396980 100644 --- a/lib/widgets/auth/auth_header.dart +++ b/lib/widgets/auth/auth_header.dart @@ -6,7 +6,7 @@ import 'package:hexcolor/hexcolor.dart'; import '../../config/size_config.dart'; import '../../lookups/auth_lookup.dart'; - +//TODO Elham delete this widget class AuthHeader extends StatelessWidget { var userType; AuthHeader(this.userType); diff --git a/lib/widgets/auth/method_card.dart b/lib/widgets/auth/method_card.dart index 94bd261b..79721381 100644 --- a/lib/widgets/auth/method_card.dart +++ b/lib/widgets/auth/method_card.dart @@ -20,6 +20,7 @@ class MethodCard extends StatefulWidget { class _MethodCardState extends State { + //TODO Elham change it to list Enum var _availableBiometrics; final LocalAuthentication auth = LocalAuthentication(); @@ -65,6 +66,7 @@ class _MethodCardState extends State { case AuthMethodTypes.WhatsApp: return InkWell( onTap: () => {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, + //TODO Elham change it to widget child: Container( margin: EdgeInsets.all(10), decoration: BoxDecoration( diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 61329758..6cbeab49 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -8,7 +8,7 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - +//TODO Elham check it class SMSOTP { final AuthMethodTypes type; final mobileNo; From 301972f9b74567c9d16d2b794bbd0210035a0ef7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 9 May 2021 12:15:32 +0300 Subject: [PATCH 024/241] small fixes --- lib/screens/auth/login_screen.dart | 7 ------- lib/screens/auth/verification_methods_screen.dart | 1 - 2 files changed, 8 deletions(-) diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index a6eab35b..c7e15b9c 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -50,7 +50,6 @@ class _LoginsreenState extends State { List projectsList = []; FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); - // HospitalViewModel hospitalViewModel; var userInfo = UserModel(); @override @@ -479,12 +478,6 @@ class _LoginsreenState extends State { } } - Future setSharedPref(key, value) async { - sharedPref.setString(key, value).then((success) { - }); - } - - saveObjToString(String key, value) async { sharedPref.setObj(key, value); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 29188194..dabe184e 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -89,7 +89,6 @@ class _VerificationMethodsScreenState extends State { body: SingleChildScrollView( child: Center( child: FractionallySizedBox( - // widthFactor: 0.9, child: Container( margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), From 72ee88d567b893ab60da8c3584d3fa08825f1b0b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 9 May 2021 13:54:03 +0300 Subject: [PATCH 025/241] working on dashboard --- lib/screens/home/dashboard_swipe_widget.dart | 208 ++++++++++--------- lib/screens/home/home_screen.dart | 24 +-- lib/widgets/dashboard/out_patient_stack.dart | 10 +- lib/widgets/dashboard/row_count.dart | 4 +- 4 files changed, 128 insertions(+), 118 deletions(-) diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart index faca68f8..de582dc2 100644 --- a/lib/screens/home/dashboard_swipe_widget.dart +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -27,55 +27,59 @@ class _DashboardSwipeWidgetState extends State { @override Widget build(BuildContext context) { - return Swiper( - onIndexChanged: (index) { - if (mounted) { - setState(() { - sliderActiveIndex = index; - widget.sliderChange(index); - }); - } - }, - itemBuilder: (BuildContext context, int index) { - return getSwipeWidget(widget.dashboardItemList, index); - }, - itemCount: 3, - // itemHeight: 300, - pagination: new SwiperCustomPagination( - builder: (BuildContext context, SwiperPluginConfig config) { - return new Stack( - alignment: Alignment.bottomCenter, - children: [ - Positioned( - bottom: 0, - child: Center( - child: InkWell( - onTap: () {}, - child: Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - config.activeIndex == 0 - ? SwiperRoundedPagination(true) - : SwiperRoundedPagination(false), - config.activeIndex == 1 - ? SwiperRoundedPagination(true) - : SwiperRoundedPagination(false), - config.activeIndex == 2 - ? SwiperRoundedPagination(true) - : SwiperRoundedPagination(false), - ], + return Container( + // height: MediaQuery.of(context).size.height * 0.35, + height: 230, + child: Swiper( + onIndexChanged: (index) { + if (mounted) { + setState(() { + sliderActiveIndex = index; + widget.sliderChange(index); + }); + } + }, + itemBuilder: (BuildContext context, int index) { + return getSwipeWidget(widget.dashboardItemList, index); + }, + itemCount: 3, + // itemHeight: 300, + pagination: new SwiperCustomPagination( + builder: (BuildContext context, SwiperPluginConfig config) { + return new Stack( + alignment: Alignment.bottomCenter, + children: [ + Positioned( + bottom: 0, + child: Center( + child: InkWell( + onTap: () {}, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + config.activeIndex == 0 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + config.activeIndex == 1 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + config.activeIndex == 2 + ? SwiperRoundedPagination(true) + : SwiperRoundedPagination(false), + ], + ), ), ), ), - ), - ) - ], - ); - }), - viewportFraction: 0.9, - // scale: 0.9, - // control: new SwiperControl(), + ) + ], + ); + }), + viewportFraction: 0.9, + // scale: 0.9, + // control: new SwiperControl(), + ), ); } @@ -83,21 +87,21 @@ class _DashboardSwipeWidgetState extends State { if (index == 1) return RoundedContainer( raduis: 16, - margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[1]))); if (index == 0) return RoundedContainer( raduis: 16, - margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[0]))); if (index == 2) return RoundedContainer( raduis: 16, - margin: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( @@ -112,61 +116,65 @@ class _DashboardSwipeWidgetState extends State { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .patients, + fontSize: 12, + fontWeight: FontWeight.bold, + fontHeight: 0.5, + ), + AppText( + TranslationBase.of(context) + .referral, + fontSize: 22, + fontWeight: FontWeight.bold, + ), + ], + )), Expanded( - flex: 1, - child: Padding( - padding: EdgeInsets.all(8), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .patients, - fontSize: 12, - fontWeight: FontWeight.bold, - fontHeight: 0.5, - ), - AppText( - TranslationBase.of(context) - .referral, - fontSize: 22, - fontWeight: FontWeight.bold, - ), - ], - ))), - Expanded( - flex: 2, + flex: 1, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - RowCounts( - dashboardItemList[2] - .summaryoptions[0] - .kPIParameter, - dashboardItemList[2] - .summaryoptions[0] - .value, - Colors.black), - RowCounts( - dashboardItemList[2] - .summaryoptions[1] - .kPIParameter, - dashboardItemList[2] - .summaryoptions[1] - .value, - Colors.grey), - RowCounts( - dashboardItemList[2] - .summaryoptions[2] - .kPIParameter, - dashboardItemList[2] - .summaryoptions[2] - .value, - Colors.red), + Expanded( + child: RowCounts( + dashboardItemList[2] + .summaryoptions[0] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[0] + .value, + Colors.black), + ), + Expanded( + child: RowCounts( + dashboardItemList[2] + .summaryoptions[1] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[1] + .value, + Colors.grey), + ), + Expanded( + child: RowCounts( + dashboardItemList[2] + .summaryoptions[2] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[2] + .value, + Colors.red), + ), ], ), ) @@ -187,7 +195,7 @@ class _DashboardSwipeWidgetState extends State { widget.model .getPatientCount(dashboardItemList[2]) .toString(), - fontSize: 30, + fontSize: 28, fontWeight: FontWeight.bold, ) ], diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index d3fe217c..4a375d6d 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -202,19 +202,17 @@ class _HomeScreenState extends State { ])), content: Column( children: [ - Container( - height: MediaQuery.of(context).size.height * 0.35, - child: model.dashboardItemsList.length > 0 - ? DashboardSwipeWidget( - model.dashboardItemsList, - model, - (sliderIndex) { - setState(() { - sliderActiveIndex = sliderIndex; - }); - }, - ) - : SizedBox()), + model.dashboardItemsList.length > 0 + ? DashboardSwipeWidget( + model.dashboardItemsList, + model, + (sliderIndex) { + setState(() { + sliderActiveIndex = sliderIndex; + }); + }, + ) + : SizedBox(), model.dashboardItemsList.length > 0 ? FractionallySizedBox( widthFactor: 0.90, diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index b3b7ed8c..2a9109c3 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -19,9 +19,13 @@ class GetOutPatientStack extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - AppText( - value.kPIName, - medium: true, + Container( + height: 30, + child: AppText( + value.kPIName, + medium: true, + fontSize: 14, + ), ), Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: list) ], diff --git a/lib/widgets/dashboard/row_count.dart b/lib/widgets/dashboard/row_count.dart index a42cccdf..a22932f4 100644 --- a/lib/widgets/dashboard/row_count.dart +++ b/lib/widgets/dashboard/row_count.dart @@ -24,7 +24,7 @@ class RowCounts extends StatelessWidget { name, color: Colors.black, textAlign: TextAlign.start, // from TextAlign.center - fontSize: 12, + fontSize: 11, textOverflow: TextOverflow.ellipsis, ), ), @@ -32,7 +32,7 @@ class RowCounts extends StatelessWidget { ' (' + count.toString() + ')', color: Colors.black, textAlign: TextAlign.center, - fontSize: 13, + fontSize: 12, fontWeight: FontWeight.bold, ) ], From 27f940b4738ab233c8222d00f82992b4db65a162 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 9 May 2021 14:45:05 +0300 Subject: [PATCH 026/241] home design --- .../home/dashboard_slider-item-widget.dart | 4 +-- lib/widgets/dashboard/activity_button.dart | 29 +++++++------------ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/lib/screens/home/dashboard_slider-item-widget.dart b/lib/screens/home/dashboard_slider-item-widget.dart index 4ee67daf..4b7c4f46 100644 --- a/lib/screens/home/dashboard_slider-item-widget.dart +++ b/lib/screens/home/dashboard_slider-item-widget.dart @@ -24,8 +24,8 @@ class DashboardSliderItemWidget extends StatelessWidget { ], ), new Container( - height: 130, - child: new ListView( + height: 110, + child: ListView( scrollDirection: Axis.horizontal, children: List.generate(item.summaryoptions.length, (int index) { diff --git a/lib/widgets/dashboard/activity_button.dart b/lib/widgets/dashboard/activity_button.dart index b8f390dd..a46fc334 100644 --- a/lib/widgets/dashboard/activity_button.dart +++ b/lib/widgets/dashboard/activity_button.dart @@ -9,39 +9,32 @@ class GetActivityButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - width: 120, + width: 110, padding: EdgeInsets.all(5), margin: EdgeInsets.all(5), - height: 130, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), child: Padding( - padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ AppText( value.value.toString(), - fontSize: 30, + fontSize: 27, fontWeight: FontWeight.bold, color: Color(0xFF2B353E), ), - Expanded( - child: Column( - children: [ - AppText( - value.kPIParameter, - textOverflow: TextOverflow.clip, - fontSize: 10, - color: Color(0xFF2B353E), - textAlign: TextAlign.start, - fontWeight: FontWeight.w700, - ), - ], - ), + AppText( + value.kPIParameter, + textOverflow: TextOverflow.clip, + fontSize: 10, + color: Color(0xFF2B353E), + textAlign: TextAlign.start, + fontWeight: FontWeight.w700, ), ], ), From 50b4b8eb500e1d81f39949f6b53e06f63e633949 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 9 May 2021 16:15:06 +0300 Subject: [PATCH 027/241] dashboard change --- lib/screens/home/dashboard_swipe_widget.dart | 15 +++++++ lib/widgets/dashboard/out_patient_stack.dart | 45 +++++++++++-------- .../shared/rounded_container_widget.dart | 12 +++-- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart index de582dc2..a6dc12eb 100644 --- a/lib/screens/home/dashboard_swipe_widget.dart +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -87,6 +87,11 @@ class _DashboardSwipeWidgetState extends State { if (index == 1) return RoundedContainer( raduis: 16, + showBorder: true, + borderColor: Colors.white, + shadowWidth: 0.2, + shadowSpreadRadius: 3, + shadowDy: 1, margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), @@ -94,6 +99,11 @@ class _DashboardSwipeWidgetState extends State { if (index == 0) return RoundedContainer( raduis: 16, + showBorder: true, + borderColor: Colors.white, + shadowWidth: 0.2, + shadowSpreadRadius: 3, + shadowDy: 1, margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Padding( padding: const EdgeInsets.all(5.0), @@ -101,6 +111,11 @@ class _DashboardSwipeWidgetState extends State { if (index == 2) return RoundedContainer( raduis: 16, + showBorder: true, + borderColor: Colors.white, + shadowWidth: 0.2, + shadowSpreadRadius: 3, + shadowDy: 1, margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index 2a9109c3..2b982e20 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -37,8 +37,15 @@ class GetOutPatientStack extends StatelessWidget { child: Container( margin: EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment( + 0.0, 1.0), // 10% of the width, so there are ten blinds. + colors: [Color(0x8FF5F6FA), Colors.red[50]], // red to yellow + tileMode: TileMode.mirror, // repeats the gradient over the canvas + ), borderRadius: BorderRadius.circular(8), - color: Colors.red[50], + // color: Colors.red[50], ), child: Stack(children: [ Positioned( @@ -64,25 +71,25 @@ class GetOutPatientStack extends StatelessWidget { child: Center( child: Align( child: FittedBox( - child: Row( - children: [ - AppText( - value.kPIParameter, - fontSize: 10, - textAlign: TextAlign.center, - color: Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - AppText( - ' (' + value.value.toString() + ') ', - fontSize: 12, - textAlign: TextAlign.center, - color: Color(0xFF2B353E), - fontWeight: FontWeight.bold, - ), - ], + child: Row( + children: [ + AppText( + value.kPIParameter, + fontSize: 10, + textAlign: TextAlign.center, + color: Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + AppText( + ' (' + value.value.toString() + ') ', + fontSize: 12, + textAlign: TextAlign.center, + color: Color(0xFF2B353E), + fontWeight: FontWeight.bold, ), - )), + ], + ), + )), ), )) ]), diff --git a/lib/widgets/shared/rounded_container_widget.dart b/lib/widgets/shared/rounded_container_widget.dart index 4cfe7b08..8364bb79 100644 --- a/lib/widgets/shared/rounded_container_widget.dart +++ b/lib/widgets/shared/rounded_container_widget.dart @@ -9,6 +9,9 @@ class RoundedContainer extends StatefulWidget { final double elevation; final bool showBorder; final Color borderColor; + final double shadowWidth; + final double shadowSpreadRadius; + final double shadowDy; final bool customCornerRaduis; final double topLeft; final double bottomRight; @@ -27,6 +30,9 @@ class RoundedContainer extends StatefulWidget { this.elevation = 1, this.showBorder = false, this.borderColor = Colors.red, + this.shadowWidth = 0.1, + this.shadowSpreadRadius = 10, + this.shadowDy = 5, this.customCornerRaduis = false, this.topLeft = 0, this.topRight = 0, @@ -59,10 +65,10 @@ class _RoundedContainerState extends State { : BorderRadius.circular(widget.raduis), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 10, + color: Colors.grey.withOpacity(widget.shadowWidth), + spreadRadius: widget.shadowSpreadRadius, blurRadius: 5, - offset: Offset(0, 5), // changes position of shadow + offset: Offset(0, widget.shadowDy), // changes position of shadow ), ]) : null, From fd9f93a9365bdfe385617c3bb709c1bbee80b060 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 9 May 2021 17:33:33 +0300 Subject: [PATCH 028/241] do some refactor and change the code to view model --- ios/Podfile.lock | 2 +- lib/core/enum/auth_method_types.dart | 22 + ...on_code_for_doctor_app_response_model.dart | 55 ++- lib/core/service/authentication_service.dart | 24 + .../viewModel/authentication_view_model.dart | 156 +++++-- lib/core/viewModel/base_view_model.dart | 7 +- .../viewModel/doctor_profile_view_model.dart | 5 + lib/root_page.dart | 2 +- lib/routes.dart | 2 +- lib/screens/auth/login_screen.dart | 141 +++--- .../auth/verification_methods_screen.dart | 413 ++++++++---------- lib/util/helpers.dart | 14 +- lib/widgets/auth/auth_header.dart | 113 ----- lib/widgets/auth/method_card.dart | 244 ----------- lib/widgets/auth/method_type_card.dart | 53 +++ .../auth/verification_methods_list.dart | 87 ++++ 16 files changed, 642 insertions(+), 698 deletions(-) delete mode 100644 lib/widgets/auth/auth_header.dart delete mode 100644 lib/widgets/auth/method_card.dart create mode 100644 lib/widgets/auth/method_type_card.dart create mode 100644 lib/widgets/auth/verification_methods_list.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 878a1850..2f4607e0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/core/enum/auth_method_types.dart b/lib/core/enum/auth_method_types.dart index 3faff89c..82577eeb 100644 --- a/lib/core/enum/auth_method_types.dart +++ b/lib/core/enum/auth_method_types.dart @@ -21,4 +21,26 @@ extension SelectedAuthMethodTypesService on AuthMethodTypes { } } + + // ignore: missing_return + static getMethodsTypeService( int typeId) { + switch (typeId) { + case 1: + return AuthMethodTypes.SMS; + break; + case 2: + return AuthMethodTypes.WhatsApp; + break; + case 3: + return AuthMethodTypes.Fingerprint; + break; + case 4: + return AuthMethodTypes.FaceID; + break; + case 5: + return AuthMethodTypes.MoreOptions; + break; + + } + } } \ No newline at end of file diff --git a/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart b/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart index 283e617f..c5ff29e6 100644 --- a/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart +++ b/lib/core/model/auth/check_activation_code_for_doctor_app_response_model.dart @@ -1,24 +1,33 @@ +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; + class CheckActivationCodeForDoctorAppResponseModel { String authenticationTokenID; List listDoctorsClinic; - List list_DoctorProfile; + List listDoctorProfile; MemberInformation memberInformation; CheckActivationCodeForDoctorAppResponseModel( {this.authenticationTokenID, - this.listDoctorsClinic, - this.memberInformation}); + this.listDoctorsClinic, + this.memberInformation}); CheckActivationCodeForDoctorAppResponseModel.fromJson( Map json) { authenticationTokenID = json['AuthenticationTokenID']; - list_DoctorProfile = json['List_DoctorProfile']; if (json['List_DoctorsClinic'] != null) { listDoctorsClinic = new List(); json['List_DoctorsClinic'].forEach((v) { listDoctorsClinic.add(new ListDoctorsClinic.fromJson(v)); }); } + + if (json['List_DoctorProfile'] != null) { + listDoctorProfile = new List(); + json['List_DoctorProfile'].forEach((v) { + listDoctorProfile.add(new DoctorProfileModel.fromJson(v)); + }); + } + memberInformation = json['memberInformation'] != null ? new MemberInformation.fromJson(json['memberInformation']) : null; @@ -27,11 +36,15 @@ class CheckActivationCodeForDoctorAppResponseModel { Map toJson() { final Map data = new Map(); data['AuthenticationTokenID'] = this.authenticationTokenID; - data['List_DoctorProfile'] = this.list_DoctorProfile; if (this.listDoctorsClinic != null) { data['List_DoctorsClinic'] = this.listDoctorsClinic.map((v) => v.toJson()).toList(); } + + if (this.listDoctorProfile != null) { + data['List_DoctorProfile'] = + this.listDoctorProfile.map((v) => v.toJson()).toList(); + } if (this.memberInformation != null) { data['memberInformation'] = this.memberInformation.toJson(); } @@ -47,13 +60,12 @@ class ListDoctorsClinic { bool isActive; String clinicName; - ListDoctorsClinic( - {this.setupID, - this.projectID, - this.doctorID, - this.clinicID, - this.isActive, - this.clinicName}); + ListDoctorsClinic({this.setupID, + this.projectID, + this.doctorID, + this.clinicID, + this.isActive, + this.clinicName}); ListDoctorsClinic.fromJson(Map json) { setupID = json['SetupID']; @@ -87,16 +99,15 @@ class MemberInformation { String preferredLanguage; List roles; - MemberInformation( - {this.clinics, - this.doctorId, - this.email, - this.employeeId, - this.memberId, - this.memberName, - this.memberNameArabic, - this.preferredLanguage, - this.roles}); + MemberInformation({this.clinics, + this.doctorId, + this.email, + this.employeeId, + this.memberId, + this.memberName, + this.memberNameArabic, + this.preferredLanguage, + this.roles}); MemberInformation.fromJson(Map json) { if (json['clinics'] != null) { diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index 9f67a3b8..d20f5dbf 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -10,6 +10,8 @@ import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:provider/provider.dart'; @@ -30,6 +32,9 @@ class AuthenticationService extends BaseService { CheckActivationCodeForDoctorAppResponseModel get checkActivationCodeForDoctorAppRes => _checkActivationCodeForDoctorAppRes; Map _insertDeviceImeiRes = {}; + List _doctorProfilesList = []; + List get doctorProfilesList => _doctorProfilesList; + Future selectDeviceImei(imei) async { try { await baseAppClient.post(SELECT_DEVICE_IMEI, @@ -144,4 +149,23 @@ class AuthenticationService extends BaseService { super.error = error; } } + + Future getDoctorProfileBasedOnClinic(ProfileReqModel profileReqModel)async { + hasError = false; + try { + await baseAppClient.post(GET_DOC_PROFILES, + onSuccess: (dynamic response, int statusCode) { + _doctorProfilesList.clear(); + response['DoctorProfileList'].forEach((v) { + _doctorProfilesList.add(DoctorProfileModel.fromJson(v)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: profileReqModel.toJson()); + } catch (error) { + hasError = true; + super.error = error; + } + } } diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 228a63e7..b5f61b05 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -3,36 +3,62 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/core/model/auth/check_activation_code_for_doctor_app_response_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; import 'package:doctor_app_flutter/core/model/auth/send_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_request_model.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; -import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:intl/intl.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth/auth_strings.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; + +import 'doctor_profile_view_model.dart'; class AuthenticationViewModel extends BaseViewModel { AuthenticationService _authService = locator(); HospitalsService _hospitalsService = locator(); List get imeiDetails => _authService.dashboardItemsList; + List get hospitals => _hospitalsService.hospitals; + NewLoginInformationModel get loginInfo => _authService.loginInfo; - SendActivationCodeForDoctorAppResponseModel get activationCodeVerificationScreenRes => _authService.activationCodeVerificationScreenRes; - SendActivationCodeForDoctorAppResponseModel get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; - CheckActivationCodeForDoctorAppResponseModel get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; + List get doctorProfilesList => _authService.doctorProfilesList; + SendActivationCodeForDoctorAppResponseModel + get activationCodeVerificationScreenRes => + _authService.activationCodeVerificationScreenRes; + + SendActivationCodeForDoctorAppResponseModel + get activationCodeForDoctorAppRes => + _authService.activationCodeForDoctorAppRes; + + CheckActivationCodeForDoctorAppResponseModel + get checkActivationCodeForDoctorAppRes => + _authService.checkActivationCodeForDoctorAppRes; NewLoginInformationModel loggedUser; GetIMEIDetailsModel user; + + UserModel userInfo = UserModel(); + final LocalAuthentication auth = LocalAuthentication(); + List _availableBiometrics; + + Future selectDeviceImei(imei) async { setState(ViewState.Busy); await _authService.selectDeviceImei(imei); @@ -88,8 +114,13 @@ class AuthenticationViewModel extends BaseViewModel { if (_authService.hasError) { error = _authService.error; setState(ViewState.ErrorLocal); - } else + } else { + sharedPref.setInt(PROJECT_ID, userInfo.projectID); + saveObjToString(LOGGED_IN_USER, loginInfo); + sharedPref.remove(LAST_LOGIN_USER); + sharedPref.setString(TOKEN, loginInfo.logInTokenID); setState(ViewState.Idle); + } } Future sendActivationCodeVerificationScreen( AuthMethodTypes authMethodType) async { @@ -168,21 +199,6 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } - - //TODO Elham remove it - getDate(DateTime date) { - final DateFormat formatter = DateFormat('dd MMM yyyy'); - - return formatter.format(date); - } - //TODO Elham remove it - getTime(DateTime date) { - final DateFormat formatter = DateFormat('HH:mm a'); - - return formatter.format(date); - } - - getType(type, context) { switch (type) { case 1: @@ -214,17 +230,16 @@ class AuthenticationViewModel extends BaseViewModel { var localLoggedUser = await sharedPref.getObj(LOGGED_IN_USER); if(localLoggedUser!= null) { loggedUser = NewLoginInformationModel.fromJson(localLoggedUser); - } var lastLogin = await sharedPref.getObj(LAST_LOGIN_USER); if (lastLogin != null) { user = GetIMEIDetailsModel.fromJson(lastLogin); } setState(ViewState.Idle); - } - setDataAfterSendActivationSuccsess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel){ + setDataAfterSendActivationSuccsess( + SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, @@ -234,4 +249,93 @@ class AuthenticationViewModel extends BaseViewModel { sharedPref.setString(LOGIN_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.logInTokenID); } + + saveObjToString(String key, value) async { + sharedPref.setObj(key, value); + } + + showIOSAuthMessages() async { + const iosStrings = const IOSAuthMessages( + cancelButton: 'cancel', + goToSettingsButton: 'settings', + goToSettingsDescription: 'Please set up your Touch ID.', + lockOut: 'Please Enable Your Touch ID'); + + try { + await auth.authenticateWithBiometrics( + localizedReason: 'Scan your fingerprint to authenticate', + useErrorDialogs: true, + stickyAuth: true, + iOSAuthStrings: iosStrings); + } on PlatformException catch (e) { + DrAppToastMsg.showErrorToast(e.toString()); + } + } + + localSetDoctorProfile(DoctorProfileModel profile) { + super.setDoctorProfile(profile); + //TODO: Remove it when we remove Doctor Profile View Model and start to use profile form base view model + Provider.of(AppGlobal.CONTEX, listen: false) + .setDoctorProfile(profile); + } + + Future getDoctorProfileBasedOnClinic(ClinicModel clinicInfo) async { + ProfileReqModel docInfo = new ProfileReqModel( + doctorID: clinicInfo.doctorID, + clinicID: clinicInfo.clinicID, + license: true, + projectID: clinicInfo.projectID, + tokenID: '', + languageID: 2); + await _authService.getDoctorProfileBasedOnClinic(docInfo); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else { + localSetDoctorProfile(doctorProfilesList.first); + setState(ViewState.Idle); + } + } + + onCheckActivationCodeSuccess() async { + sharedPref.setString( + TOKEN, + checkActivationCodeForDoctorAppRes.authenticationTokenID); + if (checkActivationCodeForDoctorAppRes.listDoctorProfile != null && + checkActivationCodeForDoctorAppRes.listDoctorProfile + .isNotEmpty) { + localSetDoctorProfile( + checkActivationCodeForDoctorAppRes.listDoctorProfile[0]); + + + } else { + sharedPref.setObj( + CLINIC_NAME, + checkActivationCodeForDoctorAppRes.listDoctorsClinic); + ClinicModel clinic = ClinicModel.fromJson( + checkActivationCodeForDoctorAppRes.listDoctorsClinic[0] + .toJson()); + await getDoctorProfileBasedOnClinic(clinic); + } + } + + Future checkIfBiometricAvailable(BiometricType biometricType) async { + bool isAvailable = false; + await _getAvailableBiometrics(); + if (_availableBiometrics != null) { + for (var i = 0; i < _availableBiometrics.length; i++) { + if (biometricType == _availableBiometrics[i]) isAvailable = true; + } + } + return isAvailable; + } + + Future _getAvailableBiometrics() async { + try { + _availableBiometrics = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + print(e); + } + } + } diff --git a/lib/core/viewModel/base_view_model.dart b/lib/core/viewModel/base_view_model.dart index 43e83c9b..fe4dbd22 100644 --- a/lib/core/viewModel/base_view_model.dart +++ b/lib/core/viewModel/base_view_model.dart @@ -45,5 +45,10 @@ class BaseViewModel extends ChangeNotifier { } else { return doctorProfile; } -} + } + + setDoctorProfile(DoctorProfileModel doctorProfile){ + sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); + doctorProfile = doctorProfile; + } } diff --git a/lib/core/viewModel/doctor_profile_view_model.dart b/lib/core/viewModel/doctor_profile_view_model.dart index d336dd8d..4dcaf050 100644 --- a/lib/core/viewModel/doctor_profile_view_model.dart +++ b/lib/core/viewModel/doctor_profile_view_model.dart @@ -1,14 +1,19 @@ import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import '../../locator.dart'; + enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } class DoctorProfileViewModel extends BaseViewModel { List doctorsClinicList = []; + AuthenticationService _authService = locator(); + String selectedClinicName; bool isLogin = false; diff --git a/lib/root_page.dart b/lib/root_page.dart index 7df1b7cb..3b47290b 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -21,7 +21,7 @@ class RootPage extends StatelessWidget { ); break; case APP_STATUS.UNAUTHENTICATED: - return Loginsreen(); + return LoginScreen(); break; case APP_STATUS.AUTHENTICATED: return LandingPage(); diff --git a/lib/routes.dart b/lib/routes.dart index 90e061b8..5ec36ae3 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -64,7 +64,7 @@ const String RADIOLOGY_PATIENT = 'radiology-patient'; var routes = { ROOT: (_) => RootPage(), HOME: (_) => LandingPage(), - LOGIN: (_) => Loginsreen(), + LOGIN: (_) => LoginScreen(), VERIFICATION_METHODS: (_) => VerificationMethodsScreen(), PATIENTS_PROFILE: (_) => PatientProfileScreen(), LAB_RESULT: (_) => LabsHomePage(), diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 91af7a2f..429aff5a 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'dart:io'; import 'package:doctor_app_flutter/config/config.dart'; @@ -9,7 +8,6 @@ import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_m import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/doctor/user_model.dart'; import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -24,20 +22,18 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; -import '../../lookups/auth_lookup.dart'; import '../../util/dr_app_shared_pref.dart'; -import '../../widgets/auth/auth_header.dart'; import '../../widgets/shared/app_scaffold_widget.dart'; + //TODO Elham remove it DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); -//TODO Elham change the name -class Loginsreen extends StatefulWidget { + +class LoginScreen extends StatefulWidget { @override - _LoginsreenState createState() => _LoginsreenState(); + _LoginScreenState createState() => _LoginScreenState(); } -class _LoginsreenState extends State { - +class _LoginScreenState extends State { String platformImei; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); bool _isLoading = true; @@ -50,9 +46,7 @@ class _LoginsreenState extends State { List projectsList = []; FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); - // HospitalViewModel hospitalViewModel; - //TODO Elham to change it ti UserModel - var userInfo = UserModel(); + @override void initState() { @@ -99,11 +93,7 @@ class _LoginsreenState extends State { @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); - - return BaseView( - //TODO Elham remove it - onModelReady: (model) => {}, builder: (_, model, w) => AppScaffold( baseViewModel: model, @@ -123,7 +113,71 @@ class _LoginsreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ - AuthHeader(loginType.knownUser), + //TODO Use App Text rather than text + Container( + + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + SizedBox( + height: 30, + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment + .start, children: [ + SizedBox( + height: 10, + ), + Text( + TranslationBase + .of(context) + .welcomeTo, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight + .w600, + fontFamily: 'Poppins'), + ), + Text( + TranslationBase + .of(context) + .drSulaimanAlHabib, + style: TextStyle( + fontWeight: FontWeight + .w800, + fontSize: SizeConfig + .isMobile + ? 24 + : SizeConfig + .realScreenWidth * + 0.029, + fontFamily: 'Poppins'), + ), + + Text( + "Doctor App", + style: TextStyle( + fontSize: + SizeConfig.isMobile + ? 16 + : SizeConfig + .realScreenWidth * + 0.030, + fontWeight: FontWeight + .w800, + color: HexColor( + '#B8382C')), + ), + ]), + ], + )), SizedBox( height: 40, ), @@ -203,7 +257,7 @@ class _LoginsreenState extends State { onSaved: (value) { if (value != null) setState(() { - userInfo + model.userInfo .userID = value .trim(); @@ -212,7 +266,7 @@ class _LoginsreenState extends State { onChanged: (value) { if (value != null) setState(() { - userInfo + model.userInfo .userID = value .trim(); @@ -276,7 +330,7 @@ class _LoginsreenState extends State { if (value != null) setState(() { - userInfo + model.userInfo .password = value; }); @@ -286,7 +340,7 @@ class _LoginsreenState extends State { if (value != null) setState(() { - userInfo + model.userInfo .password = value; }); @@ -300,11 +354,12 @@ class _LoginsreenState extends State { context, projectsList, 'facilityName', - onSelectProject); + onSelectProject, + model); }, onTap: () { this.getProjects( - userInfo + model.userInfo .userID, model); }, ) @@ -352,7 +407,8 @@ class _LoginsreenState extends State { context, projectsList, 'facilityName', - onSelectProject); + onSelectProject, + model); }, validator: ( value) { @@ -424,9 +480,10 @@ class _LoginsreenState extends State { .login, color: HexColor( '#D02127'), - disabled: userInfo + disabled: model.userInfo .userID == null || - userInfo.password == + model.userInfo + .password == null, fontWeight: FontWeight .bold, @@ -445,7 +502,7 @@ class _LoginsreenState extends State { ]) : Center(child: AppLoaderWidget()), ), - )); + ), ); } SizedBox buildSizedBox() { @@ -459,44 +516,28 @@ class _LoginsreenState extends State { if (loginFormKey.currentState.validate()) { loginFormKey.currentState.save(); GifLoaderDialogUtils.showMyDialog(context); - sharedPref.setInt(PROJECT_ID, userInfo.projectID); - //TODO Elham move the sharedPref to view model - await model.login(userInfo); + await model.login(model.userInfo); if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); - } else { - saveObjToString(LOGGED_IN_USER, model.loginInfo); - sharedPref.remove(LAST_LOGIN_USER); - sharedPref.setString(TOKEN, model.loginInfo.logInTokenID); - //TODO Elham move the sharedPref to view model GifLoaderDialogUtils.hideDialog(context); Navigator.of(context).pushReplacement( MaterialPageRoute( - builder: (BuildContext context) => VerificationMethodsScreen( - password: userInfo.password, + builder: (BuildContext context) => + VerificationMethodsScreen( + password: model.userInfo.password, ), ), ); } } } - //TODO Elham to it view model - Future setSharedPref(key, value) async { - sharedPref.setString(key, value).then((success) { - }); - } - -//TODO Elham to it view model - saveObjToString(String key, value) async { - sharedPref.setObj(key, value); - } - onSelectProject(index) { + onSelectProject(index, AuthenticationViewModel model) { setState(() { - userInfo.projectID = projectsList[index].facilityId; + model.userInfo.projectID = projectsList[index].facilityId; projectIdController.text = projectsList[index].facilityName; }); @@ -510,7 +551,7 @@ class _LoginsreenState extends State { if(model.state == ViewState.Idle) { projectsList = model.hospitals; setState(() { - userInfo.projectID = projectsList[0].facilityId; + model.userInfo.projectID = projectsList[0].facilityId; projectIdController.text = projectsList[0].facilityName; }); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 5105707a..1c16bda9 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -5,12 +5,8 @@ import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; -import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -19,9 +15,7 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:local_auth/auth_strings.dart'; -import 'package:local_auth/local_auth.dart'; +import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import '../../config/size_config.dart'; @@ -30,17 +24,15 @@ import '../../landing_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../util/helpers.dart'; -import '../../widgets/auth/method_card.dart'; +import '../../widgets/auth/verification_methods_list.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); class VerificationMethodsScreen extends StatefulWidget { - VerificationMethodsScreen({this.changeLoadingState, this.password}); + VerificationMethodsScreen({this.password}); final password; - //TODO Elham remove this fun - final Function changeLoadingState; @override _VerificationMethodsScreenState createState() => _VerificationMethodsScreenState(); @@ -51,31 +43,11 @@ class _VerificationMethodsScreenState extends State { ProjectViewModel projectsProvider; bool isMoreOption = false; bool onlySMSBox = false; - var loginTokenID; DoctorProfileViewModel doctorProfileViewModel; - - bool authenticated; - AuthMethodTypes fingerPrintBefore; - AuthMethodTypes selectedOption; AuthenticationViewModel model; - final LocalAuthentication auth = LocalAuthentication(); - - //TODO Elham remove this fun - @override - void initState() { - super.initState(); - } - -//TODO Elham remove this fun - @override - void didChangeDependencies() async{ - super.didChangeDependencies(); - - } - @override Widget build(BuildContext context) { doctorProfileViewModel = Provider.of(context); @@ -93,7 +65,6 @@ class _VerificationMethodsScreenState extends State { child: FractionallySizedBox( child: Container( margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - height: SizeConfig.realScreenHeight * .95, width: SizeConfig.realScreenWidth, child: Column( @@ -102,7 +73,6 @@ class _VerificationMethodsScreenState extends State { children: [ Container( child: Column( - children: [ SizedBox( height: 100, @@ -146,54 +116,61 @@ class _VerificationMethodsScreenState extends State { style: TextStyle( fontFamily: 'Poppins', fontWeight: - FontWeight.w800, - fontSize: 14), - ), - subtitle: AppText( - model.getType( - model.user.logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - model.user.editedOn != null - ? model.getDate( - DateUtils - .convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != null - ? model - .getDate(DateUtils - .convertStringToDate( - model.user.createdOn)) - : '--', - textAlign: TextAlign.right, - fontSize: 14, - fontWeight: FontWeight.w800, - ), - subtitle: AppText( - model.user.editedOn != null - ? model.getTime( - DateUtils - .convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != null - ? model - .getTime(DateUtils - .convertStringToDate( - model.user.createdOn)) - : '--', - textAlign: TextAlign.right, - fontSize: 14, - ), - )) - ], - )), + FontWeight + .w800, + fontSize: 14), + ), + subtitle: AppText( + model.getType( + model.user + .logInTypeID, + context), + fontSize: 14, + ))), + Flexible( + flex: 2, + child: ListTile( + title: AppText( + model.user.editedOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate( + model.user + .editedOn)) + : model.user.createdOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate(model + .user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 14, + fontWeight: + FontWeight.w800, + ), + subtitle: AppText( + model.user.editedOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate( + model.user + .editedOn)) + : model.user.createdOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate(model + .user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 14, + ), + )) + ], + )), ], ) : Column( @@ -228,43 +205,39 @@ class _VerificationMethodsScreenState extends State { children: [ Expanded( child: InkWell( - onTap: () => { - // TODO check this logic it seem it will create bug to us - authenticateUser(AuthMethodTypes.Fingerprint, true) - }, - child: MethodCard( - authMethodType: model.user - .logInTypeID == - 4 - ? AuthMethodTypes.FaceID - : model.user.logInTypeID == 2 - ? AuthMethodTypes - .WhatsApp - : model.user.logInTypeID == - 3 - ? AuthMethodTypes - .Fingerprint - : AuthMethodTypes - .SMS, + onTap: () => + { + // TODO check this logic it seem it will create bug to us + authenticateUser( + AuthMethodTypes + .Fingerprint, true) + }, + child: VerificationMethodsList( + model: model, + authMethodType: SelectedAuthMethodTypesService + .getMethodsTypeService( + model.user + .logInTypeID), authenticateUser: (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), )), ), Expanded( - child: MethodCard( - authMethodType: + child: VerificationMethodsList( + model: model, + authMethodType: AuthMethodTypes.MoreOptions, - onShowMore: () { - setState(() { - isMoreOption = true; - }); - }, - )) + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) ]), ]) : Column( @@ -277,29 +250,31 @@ class _VerificationMethodsScreenState extends State { MainAxisAlignment.center, children: [ Expanded( - child: MethodCard( - authMethodType: + child: VerificationMethodsList( + model: model, + authMethodType: AuthMethodTypes.Fingerprint, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => authenticateUser( authMethodType, isActive), - )), + )), Expanded( - child: MethodCard( - authMethodType: + child: VerificationMethodsList( + model: model, + authMethodType: AuthMethodTypes.FaceID, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => authenticateUser( authMethodType, isActive), - )) + )) ], ) : SizedBox(), @@ -308,60 +283,79 @@ class _VerificationMethodsScreenState extends State { MainAxisAlignment.center, children: [ Expanded( - child: MethodCard( - authMethodType: AuthMethodTypes.SMS, - authenticateUser: - (AuthMethodTypes authMethodType, - isActive) => + child: VerificationMethodsList( + model: model, + authMethodType: AuthMethodTypes + .SMS, + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => authenticateUser( authMethodType, isActive), - )), + )), Expanded( - child: MethodCard( - authMethodType: + child: VerificationMethodsList( + model: model, + authMethodType: AuthMethodTypes.WhatsApp, - authenticateUser: - (AuthMethodTypes authMethodType, - isActive) => + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => authenticateUser( authMethodType, isActive), - )) + )) ], ), - ]), + ]), // ) ], ), ), - //TODO Elham move it to bottom sheet - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - model.user != null - ? Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context) - .useAnotherAccount, - color: Colors.red[700], - onPressed: () { - Navigator.of(context).pushNamed(LOGIN); - }, - )), - ], - ) - : SizedBox(), - ], - ), ], ), - ), + ), ), ), ), - )); + bottomSheet: model.user == null ? SizedBox(height: 0,) : Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all( + color: HexColor('#707070'), + width: 0), + ), + height: 90, + width: double.infinity, + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + AppButton( + title: TranslationBase + .of(context) + .useAnotherAccount, + color: Colors.red[700], + onPressed: () { + Navigator.of(context).pushNamed(LOGIN); + }, + ), + + SizedBox(height: 25,) + ], + ), + ), + ),), + ) + + ); } sendActivationCodeByOtpNotificationType( @@ -391,8 +385,6 @@ class _VerificationMethodsScreenState extends State { sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); - - await model .sendActivationCodeVerificationScreen(authMethodType); @@ -466,32 +458,21 @@ class _VerificationMethodsScreenState extends State { }, () => { - widget.changeLoadingState(false), print('Faild..'), }, ).displayDialog(context); } -//TODO Elham move it to view model loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { if (isActive) { - const iosStrings = const IOSAuthMessages( - cancelButton: 'cancel', - goToSettingsButton: 'settings', - goToSettingsDescription: 'Please set up your Touch ID.', - lockOut: 'Please reenable your Touch ID'); - - try { - authenticated = await auth.authenticateWithBiometrics( - localizedReason: 'Scan your fingerprint to authenticate', - useErrorDialogs: true, - stickyAuth: true, - iOSAuthStrings: iosStrings); - } on PlatformException catch (e) { - DrAppToastMsg.showErrorToast(e.toString()); - } + await model.showIOSAuthMessages(); if (!mounted) return; - if (model.user != null && (model.user.logInTypeID == 3 || model.user.logInTypeID == 4)) { + if (model.user != null && + (SelectedAuthMethodTypesService.getMethodsTypeService( + model.user.logInTypeID) == + AuthMethodTypes.Fingerprint || + SelectedAuthMethodTypesService.getMethodsTypeService( + model.user.logInTypeID) == AuthMethodTypes.FaceID)) { this.sendActivationCode(authMethodTypes); } else { setState(() { @@ -502,64 +483,30 @@ class _VerificationMethodsScreenState extends State { } checkActivationCode({value}) async { - - await model.checkActivationCodeForDoctorApp(activationCode:value ); - + await model.checkActivationCodeForDoctorApp(activationCode: value); if (model.state == ViewState.ErrorLocal) { Navigator.pop(context); Helpers.showErrorToast(model.error); } else { - sharedPref.setString( - TOKEN, model.checkActivationCodeForDoctorAppRes.authenticationTokenID); - //TODO Elham check the logic - if (model.checkActivationCodeForDoctorAppRes.listDoctorsClinic.isNotEmpty) { - loginProcessCompleted(model.checkActivationCodeForDoctorAppRes.list_DoctorProfile[0]); - sharedPref.setObj( - CLINIC_NAME, - model - .checkActivationCodeForDoctorAppRes.listDoctorsClinic); - } else { - sharedPref.setObj( - CLINIC_NAME, - model - .checkActivationCodeForDoctorAppRes.listDoctorsClinic); - ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes.listDoctorsClinic[0].toJson()); - getDocProfiles(clinic); - } + await model.onCheckActivationCodeSuccess(); + navigateToLandingPage(); } } - //TODO Elham move it to view model - loginProcessCompleted(Map profile) { - var doctor = DoctorProfileModel.fromJson(profile); - doctorProfileViewModel.setDoctorProfile(doctor); - sharedPref.setObj(DOCTOR_PROFILE, profile); - projectsProvider.isLogin = true; - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: LandingPage(), - ), - (r) => false); - } -//TODO Elham move it to view model - getDocProfiles(ClinicModel clinicInfo) { - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: clinicInfo.doctorID, - clinicID: clinicInfo.clinicID, - license: true, - projectID: clinicInfo.projectID, - tokenID: '', - languageID: 2); - doctorProfileViewModel.getDocProfiles(docInfo.toJson()).then((res) { - if (res['MessageStatus'] == 1) { - loginProcessCompleted(res['DoctorProfileList'][0]); - } else { - Helpers.showErrorToast(res['ErrorEndUserMessage']); - } - }).catchError((err) { - Helpers.showErrorToast(err); - }); + navigateToLandingPage() { + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + } else { + projectsProvider.isLogin = true; + + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), (r) => false); + } } + + } diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 6967a8aa..eb702d8d 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -1,6 +1,8 @@ import 'package:connectivity/connectivity.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/list_doctor_working_hours_table_model.dart'; import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; @@ -22,7 +24,7 @@ class Helpers { static int cupertinoPickerIndex = 0; get currentLanguage => null; - static showCupertinoPicker(context, items, decKey, onSelectFun) { + static showCupertinoPicker(context, List items, decKey, onSelectFun, AuthenticationViewModel model) { showModalBottomSheet( isDismissible: false, context: context, @@ -53,7 +55,7 @@ class Helpers { ), onPressed: () { Navigator.pop(context); - onSelectFun(cupertinoPickerIndex); + onSelectFun(cupertinoPickerIndex, model); }, ) ], @@ -63,7 +65,7 @@ class Helpers { height: SizeConfig.realScreenHeight * 0.3, color: Color(0xfff7f7f7), child: - buildPickerItems(context, items, decKey, onSelectFun)) + buildPickerItems(context, items, decKey, onSelectFun, model)) ], ), ); @@ -73,14 +75,14 @@ class Helpers { static TextStyle textStyle(context) => TextStyle(color: Theme.of(context).primaryColor); - static buildPickerItems(context, List items, decKey, onSelectFun) { + static buildPickerItems(context, List items, decKey, onSelectFun, model) { return CupertinoPicker( magnification: 1.5, scrollController: FixedExtentScrollController(initialItem: cupertinoPickerIndex), children: items.map((item) { return Text( - '${item["$decKey"]}', + '${item.facilityName}', style: TextStyle(fontSize: SizeConfig.textMultiplier * 2), ); }).toList(), @@ -151,7 +153,7 @@ class Helpers { Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( - page: Loginsreen(), + page: LoginScreen(), ), (r) => false); } diff --git a/lib/widgets/auth/auth_header.dart b/lib/widgets/auth/auth_header.dart deleted file mode 100644 index 27396980..00000000 --- a/lib/widgets/auth/auth_header.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:hexcolor/hexcolor.dart'; - -import '../../config/size_config.dart'; -import '../../lookups/auth_lookup.dart'; -//TODO Elham delete this widget -class AuthHeader extends StatelessWidget { - var userType; - AuthHeader(this.userType); - - @override - Widget build(BuildContext context) { - var screen = Container( - margin: SizeConfig.isMobile - ? null - : EdgeInsetsDirectional.fromSTEB(SizeConfig.realScreenWidth * 0.30, - SizeConfig.realScreenWidth * 0.1, 0, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 30, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: SizeConfig.isMobile - ? [ - SizedBox( - height: 10, - ), - buildWelText(context), - buildDrSulText(context), - ] - : [ - SizedBox( - height: 10, - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - buildWelText(context), - buildDrSulText(context), - ], - ), - ], - ), - buildDrAppContainer(context) - ], - )); - return screen; - } - - - Container buildDrAppContainer(BuildContext context) { - if (userType == loginType.changePassword || - userType == loginType.verifyPassword || - userType == loginType.verificationMethods) { - return Container(); - } - return Container( - child: Text( - "Doctor App", - style: TextStyle( - fontSize: - SizeConfig.isMobile ? 16 : SizeConfig.realScreenWidth * 0.030, - fontWeight: FontWeight.w800, - color: HexColor('#B8382C')), - ), - ); - } - - Text buildDrSulText(BuildContext context) { - if (userType == loginType.changePassword || - userType == loginType.verifyPassword || - userType == loginType.verificationMethods) { - return Text(''); - } - return Text( - TranslationBase.of(context).drSulaimanAlHabib, - style: TextStyle( - fontWeight: FontWeight.w800, - fontSize: - SizeConfig.isMobile ? 24 : SizeConfig.realScreenWidth * 0.029, - fontFamily: 'Poppins'), - ); - } - - Widget buildWelText(BuildContext context) { - String text = TranslationBase.of(context).welcomeTo; - if (userType == loginType.unknownUser) { - text = TranslationBase.of(context).welcomeBackTo; - } - if (userType == loginType.changePassword || - userType == loginType.verifyPassword || - userType == loginType.verificationMethods) { - return Text(''); - } - return AppText( - text, - // style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ); - } -} diff --git a/lib/widgets/auth/method_card.dart b/lib/widgets/auth/method_card.dart deleted file mode 100644 index 79721381..00000000 --- a/lib/widgets/auth/method_card.dart +++ /dev/null @@ -1,244 +0,0 @@ -import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:local_auth/local_auth.dart'; -import 'package:provider/provider.dart'; - -class MethodCard extends StatefulWidget { - final AuthMethodTypes authMethodType; - final Function ( AuthMethodTypes type, bool isActive) authenticateUser; - final Function onShowMore; - - const MethodCard({Key key, this.authMethodType, this.authenticateUser, this.onShowMore}) : super(key: key); - - @override - _MethodCardState createState() => _MethodCardState(); -} - -class _MethodCardState extends State { - - //TODO Elham change it to list Enum - var _availableBiometrics; - - final LocalAuthentication auth = LocalAuthentication(); - ProjectViewModel projectsProvider; - - - - @override - void initState() { - super.initState(); - _getAvailableBiometrics(); - } - - - bool checkIfBiometricAvailable(BiometricType biometricType) { - bool isAvailable = false; - if (_availableBiometrics != null) { - for (var i = 0; i < _availableBiometrics.length; i++) { - if (biometricType == _availableBiometrics[i]) isAvailable = true; - } - } - return isAvailable; - } - - Future _getAvailableBiometrics() async { - var availableBiometrics; - try { - availableBiometrics = await auth.getAvailableBiometrics(); - } on PlatformException catch (e) { - print(e); - } - if (!mounted) return; - - setState(() { - _availableBiometrics = availableBiometrics; - }); - } - @override - Widget build(BuildContext context) { - projectsProvider = Provider.of(context); - - switch (widget.authMethodType) { - case AuthMethodTypes.WhatsApp: - return InkWell( - onTap: () => {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, - //TODO Elham change it to widget - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - 'assets/images/verify-whtsapp.png', - height: 60, - width: 60, - ), - ], - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyWhatsApp, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.SMS: - return InkWell( - onTap: () => {widget.authenticateUser(AuthMethodTypes.SMS, true)}, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verify-sms.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifySMS, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.Fingerprint: - return InkWell( - onTap: () => { - if (checkIfBiometricAvailable(BiometricType.fingerprint)) - {widget.authenticateUser(AuthMethodTypes.Fingerprint, true)} - }, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_fingerprint_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFingerprint, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.FaceID: - return InkWell( - onTap: () { - if (checkIfBiometricAvailable(BiometricType.face)) { - widget.authenticateUser(AuthMethodTypes.FaceID, true); - } - }, - child: - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - margin: EdgeInsets.all(10), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_faceid_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFaceID, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - - default: - return InkWell( - onTap: widget.onShowMore, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/login/more_icon.png', - height: 60, - width: 60, - ), - projectsProvider.isArabic - ? SizedBox( - height: 20, - ) - : SizedBox( - height: 10, - ), - AppText( - TranslationBase.of(context).moreVerification, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - }; - } -} diff --git a/lib/widgets/auth/method_type_card.dart b/lib/widgets/auth/method_type_card.dart new file mode 100644 index 00000000..45190d2c --- /dev/null +++ b/lib/widgets/auth/method_type_card.dart @@ -0,0 +1,53 @@ +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class MethodTypeCard extends StatelessWidget { + const MethodTypeCard({ + Key key, + this.assetPath, + this.onTap, + this.label, + }) : super(key: key); + final String assetPath; + final Function onTap; + final String label; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + assetPath, + height: 60, + width: 60, + ), + ], + ), + SizedBox( + height: 20, + ), + AppText( + label, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + )), + ); + } +} diff --git a/lib/widgets/auth/verification_methods_list.dart b/lib/widgets/auth/verification_methods_list.dart new file mode 100644 index 00000000..e42e33ba --- /dev/null +++ b/lib/widgets/auth/verification_methods_list.dart @@ -0,0 +1,87 @@ +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/auth/method_type_card.dart'; +import 'package:flutter/material.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; + +class VerificationMethodsList extends StatefulWidget { + final AuthMethodTypes authMethodType; + final Function(AuthMethodTypes type, bool isActive) authenticateUser; + final Function onShowMore; + final AuthenticationViewModel model; + + const VerificationMethodsList( + {Key key, + this.authMethodType, + this.authenticateUser, + this.onShowMore, + this.model}) + : super(key: key); + + @override + _VerificationMethodsListState createState() => + _VerificationMethodsListState(); +} + +class _VerificationMethodsListState extends State { + final LocalAuthentication auth = LocalAuthentication(); + ProjectViewModel projectsProvider; + + @override + Widget build(BuildContext context) { + projectsProvider = Provider.of(context); + + switch (widget.authMethodType) { + case AuthMethodTypes.WhatsApp: + return MethodTypeCard( + assetPath: 'assets/images/verify-whtsapp.png', + onTap: () => + {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, + label: TranslationBase.of(context).verifyWhatsApp, + ); + break; + case AuthMethodTypes.SMS: + return MethodTypeCard( + assetPath: "assets/images/verify-sms.png", + onTap: () => {widget.authenticateUser(AuthMethodTypes.SMS, true)}, + label: TranslationBase.of(context).verifySMS, + ); + break; + case AuthMethodTypes.Fingerprint: + return MethodTypeCard( + assetPath: 'assets/images/verification_fingerprint_icon.png', + onTap: () async { + if (await widget.model + .checkIfBiometricAvailable(BiometricType.fingerprint)) { + + widget.authenticateUser(AuthMethodTypes.Fingerprint, true); + } + }, + label: TranslationBase.of(context).verifyFingerprint, + ); + break; + case AuthMethodTypes.FaceID: + return MethodTypeCard( + assetPath: 'assets/images/verification_faceid_icon.png', + onTap: () async { + if (await widget.model + .checkIfBiometricAvailable(BiometricType.face)) { + widget.authenticateUser(AuthMethodTypes.FaceID, true); + } + }, + label: TranslationBase.of(context).verifyFaceID, + ); + break; + + default: + return MethodTypeCard( + assetPath: 'assets/images/login/more_icon.png', + onTap: widget.onShowMore, + label: TranslationBase.of(context).moreVerification, + ); + } + } +} From 2e71706cabfde4279ca44ff774f9001194a5a374 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 10 May 2021 15:07:03 +0300 Subject: [PATCH 029/241] add UNVERIFIED status --- lib/core/service/authentication_service.dart | 3 + .../viewModel/authentication_view_model.dart | 95 +- .../viewModel/doctor_profile_view_model.dart | 13 - lib/locator.dart | 1 - lib/main.dart | 6 +- lib/root_page.dart | 17 +- lib/screens/auth/login_screen.dart | 880 ++++++++---------- .../auth/verification_methods_screen.dart | 590 ++++++------ lib/screens/home/home_screen.dart | 5 +- .../auth/verification_methods_list.dart | 8 +- 10 files changed, 798 insertions(+), 820 deletions(-) diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index d20f5dbf..ffa22f33 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -35,6 +35,9 @@ class AuthenticationService extends BaseService { List _doctorProfilesList = []; List get doctorProfilesList => _doctorProfilesList; + + + Future selectDeviceImei(imei) async { try { await baseAppClient.post(SELECT_DEVICE_IMEI, diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index b5f61b05..c35c4e12 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; @@ -20,8 +22,10 @@ import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; @@ -29,6 +33,8 @@ import 'package:provider/provider.dart'; import 'doctor_profile_view_model.dart'; +enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED, UNVERIFIED } + class AuthenticationViewModel extends BaseViewModel { AuthenticationService _authService = locator(); HospitalsService _hospitalsService = locator(); @@ -38,18 +44,20 @@ class AuthenticationViewModel extends BaseViewModel { List get hospitals => _hospitalsService.hospitals; NewLoginInformationModel get loginInfo => _authService.loginInfo; + List get doctorProfilesList => _authService.doctorProfilesList; + SendActivationCodeForDoctorAppResponseModel - get activationCodeVerificationScreenRes => - _authService.activationCodeVerificationScreenRes; + get activationCodeVerificationScreenRes => + _authService.activationCodeVerificationScreenRes; SendActivationCodeForDoctorAppResponseModel - get activationCodeForDoctorAppRes => - _authService.activationCodeForDoctorAppRes; + get activationCodeForDoctorAppRes => + _authService.activationCodeForDoctorAppRes; CheckActivationCodeForDoctorAppResponseModel - get checkActivationCodeForDoctorAppRes => - _authService.checkActivationCodeForDoctorAppRes; + get checkActivationCodeForDoctorAppRes => + _authService.checkActivationCodeForDoctorAppRes; NewLoginInformationModel loggedUser; GetIMEIDetailsModel user; @@ -57,7 +65,14 @@ class AuthenticationViewModel extends BaseViewModel { UserModel userInfo = UserModel(); final LocalAuthentication auth = LocalAuthentication(); List _availableBiometrics; + final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + + bool isLogin = false; + bool unverified = false; + AuthenticationViewModel({bool checkDeviceInfo = false}) { + getDeviceInfoFromFirebase(); + } Future selectDeviceImei(imei) async { setState(ViewState.Busy); @@ -70,7 +85,6 @@ class AuthenticationViewModel extends BaseViewModel { } Future insertDeviceImei() async { - var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); var user = await sharedPref.getObj(LAST_LOGIN_USER); if (user != null) { @@ -116,6 +130,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); } else { sharedPref.setInt(PROJECT_ID, userInfo.projectID); + loggedUser = loginInfo; saveObjToString(LOGGED_IN_USER, loginInfo); sharedPref.remove(LAST_LOGIN_USER); sharedPref.setString(TOKEN, loginInfo.logInTokenID); @@ -183,7 +198,6 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); - } } @@ -238,8 +252,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } - setDataAfterSendActivationSuccsess( - SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { + setDataAfterSendActivationSuccsess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, @@ -300,28 +313,26 @@ class AuthenticationViewModel extends BaseViewModel { onCheckActivationCodeSuccess() async { sharedPref.setString( TOKEN, - checkActivationCodeForDoctorAppRes.authenticationTokenID); + checkActivationCodeForDoctorAppRes.authenticationTokenID); if (checkActivationCodeForDoctorAppRes.listDoctorProfile != null && checkActivationCodeForDoctorAppRes.listDoctorProfile .isNotEmpty) { localSetDoctorProfile( - checkActivationCodeForDoctorAppRes.listDoctorProfile[0]); - - + checkActivationCodeForDoctorAppRes.listDoctorProfile[0]); } else { sharedPref.setObj( CLINIC_NAME, checkActivationCodeForDoctorAppRes.listDoctorsClinic); ClinicModel clinic = ClinicModel.fromJson( - checkActivationCodeForDoctorAppRes.listDoctorsClinic[0] + checkActivationCodeForDoctorAppRes.listDoctorsClinic[0] .toJson()); - await getDoctorProfileBasedOnClinic(clinic); + await getDoctorProfileBasedOnClinic(clinic); } } Future checkIfBiometricAvailable(BiometricType biometricType) async { bool isAvailable = false; - await _getAvailableBiometrics(); + await _getAvailableBiometrics(); if (_availableBiometrics != null) { for (var i = 0; i < _availableBiometrics.length; i++) { if (biometricType == _availableBiometrics[i]) isAvailable = true; @@ -338,4 +349,54 @@ class AuthenticationViewModel extends BaseViewModel { } } + + getDeviceInfoFromFirebase() async { + _firebaseMessaging.setAutoInitEnabled(true); + if (Platform.isIOS) { + _firebaseMessaging.requestNotificationPermissions(); + } + setState(ViewState.Busy); + + _firebaseMessaging.getToken().then((String token) async { + if (DEVICE_TOKEN == "") { + DEVICE_TOKEN = token; + + await _authService.selectDeviceImei(DEVICE_TOKEN); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); + } else { + if (_authService.dashboardItemsList.length > 0) { + user =_authService.dashboardItemsList[0]; + sharedPref.setObj( + LAST_LOGIN_USER, _authService.dashboardItemsList[0]); + this.unverified = true; + // Navigator.of(AppGlobal.CONTEX).pushReplacement(MaterialPageRoute( + // builder: (BuildContext context) => VerificationMethodsScreen( + // password: null, + // ))); + } + setState(ViewState.Idle); + } + } else { + setState(ViewState.Idle); + } + }); + } + + + APP_STATUS get stutas { + if (state == ViewState.Busy) { + return APP_STATUS.LOADING; + } else { + if (this.unverified) { + return APP_STATUS.UNVERIFIED; + } else if (this.isLogin) { + return APP_STATUS.AUTHENTICATED; + } else { + return APP_STATUS.UNAUTHENTICATED; + } + } + } + } diff --git a/lib/core/viewModel/doctor_profile_view_model.dart b/lib/core/viewModel/doctor_profile_view_model.dart index 4dcaf050..6210951e 100644 --- a/lib/core/viewModel/doctor_profile_view_model.dart +++ b/lib/core/viewModel/doctor_profile_view_model.dart @@ -8,7 +8,6 @@ import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import '../../locator.dart'; -enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } class DoctorProfileViewModel extends BaseViewModel { List doctorsClinicList = []; @@ -41,18 +40,6 @@ class DoctorProfileViewModel extends BaseViewModel { } notifyListeners(); } -//TODO Elham move it auth view model - APP_STATUS get stutas { - if (isLoading) { - return APP_STATUS.LOADING; - } else { - if (this.isLogin) { - return APP_STATUS.AUTHENTICATED; - } else { - return APP_STATUS.UNAUTHENTICATED; - } - } - } Future getDocProfiles(docInfo, {bool allowChangeProfile = true}) async { diff --git a/lib/locator.dart b/lib/locator.dart index 3032c49d..869eadc2 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -90,7 +90,6 @@ void setupLocator() { /// View Model locator.registerFactory(() => DoctorReplayViewModel()); - locator.registerFactory(() => AuthenticationViewModel()); locator.registerFactory(() => ScheduleViewModel()); locator.registerFactory(() => ReferralPatientViewModel()); locator.registerFactory(() => ReferredPatientViewModel()); diff --git a/lib/main.dart b/lib/main.dart index 7c70061c..b7acdd80 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'package:provider/provider.dart'; import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; +import 'core/viewModel/authentication_view_model.dart'; import 'core/viewModel/doctor_profile_view_model.dart'; import 'core/viewModel/hospitals_view_model.dart'; import 'locator.dart'; @@ -23,7 +24,6 @@ void main() async { } class MyApp extends StatelessWidget { - // This widget is the root of your application. @override Widget build(BuildContext context) { AppGlobal.CONTEX = context; @@ -33,10 +33,10 @@ class MyApp extends StatelessWidget { SizeConfig().init(constraints, orientation); return MultiProvider( providers: [ + ChangeNotifierProvider( + create: (context) => AuthenticationViewModel()), ChangeNotifierProvider( create: (context) => DoctorProfileViewModel()), - // ChangeNotifierProvider( - // create: (context) => HospitalViewModel()), ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), diff --git a/lib/root_page.dart b/lib/root_page.dart index 3b47290b..6040b160 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -1,25 +1,30 @@ -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; +import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/dr_app_circular_progress_Indeicator.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'core/viewModel/authentication_view_model.dart'; import 'landing_page.dart'; class RootPage extends StatelessWidget { @override Widget build(BuildContext context) { - DoctorProfileViewModel authProvider = Provider.of(context); + AuthenticationViewModel authenticationViewModel = Provider.of(context); + // ignore: missing_return Widget buildRoot() { - switch (authProvider.stutas) { + switch (authenticationViewModel.stutas) { case APP_STATUS.LOADING: return Scaffold( - body: Center( - child: DrAppCircularProgressIndeicator(), - ), + body: AppLoaderWidget(), ); break; + case APP_STATUS.UNVERIFIED: + return VerificationMethodsScreen(password: null,); + break; case APP_STATUS.UNAUTHENTICATED: return LoginScreen(); break; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 429aff5a..7fbf47af 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -1,32 +1,20 @@ -import 'dart:io'; - -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; -import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; -import '../../util/dr_app_shared_pref.dart'; import '../../widgets/shared/app_scaffold_widget.dart'; -//TODO Elham remove it -DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); class LoginScreen extends StatefulWidget { @override @@ -35,10 +23,6 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { String platformImei; - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); - bool _isLoading = true; - ProjectViewModel projectViewModel; - AuthenticationService authService = AuthenticationService(); //TODO change AppTextFormField to AppTextFormFieldCustom final loginFormKey = GlobalKey(); @@ -46,463 +30,410 @@ class _LoginScreenState extends State { List projectsList = []; FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); - - - @override - void initState() { - super.initState(); - //TODO Elham move it root page and the logic in the view model - _firebaseMessaging.setAutoInitEnabled(true); - if (Platform.isIOS) { - _firebaseMessaging.requestNotificationPermissions(); - } - - _firebaseMessaging.getToken().then((String token) async { - if (DEVICE_TOKEN == "" && projectViewModel.isLogin == false) { - DEVICE_TOKEN = token; - changeLoadingState(true); - authService.selectDeviceImei(DEVICE_TOKEN).then((value) { - print(authService.dashboardItemsList); - - if (authService.dashboardItemsList.length > 0) { - sharedPref.setObj( - LAST_LOGIN_USER, authService.dashboardItemsList[0]); - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (BuildContext context) => VerificationMethodsScreen( - password: null, - ))); - } else { - changeLoadingState(false); - } - }); - } else { - changeLoadingState(false); - } - }).catchError((err) { - print(err); - }); - } - - //TODO Elham change it to GIF - void changeLoadingState(isLoading) { - setState(() { - _isLoading = isLoading; - }); - } + AuthenticationViewModel authenticationViewModel; @override Widget build(BuildContext context) { - projectViewModel = Provider.of(context); - return BaseView( - builder: (_, model, w) => - AppScaffold( - baseViewModel: model, - isShowAppBar: false, - backgroundColor: HexColor('#F8F8F8'), - body: SafeArea( - child: (_isLoading == false) - ? ListView(children: [ + authenticationViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: false, + backgroundColor: HexColor('#F8F8F8'), + body: SafeArea( + child: ListView(children: [ + Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 30), + alignment: Alignment.topLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //TODO Use App Text rather than text Container( - margin: - EdgeInsetsDirectional.fromSTEB(30, 0, 30, 30), - alignment: Alignment.topLeft, + child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - //TODO Use App Text rather than text - Container( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + SizedBox( + height: 30, + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment + .start, children: [ + SizedBox( + height: 10, + ), + Text( + TranslationBase + .of(context) + .welcomeTo, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight + .w600, + fontFamily: 'Poppins'), + ), + Text( + TranslationBase + .of(context) + .drSulaimanAlHabib, + style: TextStyle( + fontWeight: FontWeight + .w800, + fontSize: SizeConfig + .isMobile + ? 24 + : SizeConfig + .realScreenWidth * + 0.029, + fontFamily: 'Poppins'), + ), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - SizedBox( - height: 30, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment - .start, children: [ - SizedBox( - height: 10, - ), - Text( + Text( + "Doctor App", + style: TextStyle( + fontSize: + SizeConfig.isMobile + ? 16 + : SizeConfig + .realScreenWidth * + 0.030, + fontWeight: FontWeight + .w800, + color: HexColor( + '#B8382C')), + ), + ]), + ], + )), + SizedBox( + height: 40, + ), + Form( + key: loginFormKey, + child: Column( + mainAxisAlignment: MainAxisAlignment + .spaceBetween, + children: [ + Container( + width: SizeConfig + .realScreenWidth * 0.90, + height: SizeConfig + .realScreenHeight * 0.65, + child: + Column( + crossAxisAlignment: CrossAxisAlignment + .start, children: [ + buildSizedBox(), + Padding( + child: AppText( + TranslationBase + .of(context) + .enterCredentials, + fontSize: 18, + fontWeight: FontWeight + .bold, + ), + padding: EdgeInsets.only( + top: 10, bottom: 10)), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( TranslationBase .of(context) - .welcomeTo, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight - .w600, - fontFamily: 'Poppins'), - ), - Text( + .enterId, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + labelText: '', + borderColor: Colors + .white, + textInputAction: TextInputAction + .next, + + validator: (value) { + if (value != + null && value + .isEmpty) { + return TranslationBase + .of(context) + .pleaseEnterYourID; + } + return null; + }, + onSaved: (value) { + if (value != + null) setState(() { + authenticationViewModel.userInfo + .userID = + value + .trim(); + }); + }, + onChanged: (value) { + if (value != null) + setState(() { + authenticationViewModel.userInfo + .userID = + value + .trim(); + }); + }, + onFieldSubmitted: (_) { + focusPass + .nextFocus(); + }, + ) + ])), + buildSizedBox(), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( TranslationBase .of(context) - .drSulaimanAlHabib, - style: TextStyle( - fontWeight: FontWeight - .w800, - fontSize: SizeConfig - .isMobile - ? 24 - : SizeConfig - .realScreenWidth * - 0.029, - fontFamily: 'Poppins'), - ), - - Text( - "Doctor App", - style: TextStyle( - fontSize: - SizeConfig.isMobile - ? 16 - : SizeConfig - .realScreenWidth * - 0.030, - fontWeight: FontWeight - .w800, - color: HexColor( - '#B8382C')), - ), - ]), - ], - )), - SizedBox( - height: 40, - ), - Form( - key: loginFormKey, - child: Column( - mainAxisAlignment: MainAxisAlignment - .spaceBetween, - children: [ - Container( - width: SizeConfig - .realScreenWidth * 0.90, - height: SizeConfig - .realScreenHeight * 0.65, - child: - Column( - crossAxisAlignment: CrossAxisAlignment - .start, children: [ - buildSizedBox(), - Padding( - child: AppText( - TranslationBase - .of(context) - .enterCredentials, - fontSize: 18, - fontWeight: FontWeight - .bold, - ), - padding: EdgeInsets.only( - top: 10, bottom: 10)), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .enterId, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - labelText: '', - borderColor: Colors - .white, - textInputAction: TextInputAction - .next, - - validator: (value) { - if (value != - null && value - .isEmpty) { - return TranslationBase - .of(context) - .pleaseEnterYourID; - } - return null; - }, - onSaved: (value) { - if (value != - null) setState(() { - model.userInfo - .userID = - value - .trim(); - }); - }, - onChanged: (value) { - if (value != null) - setState(() { - model.userInfo - .userID = - value - .trim(); - }); - }, - onFieldSubmitted: ( - _) { - focusPass - .nextFocus(); - }, - ) - ])), - buildSizedBox(), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .enterPassword, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - focusNode: focusPass, - obscureText: true, - borderColor: Colors - .white, - textInputAction: TextInputAction - .next, - validator: (value) { - if (value != - null && value - .isEmpty) { - return TranslationBase - .of(context) - .pleaseEnterPassword; - } - return null; - }, - onSaved: (value) { - if (value != - null) - setState(() { - model.userInfo - .password = - value; - }); - - }, - onChanged: (value){ - if (value != - null) - setState(() { - model.userInfo - .password = - value; - }); - }, - onFieldSubmitted: ( - _) { - focusPass - .nextFocus(); - Helpers - .showCupertinoPicker( - context, - projectsList, - 'facilityName', - onSelectProject, - model); - }, - onTap: () { - this.getProjects( - model.userInfo - .userID, model); - }, - ) - ])), - buildSizedBox(), - projectsList.length > 0 - ? Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .selectYourProject, - fontWeight: FontWeight - .w600, - )), - AppTextFormField( - focusNode: focusProject, - controller: projectIdController, - borderColor: Colors - .white, - suffixIcon: Icons - .arrow_drop_down, - onTap: () { - Helpers - .showCupertinoPicker( - context, - projectsList, - 'facilityName', - onSelectProject, - model); - }, - validator: ( - value) { - if (value != - null && - value - .isEmpty) { - return TranslationBase - .of( - context) - .pleaseEnterYourProject; - } - return null; - }) - ])) - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .selectYourProject, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - readOnly: true, - borderColor: Colors - .white, - prefix: IconButton( - icon: Icon(Icons - .arrow_drop_down), - iconSize: 30, - padding: EdgeInsets - .only( - bottom: 30), - ), - ) - ])), - ]), - ), - Row( - mainAxisAlignment: MainAxisAlignment - .end, - children: [ - Expanded( - child: AppButton( - title: TranslationBase - .of(context) - .login, - color: HexColor( - '#D02127'), - disabled: model.userInfo - .userID == null || - model.userInfo - .password == - null, - fontWeight: FontWeight - .bold, - onPressed: () { - login(context, model); - }, - )), - ], + .enterPassword, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + focusNode: focusPass, + obscureText: true, + borderColor: Colors + .white, + textInputAction: TextInputAction + .next, + validator: (value) { + if (value != + null && value + .isEmpty) { + return TranslationBase + .of(context) + .pleaseEnterPassword; + } + return null; + }, + onSaved: (value) { + if (value != + null) + setState(() { + authenticationViewModel.userInfo + .password = + value; + }); + }, + onChanged: (value){ + if (value != + null) + setState(() { + authenticationViewModel.userInfo + .password = + value; + }); + }, + onFieldSubmitted: (_) { + focusPass + .nextFocus(); + Helpers + .showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject, + authenticationViewModel); + }, + onTap: () { + this.getProjects( + authenticationViewModel.userInfo + .userID); + }, ) - ], - ), - ) - ], - ) - ])) - ]) - : Center(child: AppLoaderWidget()), - ), - ), ); + ])), + buildSizedBox(), + projectsList.length > 0 + ? Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .selectYourProject, + fontWeight: FontWeight + .w600, + )), + AppTextFormField( + focusNode: focusProject, + controller: projectIdController, + borderColor: Colors + .white, + suffixIcon: Icons + .arrow_drop_down, + onTap: () { + Helpers + .showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject, + authenticationViewModel); + }, + validator: (value) { + if (value != + null && + value + .isEmpty) { + return TranslationBase + .of( + context) + .pleaseEnterYourProject; + } + return null; + }) + ])) + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius + .all( + Radius.circular( + 6.0)), + border: Border.all( + width: 1.0, + color: HexColor( + "#CCCCCC"), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment + .start, + children: [ + Padding( + padding: EdgeInsets + .only( + left: 10, + top: 10), + child: AppText( + TranslationBase + .of(context) + .selectYourProject, + fontWeight: FontWeight + .w800, + fontSize: 14, + )), + AppTextFormField( + readOnly: true, + borderColor: Colors + .white, + prefix: IconButton( + icon: Icon(Icons + .arrow_drop_down), + iconSize: 30, + padding: EdgeInsets + .only( + bottom: 30), + ), + ) + ])), + ]), + ), + Row( + mainAxisAlignment: MainAxisAlignment + .end, + children: [ + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .login, + color: HexColor( + '#D02127'), + disabled: authenticationViewModel.userInfo + .userID == null || + authenticationViewModel.userInfo + .password == + null, + fontWeight: FontWeight + .bold, + onPressed: () { + login(context); + }, + )), + ], + ) + ], + ), + ) + ], + ) + ])) + ]), + ), + ); } SizedBox buildSizedBox() { @@ -511,15 +442,14 @@ class _LoginScreenState extends State { ); } - login(context, - AuthenticationViewModel model,) async { + login(context,) async { if (loginFormKey.currentState.validate()) { loginFormKey.currentState.save(); GifLoaderDialogUtils.showMyDialog(context); - await model.login(model.userInfo); - if (model.state == ViewState.ErrorLocal) { + await authenticationViewModel.login(authenticationViewModel.userInfo); + if (authenticationViewModel.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(model.error); + Helpers.showErrorToast(authenticationViewModel.error); } else { GifLoaderDialogUtils.hideDialog(context); @@ -527,7 +457,7 @@ class _LoginScreenState extends State { MaterialPageRoute( builder: (BuildContext context) => VerificationMethodsScreen( - password: model.userInfo.password, + password: authenticationViewModel.userInfo.password, ), ), ); @@ -535,23 +465,23 @@ class _LoginScreenState extends State { } } - onSelectProject(index, AuthenticationViewModel model) { + onSelectProject(index) { setState(() { - model.userInfo.projectID = projectsList[index].facilityId; + authenticationViewModel.userInfo.projectID = projectsList[index].facilityId; projectIdController.text = projectsList[index].facilityName; }); primaryFocus.unfocus(); } - getProjects(memberID, AuthenticationViewModel model)async { + getProjects(memberID)async { if (memberID != null && memberID != '') { if (projectsList.length == 0) { - await model.getHospitalsList(memberID); - if(model.state == ViewState.Idle) { - projectsList = model.hospitals; + await authenticationViewModel.getHospitalsList(memberID); + if(authenticationViewModel.state == ViewState.Idle) { + projectsList = authenticationViewModel.hospitals; setState(() { - model.userInfo.projectID = projectsList[0].facilityId; + authenticationViewModel.userInfo.projectID = projectsList[0].facilityId; projectIdController.text = projectsList[0].facilityName; }); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 1c16bda9..40749b84 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -4,8 +4,8 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.dart'; @@ -19,7 +19,6 @@ import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import '../../config/size_config.dart'; -import '../../core/viewModel/doctor_profile_view_model.dart'; import '../../landing_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; @@ -46,28 +45,25 @@ class _VerificationMethodsScreenState extends State { DoctorProfileViewModel doctorProfileViewModel; AuthMethodTypes fingerPrintBefore; AuthMethodTypes selectedOption; - AuthenticationViewModel model; + AuthenticationViewModel authenticationViewModel; @override Widget build(BuildContext context) { doctorProfileViewModel = Provider.of(context); projectsProvider = Provider.of(context); - return BaseView( - onModelReady: (model) async { - this.model = model; - await model.getInitUserInfo(); - }, - builder: (_, model, w) => AppScaffold( - isShowAppBar: false, - baseViewModel: model, - body: SingleChildScrollView( - child: Center( - child: FractionallySizedBox( - child: Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - height: SizeConfig.realScreenHeight * .95, - width: SizeConfig.realScreenWidth, - child: Column( + authenticationViewModel = Provider.of(context); + + return AppScaffold( + isShowAppBar: false, + // baseViewModel: model, + body: SingleChildScrollView( + child: Center( + child: FractionallySizedBox( + child: Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), + height: SizeConfig.realScreenHeight * .95, + width: SizeConfig.realScreenWidth, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -77,284 +73,280 @@ class _VerificationMethodsScreenState extends State { SizedBox( height: 100, ), - model.user != null && isMoreOption == false + authenticationViewModel.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).welcomeBack), + AppText( + Helpers.capitalize(authenticationViewModel.user.doctorName), + fontSize: SizeConfig.textMultiplier * 3.5, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).accountInfo, + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.w600, + ), + SizedBox( + height: 20, + ), + Card( + color: Colors.white, + child: Row( + children: [ + Flexible( + flex: 3, + child: ListTile( + title: Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontWeight: + FontWeight + .w800, + fontSize: 14), + ), + subtitle: AppText( + authenticationViewModel.getType( + authenticationViewModel.user + .logInTypeID, + context), + fontSize: 14, + ))), + Flexible( + flex: 2, + child: ListTile( + title: AppText( + authenticationViewModel.user.editedOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate( + authenticationViewModel.user + .editedOn)) + : authenticationViewModel.user.createdOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 14, + fontWeight: + FontWeight.w800, + ), + subtitle: AppText( + authenticationViewModel.user.editedOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate( + authenticationViewModel.user + .editedOn)) + : authenticationViewModel.user.createdOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 14, + ), + )) + ], + )), + ], + ) + : Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + this.onlySMSBox == false + ? AppText( + TranslationBase.of(context) + .verifyLoginWith, + fontSize: + SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: + SizeConfig.textMultiplier * 2.5, + textAlign: TextAlign.start, + ), + ]), + authenticationViewModel.user != null && isMoreOption == false ? Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => + { + // TODO check this logic it seem it will create bug to us + authenticateUser( + AuthMethodTypes + .Fingerprint, true) + }, + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: SelectedAuthMethodTypesService + .getMethodsTypeService( + authenticationViewModel.user + .logInTypeID), + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + ), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.MoreOptions, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) + ]), + ]) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + onlySMSBox == false + ? Row( mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, + MainAxisAlignment.center, children: [ - AppText( - TranslationBase.of(context).welcomeBack), - AppText( - Helpers.capitalize(model.user.doctorName), - fontSize: SizeConfig.textMultiplier * 3.5, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).accountInfo, - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 20, - ), - Card( - color: Colors.white, - child: Row( - children: [ - Flexible( - flex: 3, - child: ListTile( - title: Text( - TranslationBase.of(context) - .lastLoginAt, - overflow: - TextOverflow.ellipsis, - style: TextStyle( - fontFamily: 'Poppins', - fontWeight: - FontWeight - .w800, - fontSize: 14), - ), - subtitle: AppText( - model.getType( - model.user - .logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - model.user.editedOn != - null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != - null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate(model - .user - .createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - fontWeight: - FontWeight.w800, - ), - subtitle: AppText( - model.user.editedOn != - null - ? DateUtils.getHour( - DateUtils.convertStringToDate( - model.user - .editedOn)) - : model.user.createdOn != - null - ? DateUtils.getHour( - DateUtils.convertStringToDate(model - .user - .createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - ), - )) - ], - )), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.Fingerprint, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.FaceID, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )) ], ) - : Column( + : SizedBox(), + Row( mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - this.onlySMSBox == false - ? AppText( - TranslationBase.of(context) - .verifyLoginWith, - fontSize: - SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ) - : AppText( - TranslationBase.of(context) - .verifyFingerprint2, - fontSize: - SizeConfig.textMultiplier * 2.5, - textAlign: TextAlign.start, - ), - ]), - model.user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + MainAxisAlignment.center, children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => - { - // TODO check this logic it seem it will create bug to us - authenticateUser( - AuthMethodTypes - .Fingerprint, true) - }, - child: VerificationMethodsList( - model: model, - authMethodType: SelectedAuthMethodTypesService - .getMethodsTypeService( - model.user - .logInTypeID), - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )), - ), - Expanded( - child: VerificationMethodsList( - model: model, - authMethodType: - AuthMethodTypes.MoreOptions, - onShowMore: () { - setState(() { - isMoreOption = true; - }); - }, - )) - ]), - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: VerificationMethodsList( - model: model, - authMethodType: - AuthMethodTypes.Fingerprint, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )), - Expanded( - child: VerificationMethodsList( - model: model, - authMethodType: - AuthMethodTypes.FaceID, - authenticateUser: - (AuthMethodTypes - authMethodType, - isActive) => - authenticateUser( - authMethodType, - isActive), - )) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: VerificationMethodsList( - model: model, - authMethodType: AuthMethodTypes - .SMS, - authenticateUser: - ( - AuthMethodTypes authMethodType, - isActive) => - authenticateUser( - authMethodType, isActive), - )), - Expanded( - child: VerificationMethodsList( - model: model, - authMethodType: - AuthMethodTypes.WhatsApp, - authenticateUser: - ( - AuthMethodTypes authMethodType, - isActive) => - authenticateUser( - authMethodType, isActive), - )) - ], - ), - ]), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: AuthMethodTypes + .SMS, + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.WhatsApp, + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )) + ], + ), + ]), // ) ], ), ), ], - ), - ), ), ), ), - bottomSheet: model.user == null ? SizedBox(height: 0,) : Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all( - color: HexColor('#707070'), - width: 0), - ), - height: 90, - width: double.infinity, - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - AppButton( - title: TranslationBase - .of(context) - .useAnotherAccount, - color: Colors.red[700], - onPressed: () { - Navigator.of(context).pushNamed(LOGIN); - }, - ), - - SizedBox(height: 25,) - ], + ), + ), + bottomSheet: authenticationViewModel.user == null ? SizedBox(height: 0,) : Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all( + color: HexColor('#707070'), + width: 0), + ), + height: 90, + width: double.infinity, + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + AppButton( + title: TranslationBase + .of(context) + .useAnotherAccount, + color: Colors.red[700], + onPressed: () { + Navigator.of(context).pushNamed(LOGIN); + }, ), - ), - ),), - ) + SizedBox(height: 25,) + ], + ), + ), + ),), ); } @@ -365,12 +357,12 @@ class _VerificationMethodsScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); - await model.sendActivationCodeForDoctorApp(authMethodType:authMethodType, password: widget.password ); - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); + await authenticationViewModel.sendActivationCodeForDoctorApp(authMethodType:authMethodType, password: widget.password ); + if (authenticationViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(authenticationViewModel.error); GifLoaderDialogUtils.hideDialog(context); } else { - model.setDataAfterSendActivationSuccsess(model.activationCodeForDoctorAppRes); + authenticationViewModel.setDataAfterSendActivationSuccsess(authenticationViewModel.activationCodeForDoctorAppRes); sharedPref.setString(PASSWORD, widget.password); GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); @@ -385,14 +377,14 @@ class _VerificationMethodsScreenState extends State { sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); - await model + await authenticationViewModel .sendActivationCodeVerificationScreen(authMethodType); - if (model.state == ViewState.ErrorLocal) { + if (authenticationViewModel.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(model.error); + Helpers.showErrorToast(authenticationViewModel.error); } else { - model.setDataAfterSendActivationSuccsess(model.activationCodeVerificationScreenRes); + authenticationViewModel.setDataAfterSendActivationSuccsess(authenticationViewModel.activationCodeVerificationScreenRes); if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.hideDialog(context); @@ -432,7 +424,7 @@ class _VerificationMethodsScreenState extends State { } sendActivationCode(AuthMethodTypes authMethodType) async { - if (model.user != null) { + if (authenticationViewModel.user != null) { sendActivationCodeVerificationScreen(authMethodType); } else { sendActivationCodeByOtpNotificationType(authMethodType); @@ -444,7 +436,7 @@ class _VerificationMethodsScreenState extends State { new SMSOTP( context, type, - model.loggedUser != null ? model.loggedUser.mobileNumber : model.user.mobile, + authenticationViewModel.loggedUser != null ? authenticationViewModel.loggedUser.mobileNumber : authenticationViewModel.user.mobile, (value) { showDialog( context: context, @@ -465,14 +457,14 @@ class _VerificationMethodsScreenState extends State { loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { if (isActive) { - await model.showIOSAuthMessages(); + await authenticationViewModel.showIOSAuthMessages(); if (!mounted) return; - if (model.user != null && + if (authenticationViewModel.user != null && (SelectedAuthMethodTypesService.getMethodsTypeService( - model.user.logInTypeID) == + authenticationViewModel.user.logInTypeID) == AuthMethodTypes.Fingerprint || SelectedAuthMethodTypesService.getMethodsTypeService( - model.user.logInTypeID) == AuthMethodTypes.FaceID)) { + authenticationViewModel.user.logInTypeID) == AuthMethodTypes.FaceID)) { this.sendActivationCode(authMethodTypes); } else { setState(() { @@ -483,19 +475,19 @@ class _VerificationMethodsScreenState extends State { } checkActivationCode({value}) async { - await model.checkActivationCodeForDoctorApp(activationCode: value); - if (model.state == ViewState.ErrorLocal) { + await authenticationViewModel.checkActivationCodeForDoctorApp(activationCode: value); + if (authenticationViewModel.state == ViewState.ErrorLocal) { Navigator.pop(context); - Helpers.showErrorToast(model.error); + Helpers.showErrorToast(authenticationViewModel.error); } else { - await model.onCheckActivationCodeSuccess(); + await authenticationViewModel.onCheckActivationCodeSuccess(); navigateToLandingPage(); } } navigateToLandingPage() { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); + if (authenticationViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(authenticationViewModel.error); } else { projectsProvider.isLogin = true; diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 167abc61..d48e6417 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -75,13 +75,14 @@ class _HomeScreenState extends State { var clinicId; var _patientSearchFormValues; - AuthenticationViewModel _IMEIViewModel = locator(); + AuthenticationViewModel authenticationViewModel; void didChangeDependencies() async { super.didChangeDependencies(); if (_isInit) { projectsProvider = Provider.of(context); + authenticationViewModel = Provider.of(context); projectsProvider.getDoctorClinicsList(); // _firebaseMessaging.setAutoInitEnabled(true); @@ -97,7 +98,7 @@ class _HomeScreenState extends State { _firebaseMessaging.getToken().then((String token) async { if (token != '') { DEVICE_TOKEN = token; - await _IMEIViewModel.insertDeviceImei(); + await authenticationViewModel.insertDeviceImei(); changeIsLoading(false); } diff --git a/lib/widgets/auth/verification_methods_list.dart b/lib/widgets/auth/verification_methods_list.dart index e42e33ba..de867cde 100644 --- a/lib/widgets/auth/verification_methods_list.dart +++ b/lib/widgets/auth/verification_methods_list.dart @@ -11,14 +11,14 @@ class VerificationMethodsList extends StatefulWidget { final AuthMethodTypes authMethodType; final Function(AuthMethodTypes type, bool isActive) authenticateUser; final Function onShowMore; - final AuthenticationViewModel model; + final AuthenticationViewModel authenticationViewModel; const VerificationMethodsList( {Key key, this.authMethodType, this.authenticateUser, this.onShowMore, - this.model}) + this.authenticationViewModel}) : super(key: key); @override @@ -54,7 +54,7 @@ class _VerificationMethodsListState extends State { return MethodTypeCard( assetPath: 'assets/images/verification_fingerprint_icon.png', onTap: () async { - if (await widget.model + if (await widget.authenticationViewModel .checkIfBiometricAvailable(BiometricType.fingerprint)) { widget.authenticateUser(AuthMethodTypes.Fingerprint, true); @@ -67,7 +67,7 @@ class _VerificationMethodsListState extends State { return MethodTypeCard( assetPath: 'assets/images/verification_faceid_icon.png', onTap: () async { - if (await widget.model + if (await widget.authenticationViewModel .checkIfBiometricAvailable(BiometricType.face)) { widget.authenticateUser(AuthMethodTypes.FaceID, true); } From 6815e4781454dfaa15b282beb8d63c131ef17739 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 10 May 2021 16:03:07 +0300 Subject: [PATCH 030/241] remove doctor profile view model --- lib/core/service/authentication_service.dart | 15 +---- .../viewModel/authentication_view_model.dart | 9 +-- .../viewModel/doctor_profile_view_model.dart | 67 ------------------- lib/core/viewModel/project_view_model.dart | 22 ++---- lib/main.dart | 4 -- lib/root_page.dart | 1 - .../auth/verification_methods_screen.dart | 3 - lib/screens/home/home_screen.dart | 45 +++++-------- .../out_patient/out_patient_screen.dart | 8 +-- .../patient_search_result_screen.dart | 6 +- .../patient_search/patient_search_screen.dart | 8 +-- .../profile/note/progress_note_screen.dart | 14 ++-- .../referral/my-referral-detail-screen.dart | 6 +- .../referral/my-referral-patient-screen.dart | 4 -- .../assessment/add_assessment_details.dart | 1 - .../profile/profile-welcome-widget.dart | 6 +- lib/widgets/shared/app_drawer_widget.dart | 10 +-- lib/widgets/shared/app_loader_widget.dart | 27 +------- 18 files changed, 52 insertions(+), 204 deletions(-) delete mode 100644 lib/core/viewModel/doctor_profile_view_model.dart diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index ffa22f33..f033d4f7 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -1,19 +1,16 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/auth/activation_Code_req_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/core/model/auth/check_activation_code_for_doctor_app_response_model.dart'; +import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/core/model/auth/imei_details.dart'; import 'package:doctor_app_flutter/core/model/auth/insert_imei_model.dart'; import 'package:doctor_app_flutter/core/model/auth/new_login_information_response_model.dart'; import 'package:doctor_app_flutter/core/model/auth/send_activation_code_for_doctor_app_response_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/activation_code_for_verification_screen_model.dart'; -import 'package:doctor_app_flutter/core/model/auth/check_activation_code_request_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; -import 'package:provider/provider.dart'; class AuthenticationService extends BaseService { List _imeiDetails = []; @@ -115,15 +112,7 @@ class AuthenticationService extends BaseService { try { await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, onSuccess: (dynamic response, int statusCode) { - // TODO improve the logic here - Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.clear(); _checkActivationCodeForDoctorAppRes = CheckActivationCodeForDoctorAppResponseModel.fromJson(response); - Provider.of(AppGlobal.CONTEX, listen: false).selectedClinicName = - ClinicModel.fromJson(response['List_DoctorsClinic'][0]).clinicName; - - response['List_DoctorsClinic'].forEach((v) { - Provider.of(AppGlobal.CONTEX, listen: false).doctorsClinicList.add(new ClinicModel.fromJson(v)); - }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index c35c4e12..c552e40e 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -29,9 +29,6 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; -import 'package:provider/provider.dart'; - -import 'doctor_profile_view_model.dart'; enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED, UNVERIFIED } @@ -72,6 +69,7 @@ class AuthenticationViewModel extends BaseViewModel { AuthenticationViewModel({bool checkDeviceInfo = false}) { getDeviceInfoFromFirebase(); + getDoctorProfile(); } Future selectDeviceImei(imei) async { @@ -287,9 +285,6 @@ class AuthenticationViewModel extends BaseViewModel { localSetDoctorProfile(DoctorProfileModel profile) { super.setDoctorProfile(profile); - //TODO: Remove it when we remove Doctor Profile View Model and start to use profile form base view model - Provider.of(AppGlobal.CONTEX, listen: false) - .setDoctorProfile(profile); } Future getDoctorProfileBasedOnClinic(ClinicModel clinicInfo) async { @@ -358,7 +353,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Busy); _firebaseMessaging.getToken().then((String token) async { - if (DEVICE_TOKEN == "") { + if (DEVICE_TOKEN == "" && !isLogin) { DEVICE_TOKEN = token; await _authService.selectDeviceImei(DEVICE_TOKEN); diff --git a/lib/core/viewModel/doctor_profile_view_model.dart b/lib/core/viewModel/doctor_profile_view_model.dart deleted file mode 100644 index 6210951e..00000000 --- a/lib/core/viewModel/doctor_profile_view_model.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:doctor_app_flutter/client/base_app_client.dart'; -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/core/service/authentication_service.dart'; -import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; -import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; - -import '../../locator.dart'; - - -class DoctorProfileViewModel extends BaseViewModel { - List doctorsClinicList = []; - AuthenticationService _authService = locator(); - - - String selectedClinicName; - bool isLogin = false; - bool isLoading = true; - DoctorProfileModel doctorProfile; - BaseAppClient baseAppClient = BaseAppClient(); - setDoctorProfile(DoctorProfileModel profileModel) { - doctorProfile = profileModel; - notifyListeners(); - } - - DoctorProfileViewModel() { - getUserProfile(); - } - - getUserProfile() async { - Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - if (profile != null) { - doctorProfile = new DoctorProfileModel.fromJson(profile); - isLoading = false; - isLogin = true; - } else { - isLoading = false; - isLogin = false; - } - notifyListeners(); - } - - Future getDocProfiles(docInfo, - {bool allowChangeProfile = true}) async { - try { - dynamic localRes; - await baseAppClient.post(GET_DOC_PROFILES, - onSuccess: (dynamic response, int statusCode) { - localRes = response; - if (allowChangeProfile) { - doctorProfile = - DoctorProfileModel.fromJson(response['DoctorProfileList'][0]); - selectedClinicName = - response['DoctorProfileList'][0]['ClinicDescription']; - } - }, onFailure: (String error, int statusCode) { - throw error; - }, body: docInfo); - notifyListeners(); - return Future.value(localRes); - } catch (error) { - print(error); - throw error; - } - } -} diff --git a/lib/core/viewModel/project_view_model.dart b/lib/core/viewModel/project_view_model.dart index 0bf0c844..494e3b10 100644 --- a/lib/core/viewModel/project_view_model.dart +++ b/lib/core/viewModel/project_view_model.dart @@ -4,15 +4,15 @@ import 'package:connectivity/connectivity.dart'; import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; +import 'authentication_view_model.dart'; + Helpers helpers = Helpers(); class ProjectViewModel with ChangeNotifier { @@ -116,19 +116,9 @@ class ProjectViewModel with ChangeNotifier { void getProfile() async { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: doctorProfile.doctorID, - clinicID: doctorProfile.clinicID, - license: true, - projectID: doctorProfile.projectID, - ); - - Provider.of(AppGlobal.CONTEX, listen: false) - .getDocProfiles(docInfo.toJson()) - .then((res) async { - sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); - }).catchError((err) { - print(err); - }); + ClinicModel clinicModel = ClinicModel(doctorID:doctorProfile.doctorID,clinicID: doctorProfile.clinicID, projectID: doctorProfile.projectID,); + + await Provider.of(AppGlobal.CONTEX, listen: false) + .getDoctorProfileBasedOnClinic(clinicModel); } } diff --git a/lib/main.dart b/lib/main.dart index b7acdd80..a95378e5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,8 +12,6 @@ import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; import 'core/viewModel/authentication_view_model.dart'; -import 'core/viewModel/doctor_profile_view_model.dart'; -import 'core/viewModel/hospitals_view_model.dart'; import 'locator.dart'; void main() async { @@ -35,8 +33,6 @@ class MyApp extends StatelessWidget { providers: [ ChangeNotifierProvider( create: (context) => AuthenticationViewModel()), - ChangeNotifierProvider( - create: (context) => DoctorProfileViewModel()), ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), diff --git a/lib/root_page.dart b/lib/root_page.dart index 6040b160..5c14288e 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -14,7 +14,6 @@ class RootPage extends StatelessWidget { @override Widget build(BuildContext context) { AuthenticationViewModel authenticationViewModel = Provider.of(context); - // ignore: missing_return Widget buildRoot() { switch (authenticationViewModel.stutas) { case APP_STATUS.LOADING: diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 40749b84..9ff1f86c 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -4,7 +4,6 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -42,14 +41,12 @@ class _VerificationMethodsScreenState extends State { ProjectViewModel projectsProvider; bool isMoreOption = false; bool onlySMSBox = false; - DoctorProfileViewModel doctorProfileViewModel; AuthMethodTypes fingerPrintBefore; AuthMethodTypes selectedOption; AuthenticationViewModel authenticationViewModel; @override Widget build(BuildContext context) { - doctorProfileViewModel = Provider.of(context); projectsProvider = Provider.of(context); authenticationViewModel = Provider.of(context); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index d48e6417..6fa38a43 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -2,26 +2,21 @@ import 'package:charts_flutter/flutter.dart' as charts; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/patient_type.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; 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/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/out_patient/out_patient_screen.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_screen.dart'; -import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_result_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; @@ -35,6 +30,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/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; @@ -43,7 +39,6 @@ import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:provider/provider.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; -import '../../locator.dart'; import '../../widgets/shared/app_texts_widget.dart'; import '../../widgets/shared/rounded_container_widget.dart'; import 'home_page_card.dart'; @@ -63,7 +58,6 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); - DoctorProfileViewModel authProvider; bool isLoading = false; ProjectViewModel projectsProvider; var _isInit = true; @@ -111,7 +105,6 @@ class _HomeScreenState extends State { @override Widget build(BuildContext context) { myContext = context; - authProvider = Provider.of(context); projectsProvider = Provider.of(context); FocusScopeNode currentFocus = FocusScope.of(context); @@ -584,7 +577,7 @@ class _HomeScreenState extends State { PatientSearchRequestModel( from: date, to: date, - doctorID: authProvider + doctorID: authenticationViewModel .doctorProfile .doctorID)), )); @@ -811,24 +804,16 @@ class _HomeScreenState extends State { } changeClinic(clinicId, BuildContext context, model) async { - // Navigator.pop(context); - changeIsLoading(true); - Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: doctorProfile.doctorID, - clinicID: clinicId, - license: true, - projectID: doctorProfile.projectID, - tokenID: '', - languageID: 2); - authProvider.getDocProfiles(docInfo.toJson()).then((res) async { - changeIsLoading(false); - sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); - }).catchError((err) { - changeIsLoading(false); - Helpers.showErrorToast(err); - }); + GifLoaderDialogUtils.showMyDialog(context); + DoctorProfileModel doctorProfile = authenticationViewModel.doctorProfile; + + ClinicModel clinic = ClinicModel(clinicID:clinicId, doctorID: doctorProfile.doctorID,projectID: doctorProfile.projectID, ); + await authenticationViewModel.getDoctorProfileBasedOnClinic(clinic); + if(authenticationViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(authenticationViewModel.error); + + } + GifLoaderDialogUtils.hideDialog(context); } changeIsLoading(bool val) { diff --git a/lib/screens/patients/out_patient/out_patient_screen.dart b/lib/screens/patients/out_patient/out_patient_screen.dart index c6549568..77324ea5 100644 --- a/lib/screens/patients/out_patient/out_patient_screen.dart +++ b/lib/screens/patients/out_patient/out_patient_screen.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; @@ -60,9 +60,9 @@ class OutPatientsScreen extends StatefulWidget { class _OutPatientsScreenState extends State { int clinicId; - DoctorProfileViewModel authProvider; + AuthenticationViewModel authenticationViewModel; - List _times = []; //['All', 'Today', 'Tomorrow', 'Next Week']; + List _times = []; int _activeLocation = 1; String patientType; @@ -79,7 +79,7 @@ class _OutPatientsScreenState extends State { @override Widget build(BuildContext context) { - authProvider = Provider.of(context); + authenticationViewModel = Provider.of(context); _times = [ TranslationBase .of(context) diff --git a/lib/screens/patients/patient_search/patient_search_result_screen.dart b/lib/screens/patients/patient_search/patient_search_result_screen.dart index 05de14db..9e53ab19 100644 --- a/lib/screens/patients/patient_search/patient_search_result_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_result_screen.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patient_model.dart'; @@ -48,7 +48,7 @@ class PatientsSearchResultScreen extends StatefulWidget { class _PatientsSearchResultScreenState extends State { int clinicId; - DoctorProfileViewModel authProvider; + AuthenticationViewModel authenticationViewModel; String patientType; @@ -64,7 +64,7 @@ class _PatientsSearchResultScreenState @override Widget build(BuildContext context) { - authProvider = Provider.of(context); + authenticationViewModel = Provider.of(context); return BaseView( onModelReady: (model) async { if(!widget.isSearchWithKeyInfo && widget.selectedPatientType == PatientType.OutPatient) { diff --git a/lib/screens/patients/patient_search/patient_search_screen.dart b/lib/screens/patients/patient_search/patient_search_screen.dart index 192a37c9..682d28c3 100644 --- a/lib/screens/patients/patient_search/patient_search_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_screen.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/model/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_result_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; @@ -29,11 +29,11 @@ class _PatientSearchScreenState extends State { TextEditingController middleNameInfoController = TextEditingController(); TextEditingController lastNameFileInfoController = TextEditingController(); PatientType selectedPatientType = PatientType.inPatient; - DoctorProfileViewModel authProvider; + AuthenticationViewModel authenticationViewModel; @override Widget build(BuildContext context) { - authProvider =Provider.of(context); + authenticationViewModel = Provider.of(context); return BaseView( onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( @@ -147,7 +147,7 @@ class _PatientSearchScreenState extends State { isFormSubmitted = true; }); PatientSearchRequestModel patientSearchRequestModel = - PatientSearchRequestModel(doctorID: authProvider.doctorProfile.doctorID); + PatientSearchRequestModel(doctorID: authenticationViewModel.doctorProfile.doctorID); if (showOther) { patientSearchRequestModel.firstName = firstNameInfoController.text.trim().isEmpty?"0":firstNameInfoController.text.trim(); patientSearchRequestModel.middleName = middleNameInfoController.text.trim().isEmpty?"0":middleNameInfoController.text.trim(); diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 38b4edad..fdc9a3ce 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -1,6 +1,6 @@ import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -39,10 +39,8 @@ class ProgressNoteScreen extends StatefulWidget { class _ProgressNoteState extends State { List notesList; var filteredNotesList; - final _controller = TextEditingController(); - var _isInit = true; bool isDischargedPatient = false; - DoctorProfileViewModel authProvider; + AuthenticationViewModel authenticationViewModel; ProjectViewModel projectViewModel; getProgressNoteList(BuildContext context, PatientViewModel model, @@ -71,7 +69,7 @@ class _ProgressNoteState extends State { @override Widget build(BuildContext context) { - authProvider = Provider.of(context); + authenticationViewModel = Provider.of(context); projectViewModel = Provider.of(context); final routeArgs = ModalRoute .of(context) @@ -141,7 +139,7 @@ class _ProgressNoteState extends State { bgColor: model.patientProgressNoteList[index] .status == 1 && - authProvider.doctorProfile.doctorID != + authenticationViewModel.doctorProfile.doctorID != model .patientProgressNoteList[ index] @@ -167,7 +165,7 @@ class _ProgressNoteState extends State { index] .status == 1 && - authProvider + authenticationViewModel .doctorProfile.doctorID != model .patientProgressNoteList[ @@ -213,7 +211,7 @@ class _ProgressNoteState extends State { index] .status != 4 && - authProvider + authenticationViewModel .doctorProfile.doctorID == model .patientProgressNoteList[ diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 8eea6c34..0a690307 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -1,6 +1,5 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/my_referral/PendingReferral.dart'; @@ -15,16 +14,13 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; +// ignore: must_be_immutable class MyReferralDetailScreen extends StatelessWidget { PendingReferral pendingReferral; @override Widget build(BuildContext context) { - final gridHeight = (MediaQuery.of(context).size.width * 0.3) * 1.8; - - DoctorProfileViewModel authProvider = Provider.of(context); final routeArgs = ModalRoute.of(context).settings.arguments as Map; pendingReferral = routeArgs['referral']; diff --git a/lib/screens/patients/profile/referral/my-referral-patient-screen.dart b/lib/screens/patients/profile/referral/my-referral-patient-screen.dart index 1482db74..fe6fd2db 100644 --- a/lib/screens/patients/profile/referral/my-referral-patient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-patient-screen.dart @@ -1,4 +1,3 @@ -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -7,15 +6,12 @@ import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; import '../../../../routes.dart'; class MyReferralPatientScreen extends StatelessWidget { - // previous design page is: MyReferralPatient @override Widget build(BuildContext context) { - DoctorProfileViewModel authProvider = Provider.of(context); return BaseView( onModelReady: (model) => model.getPendingReferralPatients(), diff --git a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart index 57e2e53f..a30842f8 100644 --- a/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart +++ b/lib/screens/patients/profile/soap_update/assessment/add_assessment_details.dart @@ -3,7 +3,6 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -// import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PatchAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; diff --git a/lib/widgets/patients/profile/profile-welcome-widget.dart b/lib/widgets/patients/profile/profile-welcome-widget.dart index 577d94bd..4d76fe41 100644 --- a/lib/widgets/patients/profile/profile-welcome-widget.dart +++ b/lib/widgets/patients/profile/profile-welcome-widget.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -11,7 +11,7 @@ class ProfileWelcomeWidget extends StatelessWidget { @override Widget build(BuildContext context) { - DoctorProfileViewModel authProvider = Provider.of(context); + AuthenticationViewModel authenticationViewModel = Provider.of(context); return Container( height: height, @@ -55,7 +55,7 @@ class ProfileWelcomeWidget extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.network( - authProvider.doctorProfile.doctorImageURL, + authenticationViewModel.doctorProfile.doctorImageURL, fit: BoxFit.fill, width: 75, height: 75, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index 5ca6bf84..a69b1370 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -1,4 +1,4 @@ -import 'package:doctor_app_flutter/core/viewModel/doctor_profile_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/reschedule-leaves/add-rescheduleleave.dart'; @@ -28,7 +28,7 @@ class _AppDrawerState extends State { @override Widget build(BuildContext context) { - DoctorProfileViewModel authProvider = Provider.of(context); + AuthenticationViewModel authenticationViewModel = Provider.of(context); projectsProvider = Provider.of(context); return RoundedContainer( child: Container( @@ -69,7 +69,7 @@ class _AppDrawerState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, ), SizedBox(height: 5), - if (authProvider.doctorProfile != null) + if (authenticationViewModel.doctorProfile != null) InkWell( onTap: () { // TODO: return it back when its needed @@ -85,7 +85,7 @@ class _AppDrawerState extends State { padding: EdgeInsets.only(top: 10), child: AppText( TranslationBase.of(context).dr + - authProvider.doctorProfile?.doctorName, + authenticationViewModel.doctorProfile?.doctorName, fontWeight: FontWeight.bold, color: Color(0xFF2E303A), fontFamily: 'Poppins', @@ -95,7 +95,7 @@ class _AppDrawerState extends State { Padding( padding: EdgeInsets.only(top: 0), child: AppText( - authProvider.doctorProfile?.clinicDescription, + authenticationViewModel.doctorProfile?.clinicDescription, fontWeight: FontWeight.w600, color: Color(0xFF2E303A), fontSize: 15, diff --git a/lib/widgets/shared/app_loader_widget.dart b/lib/widgets/shared/app_loader_widget.dart index 7b1f1718..ef614209 100644 --- a/lib/widgets/shared/app_loader_widget.dart +++ b/lib/widgets/shared/app_loader_widget.dart @@ -3,13 +3,6 @@ import 'package:progress_hud_v2/progress_hud.dart'; import 'loader/gif_loader_container.dart'; -/* - *@author: Elham Rababah - *@Date:19/4/2020 - *@param: - *@return: Positioned - *@desc: AppLoaderWidget to create loader - */ class AppLoaderWidget extends StatefulWidget { AppLoaderWidget({Key key, this.title, this.containerColor}) : super(key: key); @@ -21,25 +14,7 @@ class AppLoaderWidget extends StatefulWidget { } class _AppLoaderWidgetState extends State { - ProgressHUD _progressHUD; - @override - void initState() { - super.initState(); -/* - *@author: Elham Rababah - *@Date:19/4/2020 - *@param: - *@return: - *@desc: create loader the desing - */ - _progressHUD = new ProgressHUD( - backgroundColor: widget.containerColor == null ? Colors.black12 : widget.containerColor, - color: Colors.black, - // containerColor: Colors.blue, - borderRadius: 5.0, - // text: 'Loading...', - ); - } + @override Widget build(BuildContext context) { From 0adcfecccea04002eb9c6a298ceff698ad6db1ce Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 11:22:28 +0300 Subject: [PATCH 031/241] fix auth bug --- lib/config/config.dart | 2 +- .../viewModel/authentication_view_model.dart | 17 ++------ .../auth/verification_methods_screen.dart | 6 +-- lib/screens/home/home_screen.dart | 2 +- lib/widgets/auth/sms-popup.dart | 40 ++--------------- .../profile/profile-welcome-widget.dart | 43 ++----------------- pubspec.lock | 6 +-- 7 files changed, 17 insertions(+), 99 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index ec8efe26..382e84b2 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -337,7 +337,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 6.0; +const VERSION_ID = 6.1; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index c552e40e..77f76abb 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -17,6 +17,7 @@ import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_m import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/service/hospitals/hospitals_service.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; @@ -29,6 +30,7 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED, UNVERIFIED } @@ -237,19 +239,6 @@ class AuthenticationViewModel extends BaseViewModel { } } - getInitUserInfo()async{ - setState(ViewState.Busy); - var localLoggedUser = await sharedPref.getObj(LOGGED_IN_USER); - if(localLoggedUser!= null) { - loggedUser = NewLoginInformationModel.fromJson(localLoggedUser); - } - var lastLogin = await sharedPref.getObj(LAST_LOGIN_USER); - if (lastLogin != null) { - user = GetIMEIDetailsModel.fromJson(lastLogin); - } - setState(ViewState.Idle); - } - setDataAfterSendActivationSuccsess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); @@ -353,7 +342,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Busy); _firebaseMessaging.getToken().then((String token) async { - if (DEVICE_TOKEN == "" && !isLogin) { + if (DEVICE_TOKEN == "" && !ProjectViewModel().isLogin) { DEVICE_TOKEN = token; await _authService.selectDeviceImei(DEVICE_TOKEN); diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 9ff1f86c..afd5604c 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -8,6 +8,7 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_loader_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/shared/buttons/app_buttons_widget.dart'; @@ -429,7 +430,6 @@ class _VerificationMethodsScreenState extends State { } startSMSService(AuthMethodTypes type) { - // TODO improve this logic new SMSOTP( context, type, @@ -438,9 +438,7 @@ class _VerificationMethodsScreenState extends State { showDialog( context: context, builder: (BuildContext context) { - return Center( - child: CircularProgressIndicator(), - ); + return AppLoaderWidget(); }); this.checkActivationCode(value: value); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 6fa38a43..72ffc5c5 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -229,7 +229,7 @@ class _HomeScreenState extends State { ), ], ), - isClilic: true, + isClinic: true, height: 50, ), ]) diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 6cbeab49..532f9cc1 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -20,10 +21,6 @@ class SMSOTP { Future timer; - static BuildContext _context; - - static bool _loading; - SMSOTP( this.context, this.type, @@ -285,8 +282,6 @@ class SMSOTP { InputDecoration buildInputDecoration(BuildContext context) { return InputDecoration( counterText: " ", - // ts/images/password_icon.png - // contentPadding: EdgeInsets.only(top: 20, bottom: 20), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10)), borderSide: BorderSide(color: Colors.grey[300]), @@ -306,6 +301,7 @@ class SMSOTP { ); } + // ignore: missing_return String validateCodeDigit(value) { if (value.isEmpty) { return ' '; @@ -317,7 +313,6 @@ class SMSOTP { } checkValue() { - //print(verifyAccountFormValue); if (verifyAccountForm.currentState.validate()) { onSuccess(digit1.text.toString() + digit2.text.toString() + @@ -343,6 +338,7 @@ class SMSOTP { startTimer(setState) { this.remainingTime--; + print(isClosed); setState(() { displayTime = this.getSecondsAsDigitalClock(this.remainingTime); }); @@ -355,34 +351,4 @@ class SMSOTP { } }); } - - static void showLoadingDialog(BuildContext context, bool _loading) async { - _context = context; - - if (_loading == false) { - Navigator.of(context).pop(); - return; - } - _loading = true; - await showDialog( - context: _context, - barrierDismissible: false, - builder: (BuildContext context) { - return SimpleDialog( - elevation: 0.0, - backgroundColor: Colors.transparent, - children: [ - Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.black), - ), - ) - ], - ); - }); - } - - static void hideSMSBox(context) { - Navigator.pop(context); - } } diff --git a/lib/widgets/patients/profile/profile-welcome-widget.dart b/lib/widgets/patients/profile/profile-welcome-widget.dart index 4d76fe41..53228bc2 100644 --- a/lib/widgets/patients/profile/profile-welcome-widget.dart +++ b/lib/widgets/patients/profile/profile-welcome-widget.dart @@ -5,9 +5,9 @@ import 'package:provider/provider.dart'; class ProfileWelcomeWidget extends StatelessWidget { final Widget clinicWidget; final double height; - final bool isClilic; + final bool isClinic; ProfileWelcomeWidget(this.clinicWidget, - {this.height = 150, this.isClilic = false}); + {this.height = 150, this.isClinic = false}); @override Widget build(BuildContext context) { @@ -23,33 +23,11 @@ class ProfileWelcomeWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: [ - this.isClilic == true ? clinicWidget : SizedBox(), - // Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // mainAxisAlignment: MainAxisAlignment.start, - // children: [ - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).welcome, - // fontSize: SizeConfig.textMultiplier * 1.7, - // color: Colors.black, - // ) - // ], - // ), - // Row( - // mainAxisAlignment: MainAxisAlignment.end, - // children: [ - // AppText( - // // TranslationBase.of(context).dr + - // ' ${authProvider.doctorProfile.doctorName}', - // fontWeight: FontWeight.bold, - // fontSize: SizeConfig.textMultiplier * 2.5, - // color: Colors.black, - // ), + this.isClinic == true ? clinicWidget : SizedBox(), SizedBox( width: 20, ), + if(authenticationViewModel.doctorProfile!=null) CircleAvatar( // radius: (52) child: ClipRRect( @@ -63,23 +41,10 @@ class ProfileWelcomeWidget extends StatelessWidget { ), backgroundColor: Colors.transparent, ), - // ], - // ), SizedBox( height: 20, ), - /// ], - // ), - // Expanded( - // child: Column( - // mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.end, - // children: [ - - // ], - // ), - // ), ], )), ); diff --git a/pubspec.lock b/pubspec.lock index 1a572a0a..825db695 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -615,7 +615,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -907,7 +907,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1098,5 +1098,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 1eeaaa48cae31f4af542af367688ac95ea2c447c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 11:23:05 +0300 Subject: [PATCH 032/241] remove comment --- lib/widgets/auth/sms-popup.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 532f9cc1..5f073eca 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -9,7 +9,6 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -//TODO Elham check it class SMSOTP { final AuthMethodTypes type; final mobileNo; From c9e7fb98835a81fcf7fadb58d69553ff9c6016b6 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 11:26:26 +0300 Subject: [PATCH 033/241] small fix --- lib/widgets/auth/sms-popup.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 5f073eca..cf16a0f1 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -18,8 +18,6 @@ class SMSOTP { int remainingTime = 600; - Future timer; - SMSOTP( this.context, this.type, @@ -337,12 +335,11 @@ class SMSOTP { startTimer(setState) { this.remainingTime--; - print(isClosed); setState(() { displayTime = this.getSecondsAsDigitalClock(this.remainingTime); }); - timer = Future.delayed(Duration(seconds: 1), () { + Future.delayed(Duration(seconds: 1), () { if (this.remainingTime > 0) { if (isClosed == false) startTimer(setState); } else { From e0be4ec1bead8d88d742f45849666d0fcffe6ca9 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 11:48:16 +0300 Subject: [PATCH 034/241] move logout function from helper to authentication view model --- lib/client/base_app_client.dart | 3 ++- lib/config/config.dart | 3 --- .../viewModel/authentication_view_model.dart | 26 ++++++++++++++----- lib/root_page.dart | 2 +- lib/util/helpers.dart | 14 ---------- lib/widgets/shared/app_drawer_widget.dart | 2 +- 6 files changed, 24 insertions(+), 26 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index d6a72ab6..d79f0338 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; @@ -97,7 +98,7 @@ class BaseAppClient { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { - await Helpers.logout(); + await AuthenticationViewModel().logout(); Helpers.showErrorToast('Your session expired Please login again'); } if (isAllowAny) { diff --git a/lib/config/config.dart b/lib/config/config.dart index 382e84b2..852e7bab 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -326,9 +326,6 @@ var SERVICES_PATIANT_HEADER_AR = [ "المريض المحول مني", "المريض الواصل" ]; -//****************** - -// Colors ////// by : ibrahim var DEVICE_TOKEN = ""; const PRIMARY_COLOR = 0xff515B5D; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 77f76abb..6022dceb 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -23,10 +23,13 @@ import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; -import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; +import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; @@ -355,10 +358,6 @@ class AuthenticationViewModel extends BaseViewModel { sharedPref.setObj( LAST_LOGIN_USER, _authService.dashboardItemsList[0]); this.unverified = true; - // Navigator.of(AppGlobal.CONTEX).pushReplacement(MaterialPageRoute( - // builder: (BuildContext context) => VerificationMethodsScreen( - // password: null, - // ))); } setState(ViewState.Idle); } @@ -369,7 +368,7 @@ class AuthenticationViewModel extends BaseViewModel { } - APP_STATUS get stutas { + APP_STATUS get status { if (state == ViewState.Busy) { return APP_STATUS.LOADING; } else { @@ -383,4 +382,19 @@ class AuthenticationViewModel extends BaseViewModel { } } + + logout() async { + DEVICE_TOKEN = ""; + String lang = await sharedPref.getString(APP_Language); + await Helpers.clearSharedPref(); + sharedPref.setString(APP_Language, lang); + ProjectViewModel().isLogin = false; + Navigator.pushAndRemoveUntil( + AppGlobal.CONTEX, + FadePage( + page: LoginScreen(), + ), + (r) => false); + } + } diff --git a/lib/root_page.dart b/lib/root_page.dart index 5c14288e..35a3fa44 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -15,7 +15,7 @@ class RootPage extends StatelessWidget { Widget build(BuildContext context) { AuthenticationViewModel authenticationViewModel = Provider.of(context); Widget buildRoot() { - switch (authenticationViewModel.stutas) { + switch (authenticationViewModel.status) { case APP_STATUS.LOADING: return Scaffold( body: AppLoaderWidget(), diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index eb702d8d..0f8f5183 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -144,20 +144,6 @@ class Helpers { await sharedPref.clear(); } - static logout() async { - DEVICE_TOKEN = ""; - String lang = await sharedPref.getString(APP_Language); - await clearSharedPref(); - sharedPref.setString(APP_Language, lang); - ProjectViewModel().isLogin = false; - Navigator.pushAndRemoveUntil( - AppGlobal.CONTEX, - FadePage( - page: LoginScreen(), - ), - (r) => false); - } - navigateToUpdatePage(String message, String androidLink, iosLink) { Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index a69b1370..db328462 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -172,7 +172,7 @@ class _AppDrawerState extends State { ), onTap: () async { Navigator.pop(context); - await Helpers.logout(); + await AuthenticationViewModel().logout(); projectsProvider.isLogin = false; }, ), From 8ac040a809c6ced4bacd3fe4b5d51e5f33022218 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Sun, 16 May 2021 12:23:57 +0300 Subject: [PATCH 035/241] hot fix --- .../patients/profile/medical_report/MedicalReportPage.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 6b85fa80..8dad1bc4 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -86,13 +86,13 @@ class MedicalReportPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ AppText( - '${DateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', + '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', color: Colors.black, fontWeight: FontWeight.w600, fontSize: 14, ), AppText( - '${DateUtils.getHour(DateTime.now())}', + '${AppDateUtils.getHour(DateTime.now())}', fontWeight: FontWeight.w600, color: Colors.grey[700], fontSize: 14, From 0d8684481db5c51a7f3165ec7c11171ef2baff80 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 14:03:21 +0300 Subject: [PATCH 036/241] fix sms error and some design issue --- .../viewModel/authentication_view_model.dart | 30 +++++++++++++++---- .../auth/verification_methods_screen.dart | 16 ++++++++-- lib/widgets/auth/method_type_card.dart | 5 ++-- lib/widgets/auth/sms-popup.dart | 8 +++-- .../auth/verification_methods_list.dart | 1 + 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 6022dceb..d6afa270 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -23,6 +23,7 @@ import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/root_page.dart'; import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -77,6 +78,7 @@ class AuthenticationViewModel extends BaseViewModel { getDoctorProfile(); } + /// select Device IMEI Future selectDeviceImei(imei) async { setState(ViewState.Busy); await _authService.selectDeviceImei(imei); @@ -87,6 +89,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + /// Insert Device IMEI Future insertDeviceImei() async { var loggedIn = await sharedPref.getObj(LOGGED_IN_USER); var user = await sharedPref.getObj(LAST_LOGIN_USER); @@ -125,6 +128,8 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + + /// first step login Future login(UserModel userInfo) async { setState(ViewState.BusyLocal); await _authService.login(userInfo); @@ -141,6 +146,7 @@ class AuthenticationViewModel extends BaseViewModel { } } + /// send activation code for for msg methods Future sendActivationCodeVerificationScreen( AuthMethodTypes authMethodType) async { setState(ViewState.BusyLocal); ActivationCodeForVerificationScreenModel activationCodeModel = @@ -162,6 +168,7 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + /// send activation code for silent login Future sendActivationCodeForDoctorApp({AuthMethodTypes authMethodType, String password }) async { setState(ViewState.BusyLocal); int projectID = await sharedPref.getInt(PROJECT_ID); @@ -180,6 +187,8 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + + /// check activation Future checkActivationCodeForDoctorApp({String activationCode}) async { setState(ViewState.BusyLocal); CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = @@ -204,7 +213,7 @@ class AuthenticationViewModel extends BaseViewModel { } } - + /// get list of Hospitals Future getHospitalsList(memberID) async { GetHospitalsRequestModel getHospitalsRequestModel =GetHospitalsRequestModel(); getHospitalsRequestModel.memberID = memberID; @@ -216,6 +225,8 @@ class AuthenticationViewModel extends BaseViewModel { setState(ViewState.Idle); } + + /// get type name based on id. getType(type, context) { switch (type) { case 1: @@ -242,7 +253,8 @@ class AuthenticationViewModel extends BaseViewModel { } } - setDataAfterSendActivationSuccsess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { + /// add some logic in case of send activation code is success + setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, @@ -257,6 +269,7 @@ class AuthenticationViewModel extends BaseViewModel { sharedPref.setObj(key, value); } + /// ask user to add his biometric showIOSAuthMessages() async { const iosStrings = const IOSAuthMessages( cancelButton: 'cancel', @@ -275,10 +288,12 @@ class AuthenticationViewModel extends BaseViewModel { } } + /// add profile to base view model super class localSetDoctorProfile(DoctorProfileModel profile) { super.setDoctorProfile(profile); } + /// get doctor profile based on clinic model Future getDoctorProfileBasedOnClinic(ClinicModel clinicInfo) async { ProfileReqModel docInfo = new ProfileReqModel( doctorID: clinicInfo.doctorID, @@ -297,6 +312,7 @@ class AuthenticationViewModel extends BaseViewModel { } } + /// add some logic in case of check activation code is success onCheckActivationCodeSuccess() async { sharedPref.setString( TOKEN, @@ -317,6 +333,7 @@ class AuthenticationViewModel extends BaseViewModel { } } + /// check specific biometric if it available or not Future checkIfBiometricAvailable(BiometricType biometricType) async { bool isAvailable = false; await _getAvailableBiometrics(); @@ -328,6 +345,7 @@ class AuthenticationViewModel extends BaseViewModel { return isAvailable; } + /// get all available biometric on the device for local Auth service Future _getAvailableBiometrics() async { try { _availableBiometrics = await auth.getAvailableBiometrics(); @@ -336,7 +354,7 @@ class AuthenticationViewModel extends BaseViewModel { } } - + /// call firebase service to check if the user already login in before or not getDeviceInfoFromFirebase() async { _firebaseMessaging.setAutoInitEnabled(true); if (Platform.isIOS) { @@ -367,7 +385,7 @@ class AuthenticationViewModel extends BaseViewModel { }); } - + /// determine the status of the app APP_STATUS get status { if (state == ViewState.Busy) { return APP_STATUS.LOADING; @@ -382,7 +400,7 @@ class AuthenticationViewModel extends BaseViewModel { } } - + /// logout function logout() async { DEVICE_TOKEN = ""; String lang = await sharedPref.getString(APP_Language); @@ -392,7 +410,7 @@ class AuthenticationViewModel extends BaseViewModel { Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( - page: LoginScreen(), + page: RootPage(), ), (r) => false); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index afd5604c..1e61d553 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -1,5 +1,6 @@ import 'dart:io' show Platform; +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; @@ -20,10 +21,12 @@ import 'package:provider/provider.dart'; import '../../config/size_config.dart'; import '../../landing_page.dart'; +import '../../root_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../util/helpers.dart'; import '../../widgets/auth/verification_methods_list.dart'; +import 'login_screen.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); @@ -53,6 +56,7 @@ class _VerificationMethodsScreenState extends State { return AppScaffold( isShowAppBar: false, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, // baseViewModel: model, body: SingleChildScrollView( child: Center( @@ -336,7 +340,13 @@ class _VerificationMethodsScreenState extends State { .useAnotherAccount, color: Colors.red[700], onPressed: () { - Navigator.of(context).pushNamed(LOGIN); + projectsProvider.isLogin = true; + Navigator.pushAndRemoveUntil( + AppGlobal.CONTEX, + FadePage( + page: RootPage(), + ), + (r) => false); }, ), @@ -360,7 +370,7 @@ class _VerificationMethodsScreenState extends State { Helpers.showErrorToast(authenticationViewModel.error); GifLoaderDialogUtils.hideDialog(context); } else { - authenticationViewModel.setDataAfterSendActivationSuccsess(authenticationViewModel.activationCodeForDoctorAppRes); + authenticationViewModel.setDataAfterSendActivationSuccess(authenticationViewModel.activationCodeForDoctorAppRes); sharedPref.setString(PASSWORD, widget.password); GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); @@ -382,7 +392,7 @@ class _VerificationMethodsScreenState extends State { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(authenticationViewModel.error); } else { - authenticationViewModel.setDataAfterSendActivationSuccsess(authenticationViewModel.activationCodeVerificationScreenRes); + authenticationViewModel.setDataAfterSendActivationSuccess(authenticationViewModel.activationCodeVerificationScreenRes); if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/widgets/auth/method_type_card.dart b/lib/widgets/auth/method_type_card.dart index 45190d2c..d991020c 100644 --- a/lib/widgets/auth/method_type_card.dart +++ b/lib/widgets/auth/method_type_card.dart @@ -6,11 +6,12 @@ class MethodTypeCard extends StatelessWidget { Key key, this.assetPath, this.onTap, - this.label, + this.label, this.height = 20, }) : super(key: key); final String assetPath; final Function onTap; final String label; + final double height; @override Widget build(BuildContext context) { @@ -38,7 +39,7 @@ class MethodTypeCard extends StatelessWidget { ], ), SizedBox( - height: 20, + height:height , ), AppText( label, diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index cf16a0f1..ed926545 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -309,12 +309,14 @@ class SMSOTP { } } - checkValue() { + checkValue() async { if (verifyAccountForm.currentState.validate()) { onSuccess(digit1.text.toString() + digit2.text.toString() + digit3.text.toString() + digit4.text.toString()); + this.isClosed = true; + } } @@ -341,7 +343,9 @@ class SMSOTP { Future.delayed(Duration(seconds: 1), () { if (this.remainingTime > 0) { - if (isClosed == false) startTimer(setState); + if (isClosed == false) { + startTimer(setState); + } } else { Navigator.pop(context); } diff --git a/lib/widgets/auth/verification_methods_list.dart b/lib/widgets/auth/verification_methods_list.dart index de867cde..b6efe748 100644 --- a/lib/widgets/auth/verification_methods_list.dart +++ b/lib/widgets/auth/verification_methods_list.dart @@ -81,6 +81,7 @@ class _VerificationMethodsListState extends State { assetPath: 'assets/images/login/more_icon.png', onTap: widget.onShowMore, label: TranslationBase.of(context).moreVerification, + height: 0, ); } } From 6b6243232c01abcdd4a7a98b8d2bda228532ead1 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 16 May 2021 14:51:30 +0300 Subject: [PATCH 037/241] Procedure template service --- lib/config/config.dart | 5 +- .../Procedure_template_request_model.dart | 120 ++++++++++++++++++ .../procedure/procedure_templateModel.dart | 56 ++++++++ .../procedure/procedure_service.dart | 26 ++++ lib/core/viewModel/procedure_View_model.dart | 15 +++ pubspec.lock | 8 +- 6 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 lib/core/model/procedure/Procedure_template_request_model.dart create mode 100644 lib/core/model/procedure/procedure_templateModel.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index ec8efe26..acb9e1c7 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -283,6 +283,9 @@ const GET_SICK_LEAVE_PATIENT = "Services/Patients.svc/REST/GetPatientSickLeave"; const GET_MY_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GetMyOutPatient"; +const GET_PROCEDURE_TEMPLETE = + 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ @@ -337,7 +340,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 6.0; +const VERSION_ID = 6.1; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/core/model/procedure/Procedure_template_request_model.dart b/lib/core/model/procedure/Procedure_template_request_model.dart new file mode 100644 index 00000000..698178e3 --- /dev/null +++ b/lib/core/model/procedure/Procedure_template_request_model.dart @@ -0,0 +1,120 @@ +class ProcedureTempleteRequestModel { + int doctorID; + String firstName; + String middleName; + String lastName; + String patientMobileNumber; + String patientIdentificationID; + int patientID; + String from; + String to; + int searchType; + String mobileNo; + String identificationNo; + int editedBy; + int projectID; + int clinicID; + String tokenID; + int languageID; + String stamp; + String iPAdress; + double versionID; + int channel; + String sessionID; + bool isLoginForDoctorApp; + bool patientOutSA; + String vidaAuthTokenID; + String vidaRefreshTokenID; + int deviceTypeID; + + ProcedureTempleteRequestModel( + {this.doctorID, + this.firstName, + this.middleName, + this.lastName, + this.patientMobileNumber, + this.patientIdentificationID, + this.patientID, + this.from, + this.to, + this.searchType, + this.mobileNo, + this.identificationNo, + this.editedBy, + this.projectID, + this.clinicID, + this.tokenID, + this.languageID, + this.stamp, + this.iPAdress, + this.versionID, + this.channel, + this.sessionID, + this.isLoginForDoctorApp, + this.patientOutSA, + this.vidaAuthTokenID, + this.vidaRefreshTokenID, + this.deviceTypeID}); + + ProcedureTempleteRequestModel.fromJson(Map json) { + doctorID = json['DoctorID']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + patientMobileNumber = json['PatientMobileNumber']; + patientIdentificationID = json['PatientIdentificationID']; + patientID = json['PatientID']; + from = json['From']; + to = json['To']; + searchType = json['SearchType']; + mobileNo = json['MobileNo']; + identificationNo = json['IdentificationNo']; + editedBy = json['EditedBy']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + tokenID = json['TokenID']; + languageID = json['LanguageID']; + stamp = json['stamp']; + iPAdress = json['IPAdress']; + versionID = json['VersionID']; + channel = json['Channel']; + sessionID = json['SessionID']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + patientOutSA = json['PatientOutSA']; + vidaAuthTokenID = json['VidaAuthTokenID']; + vidaRefreshTokenID = json['VidaRefreshTokenID']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['DoctorID'] = this.doctorID; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['PatientID'] = this.patientID; + data['From'] = this.from; + data['To'] = this.to; + data['SearchType'] = this.searchType; + data['MobileNo'] = this.mobileNo; + data['IdentificationNo'] = this.identificationNo; + data['EditedBy'] = this.editedBy; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['TokenID'] = this.tokenID; + data['LanguageID'] = this.languageID; + data['stamp'] = this.stamp; + data['IPAdress'] = this.iPAdress; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['SessionID'] = this.sessionID; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['PatientOutSA'] = this.patientOutSA; + data['VidaAuthTokenID'] = this.vidaAuthTokenID; + data['VidaRefreshTokenID'] = this.vidaRefreshTokenID; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/model/procedure/procedure_templateModel.dart b/lib/core/model/procedure/procedure_templateModel.dart new file mode 100644 index 00000000..3b12d646 --- /dev/null +++ b/lib/core/model/procedure/procedure_templateModel.dart @@ -0,0 +1,56 @@ +class ProcedureTempleteModel { + String setupID; + int projectID; + int clinicID; + int doctorID; + int templateID; + String templateName; + bool isActive; + int createdBy; + String createdOn; + dynamic editedBy; + dynamic editedOn; + + ProcedureTempleteModel( + {this.setupID, + this.projectID, + this.clinicID, + this.doctorID, + this.templateID, + this.templateName, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn}); + + ProcedureTempleteModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + templateID = json['TemplateID']; + templateName = json['TemplateName']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['TemplateID'] = this.templateID; + data['TemplateName'] = this.templateName; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + return data; + } +} diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index b403edf0..d0d88f83 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -1,9 +1,11 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/Procedure_template_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_procedure_req_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/update_procedure_request_model.dart'; @@ -19,9 +21,15 @@ class ProcedureService extends BaseService { List procedureslist = List(); List categoryList = []; + List _templateList = List(); + List get templateList => _templateList; + GetOrderedProcedureRequestModel _getOrderedProcedureRequestModel = GetOrderedProcedureRequestModel(); + ProcedureTempleteRequestModel _procedureTempleteRequestModel = + ProcedureTempleteRequestModel(); + GetProcedureReqModel _getProcedureReqModel = GetProcedureReqModel( // clinicId: 17, // pageSize: 10, @@ -46,6 +54,24 @@ class ProcedureService extends BaseService { //search: ["DENTAL"], ); + Future getProcedureTemplate( + {int doctorId, int projectId, int clinicId}) async { + _procedureTempleteRequestModel = ProcedureTempleteRequestModel(); + hasError = false; + //insuranceApprovalInPatient.clear(); + + await baseAppClient.post(GET_PROCEDURE_TEMPLETE, + onSuccess: (dynamic response, int statusCode) { + //prescriptionsList.clear(); + response['HIS_ProcedureTemplateList'].forEach((template) { + _templateList.add(ProcedureTempleteModel.fromJson(template)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: Map()); + } + Future getProcedure({int mrn}) async { _getOrderedProcedureRequestModel = GetOrderedProcedureRequestModel(patientMRN: mrn); diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 32a40e7e..aca47f10 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -7,6 +7,7 @@ import 'package:doctor_app_flutter/core/model/labs/patient_lab_special_result.da import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/update_procedure_request_model.dart'; @@ -48,6 +49,8 @@ class ProcedureViewModel extends BaseViewModel { List get labOrdersResultsList => _labsService.labOrdersResultsList; + List get ProcedureTemplate => + _procedureService.templateList; List _patientLabOrdersListClinic = List(); List _patientLabOrdersListHospital = List(); @@ -92,6 +95,18 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getProcedureTemplate() async { + hasError = false; + //_insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _procedureService.getProcedureTemplate(); + if (_procedureService.hasError) { + error = _procedureService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + Future postProcedure( PostProcedureReqModel postProcedureReqModel, int mrn) async { hasError = false; diff --git a/pubspec.lock b/pubspec.lock index ee31002d..1a572a0a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -573,7 +573,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" + version: "0.6.3-nullsafety.1" json_annotation: dependency: transitive description: @@ -615,7 +615,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.4" mime: dependency: transitive description: @@ -907,7 +907,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" sticky_headers: dependency: "direct main" description: @@ -1098,5 +1098,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <2.11.0" + dart: ">=2.10.0 <=2.11.0-213.1.beta" flutter: ">=1.22.0 <2.0.0" From a9bd02a908ddb42af134532e8cc433d645c00a34 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 16 May 2021 16:08:35 +0300 Subject: [PATCH 038/241] first step from user another account --- lib/screens/auth/verification_methods_screen.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 1e61d553..c03d5946 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -341,12 +341,15 @@ class _VerificationMethodsScreenState extends State { color: Colors.red[700], onPressed: () { projectsProvider.isLogin = true; + authenticationViewModel.unverified = false; + authenticationViewModel.isLogin = false; Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( page: RootPage(), ), (r) => false); + // Navigator.of(context).pushNamed(LOGIN); }, ), From 9b34c2c83334ce8c82b076d593a11cd1b0aaaf6b Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 17 May 2021 11:29:04 +0300 Subject: [PATCH 039/241] first step from live care --- assets/fonts/DoctorApp.ttf | Bin 45888 -> 47612 bytes lib/client/base_app_client.dart | 8 +- lib/config/localized_values.dart | 9 + lib/icons_app/config.json | 144 ++++- lib/icons_app/doctor_app_icons.dart | 553 ++++++------------ lib/screens/live_care/end_call_screen.dart | 186 ++++++ .../PatientProfileCardModel.dart | 5 + .../patient_profile_screen.dart | 104 ++-- lib/util/translations_delegate_base.dart | 9 + .../profile/PatientProfileButton.dart | 8 +- 10 files changed, 608 insertions(+), 418 deletions(-) create mode 100644 lib/screens/live_care/end_call_screen.dart diff --git a/assets/fonts/DoctorApp.ttf b/assets/fonts/DoctorApp.ttf index aa10880991963672acd2560e0c9177fe47a9defe..4ef2028b7feaa5f733cec0d613fc879e5575424f 100644 GIT binary patch delta 2315 zcmZuyeQaCR6+h=a+s`lY*R$h~KoiFwc}^TBu^sz4Yn_xr*SPs&O|ouH(lt(EH*Or; zO;YHlf)Rp0*d~!Kus=2mXzElUl@B!qF;r3hm|%j9@khtU2-8%d$!4fq_fa+}dER+; zI;L%we(#=p@44sv&bjAYzwrlV>#xk3r|1E|?*qW$xus;`_4S|s7JxkuQ2+Vy?6=e1 z=O)_$OsfFTo?b{L=Yv1m+#=oI6Ql)NxO1QVO_Hw=ybDXKr+;;*vXAV2N_ZoipG$tc za_K$*;~MQ>UrL@X;6+xTJqOKOa>=FCm5=TKJHShylT%$Gzq0z)kt06^*!Ty4Ms@az zXKw+JbP2!CmHv3l82>xevn5)A&9{De@%C8xbLFUgi=Cyp78qrfe#*JRdNZEH=8ZM{ z1-7WCD;3pEazy8=2mq))AURXH#r(KZS)X9{-dn1k1H2AwRSM8p2f&m-g|Cpsx~d1J z^jzta@=Q5hsQ{Fqbgg`(Jg>+*KZH7*#vGnmzs~*%_pHCC%5=oxD0~Z!!3-o}7Up0c zQjmt@umBl20gI4@CCEXZh-)?usTnkZPO-+Tc5GhVnALnw%~Lu{1lY6jS$&!*mafs9 z0Mj)7rUr=9_D1w zKNxKpePnd&Ym}9Z^G4U>MWr%;y~<2MD`lJ0bYmAvv3?BO?9He#Vs&9JN}^A6a|U#x zO@ntl!E^0aqtQCCd1G@z5!yNa36&ZJRI4(dW@-`!hg782+iRVenwn6?c1|_KXw~Ct zEfWaTgd#ANN+qK{%8o+=_=!S9^tjY+1Ji_-23wCSEcKzqDWeAeG*V%=@~+nEtQ8^8D zWp!B&VagP(ndzSBDk;%+tGt9S4tc)9H!pBRZV(^*a2zrCPnGDXoJe{@k3 z7VGP#+wN)G{-^pYKE~%KI&>=vA+|(>jBqD(0kl#!6lb?-S*&Qs9;?SK_Mu>P2|ZEI zmwfvWN0@{=6moCBO5e*U1>|>97X*iVY2pE)u~EQhg~s_}$o-`f-k(;q-tKn@7i4Jy zN5>llc}CHF;NN7%ZN?<(J?hre?Gbw`CR;o;!e>{zf{t;mugdr*=_xdQZ8%*HL(zrY}T(bZSt|! zey{5AuKmsjHO5hM(Hk;vJuaX-EM%F%u7vJE=l}S^VXU<Ezcf6@c_$fiDcy#740ICYyby%=~}3lscE^G zJsgvWqmNz^)+6-zH1yEei&C?4SNQVmi)TXKlZVys*4>|;-5rnbo=x9XDD*nq=y8~w zX0wwWn|Si|tLK6*7g5=~p=fQ7;6eahK{qmnU9MdQrE9A13G)=aCymepV4;?ap|6W7 zgB}wbbu(2)H=@REak<54QHb;-^)gCfdfFN|q*u>???^@?@&g>pnRqnlEp=uKHz40K zc1*}O_2xRWnM)vV3>ZmG{-Uae!xGJrPjF`1*ULBSOj^#2U(l*D+Ei}7b1s?9)~EB?`P6b} zzL3gkYBHD2!zE^GliB`o&9U{{^IECkg-n delta 565 zcmXw!OK1~O6o&shj~LtF)FMVAh^6Anh0vl41!-65OTmS-*4mCqCIfA3#E4Z2Eh>U2 zG~q7WML-3s2*M1C5awB2%!7zV`Aupw9!X$MaK{oX4wwdjRVWuxPkBJGZ6 zh0@G&Z#2YxU&zwbbjBW?y?PYb@}Bv-f<03dxAm>ecJRFWtX;^}KBkZa?%(4}6UFKC zrOUss@dFpYT&;4FDE>^~Z}4*x={9JjbD_E+2I- zFL#M^qQfhTS3=I}hmNf@+7NG`H>!Pf3!tsQ5LI4iX)Mr!3&C1PCsMBVkt6 z8;{`JPcbYU88g=8y5UOO+{T45SuyLfYHqR;YBD~*G4Fdzv74sXmB?sw;Rv9>Df(m+ zjM1Y_aGF*b!8ollf(cq>1U9WQ0{(TVGJ*`9Z35+76DT_kOn`+fThF$qwRCs-dtY~7 qwLjJWVZa%9J=i;R#VfUSEO?vmwpk)CQ~q1;j~_SW> localizedValues = { "medicalReportAdd": {"en": "Add Medical Report", "ar": "إضافة تقرير طبي"}, "medicalReportVerify": {"en": "Verify Medical Report", "ar": "تحقق من التقرير الطبي"}, "comments": {"en": "Comments", "ar": "تعليقات"}, + "initiateCall ": {"en": "Initiate Call ", "ar": "بدء الاتصال"}, + "transferTo": {"en": "Transfer To ", "ar": "حول إلى"}, + "admin": {"en": "Admin", "ar": "مشرف"}, + "instructions": {"en": "Instructions", "ar": "تعليمات"}, + "sendLC": {"en": "Send", "ar": "تعليمات"}, + "endLC": {"en": "End", "ar": "انهاء"}, + "consultation": {"en": "Consultation", "ar": "استشارة"}, + "resume": {"en": "Resume", "ar": "استأنف"}, + "theCall": {"en": "The Call", "ar": "الاتصال"}, }; diff --git a/lib/icons_app/config.json b/lib/icons_app/config.json index a5f1b893..20885d74 100644 --- a/lib/icons_app/config.json +++ b/lib/icons_app/config.json @@ -2513,9 +2513,9 @@ { "uid": "fbbe1c278b442a4840b03064fe4a2ea4", "css": "respiration-rate-1", - "code": 59499, + "code": 59510, "src": "custom_icons", - "selected": false, + "selected": true, "svg": { "path": "M989.3 410.2C907.2 230.7 805.1 123.6 716.1 123.6A91.6 91.6 0 0 0 667.3 137C595.3 181.3 592 319.6 591.9 334.9 591.9 339.7 590.8 377.9 590 431.1L560.9 420.4V20.1A20.3 20.3 0 0 0 540.6-0.2H499.9A20.3 20.3 0 0 0 479.6 20.1V420.4L450.5 431.1C449.7 378 448.7 339.9 448.6 335.3 448.6 319.6 445.2 181.3 373.2 137A91.6 91.6 0 0 0 324.4 123.6C235.5 123.6 133.3 230.8 51.2 410.3-57.1 647.8 39 972 43.2 985.6A20.1 20.1 0 0 0 67.1 999.3 1776.9 1776.9 0 0 0 243.4 946.2C369.2 900.2 434.5 855.1 442.6 808.2A2836.5 2836.5 0 0 0 451.6 473.7L506.5 453.4H534.7L589.6 473.7A2835.8 2835.8 0 0 0 598.6 808.2C606.7 855.1 671.8 900.2 797.8 946.2A1778.4 1778.4 0 0 0 974.1 999.5 20.1 20.1 0 0 0 998 985.7C1001.8 972 1097.9 647.8 989.3 410.2ZM393.1 500.5L249.7 574.6V634.8L260.7 668.2 288.1 694.8A20.3 20.3 0 0 1 260.1 723.7L230.5 695.2 197 732.2A20.3 20.3 0 0 1 167.2 705.1L209.4 658.4V595.3L130.2 636.3A20.3 20.3 0 1 1 111.7 600.5L129.3 591.4 97.8 566.3A20.3 20.3 0 0 1 122.9 534.8L168.5 571.2 278.8 514.3 184.4 442.5A20.3 20.3 0 0 1 208.8 410.4L239.3 433.5 241.9 410.2A20.3 20.3 0 0 1 281.9 414.6L276.5 461.8 318.5 493.7 374.5 464.8A20.3 20.3 0 1 1 393 500.5ZM942.9 566.3L911.4 591.4 929 600.5A20.3 20.3 0 1 1 910.5 636.3L831.4 595.3V658.2L873.7 705A20.3 20.3 0 0 1 843.8 732.1L810.3 695.1 780.8 723.6A20.3 20.3 0 0 1 752.7 694.7L780.1 668.1 791.1 634.7V574.5L647.7 500.4A20.3 20.3 0 1 1 666.2 464.6L722.2 493.6 764.2 461.7 759 414.5A20.3 20.3 0 1 1 799 410L801.6 433.4 832.1 410.2A20.3 20.3 0 0 1 856.5 442.3L761.9 514 872.2 570.9 917.9 534.5A20.3 20.3 0 0 1 943 566Z", "width": 1041 @@ -2523,6 +2523,146 @@ "search": [ "respiration-rate" ] + }, + { + "uid": "002f9ea7269e8e2ca9a28d0e87f09a2c", + "css": "end-call", + "code": 59604, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M282.4 546.3L133.8 620.6A13.6 13.6 0 0 1 118.2 618L77 576.8A108.8 108.8 0 0 1 77 423 598.3 598.3 0 0 1 923.2 423.2 108.6 108.6 0 0 1 923.2 576.8L882 618A13.6 13.6 0 0 1 866.4 620.6L717.6 546.3A13.6 13.6 0 0 1 710.4 531.5L727.1 448.2A13.8 13.8 0 0 0 719.3 432.9 565.7 565.7 0 0 0 280.8 432.9 13.8 13.8 0 0 0 273 448.3L289.6 531.4A13.6 13.6 0 0 1 282.3 546.2Z", + "width": 1000 + }, + "search": [ + "end-call" + ] + }, + { + "uid": "ace119a586c0a290d5da68f59038e160", + "css": "end-consultaion", + "code": 59605, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M664.4 0H92.6A92.7 92.7 0 0 0 0 92.6V907.4A92.7 92.7 0 0 0 92.6 1000H664.3A92.7 92.7 0 0 0 756.9 907.4V92.6A92.7 92.7 0 0 0 664.4 0ZM118.7 167.8L176.4 68.5A20.8 20.8 0 1 1 212.4 89.3L173 157.2H587.9L556.4 87.4A20.8 20.8 0 1 1 594.4 70.1L639.1 169.5A20.8 20.8 0 0 1 620.1 198.9H136.8A20.8 20.8 0 0 1 118.7 167.8ZM644.6 608.6H492.4A20.8 20.8 0 0 1 472.7 594.7L458.3 554.1 423.7 813.6A20.8 20.8 0 0 1 403.7 831.6H403.1A20.8 20.8 0 0 1 382.7 814.7L312.5 452.1 266.5 606.1A20.8 20.8 0 0 1 246.6 621H112.3A20.8 20.8 0 1 1 112.3 579.5H231.1L296.8 358.9A20.8 20.8 0 0 1 337.2 360.9L399.1 681.8 428.4 463.2A20.8 20.8 0 0 1 446.8 445.3 21.3 21.3 0 0 1 468.7 459.1L507 567.1H644.5A20.8 20.8 0 1 1 644.5 608.6Z", + "width": 757 + }, + "search": [ + "end-consultaion" + ] + }, + { + "uid": "62a5ade64a871b2006d088b4e107506f", + "css": "folder-open", + "code": 59606, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M1130.2 347.1A103.3 103.3 0 0 0 1027.1 244.8H565.1L102.7 246.1A103.3 103.3 0 0 0 0 349.8 17.1 17.1 0 0 0 0 352.4L89.8 898.2A103.3 103.3 0 0 0 192.8 999.9H1117.6A103.3 103.3 0 0 0 1220.7 896.8 17.1 17.1 0 0 0 1220.7 894.2ZM1269.1 113.6H814.5L724.6 6.1A16.8 16.8 0 0 0 711.3 0H344.3A103.3 103.3 0 0 0 241.2 101.7L225.3 197.9H259.5L1027.4 197.9A151.5 151.5 0 0 1 1178.1 342.7L1239.5 715.6 1254.8 807.5A102.5 102.5 0 0 0 1263.6 767.2L1371.6 220.2A16.8 16.8 0 0 0 1371.6 216.9 103.3 103.3 0 0 0 1269.1 113.6Z", + "width": 1372 + }, + "search": [ + "folder-open" + ] + }, + { + "uid": "f696b8dc00777a69a4e1e52df2955ec4", + "css": "folder", + "code": 59607, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M1029 245.6H572.9L482 137.6A15.5 15.5 0 0 0 469.6 132H101.5A102.3 102.3 0 0 0 0 234.4V897.8A102.3 102.3 0 0 0 102.2 1000H1029A102.3 102.3 0 0 0 1131.2 897.8V347.7A102.3 102.3 0 0 0 1029 245.6ZM1163 113.4H706.6L615.9 5.6A15.5 15.5 0 0 0 603.5 0H235.5A102.2 102.2 0 0 0 134.5 88H470.1A59.4 59.4 0 0 1 515.7 109.2L593.2 201.2H1029A146.5 146.5 0 0 1 1175.1 347.8V867A102.2 102.2 0 0 0 1264.6 765.7V215.4A102.3 102.3 0 0 0 1163 113.4Z", + "width": 1265 + }, + "search": [ + "folder" + ] + }, + { + "uid": "e794f7865351585b57f62ec43bba8aff", + "css": "link-in", + "code": 59608, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M333.3 750L916.6 750A83.6 83.6 0 0 0 999.9 666.6V83.3A83.6 83.6 0 0 0 916.6 0L333.3 0A83.6 83.6 0 0 0 250 83.3V666.6A83.6 83.6 0 0 0 333.3 750ZM479.1 375V476.6L789.1 166.6 833.2 210.9 523.8 520.7 625.3 520.7V583.3H458.1A41.6 41.6 0 0 1 416.5 541.6V374.9ZM416.7 833.4V916.7H83.3V583.4H166.6V500H41.7A41.8 41.8 0 0 0 0 541.7V958.4A41.9 41.9 0 0 0 41.7 1000.1H458.3A41.9 41.9 0 0 0 500 958.4V833.4Z", + "width": 1000 + }, + "search": [ + "link-in" + ] + }, + { + "uid": "8cbd9cb0e30a60dbfcd1425cb5dbc06d", + "css": "link-out", + "code": 59609, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M916.7 0H333.5A83.4 83.4 0 0 0 250 83.4V666.8A83.4 83.4 0 0 0 333.5 750.2H916.8A83.4 83.4 0 0 0 1000.2 666.8V83.4A83.4 83.4 0 0 0 916.7 0ZM770.8 375V273.3L460.8 583.3 416.7 539 726.7 229.1 625.1 229.1V166.7H791.7A41.6 41.6 0 0 1 833.4 208.3L833.4 375.2ZM416.7 833.3V916.8H83.4V583.4H166.9V500H41.6A41.8 41.8 0 0 0 0 541.6V958.3A41.8 41.8 0 0 0 41.6 1000H458.4A41.8 41.8 0 0 0 500 958.3V833.3Z", + "width": 1000 + }, + "search": [ + "link-out" + ] + }, + { + "uid": "ed96dd3085af227cc96170408b84c816", + "css": "mute-microphone", + "code": 59610, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M584.7 579.6V448.4L305.8 727.3A178.5 178.5 0 0 0 584.7 579.6ZM693 472.9H657.5A20.7 20.7 0 0 0 636.8 493.6V566.3A230.7 230.7 0 0 1 276.1 756.9L221.8 811.2A302.3 302.3 0 0 0 367.6 871.6V923.1H208.8A20.7 20.7 0 0 0 188.1 943.8V979.4A20.7 20.7 0 0 0 208.8 1000H603.3A20.7 20.7 0 0 0 624 979.4V943.8A20.7 20.7 0 0 0 603.3 923.1H444.5V871.6A312.1 312.1 0 0 0 713.8 566.4V493.7A20.7 20.7 0 0 0 693 472.9ZM795.4 79.6A56.9 56.9 0 0 0 715 79.6L584.7 209.9V178.6A178.6 178.6 0 0 0 227.4 178.6V567.1L180.4 614.2A230 230 0 0 1 175.2 566.3V493.6A20.7 20.7 0 0 0 154.5 472.9H119A20.7 20.7 0 0 0 98.3 493.6V566.3A298.4 298.4 0 0 0 119.3 675.3L16.7 777.9A56.9 56.9 0 0 0 97.1 858.4L795.4 160.1A56.9 56.9 0 0 0 795.4 79.6Z", + "width": 812 + }, + "search": [ + "mute-microphone" + ] + }, + { + "uid": "7c8fce018306529b3c40386a8e946374", + "css": "no-video", + "code": 59611, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M69.3 676.7L620.8 125.2H204A135.1 135.1 0 0 0 69.3 260.4ZM1179.1 184.9A135.9 135.9 0 0 0 1052.4 172.5L926.1 225.1A129.2 129.2 0 0 0 904.5 180.5L982.5 102.6A59.9 59.9 0 1 0 897.7 17.9L17.4 898.1A59.5 59.5 0 0 0 17.6 982.4 59.8 59.8 0 0 0 102.3 982.4L210 874.9H796.2A134.6 134.6 0 0 0 926.1 775L1052.4 827.4A134.4 134.4 0 0 0 1179.1 815 134.9 134.9 0 0 0 1239.1 702.7V297.4A134.9 134.9 0 0 0 1179.1 184.9ZM1119.1 702.7A13.7 13.7 0 0 1 1112.3 715 14.6 14.6 0 0 1 1098.4 716.6L930.9 647.5V352.6L1098.2 283.5A14.6 14.6 0 0 1 1112.1 285 13.7 13.7 0 0 1 1119 297.4Z", + "width": 1239 + }, + "search": [ + "no-video" + ] + }, + { + "uid": "7be786f4ac20cbacd06a26d712accfff", + "css": "send-instruction", + "code": 59612, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M436.7 0A436.7 436.7 0 0 0 226.4 819.5L221.3 1000 427.3 873C430.4 873 433.5 873.5 436.7 873.5A436.7 436.7 0 0 0 436.7 0ZM492.4 691.3H380.4V331H492.4ZM435.7 286.9A54.7 54.7 0 0 1 377.5 231 54.7 54.7 0 0 1 436.4 174.2 56.5 56.5 0 1 1 435.6 287Z", + "width": 873 + }, + "search": [ + "send-instruction" + ] + }, + { + "uid": "926041acc7150e19895e12f7bba3d07a", + "css": "transfer-to-admin", + "code": 59613, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M202.7 517.8L148.9 463.9A52.2 52.2 0 0 1 148.9 390.3L414.1 125 342.5 53.3A31.2 31.2 0 0 1 364.6 0H635.4A31.3 31.3 0 0 1 666.7 31.2V302.1A31.2 31.2 0 0 1 613.3 324.2L541.7 252.5 276.4 517.7A52.2 52.2 0 0 1 202.8 517.7ZM302.1 1000H31.2A31.3 31.3 0 0 1 0 968.8V697.9A31.2 31.2 0 0 1 53.3 675.8L125 747.5 390.3 482.2A52.2 52.2 0 0 1 463.9 482.2L517.8 536.1A52.2 52.2 0 0 1 517.8 609.7L252.5 875 324.1 946.7A31.2 31.2 0 0 1 302 1000Z", + "width": 667 + }, + "search": [ + "transfer-to-admin" + ] } ] } \ No newline at end of file diff --git a/lib/icons_app/doctor_app_icons.dart b/lib/icons_app/doctor_app_icons.dart index 5e5ce23a..a73be2e3 100644 --- a/lib/icons_app/doctor_app_icons.dart +++ b/lib/icons_app/doctor_app_icons.dart @@ -11,374 +11,209 @@ /// fonts: /// - asset: fonts/DoctorApp.ttf /// -/// +/// /// * MFG Labs, Copyright (C) 2012 by Daniel Bruce /// Author: MFG Labs /// License: SIL (http://scripts.sil.org/OFL) /// Homepage: http://www.mfglabs.com/ /// import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart'; class DoctorApp { DoctorApp._(); - static const _kFontFam = 'DoctorApp'; - static const String _kFontPkg = null; + static const _kFontFam = 'DoctorApp'; + static const String _kFontPkg = null; - static const IconData female_icon = - IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData male = - IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData reject_icon = - IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_icon_active = - IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData menu_icon = - IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData menu_icon_active = - IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData message_icon = - IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData message_icon_active = - IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData scdedule_icon_active = - IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData schedule_icon = - IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData discharge_patient = - IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData approved_icon = - IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData pending_icon = - IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData in_patient_white = - IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData lab_results = - IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_icon = - IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData referral_1 = - IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData progress_notes = - IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_icon_1 = - IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData operations = - IconData(0xe813, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData out_patient = - IconData(0xe814, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData patient = - IconData(0xe815, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_code = - IconData(0xe816, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData radiology = - IconData(0xe817, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData referral = - IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData male_2 = - IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_patient = - IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData female_1 = - IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_icon_active_1 = - IconData(0xe81c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData menu_icon_1 = - IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData mail = - IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData medicine_search = - IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_code_1 = - IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_1 = - IconData(0xe821, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData referred = - IconData(0xe822, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData send = - IconData(0xe823, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData sync_icon = - IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData drawer_icon = - IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData view = - IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData warning = - IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData add = - IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData close = - IconData(0xe829, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData back = - IconData(0xe82a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_summary = - IconData(0xe82b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData powered_by_cs = - IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_code_2 = - IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ecg = - IconData(0xe82e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData create_episode = - IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData booked = - IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData admission_req = - IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData walkin = - IconData(0xe832, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData reschedule_ = - IconData(0xe833, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData edit = - IconData(0xe834, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData lab_results2 = - IconData(0xe835, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData leaves = - IconData(0xe836, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData logout = - IconData(0xe837, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData obese_bmi = - IconData(0xe838, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData livecare = - IconData(0xe839, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_bmi = - IconData(0xe83a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_bmi_r = - IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData modify_episode = - IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData height = - IconData(0xe83d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData obese_bmi_r = - IconData(0xe83e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ovrweight_bmi = - IconData(0xe83f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData order_prescription = - IconData(0xe840, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData order_procedures = - IconData(0xe841, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ovrweight_bmi_r = - IconData(0xe842, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData respiration_rate = - IconData(0xe843, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData patient_sick_leave = - IconData(0xe844, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData progress_notes_1 = - IconData(0xe845, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData temperature = - IconData(0xe846, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData underweight_bmi = - IconData(0xe847, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData radiology_1 = - IconData(0xe848, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_patient_1 = - IconData(0xe849, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData referral_bg = - IconData(0xe84a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search = - IconData(0xe84b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_bg = - IconData(0xe84c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData arrival_patients = - IconData(0xe84d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData arrival_patients_bg = - IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData refer_patient = - IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData underweight_bmi_r = - IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData weight = - IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData blood_pressure = - IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData vital_signs = - IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ucaf = - IconData(0xe854, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData filter = - IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData male_1 = - IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData female = - IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData external_link = - IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_face_2 = - IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_sms_2 = - IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home = - IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_finger_2 = - IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData dr_reply_active = - IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData dr_reply = - IconData(0xe85e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData schedule_active = - IconData(0xe85f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData schedule = - IconData(0xe860, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_reader_active = - IconData(0xe861, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_reader = - IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_active = - IconData(0xe863, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData arrow_forward = - IconData(0xe864, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData heart_rate = - IconData(0xe865, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData menu_icon_active_1 = - IconData(0xe866, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData message_icon_1 = - IconData(0xe867, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData message_icon_active_1 = - IconData(0xe868, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData scdedule_icon_active_1 = - IconData(0xe869, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ovrweight_bmi_r_1 = - IconData(0xe86a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData underweight_bmi_1 = - IconData(0xe86b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData temperature_1 = - IconData(0xe86c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData underweight_bmi_r_1 = - IconData(0xe86d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData weight_1 = - IconData(0xe86e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData blood_pressure_1 = - IconData(0xe86f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_bmi_r_1 = - IconData(0xe870, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_bmi_1 = - IconData(0xe871, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData heart_rate_1 = - IconData(0xe872, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData height_1 = - IconData(0xe873, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData obese_bmi_1 = - IconData(0xe874, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ovrweight_bmi_1 = - IconData(0xe875, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_code_3 = - IconData(0xe877, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData reschedule__1 = - IconData(0xe878, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData logout_1 = - IconData(0xe879, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData livecare_1 = - IconData(0xe87a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData modify_episode_1 = - IconData(0xe87b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData order_prescription_1 = - IconData(0xe87c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData order_procedures_1 = - IconData(0xe87d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData patient_sick_leave_1 = - IconData(0xe87e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData progress_notes_2 = - IconData(0xe87f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData radiology_2 = - IconData(0xe880, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData refer_patient_1 = - IconData(0xe881, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ucaf_1 = - IconData(0xe882, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData vital_signs_1 = - IconData(0xe883, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData walkin_1 = - IconData(0xe884, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData admission_req_1 = - IconData(0xe885, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData booked_1 = - IconData(0xe886, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData create_episode_1 = - IconData(0xe887, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData ecg_1 = - IconData(0xe888, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData health_summary_1 = - IconData(0xe889, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData lab_results_1 = - IconData(0xe88a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData female_2 = - IconData(0xe88b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData filter_1 = - IconData(0xe88c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData male_3 = - IconData(0xe88d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_2 = - IconData(0xe88e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData send_1 = - IconData(0xe88f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData view_1 = - IconData(0xe890, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData warning_1 = - IconData(0xe891, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData add_1 = - IconData(0xe892, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData arrow_forward_1 = - IconData(0xe893, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData back_1 = - IconData(0xe894, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData close_1 = - IconData(0xe895, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData edit_1 = - IconData(0xe896, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData external_link_1 = - IconData(0xe897, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_finger_1 = - IconData(0xe898, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_sms_1 = - IconData(0xe899, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_face_1 = - IconData(0xe89a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_reader_1 = - IconData(0xe89b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData qr_reader_active_1 = - IconData(0xe89c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData schedule_1 = - IconData(0xe89d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData schedule_active_1 = - IconData(0xe89e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData dr_reply_1 = - IconData(0xe89f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData dr_reply_active_1 = - IconData(0xe8a0, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_1 = - IconData(0xe8a1, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData home_active_1 = - IconData(0xe8a2, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_face = - IconData(0xe8a3, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_finger = - IconData(0xe8a4, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_whtsapp = - IconData(0xe8a5, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData verify_sms = - IconData(0xe8a6, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData obese_bmi_r_1 = - IconData(0xe8a9, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData inpatient = - IconData(0xe959, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData discharge = - IconData(0xe95a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData order_sheets = - IconData(0xe95b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData call = - IconData(0xe95c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData medical_report = - IconData(0xe95d, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData painscale = - IconData(0xe95e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData oxygenation = - IconData(0xe95f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData speechtotext = - IconData(0xe960, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData search_medicines = - IconData(0xe964, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData discharge_patients = - IconData(0xe965, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static const IconData referral_discharge = - IconData(0xe966, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData female_icon = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData male = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData reject_icon = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_icon_active = IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData menu_icon = IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData menu_icon_active = IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData message_icon = IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData message_icon_active = IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData scdedule_icon_active = IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData schedule_icon = IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData discharge_patient = IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData approved_icon = IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData pending_icon = IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData in_patient_white = IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData lab_results = IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_icon = IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData referral_1 = IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData progress_notes = IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_icon_1 = IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData operations = IconData(0xe813, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData out_patient = IconData(0xe814, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData patient = IconData(0xe815, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_code = IconData(0xe816, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData radiology = IconData(0xe817, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData referral = IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData male_2 = IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_patient = IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData female_1 = IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_icon_active_1 = IconData(0xe81c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData menu_icon_1 = IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData mail = IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData medicine_search = IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_code_1 = IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_1 = IconData(0xe821, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData referred = IconData(0xe822, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData send = IconData(0xe823, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData sync_icon = IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData drawer_icon = IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData view = IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData warning = IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData add = IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData close = IconData(0xe829, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData back = IconData(0xe82a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_summary = IconData(0xe82b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData powered_by_cs = IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_code_2 = IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ecg = IconData(0xe82e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData create_episode = IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData booked = IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData admission_req = IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData walkin = IconData(0xe832, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData reschedule_ = IconData(0xe833, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData edit = IconData(0xe834, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData leaves = IconData(0xe836, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData logout = IconData(0xe837, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData obese_bmi = IconData(0xe838, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData livecare = IconData(0xe839, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_bmi = IconData(0xe83a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_bmi_r = IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData modify_episode = IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData height = IconData(0xe83d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData obese_bmi_r = IconData(0xe83e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ovrweight_bmi = IconData(0xe83f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData order_prescription = IconData(0xe840, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData order_procedures = IconData(0xe841, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ovrweight_bmi_r = IconData(0xe842, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData respiration_rate = IconData(0xe843, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData patient_sick_leave = IconData(0xe844, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData progress_notes_1 = IconData(0xe845, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData temperature = IconData(0xe846, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData underweight_bmi = IconData(0xe847, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData radiology_1 = IconData(0xe848, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_patient_1 = IconData(0xe849, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData referral_bg = IconData(0xe84a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search = IconData(0xe84b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_bg = IconData(0xe84c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData arrival_patients = IconData(0xe84d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData arrival_patients_bg = IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData refer_patient = IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData underweight_bmi_r = IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData weight = IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData blood_pressure = IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData vital_signs = IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ucaf = IconData(0xe854, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData filter = IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData male_1 = IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData female = IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData external_link = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_face_2 = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_sms_2 = IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home = IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_finger_2 = IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData dr_reply_active = IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData dr_reply = IconData(0xe85e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData schedule_active = IconData(0xe85f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData schedule = IconData(0xe860, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_reader_active = IconData(0xe861, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_reader = IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_active = IconData(0xe863, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData arrow_forward = IconData(0xe864, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData heart_rate = IconData(0xe865, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData menu_icon_active_1 = IconData(0xe866, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData message_icon_1 = IconData(0xe867, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData message_icon_active_1 = IconData(0xe868, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData scdedule_icon_active_1 = IconData(0xe869, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ovrweight_bmi_r_1 = IconData(0xe86a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData underweight_bmi_1 = IconData(0xe86b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData temperature_1 = IconData(0xe86c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData underweight_bmi_r_1 = IconData(0xe86d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData weight_1 = IconData(0xe86e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData blood_pressure_1 = IconData(0xe86f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_bmi_r_1 = IconData(0xe870, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_bmi_1 = IconData(0xe871, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData heart_rate_1 = IconData(0xe872, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData height_1 = IconData(0xe873, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData obese_bmi_1 = IconData(0xe874, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ovrweight_bmi_1 = IconData(0xe875, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData respiration_rate_1 = IconData(0xe876, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_code_3 = IconData(0xe877, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData reschedule__1 = IconData(0xe878, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData logout_1 = IconData(0xe879, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData livecare_1 = IconData(0xe87a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData modify_episode_1 = IconData(0xe87b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData order_prescription_1 = IconData(0xe87c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData order_procedures_1 = IconData(0xe87d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData patient_sick_leave_1 = IconData(0xe87e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData progress_notes_2 = IconData(0xe87f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData radiology_2 = IconData(0xe880, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData refer_patient_1 = IconData(0xe881, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ucaf_1 = IconData(0xe882, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData vital_signs_1 = IconData(0xe883, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData walkin_1 = IconData(0xe884, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData admission_req_1 = IconData(0xe885, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData booked_1 = IconData(0xe886, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData create_episode_1 = IconData(0xe887, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ecg_1 = IconData(0xe888, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData health_summary_1 = IconData(0xe889, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData lab_results_1 = IconData(0xe88a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData female_2 = IconData(0xe88b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData filter_1 = IconData(0xe88c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData male_3 = IconData(0xe88d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_2 = IconData(0xe88e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData send_1 = IconData(0xe88f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData view_1 = IconData(0xe890, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData warning_1 = IconData(0xe891, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData add_1 = IconData(0xe892, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData arrow_forward_1 = IconData(0xe893, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData back_1 = IconData(0xe894, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData close_1 = IconData(0xe895, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData edit_1 = IconData(0xe896, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData external_link_1 = IconData(0xe897, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_finger_1 = IconData(0xe898, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_sms_1 = IconData(0xe899, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_face_1 = IconData(0xe89a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_reader_1 = IconData(0xe89b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData qr_reader_active_1 = IconData(0xe89c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData schedule_1 = IconData(0xe89d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData schedule_active_1 = IconData(0xe89e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData dr_reply_1 = IconData(0xe89f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData dr_reply_active_1 = IconData(0xe8a0, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_1 = IconData(0xe8a1, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData home_active_1 = IconData(0xe8a2, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_face = IconData(0xe8a3, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_finger = IconData(0xe8a4, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_whtsapp = IconData(0xe8a5, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData verify_sms = IconData(0xe8a6, fontFamily: _kFontFam, fontPackage: _kFontPkg); + /// static const IconData 124 = IconData(0xe8a7, fontFamily: _kFontFam, fontPackage: _kFontPkg); + ///static const IconData 123 = IconData(0xe8a8, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData obese_bmi_r_1 = IconData(0xe8a9, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData end_call = IconData(0xe8d4, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData end_consultaion = IconData(0xe8d5, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData folder_open = IconData(0xe8d6, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData folder = IconData(0xe8d7, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData link_in = IconData(0xe8d8, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData link_out = IconData(0xe8d9, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData mute_microphone = IconData(0xe8da, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData no_video = IconData(0xe8db, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData send_instruction = IconData(0xe8dc, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData transfer_to_admin = IconData(0xe8dd, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData inpatient = IconData(0xe959, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData discharge = IconData(0xe95a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData order_sheets = IconData(0xe95b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData call = IconData(0xe95c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData medical_report = IconData(0xe95d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData painscale = IconData(0xe95e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData oxygenation = IconData(0xe95f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData speechtotext = IconData(0xe960, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData search_medicines = IconData(0xe964, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData discharge_patients = IconData(0xe965, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData referral_discharge = IconData(0xe966, fontFamily: _kFontFam, fontPackage: _kFontPkg); } diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart new file mode 100644 index 00000000..b4a7c415 --- /dev/null +++ b/lib/screens/live_care/end_call_screen.dart @@ -0,0 +1,186 @@ +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/PatientProfileCardModel.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/PatientProfileButton.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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/buttons/app_buttons_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:hexcolor/hexcolor.dart'; + +import '../../routes.dart'; + +class EndCallScreen extends StatefulWidget { + final PatiantInformtion patient; + + const EndCallScreen({Key key, this.patient}) : super(key: key); + + @override + _EndCallScreenState createState() => _EndCallScreenState(); +} + +class _EndCallScreenState extends State { + bool isInpatient = false; + + bool isDischargedPatient = false; + bool isSearchAndOut = false; + String patientType; + String arrivalType; + String from; + String to; + + @override + Widget build(BuildContext context) { + final List cardsList = [ + PatientProfileCardModel(TranslationBase.of(context).resume, + TranslationBase.of(context).theCall, '', 'patient/vital_signs.png', + isInPatient: isInpatient, onTap: () {}, isDartIcon: true, + dartIcon: DoctorApp.call), + PatientProfileCardModel( + TranslationBase.of(context).endLC, + TranslationBase.of(context).consultation, + '', + 'patient/vital_signs.png', + isInPatient: isInpatient, + onTap: () {}, + isDartIcon: true, + dartIcon: DoctorApp.end_consultaion + ), + PatientProfileCardModel( + TranslationBase.of(context).sendLC, + TranslationBase.of(context).instruction, + "", + 'patient/health_summary.png', + onTap: () {}, + isInPatient: isInpatient, + isDartIcon: true, + dartIcon: DoctorApp.send_instruction + ), + PatientProfileCardModel( + TranslationBase.of(context).transferTo, + TranslationBase.of(context).admin, + '', + 'patient/health_summary.png', + onTap: () {}, + isInPatient: isInpatient, + + isDartIcon: true, + dartIcon: DoctorApp.transfer_to_admin + ), + ]; + + return AppScaffold( + appBarTitle: TranslationBase.of(context).patientProfile, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + isShowAppBar: true, + appBar: PatientProfileHeaderNewDesignAppBar( + widget.patient, arrivalType ?? '7', '1', + isInpatient: isInpatient, + height: (widget.patient.patientStatusType != null && + widget.patient.patientStatusType == 43) + ? 210 + : isDischargedPatient + ? 240 + : 0, + isDischargedPatient: isDischargedPatient), + body: Container( + height: !isSearchAndOut + ? isDischargedPatient + ? MediaQuery.of(context).size.height * 0.64 + : MediaQuery.of(context).size.height * 0.65 + : MediaQuery.of(context).size.height * 0.69, + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 15.0, horizontal: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).patient, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + AppText(TranslationBase.of(context).endcall, + fontSize: 26, + fontWeight: FontWeight.bold, + ), + SizedBox(height: 10,), + StaggeredGridView.countBuilder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + crossAxisCount: 3, + itemCount: cardsList.length, + staggeredTileBuilder: (int index) => StaggeredTile.fit(1), + itemBuilder: (BuildContext context, int index) => + PatientProfileButton( + patient: widget.patient, + patientType: patientType, + arrivalType: arrivalType, + from: from, + to: to, + nameLine1: cardsList[index].nameLine1, + nameLine2: cardsList[index].nameLine2, + route: cardsList[index].route, + icon: cardsList[index].icon, + isInPatient: cardsList[index].isInPatient, + isDischargedPatient: cardsList[index].isDischargedPatient, + isDisable: cardsList[index].isDisable, + onTap: cardsList[index].onTap, + isLoading: cardsList[index].isLoading, + isDartIcon: cardsList[index].isDartIcon, + dartIcon: cardsList[index].dartIcon, + ), + ), + ], + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ) + ], + ), + ), + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + fontWeight: FontWeight.w700, + color: Colors.red[600], + title: "Close", //TranslationBase.of(context).close, + onPressed: () async {}, + ), + ), + ), + ), + SizedBox( + height: 5, + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart index 3b566d81..eb9a3eaa 100644 --- a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart +++ b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + class PatientProfileCardModel { final String nameLine1; final String nameLine2; @@ -9,6 +11,8 @@ class PatientProfileCardModel { final Function onTap; final bool isDischargedPatient; final bool isSelectInpatient; + final bool isDartIcon; + final IconData dartIcon; PatientProfileCardModel( this.nameLine1, @@ -21,5 +25,6 @@ class PatientProfileCardModel { this.onTap, this.isDischargedPatient = false, this.isSelectInpatient = false, + this.isDartIcon = false,this.dartIcon }); } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index aa2b5276..2424da36 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,20 +1,19 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.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/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; import '../../../../routes.dart'; @@ -28,6 +27,7 @@ class _PatientProfileScreenState extends State PatiantInformtion patient; bool isFromSearch = false; + bool isFromLiveCare = true; bool isInpatient = false; @@ -94,7 +94,6 @@ class _PatientProfileScreenState extends State Column( children: [ PatientProfileHeaderNewDesignAppBar( - patient, arrivalType ?? '0', patientType, @@ -146,9 +145,13 @@ class _PatientProfileScreenState extends State to: to, ), ), - ], + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ) + ], ), ), + ], ), if (patient.patientStatusType != null && @@ -237,62 +240,57 @@ class _PatientProfileScreenState extends State }), ], ), - )), + )), ], ), ], ), - )); - } - - Widget tabsBar(BuildContext context, Size screenSize) { - List _tabs = [ - "Inpatient Info".toUpperCase(), - "Outpatient Info".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); - }); - }, - 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, + bottomSheet: isFromLiveCare ? Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), + ), + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: MediaQuery + .of(context) + .size + .height * 0.1, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + fontWeight: FontWeight.w700, + color: Colors.green[600], + title: TranslationBase + .of(context) + .initiateCall, + onPressed: () async { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); + }, + ), ), ), ), - ), + SizedBox( + height: 5, + ), + ], ), - ); - }).toList(), - ), + ) : Container(), + ), + + ); } } diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 8c2bf15b..a80deee9 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1332,6 +1332,15 @@ class TranslationBase { String get medicalReportAdd => localizedValues['medicalReportAdd'][locale.languageCode]; String get medicalReportVerify => localizedValues['medicalReportVerify'][locale.languageCode]; String get comments => localizedValues['comments'][locale.languageCode]; + String get initiateCall => localizedValues['initiateCall '][locale.languageCode]; + String get transferTo => localizedValues['transferTo'][locale.languageCode]; + String get admin => localizedValues['admin'][locale.languageCode]; + String get instructions => localizedValues['instructions'][locale.languageCode]; + String get sendLC => localizedValues['sendLC'][locale.languageCode]; + String get endLC => localizedValues['endLC'][locale.languageCode]; + String get consultation => localizedValues['consultation'][locale.languageCode]; + String get resume => localizedValues['resume'][locale.languageCode]; + String get theCall => localizedValues['theCall'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/patients/profile/PatientProfileButton.dart b/lib/widgets/patients/profile/PatientProfileButton.dart index 2cf9a5ca..c5580568 100644 --- a/lib/widgets/patients/profile/PatientProfileButton.dart +++ b/lib/widgets/patients/profile/PatientProfileButton.dart @@ -24,6 +24,8 @@ class PatientProfileButton extends StatelessWidget { final Function onTap; final bool isDischargedPatient; final bool isSelectInpatient; + final bool isDartIcon; + final IconData dartIcon; PatientProfileButton({ Key key, @@ -42,6 +44,8 @@ class PatientProfileButton extends StatelessWidget { this.isInPatient = false, this.isDischargedPatient = false, this.isSelectInpatient = false, + this.isDartIcon = false, + this.dartIcon, }) : super(key: key); @override @@ -66,7 +70,9 @@ class PatientProfileButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Container( - child: new Image.asset( + child: isDartIcon ? Icon( + dartIcon, size: 30, color: Color(0xFF333C45),) : new Image + .asset( url + icon, width: 30, height: 30, From 6933b6577f8a0ef88107a36b01fe6a7f6a8421c0 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 17 May 2021 11:54:38 +0300 Subject: [PATCH 040/241] add session time out. --- lib/client/base_app_client.dart | 10 +++++++++- lib/core/viewModel/authentication_view_model.dart | 11 +++++++++-- lib/screens/auth/verification_methods_screen.dart | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index d79f0338..3aac5e92 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -22,6 +22,8 @@ class BaseAppClient { Function(String error, int statusCode) onFailure, bool isAllowAny = false}) async { String url = BASE_URL + endPoint; + + bool callLog= true; try { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); String token = await sharedPref.getString(TOKEN); @@ -88,6 +90,12 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400) { onFailure(Helpers.generateContactAdminMsg(), statusCode); } else { + if(callLog){ + callLog = false; + await AuthenticationViewModel().logout(isSessionTimeout: true); + + } + var parsed = json.decode(response.body.toString()); if (parsed['ErrorType'] == 4) { helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'], @@ -98,7 +106,7 @@ class BaseAppClient { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { - await AuthenticationViewModel().logout(); + await AuthenticationViewModel().logout(isSessionTimeout: true); Helpers.showErrorToast('Your session expired Please login again'); } if (isAllowAny) { diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index d6afa270..3b8cf02f 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -74,7 +74,7 @@ class AuthenticationViewModel extends BaseViewModel { bool unverified = false; AuthenticationViewModel({bool checkDeviceInfo = false}) { - getDeviceInfoFromFirebase(); + getDeviceInfoFromFirebase(); getDoctorProfile(); } @@ -401,12 +401,14 @@ class AuthenticationViewModel extends BaseViewModel { } /// logout function - logout() async { + logout({bool isSessionTimeout = false}) async { DEVICE_TOKEN = ""; String lang = await sharedPref.getString(APP_Language); await Helpers.clearSharedPref(); sharedPref.setString(APP_Language, lang); ProjectViewModel().isLogin = false; + if(isSessionTimeout) + await getDeviceInfoFromFirebase(); Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( @@ -415,4 +417,9 @@ class AuthenticationViewModel extends BaseViewModel { (r) => false); } + deleteUser(){ + user = null; + notifyListeners(); + } + } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index c03d5946..5aa626be 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -343,6 +343,8 @@ class _VerificationMethodsScreenState extends State { projectsProvider.isLogin = true; authenticationViewModel.unverified = false; authenticationViewModel.isLogin = false; + authenticationViewModel.deleteUser(); + Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( From 1187c3b605b7fc61af7abe7b931ca780a8458d54 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 17 May 2021 12:28:21 +0300 Subject: [PATCH 041/241] fix authentication provider --- ios/Podfile.lock | 2 +- lib/client/base_app_client.dart | 9 +---- .../viewModel/authentication_view_model.dart | 38 +++++++++---------- lib/widgets/shared/app_drawer_widget.dart | 2 +- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2f4607e0..878a1850 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.1 diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 3aac5e92..68a84820 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -10,6 +10,7 @@ import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart' as http; +import 'package:provider/provider.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = new Helpers(); @@ -90,12 +91,6 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400) { onFailure(Helpers.generateContactAdminMsg(), statusCode); } else { - if(callLog){ - callLog = false; - await AuthenticationViewModel().logout(isSessionTimeout: true); - - } - var parsed = json.decode(response.body.toString()); if (parsed['ErrorType'] == 4) { helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'], @@ -106,7 +101,7 @@ class BaseAppClient { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { - await AuthenticationViewModel().logout(isSessionTimeout: true); + await Provider.of(AppGlobal.CONTEX, listen: false).logout(isSessionTimeout: true); Helpers.showErrorToast('Your session expired Please login again'); } if (isAllowAny) { diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 3b8cf02f..8e9c3541 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -361,28 +361,26 @@ class AuthenticationViewModel extends BaseViewModel { _firebaseMessaging.requestNotificationPermissions(); } setState(ViewState.Busy); - - _firebaseMessaging.getToken().then((String token) async { - if (DEVICE_TOKEN == "" && !ProjectViewModel().isLogin) { - DEVICE_TOKEN = token; - - await _authService.selectDeviceImei(DEVICE_TOKEN); - if (_authService.hasError) { - error = _authService.error; - setState(ViewState.ErrorLocal); - } else { - if (_authService.dashboardItemsList.length > 0) { - user =_authService.dashboardItemsList[0]; - sharedPref.setObj( - LAST_LOGIN_USER, _authService.dashboardItemsList[0]); - this.unverified = true; - } - setState(ViewState.Idle); - } + var token = await _firebaseMessaging.getToken(); + if (DEVICE_TOKEN == "" && !ProjectViewModel().isLogin) { + DEVICE_TOKEN = token; + + await _authService.selectDeviceImei(DEVICE_TOKEN); + if (_authService.hasError) { + error = _authService.error; + setState(ViewState.ErrorLocal); } else { + if (_authService.dashboardItemsList.length > 0) { + user =_authService.dashboardItemsList[0]; + sharedPref.setObj( + LAST_LOGIN_USER, _authService.dashboardItemsList[0]); + this.unverified = true; + } setState(ViewState.Idle); } - }); + } else { + setState(ViewState.Idle); + } } /// determine the status of the app @@ -407,6 +405,7 @@ class AuthenticationViewModel extends BaseViewModel { await Helpers.clearSharedPref(); sharedPref.setString(APP_Language, lang); ProjectViewModel().isLogin = false; + deleteUser(); if(isSessionTimeout) await getDeviceInfoFromFirebase(); Navigator.pushAndRemoveUntil( @@ -419,6 +418,7 @@ class AuthenticationViewModel extends BaseViewModel { deleteUser(){ user = null; + unverified = false; notifyListeners(); } diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index db328462..ee7f0276 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -172,7 +172,7 @@ class _AppDrawerState extends State { ), onTap: () async { Navigator.pop(context); - await AuthenticationViewModel().logout(); + await authenticationViewModel.logout(); projectsProvider.isLogin = false; }, ), From 6192d9a84fb45e0191d894d859b928e68f37aa06 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 17 May 2021 15:05:08 +0300 Subject: [PATCH 042/241] working on medical-profile --- lib/client/base_app_client.dart | 26 +- lib/config/config.dart | 7 +- lib/config/localized_values.dart | 4 + .../PatientMedicalReportService.dart | 65 ++++ .../PatientMedicalReportViewModel.dart | 43 +++ lib/locator.dart | 4 + .../MedicalReport/MeidcalReportModel.dart | 60 +++ lib/routes.dart | 9 + .../admission-request_second-screen.dart | 2 +- .../AddVerifyMedicalReport.dart | 357 ++++++++++++++---- .../medical_report/MedicalReportPage.dart | 201 +++++----- .../profile_gird_for_InPatient.dart | 4 +- lib/util/translations_delegate_base.dart | 4 + 13 files changed, 601 insertions(+), 185 deletions(-) create mode 100644 lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart create mode 100644 lib/core/viewModel/PatientMedicalReportViewModel.dart create mode 100644 lib/models/patient/MedicalReport/MeidcalReportModel.dart diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index bd4b0cd4..718a3839 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -67,11 +67,11 @@ class BaseAppClient { await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); } - int projectID = await sharedPref.getInt(PROJECT_ID); - if(projectID ==2 || projectID == 3) - body['PatientOutSA'] = true; - else - body['PatientOutSA'] = false; + int projectID = await sharedPref.getInt(PROJECT_ID); + if (projectID == 2 || projectID == 3) + body['PatientOutSA'] = true; + else + body['PatientOutSA'] = false; body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; print("URL : $url"); @@ -140,13 +140,11 @@ class BaseAppClient { String token = await sharedPref.getString(TOKEN); var languageID = await sharedPref.getStringWithDefaultValue(APP_Language, 'en'); - if (body.containsKey('SetupID')) { - body['SetupID'] = body.containsKey('SetupID') - ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID - : SETUP_ID; - } + body['SetupID'] = body.containsKey('SetupID') + ? body['SetupID'] != null + ? body['SetupID'] + : SETUP_ID + : SETUP_ID; body['VersionID'] = VERSION_ID; body['Channel'] = CHANNEL; @@ -187,7 +185,7 @@ class BaseAppClient { : PATIENT_TYPE_ID : PATIENT_TYPE_ID; - body['TokenID'] = token; + body['TokenID'] = body.containsKey('TokenID') ? body['TokenID'] : token; body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : patient.patientId ?? patient.patientMRN; @@ -196,7 +194,7 @@ class BaseAppClient { body['SessionID'] = SESSION_ID; //getSe int projectID = await sharedPref.getInt(PROJECT_ID); - if(projectID ==2 || projectID == 3) + if (projectID == 2 || projectID == 3) body['PatientOutSA'] = true; else body['PatientOutSA'] = false; diff --git a/lib/config/config.dart b/lib/config/config.dart index ec8efe26..3e8bbcb5 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -283,6 +283,11 @@ const GET_SICK_LEAVE_PATIENT = "Services/Patients.svc/REST/GetPatientSickLeave"; const GET_MY_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GetMyOutPatient"; + +const PATIENT_MEDICAL_REPORT_GET_LIST = "Services/Patients.svc/REST/DAPP_ListMedicalReport"; +const PATIENT_MEDICAL_REPORT_INSERT = "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; +const PATIENT_MEDICAL_REPORT_VERIFIED = "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ @@ -337,7 +342,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 6.0; +const VERSION_ID = 6.1; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7591bfda..d22358b1 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -977,4 +977,8 @@ const Map> localizedValues = { "medicalReportAdd": {"en": "Add Medical Report", "ar": "إضافة تقرير طبي"}, "medicalReportVerify": {"en": "Verify Medical Report", "ar": "تحقق من التقرير الطبي"}, "comments": {"en": "Comments", "ar": "تعليقات"}, + "createNewMedicalReport": {"en": "Create New Medical Report", "ar": "إنشاء تقرير طبي جديد"}, + "historyPhysicalFinding": {"en": "History and Physical Finding", "ar": "التاريخ والاكتشاف المادي"}, + "laboratoryPhysicalData": {"en": "Laboratory and Physical Data", "ar": "المعامل والبيانات الفيزيائية"}, + "impressionRecommendation": {"en": "Impression and Recommendation", "ar": "الانطباع والتوصية"}, }; diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart new file mode 100644 index 00000000..64cce97a --- /dev/null +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -0,0 +1,65 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class PatientMedicalReportService extends BaseService { + List medicalReportList = []; + + Future getMedicalReportList(PatiantInformtion patient) async { + hasError = false; + Map body = Map(); + body['TokenID'] = "@dm!n"; + body['SetupID'] = "91877"; + body['AdmissionNo'] = patient.admissionNo; + + await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, + onSuccess: (dynamic response, int statusCode) { + + medicalReportList.clear(); + if (response['DAPP_ListMedicalReportList'] != null) { + response['DAPP_ListMedicalReportList'].forEach((v) { + medicalReportList.add(MedicalReportModel.fromJson(v)); + }); + } + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error.toString(); + }, body: body, patient: patient); + } + + Future insertMedicalReport(PatiantInformtion patient, String htmlText) async { + hasError = false; + Map body = Map(); + body['TokenID'] = "@dm!n"; + body['SetupID'] = "91877"; + body['AdmissionNo'] = patient.admissionNo; + body['MedicalReportHTML'] = htmlText; + + await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_INSERT, + onSuccess: (dynamic response, int statusCode) { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error.toString(); + }, body: body, patient: patient); + } + + Future verifyMedicalReport(PatiantInformtion patient, MedicalReportModel medicalReport) async { + hasError = false; + Map body = Map(); + body['TokenID'] = "@dm!n"; + body['SetupID'] = "91877"; + body['AdmissionNo'] = patient.admissionNo; + body['InvoiceNo'] = medicalReport.invoiceNo; + body['LineItemNo'] = medicalReport.lineItemNo; + + await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_VERIFIED, + onSuccess: (dynamic response, int statusCode) { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error.toString(); + }, body: body, patient: patient); + } +} diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart new file mode 100644 index 00000000..8d7b5c63 --- /dev/null +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -0,0 +1,43 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +import '../../locator.dart'; + +class PatientMedicalReportViewModel extends BaseViewModel { + PatientMedicalReportService _service = locator(); + + List get medicalReportList => _service.medicalReportList; + + Future getMedicalReportList(PatiantInformtion patient) async { + setState(ViewState.Busy); + await _service.getMedicalReportList(patient); + if (_service.hasError) { + error = _service.error; + setState(ViewState.ErrorLocal); // ViewState.Error + } else + setState(ViewState.Idle); + } + + Future insertMedicalReport(PatiantInformtion patient, String htmlText)async { + setState(ViewState.Busy); + await _service.insertMedicalReport(patient, htmlText); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future verifyMedicalReport(PatiantInformtion patient, MedicalReportModel medicalReport) async { + setState(ViewState.Busy); + await _service.verifyMedicalReport(patient, medicalReport); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/locator.dart b/lib/locator.dart index 321b3ffa..f885d4c4 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -15,6 +15,7 @@ import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; import 'core/service/patient/MyReferralPatientService.dart'; import 'core/service/patient/PatientMuseService.dart'; import 'core/service/patient/ReferralService.dart'; +import 'core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart'; import 'core/service/patient_medical_file/medical_report/medical_file_service.dart'; import 'core/service/patient_medical_file/prescription/prescription_service.dart'; import 'core/service/patient_medical_file/procedure/procedure_service.dart'; @@ -36,6 +37,7 @@ import 'core/service/patient/referred_patient_service.dart'; import 'core/service/home/schedule_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; +import 'core/viewModel/PatientMedicalReportViewModel.dart'; import 'core/viewModel/PatientMuseViewModel.dart'; import 'core/viewModel/PatientSearchViewModel.dart'; import 'core/viewModel/SOAP_view_model.dart'; @@ -84,6 +86,7 @@ void setupLocator() { locator.registerLazySingleton(() => DischargedPatientService()); locator.registerLazySingleton(() => PatientInPatientService()); locator.registerLazySingleton(() => OutPatientService()); + locator.registerLazySingleton(() => PatientMedicalReportService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -110,4 +113,5 @@ void setupLocator() { locator.registerFactory(() => PrescriptionsViewModel()); locator.registerFactory(() => DischargedPatientViewModel()); locator.registerFactory(() => PatientSearchViewModel()); + locator.registerFactory(() => PatientMedicalReportViewModel()); } diff --git a/lib/models/patient/MedicalReport/MeidcalReportModel.dart b/lib/models/patient/MedicalReport/MeidcalReportModel.dart new file mode 100644 index 00000000..450b93f6 --- /dev/null +++ b/lib/models/patient/MedicalReport/MeidcalReportModel.dart @@ -0,0 +1,60 @@ +class MedicalReportModel { + String reportData; + String setupID; + int projectID; + int patientID; + String invoiceNo; + int status; + String verifiedOn; + int verifiedBy; + String editedOn; + int editedBy; + int lineItemNo; + String reportDataHtml; + + MedicalReportModel( + {this.reportData, + this.setupID, + this.projectID, + this.patientID, + this.invoiceNo, + this.status, + this.verifiedOn, + this.verifiedBy, + this.editedOn, + this.editedBy, + this.lineItemNo, + this.reportDataHtml}); + + MedicalReportModel.fromJson(Map json) { + reportData = json['ReportData']; + setupID = json['SetupID']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + invoiceNo = json['InvoiceNo']; + status = json['Status']; + verifiedOn = json['VerifiedOn']; + verifiedBy = json['VerifiedBy']; + editedOn = json['EditedOn']; + editedBy = json['EditedBy']; + lineItemNo = json['LineItemNo']; + reportDataHtml = json['ReportDataHtml']; + } + + Map toJson() { + final Map data = new Map(); + data['ReportData'] = this.reportData; + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['InvoiceNo'] = this.invoiceNo; + data['Status'] = this.status; + data['VerifiedOn'] = this.verifiedOn; + data['VerifiedBy'] = this.verifiedBy; + data['EditedOn'] = this.editedOn; + data['EditedBy'] = this.editedBy; + data['LineItemNo'] = this.lineItemNo; + data['ReportDataHtml'] = this.reportDataHtml; + return data; + } +} diff --git a/lib/routes.dart b/lib/routes.dart index 2684cd82..c0168762 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -5,6 +5,9 @@ import 'package:doctor_app_flutter/screens/patients/insurance_approval_screen_pa import 'package:doctor_app_flutter/screens/patients/profile/UCAF/UCAF-detail-screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/UCAF/UCAF-input-screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/lab_result/labs_home_page.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/medical_report/MedicalReportDetailPage.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/medical_report/MedicalReportPage.dart'; import 'package:doctor_app_flutter/screens/patients/profile/note/progress_note_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/prescriptions/in_patient_prescription_details_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/radiology/radiology_home_page.dart'; @@ -51,6 +54,9 @@ const String UPDATE_EPISODE = 'patients/update-episode'; const String PATIENT_ADMISSION_REQUEST = 'patients/admission-request'; const String PATIENT_ADMISSION_REQUEST_2 = 'patients/admission-request-second'; const String PATIENT_ADMISSION_REQUEST_3 = 'patients/admission-request-third'; +const String PATIENT_MEDICAL_REPORT = 'patients/medical-report'; +const String PATIENT_MEDICAL_REPORT_INSERT = 'patients/medical-report-insert'; +const String PATIENT_MEDICAL_REPORT_DETAIL = 'patients/medical-report-detail'; const String PATIENT_UCAF_REQUEST = 'patients/ucaf'; const String PATIENT_UCAF_DETAIL = 'patients/ucaf/detail'; const String PATIENT_ECG = 'patients/ecg'; @@ -79,6 +85,9 @@ var routes = { PATIENT_ADMISSION_REQUEST: (_) => AdmissionRequestFirstScreen(), PATIENT_ADMISSION_REQUEST_2: (_) => AdmissionRequestSecondScreen(), PATIENT_ADMISSION_REQUEST_3: (_) => AdmissionRequestThirdScreen(), + PATIENT_MEDICAL_REPORT: (_) => MedicalReportPage(), + PATIENT_MEDICAL_REPORT_INSERT: (_) => AddVerifyMedicalReport(), + PATIENT_MEDICAL_REPORT_DETAIL: (_) => MedicalReportDetailPage(), CREATE_EPISODE: (_) => UpdateSoapIndex( isUpdate: true, ), diff --git a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart index 8627d224..bea487f7 100644 --- a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart @@ -477,7 +477,7 @@ class _AdmissionRequestSecondScreenState Expanded( child: AppButton( title: TranslationBase.of(context).previous, - color: HexColor("#EAEAEA"), + color: Color(0xffEAEAEA), fontColor: Colors.black, onPressed: () { Navigator.pop(context); diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 1b33aecb..f562f7b2 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -1,8 +1,9 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; -import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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/shared/app_scaffold_widget.dart'; @@ -16,21 +17,25 @@ import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; class AddVerifyMedicalReport extends StatefulWidget { - final MedicalReportStatus status; - - AddVerifyMedicalReport(this.status); - @override _AddVerifyMedicalReportState createState() => _AddVerifyMedicalReportState(); } class _AddVerifyMedicalReportState extends State { - stt.SpeechToText speech = stt.SpeechToText(); - var reconizedWord; + stt.SpeechToText speechHistoryFinding = stt.SpeechToText(); + stt.SpeechToText speechLaboratoryData = stt.SpeechToText(); + stt.SpeechToText speechRecommendation = stt.SpeechToText(); + var recognizedWord1; + var recognizedWord2; + var recognizedWord3; var event = RobotProvider(); - TextEditingController commentController = TextEditingController(); + TextEditingController historyFindingController = TextEditingController(); + TextEditingController laboratoryDataController = TextEditingController(); + TextEditingController recommendationController = TextEditingController(); String commentsError; + String comments2Error; + String comments3Error; @override void initState() { @@ -38,7 +43,15 @@ class _AddVerifyMedicalReportState extends State { event.controller.stream.listen((p) { if (p['startPopUp'] == 'true') { if (this.mounted) { - initSpeechState().then((value) => {onVoiceText()}); + initSpeechState().then((value) { + onVoiceText(); + }); + initSpeechState2().then((value) { + onVoiceText2(); + }); + initSpeechState3().then((value) { + onVoiceText3(); + }); } } }); @@ -48,79 +61,201 @@ class _AddVerifyMedicalReportState extends State { @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); + final routeArgs = ModalRoute.of(context).settings.arguments as Map; + PatiantInformtion patient = routeArgs['patient']; + MedicalReportStatus status = routeArgs['status']; - return BaseView( + return BaseView( builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBarTitle: widget.status == MedicalReportStatus.ADD + appBarTitle: status == MedicalReportStatus.ADD ? TranslationBase.of(context).medicalReportAdd : TranslationBase.of(context).medicalReportVerify, backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: Column( children: [ Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Stack( - children: [ - AppTextFieldCustom( - hintText: TranslationBase.of(context) - .sickLeaveComments, - controller: commentController, - maxLines: 30, - minLines: 20, - hasBorder: true, - validationError: commentsError, - ), - Positioned( - top: -2, - //MediaQuery.of(context).size.height * 0, - right: projectViewModel.isArabic - ? MediaQuery.of(context).size.width * - 0.75 - : 15, - child: Column( + child: Container( + margin: EdgeInsets.all(16), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + AppTextFieldCustom( + hintText: TranslationBase.of(context) + .historyPhysicalFinding, + controller: historyFindingController, + maxLines: 15, + minLines: 10, + hasBorder: true, + validationError: commentsError, + ), + Positioned( + top: -2, + //MediaQuery.of(context).size.height * 0, + right: projectViewModel.isArabic + ? MediaQuery.of(context) + .size + .width * + 0.75 + : 15, + child: Column( + children: [ + IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35), + onPressed: () { + initSpeechState().then( + (value) => + {onVoiceText()}); + }, + ), + ], + )), + ], + ), + Stack( + children: [ + AppTextFieldCustom( + hintText: TranslationBase.of(context) + .laboratoryPhysicalData, + controller: laboratoryDataController, + maxLines: 15, + minLines: 10, + hasBorder: true, + validationError: comments2Error, + ), + Positioned( + top: -2, + //MediaQuery.of(context).size.height * 0, + right: projectViewModel.isArabic + ? MediaQuery.of(context) + .size + .width * + 0.75 + : 15, + child: Column( + children: [ + IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35), + onPressed: () { + initSpeechState2().then( + (value) => + {onVoiceText2()}); + }, + ), + ], + )), + ], + ), + Stack( children: [ - IconButton( - icon: Icon(DoctorApp.speechtotext, - color: Colors.black, size: 35), - onPressed: () { - initSpeechState().then( - (value) => {onVoiceText()}); - }, + AppTextFieldCustom( + hintText: TranslationBase.of(context) + .impressionRecommendation, + controller: recommendationController, + maxLines: 15, + minLines: 10, + hasBorder: true, + validationError: comments3Error, ), + Positioned( + top: -2, + //MediaQuery.of(context).size.height * 0, + right: projectViewModel.isArabic + ? MediaQuery.of(context) + .size + .width * + 0.75 + : 15, + child: Column( + children: [ + IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35), + onPressed: () { + initSpeechState3().then( + (value) => + {onVoiceText3()}); + }, + ), + ], + )), ], - )), - ], + ), + ], + ), + ), ), - ], - ), + ), + ], ), ), ), Container( - margin: EdgeInsets.all(16.0), - child: AppButton( - title: widget.status == MedicalReportStatus.ADD - ? TranslationBase.of(context).medicalReportAdd - : TranslationBase.of(context).medicalReportVerify, - color: Color(0xff359846), - // disabled: progressNoteController.text.isEmpty, - fontWeight: FontWeight.w700, - onPressed: () { - setState(() { - if (commentController.text == "") { - commentsError = - TranslationBase.of(context).fieldRequired; - } else { - commentsError = null; - } - }); - }, + padding: EdgeInsets.all(16.0), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: AppButton( + title: status == MedicalReportStatus.ADD + ? TranslationBase.of(context).save + : TranslationBase.of(context).save, + color: Color(0xffEAEAEA), + fontColor: Colors.black, + // disabled: progressNoteController.text.isEmpty, + fontWeight: FontWeight.w700, + onPressed: () { + setState(() { + if (historyFindingController.text == "") { + commentsError = + TranslationBase.of(context).fieldRequired; + } else { + commentsError = null; + } + }); + }, + ), + ), + SizedBox( + width: 8, + ), + Expanded( + child: AppButton( + title: status == MedicalReportStatus.ADD + ? TranslationBase.of(context).add + : TranslationBase.of(context).verify, + color: Color(0xff359846), + // disabled: progressNoteController.text.isEmpty, + fontWeight: FontWeight.w700, + onPressed: () { + setState(() { + if (historyFindingController.text == "") { + commentsError = + TranslationBase.of(context).fieldRequired; + } else { + commentsError = null; + } + }); + }, + ), + ), + ], ), ), ], @@ -131,10 +266,10 @@ class _AddVerifyMedicalReportState extends State { onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speech.initialize( + bool available = await speechHistoryFinding.initialize( onStatus: statusListener, onError: errorListener); if (available) { - speech.listen( + speechHistoryFinding.listen( onResult: resultListener, listenMode: stt.ListenMode.confirmation, localeId: lang == 'en' ? 'en-US' : 'ar-SA', @@ -144,6 +279,38 @@ class _AddVerifyMedicalReportState extends State { } } + onVoiceText2() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speechLaboratoryData.initialize( + onStatus: statusListener, onError: errorListener); + if (available) { + speechLaboratoryData.listen( + onResult: resultListener2, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + + onVoiceText3() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speechRecommendation.initialize( + onStatus: statusListener, onError: errorListener); + if (available) { + speechRecommendation.listen( + onResult: resultListener3, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + void errorListener(SpeechRecognitionError error) { event.setValue({"searchText": 'null'}); //SpeechToText.closeAlertDialog(context); @@ -151,7 +318,9 @@ class _AddVerifyMedicalReportState extends State { } void statusListener(String status) { - reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; + recognizedWord1 = status == 'listening' ? 'Lisening...' : 'Sorry....'; + recognizedWord2 = status == 'listening' ? 'Lisening...' : 'Sorry....'; + recognizedWord3 = status == 'listening' ? 'Lisening...' : 'Sorry....'; } void requestPermissions() async { @@ -161,14 +330,44 @@ class _AddVerifyMedicalReportState extends State { } void resultListener(result) { - reconizedWord = result.recognizedWords; - event.setValue({"searchText": reconizedWord}); + recognizedWord1 = result.recognizedWords; + event.setValue({"searchText": recognizedWord1}); + + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speechHistoryFinding.stop(); + historyFindingController.text += recognizedWord1 + '\n'; + }); + } else { + print(result.finalResult); + } + } + + void resultListener2(result) { + recognizedWord2 = result.recognizedWords; + event.setValue({"searchText": recognizedWord2}); + + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speechLaboratoryData.stop(); + laboratoryDataController.text += recognizedWord2 + '\n'; + }); + } else { + print(result.finalResult); + } + } + + void resultListener3(result) { + recognizedWord3 = result.recognizedWords; + event.setValue({"searchText": recognizedWord3}); if (result.finalResult == true) { setState(() { SpeechToText.closeAlertDialog(context); - speech.stop(); - commentController.text += reconizedWord + '\n'; + speechRecommendation.stop(); + recommendationController.text += recognizedWord3 + '\n'; }); } else { print(result.finalResult); @@ -176,7 +375,21 @@ class _AddVerifyMedicalReportState extends State { } Future initSpeechState() async { - bool hasSpeech = await speech.initialize( + bool hasSpeech = await speechHistoryFinding.initialize( + onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } + + Future initSpeechState2() async { + bool hasSpeech = await speechLaboratoryData.initialize( + onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } + + Future initSpeechState3() async { + bool hasSpeech = await speechRecommendation.initialize( onError: errorListener, onStatus: statusListener); print(hasSpeech); if (!mounted) return; diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 8dad1bc4..1701feac 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -1,6 +1,10 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/date-utils.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -12,118 +16,125 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../../../routes.dart'; +import 'AddVerifyMedicalReport.dart'; + class MedicalReportPage extends StatelessWidget { @override Widget build(BuildContext context) { final routeArgs = ModalRoute.of(context).settings.arguments as Map; PatiantInformtion patient = routeArgs['patient']; String patientType = routeArgs['patientType']; - bool isInpatient = routeArgs['isInpatient']; + String arrivalType = routeArgs['arrivalType']; ProjectViewModel projectViewModel = Provider.of(context); - //TODO Jammal - return AppScaffold( - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patient.patientType.toString() ?? '0', - patientType, - isInpatient: isInpatient, - ), - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Column( - children: [ - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - "Medical", - style: "caption2", - color: Colors.black, - fontSize: 13, - ), - AppText( - "Report", - bold: true, - fontSize: 22, - ), - ], - ), - ), - AddNewOrder( - onTap: () { - }, - label: "Create New Medical Report", - ), - ...List.generate( - /*model.patientLabOrdersList.length,*/1, - (index) => CardWithBgWidget( - hasBorder: false, - bgColor: 0==0? Colors.red[700]:Colors.green[700], - widget: Column( - children: [ - Row( - children: [ - Expanded( + return BaseView( + onModelReady: (model) => model.getMedicalReportList(patient), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: true, + appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType,), + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + "${TranslationBase.of(context).medical}", + fontSize: SizeConfig.textMultiplier * 1.6, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A), + ), + AppText( + TranslationBase.of(context).report, + fontSize: SizeConfig.textMultiplier * 3, + fontWeight: FontWeight.bold, + color: Color(0xFF2E303A), + ) + ], + ), + ), + AddNewOrder( + onTap: () { + Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'type': MedicalReportStatus.ADD + }); + }, + label: TranslationBase.of(context).createNewMedicalReport, + ), + ...List.generate( + /*model.patientLabOrdersList.length,*/1, + (index) => CardWithBgWidget( + hasBorder: false, + bgColor: 0==0? Colors.red[700]:Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText('On Hold',color: Colors.red,), + AppText( + "Jammal" ?? "", + fontSize: 15, + bold: true, + ), + ], + )), + Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, children: [ - AppText('On Hold',color: Colors.red,), AppText( - "Jammal" ?? "", - fontSize: 15, - bold: true, - ), - ], - )), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 14, - ), - AppText( - '${AppDateUtils.getHour(DateTime.now())}', + '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', + color: Colors.black, fontWeight: FontWeight.w600, - color: Colors.grey[700], fontSize: 14, ), - ], + AppText( + '${AppDateUtils.getHour(DateTime.now())}', + fontWeight: FontWeight.w600, + color: Colors.grey[700], + fontSize: 14, + ), + ], + ), ), - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - child: LargeAvatar( - name: "Jammal", - url: null, + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: LargeAvatar( + name: "Jammal", + url: null, + ), + width: 55, + height: 55, ), - width: 55, - height: 55, - ), - Expanded(child: AppText("")), - Icon( - EvaIcons.eye, - ) - ], - ), - ], + Expanded(child: AppText("")), + Icon( + EvaIcons.eye, + ) + ], + ), + ], + ), ), - ), - ) - ], + ) + ], + ), ), ), ); diff --git a/lib/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart b/lib/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart index 1df7d236..49fa8012 100644 --- a/lib/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart +++ b/lib/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart @@ -88,10 +88,10 @@ class ProfileGridForInPatient extends StatelessWidget { PatientProfileCardModel( TranslationBase.of(context).medical, TranslationBase.of(context).report, - HEALTH_SUMMARY, + PATIENT_MEDICAL_REPORT, 'patient/health_summary.png', isInPatient: isInpatient, - isDisable: true), + isDisable: false), PatientProfileCardModel( TranslationBase.of(context).referral, TranslationBase.of(context).patient, diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 8c2bf15b..b9c64c17 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1332,6 +1332,10 @@ class TranslationBase { String get medicalReportAdd => localizedValues['medicalReportAdd'][locale.languageCode]; String get medicalReportVerify => localizedValues['medicalReportVerify'][locale.languageCode]; String get comments => localizedValues['comments'][locale.languageCode]; + String get createNewMedicalReport => localizedValues['createNewMedicalReport'][locale.languageCode]; + String get historyPhysicalFinding => localizedValues['historyPhysicalFinding'][locale.languageCode]; + String get laboratoryPhysicalData => localizedValues['laboratoryPhysicalData'][locale.languageCode]; + String get impressionRecommendation => localizedValues['impressionRecommendation'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 3b800bcd1986b9aa604d4a3f536b8ca30656297b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 17 May 2021 15:10:37 +0300 Subject: [PATCH 043/241] favourite procedure templates --- lib/config/config.dart | 2 +- .../procedures/add-favourite-procedure.dart | 0 .../procedures/add-procedure-form.dart | 590 +++++++++--------- .../procedures/add_procedure_homeScreen.dart | 215 +++++++ lib/screens/procedures/procedure_screen.dart | 3 +- 5 files changed, 516 insertions(+), 294 deletions(-) create mode 100644 lib/screens/procedures/add-favourite-procedure.dart create mode 100644 lib/screens/procedures/add_procedure_homeScreen.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index acb9e1c7..5b9f594a 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,7 +5,7 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +//const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index df748922..2b62d2bf 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -145,307 +145,313 @@ class _AddSelectedProcedureState extends State { builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: - (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + ), + Expanded( + child: NetworkBaseView( + baseViewModel: model, + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: (BuildContext context, + ScrollController scrollController) { + return SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppText( - TranslationBase.of(context) - .pleaseEnterProcedure, - fontWeight: FontWeight.w700, - fontSize: 20, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + AppText( + TranslationBase.of(context) + .pleaseEnterProcedure, + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ]), + SizedBox( + height: + MediaQuery.of(context).size.height * 0.04, ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Row( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.85, - child: AppTextFieldCustom( - hintText: TranslationBase.of(context) - .searchProcedureHere, - isTextFieldHasSuffix: false, + Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * + 0.81, + child: AppTextFieldCustom( + hintText: TranslationBase.of(context) + .searchProcedureHere, + isTextFieldHasSuffix: false, - maxLines: 1, - minLines: 1, - hasBorder: true, - controller: procedureName, - // onSubmitted: (_) { - // model.getProcedureCategory( - // categoryName: procedureName.text); - // }, - onClick: () { - if (procedureName.text.isNotEmpty && - procedureName.text.length >= 3) - model.getProcedureCategory( - categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .atLeastThreeCharacters, - ); - }, + maxLines: 1, + minLines: 1, + hasBorder: true, + controller: procedureName, + // onSubmitted: (_) { + // model.getProcedureCategory( + // categoryName: procedureName.text); + // }, + onClick: () { + if (procedureName.text.isNotEmpty && + procedureName.text.length >= 3) + model.getProcedureCategory( + categoryName: + procedureName.text); + else + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .atLeastThreeCharacters, + ); + }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * + 0.02, + ), + InkWell( + onTap: () { + if (procedureName.text.isNotEmpty && + procedureName.text.length >= 3) + model.getProcedureCategory( + categoryName: procedureName.text); + else + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .atLeastThreeCharacters, + ); + }, + child: Icon( + Icons.search, + size: 25.0, + ), + ), + ], ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.02, - ), - InkWell( - onTap: () { - if (procedureName.text.isNotEmpty && - procedureName.text.length >= 3) - model.getProcedureCategory( - categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .atLeastThreeCharacters, - ); - }, - child: Icon( - Icons.search, - size: 25.0, + // SizedBox( + // width: MediaQuery.of(context).size.width * 0.29, + // ), + // InkWell( + // child: Icon( + // Icons.close, + // size: 24.0, + // ), + // onTap: () { + // Navigator.pop(context); + // }, + // ), + // ], + // ), + // SizedBox( + // height: 10.0, + // ), + // Container( + // height: screenSize.height * 0.070, + // child: InkWell( + // onTap: model.categoryList != null && + // model.categoryList.length > 0 + // ? () { + // ListSelectDialog dialog = + // ListSelectDialog( + // list: model.categoryList, + // attributeName: 'categoryName', + // attributeValueId: 'categoryId', + // okText: TranslationBase.of(context).ok, + // okFunction: (selectedValue) { + // setState(() { + // selectedCategory = selectedValue; + // model.getProcedureCategory( + // categoryName: selectedCategory[ + // 'categoryName'], + // categoryID: selectedCategory[ + // 'categoryId'] <= + // 9 + // ? "0" + + // selectedCategory[ + // 'categoryId'] + // .toString() + // : selectedCategory[ + // 'categoryId'] + // .toString()); + // }); + // }, + // ); + // showDialog( + // barrierDismissible: false, + // context: context, + // builder: (BuildContext context) { + // return dialog; + // }, + // ); + // //model.getProcedureCategory(); + // } + // : null, + // child: TextField( + // decoration: textFieldSelectorDecoration( + // TranslationBase.of(context) + // .procedureCategorise, + // selectedCategory != null + // ? selectedCategory['categoryName'] + // : null, + // true, + // suffixIcon: Icon( + // Icons.search, + // color: Colors.black, + // )), + // enabled: false, + // ), + // ), + // ), + if (procedureName.text.isNotEmpty && + model.procedureList.length != 0) + NetworkBaseView( + baseViewModel: model, + child: + // selectedCategory != null + // ? selectedCategory['categoryId'] == 02 || + // selectedCategory['categoryId'] == 03 + // ? + EntityListCheckboxSearchWidget( + model: widget.model, + masterList: widget + .model.categoriesList[0].entityList, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), + ) + // : ProcedureListWidget( + // model: widget.model, + // masterList: widget.model + // .categoriesList[0].entityList, + // removeHistory: (item) { + // setState(() { + // entityList.remove(item); + // }); + // }, + // addHistory: (history) { + // setState(() { + // entityList.add(history); + // }); + // }, + // addSelectedHistories: () { + // //TODO build your fun herr + // // widget.addSelectedHistories(); + // }, + // isEntityListSelected: (master) => + // isEntityListSelected(master), + // ) + // : null, + ), + SizedBox( + height: 15.0, ), - ), - ], - ), - // SizedBox( - // width: MediaQuery.of(context).size.width * 0.29, - // ), - // InkWell( - // child: Icon( - // Icons.close, - // size: 24.0, - // ), - // onTap: () { - // Navigator.pop(context); - // }, - // ), - // ], - // ), - // SizedBox( - // height: 10.0, - // ), - // Container( - // height: screenSize.height * 0.070, - // child: InkWell( - // onTap: model.categoryList != null && - // model.categoryList.length > 0 - // ? () { - // ListSelectDialog dialog = - // ListSelectDialog( - // list: model.categoryList, - // attributeName: 'categoryName', - // attributeValueId: 'categoryId', - // okText: TranslationBase.of(context).ok, - // okFunction: (selectedValue) { - // setState(() { - // selectedCategory = selectedValue; - // model.getProcedureCategory( - // categoryName: selectedCategory[ - // 'categoryName'], - // categoryID: selectedCategory[ - // 'categoryId'] <= - // 9 - // ? "0" + - // selectedCategory[ - // 'categoryId'] - // .toString() - // : selectedCategory[ - // 'categoryId'] - // .toString()); - // }); - // }, - // ); - // showDialog( - // barrierDismissible: false, - // context: context, - // builder: (BuildContext context) { - // return dialog; - // }, - // ); - // //model.getProcedureCategory(); - // } - // : null, - // child: TextField( - // decoration: textFieldSelectorDecoration( - // TranslationBase.of(context) - // .procedureCategorise, - // selectedCategory != null - // ? selectedCategory['categoryName'] - // : null, - // true, - // suffixIcon: Icon( - // Icons.search, - // color: Colors.black, - // )), - // enabled: false, - // ), - // ), - // ), - if (procedureName.text.isNotEmpty && - model.procedureList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: - // selectedCategory != null - // ? selectedCategory['categoryId'] == 02 || - // selectedCategory['categoryId'] == 03 - // ? - EntityListCheckboxSearchWidget( - model: widget.model, - masterList: - widget.model.categoriesList[0].entityList, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => - isEntityListSelected(master), + Column( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + // Container( + // child: Row( + // children: [ + // AppText( + // TranslationBase.of(context).orderType), + // Radio( + // activeColor: Color(0xFFB9382C), + // value: 1, + // groupValue: selectedType, + // onChanged: (value) { + // setSelectedType(value); + // }, + // ), + // Text('routine'), + // Radio( + // activeColor: Color(0xFFB9382C), + // groupValue: selectedType, + // value: 0, + // onChanged: (value) { + // setSelectedType(value); + // }, + // ), + // Text(TranslationBase.of(context).urgent), + // ], + // ), + // ), + // SizedBox( + // height: 15.0, + // ), + // TextFields( + // hintText: TranslationBase.of(context).remarks, + // controller: remarksController, + // minLines: 3, + // maxLines: 5, + // ), + SizedBox( + height: 100.0, + ), + ], ) - // : ProcedureListWidget( - // model: widget.model, - // masterList: widget.model - // .categoriesList[0].entityList, - // removeHistory: (item) { - // setState(() { - // entityList.remove(item); - // }); - // }, - // addHistory: (history) { - // setState(() { - // entityList.add(history); - // }); - // }, - // addSelectedHistories: () { - // //TODO build your fun herr - // // widget.addSelectedHistories(); - // }, - // isEntityListSelected: (master) => - // isEntityListSelected(master), - // ) - // : null, - ), - SizedBox( - height: 15.0, + ], + ), ), - Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // Container( - // child: Row( - // children: [ - // AppText( - // TranslationBase.of(context).orderType), - // Radio( - // activeColor: Color(0xFFB9382C), - // value: 1, - // groupValue: selectedType, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text('routine'), - // Radio( - // activeColor: Color(0xFFB9382C), - // groupValue: selectedType, - // value: 0, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text(TranslationBase.of(context).urgent), - // ], - // ), - // ), - // SizedBox( - // height: 15.0, - // ), - // TextFields( - // hintText: TranslationBase.of(context).remarks, - // controller: remarksController, - // minLines: 3, - // maxLines: 5, - // ), - SizedBox( - height: 100.0, - ), - ], - ) - ], - ), - ), - ), - ); - }), - ), - bottomSheet: Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addSelectedProcedures, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () { - //print(entityList.toString()); - onPressed: - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .fillTheMandatoryProcedureDetails, - ); - return; - } + ), + ); + }), + ), + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: TranslationBase.of(context).addSelectedProcedures, + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () { + //print(entityList.toString()); + onPressed: + if (entityList.isEmpty == true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .fillTheMandatoryProcedureDetails, + ); + return; + } - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, + Navigator.pop(context); + postProcedure( + orderType: selectedType.toString(), + entityList: entityList, + patient: patient, + model: widget.model, + remarks: remarksController.text); + }, + ), + ], ), - ], - ), + ), + ], ), ), ); diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/add_procedure_homeScreen.dart new file mode 100644 index 00000000..13695747 --- /dev/null +++ b/lib/screens/procedures/add_procedure_homeScreen.dart @@ -0,0 +1,215 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class AddProcedureHome extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + const AddProcedureHome({Key key, this.model, this.patient}) : super(key: key); + @override + _AddProcedureHomeState createState() => + _AddProcedureHomeState(patient: patient, model: model); +} + +class _AddProcedureHomeState extends State + with SingleTickerProviderStateMixin { + _AddProcedureHomeState({this.patient, this.model}); + ProcedureViewModel model; + PatiantInformtion patient; + TabController _tabController; + int _activeTab = 0; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + _tabController.addListener(_handleTabSelection); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + _handleTabSelection() { + setState(() { + _activeTab = _tabController.index; + }); + } + + @override + Widget build(BuildContext context) { + //final routeArgs = ModalRoute.of(context).settings.arguments as Map; + //PatiantInformtion patient = routeArgs['patient']; + final screenSize = MediaQuery.of(context).size; + return BaseView( + //onModelReady: (model) => model.getCategory(), + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: NetworkBaseView( + baseViewModel: model, + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: + (BuildContext context, ScrollController scrollController) { + return Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText( + 'Add Procedure', + fontWeight: FontWeight.w700, + fontSize: 20, + ), + InkWell( + child: Icon( + Icons.close, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ) + ]), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + Expanded( + child: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight( + MediaQuery.of(context).size.height * 0.070), + child: Container( + height: + MediaQuery.of(context).size.height * 0.070, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5), //width: 0.7 + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorColor: Colors.transparent, + indicatorWeight: 1.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only( + top: 0, left: 0, right: 0, bottom: 0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + tabWidget( + screenSize, + _activeTab == 0, + 'All Procedures', + ), + tabWidget( + screenSize, + _activeTab == 1, + "Favorite Templates", + ), + ], + ), + ), + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + AddSelectedProcedure( + model: model, + patient: patient, + ), + AddSelectedProcedure( + model: model, + patient: patient, + ) + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }), + ), + ), + ); + } + + Widget tabWidget(Size screenSize, bool isActive, String title, + {int counter = -1}) { + return 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: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + title, + fontSize: SizeConfig.textMultiplier * 1.5, + color: isActive ? Colors.white : Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + if (counter != -1) + Container( + margin: EdgeInsets.all(4), + width: 15, + height: 15, + decoration: BoxDecoration( + color: isActive ? Colors.white : Color(0xFFD02127), + shape: BoxShape.circle, + ), + child: Center( + child: FittedBox( + child: AppText( + "$counter", + fontSize: SizeConfig.textMultiplier * 1.5, + color: !isActive ? Colors.white : Color(0xFFD02127), + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 7e18055d..b964392e 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -6,6 +6,7 @@ import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.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/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -104,7 +105,7 @@ class ProcedureScreen extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddSelectedProcedure( + builder: (context) => AddProcedureHome( patient: patient, model: model, )), From 515955663af98f14ca49dca8763406f459cb9d86 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 17 May 2021 16:26:37 +0300 Subject: [PATCH 044/241] add verification --- lib/config/localized_values.dart | 9 +- .../viewModel/authentication_view_model.dart | 10 +- lib/core/viewModel/project_view_model.dart | 1 - lib/screens/auth/login_screen.dart | 56 +++-- .../auth/verification_methods_screen.dart | 237 +++++++++++------- lib/util/translations_delegate_base.dart | 2 + lib/widgets/auth/method_type_card.dart | 12 +- .../auth/verification_methods_list.dart | 16 +- lib/widgets/shared/app_drawer_widget.dart | 1 - 9 files changed, 211 insertions(+), 133 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d09d33f4..16be8d8e 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -576,10 +576,11 @@ const Map> localizedValues = { "ar": "الرجاء اختيار احدى الخيارات التالية للتحقق من البيانات" }, "register-user": {"en": "Register", "ar": "تسجيل"}, - "verify-with-fingerprint": {"en": "Verify through Fingerprint", "ar": "بصمة"}, - "verify-with-faceid": {"en": "Verify through Face ID", "ar": "معرف الوجه"}, - "verify-with-sms": {"en": "Verify through SMS", "ar": "الرسائل القصيرة"}, - "verify-with-whatsapp": {"en": "Verify through WhatsApp", "ar": " الواتس اب"}, + "verify-with-fingerprint": {"en": "Fingerprint", "ar": "بصمة"}, + "verify-with-faceid": {"en": "Face ID", "ar": "معرف الوجه"}, + "verify-with-sms": {"en": " SMS", "ar": "الرسائل القصيرة"}, + "verify-with-whatsapp": {"en": "WhatsApp", "ar": " الواتس اب"}, + "verify-with": {"en": "Verify through ", "ar": " الواتس اب"}, "last-login": { "en": "Last login details:", "ar": "تفاصيل تسجيل الدخول الأخير:" diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 8e9c3541..223b303b 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -188,7 +188,7 @@ class AuthenticationViewModel extends BaseViewModel { } - /// check activation + /// check activation code for sms and whats app Future checkActivationCodeForDoctorApp({String activationCode}) async { setState(ViewState.BusyLocal); CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = @@ -253,7 +253,7 @@ class AuthenticationViewModel extends BaseViewModel { } } - /// add some logic in case of send activation code is success + /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); @@ -362,7 +362,7 @@ class AuthenticationViewModel extends BaseViewModel { } setState(ViewState.Busy); var token = await _firebaseMessaging.getToken(); - if (DEVICE_TOKEN == "" && !ProjectViewModel().isLogin) { + if (DEVICE_TOKEN == "") { DEVICE_TOKEN = token; await _authService.selectDeviceImei(DEVICE_TOKEN); @@ -404,7 +404,6 @@ class AuthenticationViewModel extends BaseViewModel { String lang = await sharedPref.getString(APP_Language); await Helpers.clearSharedPref(); sharedPref.setString(APP_Language, lang); - ProjectViewModel().isLogin = false; deleteUser(); if(isSessionTimeout) await getDeviceInfoFromFirebase(); @@ -419,7 +418,8 @@ class AuthenticationViewModel extends BaseViewModel { deleteUser(){ user = null; unverified = false; - notifyListeners(); + isLogin = false; + notifyListeners(); } } diff --git a/lib/core/viewModel/project_view_model.dart b/lib/core/viewModel/project_view_model.dart index 494e3b10..f464df0e 100644 --- a/lib/core/viewModel/project_view_model.dart +++ b/lib/core/viewModel/project_view_model.dart @@ -24,7 +24,6 @@ class ProjectViewModel with ChangeNotifier { List doctorClinicsList = []; bool isLoading = false; bool isError = false; - bool isLogin = false; String error = ''; BaseAppClient baseAppClient = BaseAppClient(); diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 7fbf47af..b8d5cca3 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -401,30 +401,6 @@ class _LoginScreenState extends State { ])), ]), ), - Row( - mainAxisAlignment: MainAxisAlignment - .end, - children: [ - Expanded( - child: AppButton( - title: TranslationBase - .of(context) - .login, - color: HexColor( - '#D02127'), - disabled: authenticationViewModel.userInfo - .userID == null || - authenticationViewModel.userInfo - .password == - null, - fontWeight: FontWeight - .bold, - onPressed: () { - login(context); - }, - )), - ], - ) ], ), ) @@ -433,6 +409,38 @@ class _LoginScreenState extends State { ])) ]), ), + bottomSheet: Container( + + height: 90, + width: double.infinity, + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + AppButton( + title: TranslationBase + .of(context) + .login, + color: Color(0xFFD02127), + disabled: authenticationViewModel.userInfo + .userID == null || + authenticationViewModel.userInfo + .password == + null, + fontWeight: FontWeight + .bold, + onPressed: () { + login(context); + }, + ), + + SizedBox(height: 25,) + ], + ), + ), + ),), ); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 5aa626be..35d8366d 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -67,13 +67,24 @@ class _VerificationMethodsScreenState extends State { width: SizeConfig.realScreenWidth, child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + SizedBox( + height: 80, + ), + InkWell( + onTap: (){ + Navigator.of(context).pop(); + }, + child: Icon(Icons.arrow_back_ios,color: Color(0xFF2B353E),) + + ), Container( + child: Column( children: [ SizedBox( - height: 100, + height: 20, ), authenticationViewModel.user != null && isMoreOption == false ? Column( @@ -81,92 +92,144 @@ class _VerificationMethodsScreenState extends State { MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppText( - TranslationBase.of(context).welcomeBack), + TranslationBase.of(context).welcomeBack, + fontSize:12, + fontWeight: FontWeight.w700, + color: Color(0xFF2B353E), + ), AppText( Helpers.capitalize(authenticationViewModel.user.doctorName), - fontSize: SizeConfig.textMultiplier * 3.5, + fontSize: 24, + color: Color(0xFF2B353E), fontWeight: FontWeight.bold, ), SizedBox( height: 20, ), AppText( - TranslationBase.of(context).accountInfo, - fontSize: SizeConfig.textMultiplier * 2.5, + TranslationBase.of(context).accountInfo , + fontSize: 16, + color: Color(0xFF2E303A), fontWeight: FontWeight.w600, ), SizedBox( height: 20, ), - Card( + Container( + padding: EdgeInsets.all(15), + decoration: BoxDecoration( color: Colors.white, - child: Row( - children: [ - Flexible( - flex: 3, - child: ListTile( - title: Text( - TranslationBase.of(context) - .lastLoginAt, - overflow: - TextOverflow.ellipsis, - style: TextStyle( - fontFamily: 'Poppins', - fontWeight: - FontWeight - .w800, - fontSize: 14), - ), - subtitle: AppText( - authenticationViewModel.getType( - authenticationViewModel.user - .logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - authenticationViewModel.user.editedOn != - null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate( - authenticationViewModel.user - .editedOn)) - : authenticationViewModel.user.createdOn != - null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate(authenticationViewModel.user - .createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - fontWeight: - FontWeight.w800, - ), - subtitle: AppText( - authenticationViewModel.user.editedOn != - null - ? DateUtils.getHour( - DateUtils.convertStringToDate( - authenticationViewModel.user - .editedOn)) - : authenticationViewModel.user.createdOn != - null - ? DateUtils.getHour( - DateUtils.convertStringToDate(authenticationViewModel.user - .createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - ), - )) + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + border: Border.all( + color: HexColor('#707070'), + width: 0.1), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + + Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 16, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700,), + + ), + Row( + children: [ + AppText( + TranslationBase + .of(context) + .verifyWith, + fontSize: 14, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + AppText( + authenticationViewModel.getType( + authenticationViewModel.user + .logInTypeID, + context), + fontSize: 14, + color: Color(0xFF2B353E), + + fontWeight: FontWeight.w700, + ), + ], + ) + ], + crossAxisAlignment: CrossAxisAlignment.start,), + Column(children: [ + AppText( + authenticationViewModel.user.editedOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate( + authenticationViewModel.user + .editedOn)) + : authenticationViewModel.user.createdOn != + null + ? DateUtils.getDayMonthYearDateFormatted( + DateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 13, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700, + ), + AppText( + authenticationViewModel.user.editedOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate( + authenticationViewModel.user + .editedOn)) + : authenticationViewModel.user.createdOn != + null + ? DateUtils.getHour( + DateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ) ], - )), + crossAxisAlignment: CrossAxisAlignment.start, + + ) + ], + ), + ), + SizedBox( + height: 20, + ), + Row( + children: [ + AppText( + "Please Verify", + fontSize: 16, + color: Color(0xFF2B353E), + + fontWeight: FontWeight.w700, + ), + ], + ) ], ) : Column( @@ -175,13 +238,17 @@ class _VerificationMethodsScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ this.onlySMSBox == false - ? AppText( + ? Container( + margin: EdgeInsets.only(bottom: 20, top: 30), + child: AppText( TranslationBase.of(context) - .verifyLoginWith, - fontSize: - SizeConfig.textMultiplier * 3.5, + .verifyLoginWith, + fontSize: 18, + color: Color(0xFF2E303A), + fontWeight: FontWeight.bold, textAlign: TextAlign.left, - ) + ), + ) : AppText( TranslationBase.of(context) .verifyFingerprint2, @@ -317,15 +384,6 @@ class _VerificationMethodsScreenState extends State { ), ), bottomSheet: authenticationViewModel.user == null ? SizedBox(height: 0,) : Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), - ), - border: Border.all( - color: HexColor('#707070'), - width: 0), - ), height: 90, width: double.infinity, child: Center( @@ -338,11 +396,8 @@ class _VerificationMethodsScreenState extends State { title: TranslationBase .of(context) .useAnotherAccount, - color: Colors.red[700], + color: Color(0xFFD02127), onPressed: () { - projectsProvider.isLogin = true; - authenticationViewModel.unverified = false; - authenticationViewModel.isLogin = false; authenticationViewModel.deleteUser(); Navigator.pushAndRemoveUntil( @@ -499,8 +554,6 @@ class _VerificationMethodsScreenState extends State { if (authenticationViewModel.state == ViewState.ErrorLocal) { Helpers.showErrorToast(authenticationViewModel.error); } else { - projectsProvider.isLogin = true; - Navigator.pushAndRemoveUntil( context, FadePage( diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index ba69e104..77230e2a 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -940,6 +940,8 @@ class TranslationBase { String get verifySMS => localizedValues['verify-with-sms'][locale.languageCode]; + String get verifyWith => + localizedValues['verify-with'][locale.languageCode]; String get verifyWhatsApp => localizedValues['verify-with-whatsapp'][locale.languageCode]; diff --git a/lib/widgets/auth/method_type_card.dart b/lib/widgets/auth/method_type_card.dart index d991020c..6d091756 100644 --- a/lib/widgets/auth/method_type_card.dart +++ b/lib/widgets/auth/method_type_card.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; class MethodTypeCard extends StatelessWidget { const MethodTypeCard({ @@ -20,9 +21,15 @@ class MethodTypeCard extends StatelessWidget { child: Container( margin: EdgeInsets.all(10), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + border: Border.all( + color: HexColor('#707070'), + width: 0.1), ), + height: 170, child: Padding( padding: EdgeInsets.fromLTRB(20, 15, 20, 15), child: Column( @@ -44,7 +51,8 @@ class MethodTypeCard extends StatelessWidget { AppText( label, fontSize: 14, - fontWeight: FontWeight.w600, + color: Color(0xFF2E303A), + fontWeight: FontWeight.bold, ) ], ), diff --git a/lib/widgets/auth/verification_methods_list.dart b/lib/widgets/auth/verification_methods_list.dart index b6efe748..27dbe8bf 100644 --- a/lib/widgets/auth/verification_methods_list.dart +++ b/lib/widgets/auth/verification_methods_list.dart @@ -40,14 +40,18 @@ class _VerificationMethodsListState extends State { assetPath: 'assets/images/verify-whtsapp.png', onTap: () => {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, - label: TranslationBase.of(context).verifyWhatsApp, + label: TranslationBase + .of(context) + .verifyWith+ TranslationBase.of(context).verifyWhatsApp, ); break; case AuthMethodTypes.SMS: return MethodTypeCard( assetPath: "assets/images/verify-sms.png", onTap: () => {widget.authenticateUser(AuthMethodTypes.SMS, true)}, - label: TranslationBase.of(context).verifySMS, + label:TranslationBase + .of(context) + .verifyWith+ TranslationBase.of(context).verifySMS, ); break; case AuthMethodTypes.Fingerprint: @@ -60,7 +64,9 @@ class _VerificationMethodsListState extends State { widget.authenticateUser(AuthMethodTypes.Fingerprint, true); } }, - label: TranslationBase.of(context).verifyFingerprint, + label: TranslationBase + .of(context) + .verifyWith+TranslationBase.of(context).verifyFingerprint, ); break; case AuthMethodTypes.FaceID: @@ -72,7 +78,9 @@ class _VerificationMethodsListState extends State { widget.authenticateUser(AuthMethodTypes.FaceID, true); } }, - label: TranslationBase.of(context).verifyFaceID, + label: TranslationBase + .of(context) + .verifyWith+TranslationBase.of(context).verifyFaceID, ); break; diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index ee7f0276..e350e39d 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -173,7 +173,6 @@ class _AppDrawerState extends State { onTap: () async { Navigator.pop(context); await authenticationViewModel.logout(); - projectsProvider.isLogin = false; }, ), ], From 14a3ca86954c5dcc40f03f38c5fb4b856c2ac769 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 17 May 2021 17:22:50 +0300 Subject: [PATCH 045/241] fix login screen design --- lib/screens/auth/login_screen.dart | 339 ++++-------------- .../auth/verification_methods_screen.dart | 2 +- lib/util/helpers.dart | 2 +- .../text_fields/app-textfield-custom.dart | 3 + 4 files changed, 74 insertions(+), 272 deletions(-) diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index b8d5cca3..84517932 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -8,6 +8,7 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.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/app_text_form_field.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -23,10 +24,13 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { String platformImei; + bool allowCallApi = true; //TODO change AppTextFormField to AppTextFormFieldCustom final loginFormKey = GlobalKey(); var projectIdController = TextEditingController(); + var userIdController = TextEditingController(); + var passwordController = TextEditingController(); List projectsList = []; FocusNode focusPass = FocusNode(); FocusNode focusProject = FocusNode(); @@ -86,8 +90,9 @@ class _LoginScreenState extends State { .of(context) .drSulaimanAlHabib, style: TextStyle( + color:Color(0xFF2B353E), fontWeight: FontWeight - .w800, + .bold, fontSize: SizeConfig .isMobile ? 24 @@ -107,9 +112,8 @@ class _LoginScreenState extends State { .realScreenWidth * 0.030, fontWeight: FontWeight - .w800, - color: HexColor( - '#B8382C')), + .w600, + color: Color(0xFFD02127)), ), ]), ], @@ -132,273 +136,69 @@ class _LoginScreenState extends State { Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ - buildSizedBox(), - Padding( - child: AppText( - TranslationBase - .of(context) - .enterCredentials, - fontSize: 18, - fontWeight: FontWeight - .bold, - ), - padding: EdgeInsets.only( - top: 10, bottom: 10)), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .enterId, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - labelText: '', - borderColor: Colors - .white, - textInputAction: TextInputAction - .next, - validator: (value) { - if (value != - null && value - .isEmpty) { - return TranslationBase - .of(context) - .pleaseEnterYourID; - } - return null; - }, - onSaved: (value) { - if (value != - null) setState(() { - authenticationViewModel.userInfo - .userID = - value - .trim(); - }); - }, - onChanged: (value) { - if (value != null) - setState(() { - authenticationViewModel.userInfo - .userID = - value - .trim(); - }); - }, - onFieldSubmitted: (_) { - focusPass - .nextFocus(); - }, - ) - ])), buildSizedBox(), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .enterPassword, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - focusNode: focusPass, - obscureText: true, - borderColor: Colors - .white, - textInputAction: TextInputAction - .next, - validator: (value) { - if (value != - null && value - .isEmpty) { - return TranslationBase - .of(context) - .pleaseEnterPassword; - } - return null; - }, - onSaved: (value) { - if (value != - null) - setState(() { - authenticationViewModel.userInfo - .password = - value; - }); - }, - onChanged: (value){ - if (value != - null) - setState(() { - authenticationViewModel.userInfo - .password = - value; - }); - }, - onFieldSubmitted: (_) { - focusPass - .nextFocus(); - Helpers - .showCupertinoPicker( - context, - projectsList, - 'facilityName', - onSelectProject, - authenticationViewModel); - }, - onTap: () { - this.getProjects( - authenticationViewModel.userInfo - .userID); - }, - ) - ])), + AppTextFieldCustom( + hintText: TranslationBase.of(context).enterId, + hasBorder: true, + controller: userIdController, + onChanged: (value){ + if (value != null) + setState(() { + authenticationViewModel.userInfo + .userID = + value + .trim(); + }); + }, + ), + buildSizedBox(), + AppTextFieldCustom( + hintText: TranslationBase.of(context).enterPassword, + hasBorder: true, + isSecure: true, + controller: passwordController, + onChanged: (value){ + if (value != null) + setState(() { + authenticationViewModel.userInfo + .password = + value + .trim(); + }); + if(allowCallApi) { + this.getProjects( + authenticationViewModel.userInfo + .userID); + setState(() { + allowCallApi = false; + }); + } + }, + onClick: (){ + + }, + ), buildSizedBox(), - projectsList.length > 0 - ? Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .selectYourProject, - fontWeight: FontWeight - .w600, - )), - AppTextFormField( - focusNode: focusProject, - controller: projectIdController, - borderColor: Colors - .white, - suffixIcon: Icons - .arrow_drop_down, - onTap: () { - Helpers - .showCupertinoPicker( - context, - projectsList, - 'facilityName', - onSelectProject, - authenticationViewModel); - }, - validator: (value) { - if (value != - null && - value - .isEmpty) { - return TranslationBase - .of( - context) - .pleaseEnterYourProject; - } - return null; - }) - ])) - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius - .all( - Radius.circular( - 6.0)), - border: Border.all( - width: 1.0, - color: HexColor( - "#CCCCCC"), - ), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment - .start, - children: [ - Padding( - padding: EdgeInsets - .only( - left: 10, - top: 10), - child: AppText( - TranslationBase - .of(context) - .selectYourProject, - fontWeight: FontWeight - .w800, - fontSize: 14, - )), - AppTextFormField( - readOnly: true, - borderColor: Colors - .white, - prefix: IconButton( - icon: Icon(Icons - .arrow_drop_down), - iconSize: 30, - padding: EdgeInsets - .only( - bottom: 30), - ), - ) - ])), + AppTextFieldCustom( + hintText: TranslationBase.of(context).selectYourProject, + hasBorder: true, + controller: projectIdController, + isTextFieldHasSuffix: true, + enabled: false, + onClick: (){ + Helpers + .showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject, + authenticationViewModel); + }, + + + ), + buildSizedBox() ]), ), ], @@ -424,13 +224,12 @@ class _LoginScreenState extends State { .of(context) .login, color: Color(0xFFD02127), + fontWeight: FontWeight.w700, disabled: authenticationViewModel.userInfo .userID == null || authenticationViewModel.userInfo .password == null, - fontWeight: FontWeight - .bold, onPressed: () { login(context); }, diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 35d8366d..4edb0f44 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -396,7 +396,7 @@ class _VerificationMethodsScreenState extends State { title: TranslationBase .of(context) .useAnotherAccount, - color: Color(0xFFD02127), + color: Color(0xFFD02127),fontWeight: FontWeight.w700, onPressed: () { authenticationViewModel.deleteUser(); diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 0f8f5183..53f81ef2 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -55,7 +55,7 @@ class Helpers { ), onPressed: () { Navigator.pop(context); - onSelectFun(cupertinoPickerIndex, model); + onSelectFun(cupertinoPickerIndex); }, ) ], diff --git a/lib/widgets/shared/text_fields/app-textfield-custom.dart b/lib/widgets/shared/text_fields/app-textfield-custom.dart index ded2568d..7e13f411 100644 --- a/lib/widgets/shared/text_fields/app-textfield-custom.dart +++ b/lib/widgets/shared/text_fields/app-textfield-custom.dart @@ -26,6 +26,7 @@ class AppTextFieldCustom extends StatefulWidget { final Function(String) onChanged; final String validationError; final bool isPrscription; + final bool isSecure; AppTextFieldCustom({ this.height = 0, @@ -45,6 +46,7 @@ class AppTextFieldCustom extends StatefulWidget { this.onChanged, this.validationError, this.isPrscription = false, + this.isSecure = false, }); @override @@ -132,6 +134,7 @@ class _AppTextFieldCustomState extends State { widget.onChanged(value); } }, + obscureText: widget.isSecure ), ) : AppText( From 84a7f44b68ee18cfc302f1fa0a139bd00b10b32a Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 17 May 2021 17:31:35 +0300 Subject: [PATCH 046/241] favourite procedure templates --- .../procedures/add-favourite-procedure.dart | 150 ++++++++++ .../procedures/add_procedure_homeScreen.dart | 7 +- .../procedures/entity_list_fav_procedure.dart | 268 ++++++++++++++++++ 3 files changed, 422 insertions(+), 3 deletions(-) create mode 100644 lib/screens/procedures/entity_list_fav_procedure.dart diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index e69de29b..a424c961 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -0,0 +1,150 @@ +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/entity_list_checkbox_search_widget.dart'; +import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:flutter/cupertino.dart'; + +class AddFavouriteProcedure extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + + const AddFavouriteProcedure({Key key, this.model, this.patient}) + : super(key: key); + @override + _AddFavouriteProcedureState createState() => _AddFavouriteProcedureState(); +} + +class _AddFavouriteProcedureState extends State { + _AddFavouriteProcedureState({this.patient, this.model}); + ProcedureViewModel model; + PatiantInformtion patient; + List entityList = List(); + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getProcedureTemplate(), + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + ), + if (model.procedureList.length != 0) + NetworkBaseView( + baseViewModel: model, + child: + // selectedCategory != null + // ? selectedCategory['categoryId'] == 02 || + // selectedCategory['categoryId'] == 03 + // ? + EntityListCheckboxSearchFavProceduresWidget( + model: widget.model, + masterList: widget.model.ProcedureTemplate, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), + ) + // : ProcedureListWidget( + // model: widget.model, + // masterList: widget.model + // .categoriesList[0].entityList, + // removeHistory: (item) { + // setState(() { + // entityList.remove(item); + // }); + // }, + // addHistory: (history) { + // setState(() { + // entityList.add(history); + // }); + // }, + // addSelectedHistories: () { + // //TODO build your fun herr + // // widget.addSelectedHistories(); + // }, + // isEntityListSelected: (master) => + // isEntityListSelected(master), + // ) + // : null, + ), + SizedBox( + height: 15.0, + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Container( + // child: Row( + // children: [ + // AppText( + // TranslationBase.of(context).orderType), + // Radio( + // activeColor: Color(0xFFB9382C), + // value: 1, + // groupValue: selectedType, + // onChanged: (value) { + // setSelectedType(value); + // }, + // ), + // Text('routine'), + // Radio( + // activeColor: Color(0xFFB9382C), + // groupValue: selectedType, + // value: 0, + // onChanged: (value) { + // setSelectedType(value); + // }, + // ), + // Text(TranslationBase.of(context).urgent), + // ], + // ), + // ), + // SizedBox( + // height: 15.0, + // ), + // TextFields( + // hintText: TranslationBase.of(context).remarks, + // controller: remarksController, + // minLines: 3, + // maxLines: 5, + // ), + SizedBox( + height: 100.0, + ), + ], + ) + ], + ), + ), + ); + } + + bool isEntityListSelected(ProcedureTempleteModel masterKey) { + Iterable history = entityList + .where((element) => masterKey.templateID == element.templateID); + if (history.length > 0) { + return true; + } + return false; + } +} diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/add_procedure_homeScreen.dart index 13695747..de242cd7 100644 --- a/lib/screens/procedures/add_procedure_homeScreen.dart +++ b/lib/screens/procedures/add_procedure_homeScreen.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -147,10 +148,10 @@ class _AddProcedureHomeState extends State model: model, patient: patient, ), - AddSelectedProcedure( - model: model, + AddFavouriteProcedure( patient: patient, - ) + model: model, + ), ], ), ), diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart new file mode 100644 index 00000000..93f264ab --- /dev/null +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -0,0 +1,268 @@ +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { + final ProcedureViewModel model; + final Function addSelectedHistories; + final Function(ProcedureTempleteModel) removeHistory; + final Function(ProcedureTempleteModel) addHistory; + final Function(ProcedureTempleteModel) addRemarks; + + final bool Function(ProcedureTempleteModel) isEntityListSelected; + final List masterList; + + EntityListCheckboxSearchFavProceduresWidget( + {Key key, + this.model, + this.addSelectedHistories, + this.removeHistory, + this.masterList, + this.addHistory, + this.isEntityListSelected, + this.addRemarks}) + : super(key: key); + + @override + _EntityListCheckboxSearchFavProceduresWidgetState createState() => + _EntityListCheckboxSearchFavProceduresWidgetState(); +} + +class _EntityListCheckboxSearchFavProceduresWidgetState + extends State { + int selectedType = 0; + int typeUrgent; + int typeRegular; + + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + + List items = List(); + List remarksList = List(); + List typeList = List(); + + @override + void initState() { + items.addAll(widget.masterList); + super.initState(); + } + + TextEditingController remarksController = TextEditingController(); + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + NetworkBaseView( + baseViewModel: widget.model, + child: Container( + height: MediaQuery.of(context).size.height * 0.75, + child: Center( + child: Container( + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.white), + child: ListView( + children: [ + TextFields( + hintText: TranslationBase.of(context).searchProcedures, + suffixIcon: EvaIcons.search, + suffixIconColor: Color(0xff2B353E), + // onChanged: (value) { + // filterSearchResults(value); + // }, + hasBorder: false, + ), + SizedBox( + height: 15, + ), + items.length != 0 + ? Column( + children: items.map((historyInfo) { + return Column( + children: [ + ExpansionTile( + title: Row( + children: [ + Checkbox( + value: widget.isEntityListSelected( + historyInfo), + activeColor: Color(0xffD02127), + onChanged: (bool newValue) { + setState(() { + if (widget.isEntityListSelected( + historyInfo)) { + widget.removeHistory( + historyInfo); + } else { + widget + .addHistory(historyInfo); + } + }); + }), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 0), + child: AppText('sss', + fontSize: 14.0, + variant: "bodyText", + bold: true, + color: Color(0xff575757)), + ), + ), + ], + ), + children: [ + Container( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 12), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets + .symmetric( + horizontal: 11), + child: AppText( + TranslationBase.of( + context) + .orderType, + fontWeight: + FontWeight.w700, + color: Color(0xff2B353E), + ), + ), + ], + ), + // Row( + // children: [ + // Radio( + // activeColor: + // Color(0xFFD02127), + // value: 0, + // groupValue: selectedType, + // onChanged: (value) { + // historyInfo.type = + // setSelectedType(value) + // .toString(); + // + // historyInfo.type = + // value.toString(); + // }, + // ), + // AppText( + // 'routine', + // color: Color(0xff575757), + // fontWeight: FontWeight.w600, + // ), + // Radio( + // activeColor: + // Color(0xFFD02127), + // groupValue: selectedType, + // value: 1, + // onChanged: (value) { + // historyInfo.type = + // setSelectedType(value) + // .toString(); + // + // historyInfo.type = + // value.toString(); + // }, + // ), + // AppText( + // TranslationBase.of(context) + // .urgent, + // color: Color(0xff575757), + // fontWeight: FontWeight.w600, + // ), + // ], + // ), + ], + ), + ), + ), + SizedBox( + height: 2.0, + ), + // Padding( + // padding: EdgeInsets.symmetric( + // horizontal: 12, vertical: 12.0), + // child: TextFields( + // hintText: TranslationBase.of(context) + // .remarks, + // //controller: remarksController, + // onChanged: (value) { + // historyInfo.remarks = value; + // }, + // minLines: 3, + // maxLines: 5, + // borderWidth: 0.5, + // borderColor: Colors.grey[500], + // ), + // ), + DividerWithSpacesAround(), + ], + ), + ], + ); + }).toList(), + ) + : Center( + child: Container( + child: AppText("Sorry , No Match", + color: Color(0xFFB9382C)), + ), + ) + ], + ), + )), + ), + ), + SizedBox( + height: 10, + ), + ], + ), + ); + } + +// void filterSearchResults(String query) { +// List dummySearchList = List(); +// dummySearchList.addAll(widget.masterList); +// if (query.isNotEmpty) { +// List dummyListData = List(); +// dummySearchList.forEach((item) { +// if (item.procedureName.toLowerCase().contains(query.toLowerCase())) { +// dummyListData.add(item); +// } +// }); +// setState(() { +// items.clear(); +// items.addAll(dummyListData); +// }); +// return; +// } else { +// setState(() { +// items.clear(); +// items.addAll(widget.masterList); +// }); +// } +// } +} From 164a7fd2fc2d80118d6ea91daaace35600addb12 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 17 May 2021 17:49:02 +0300 Subject: [PATCH 047/241] fix merge issues --- ios/Podfile.lock | 2 +- lib/core/viewModel/dashboard_view_model.dart | 25 ++++++++----------- lib/locator.dart | 8 ------ .../auth/verification_methods_screen.dart | 16 ++++++------ lib/screens/home/home_screen.dart | 7 +++--- 5 files changed, 23 insertions(+), 35 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 878a1850..2f4607e0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 7d458fc7..f37a8feb 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -1,12 +1,14 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart';import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart'; +import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import '../../locator.dart'; +import 'authentication_view_model.dart'; import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { @@ -17,7 +19,7 @@ class DashboardViewModel extends BaseViewModel { List get dashboardItemsList => _dashboardService.dashboardItemsList; - Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthViewModel authProvider) async{ + Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async{ setState(ViewState.Busy); await projectsProvider.getDoctorClinicsList(); @@ -33,9 +35,7 @@ class DashboardViewModel extends BaseViewModel { _firebaseMessaging.getToken().then((String token) async { if (token != '') { DEVICE_TOKEN = token; - var request = await sharedPref.getObj(DOCTOR_PROFILE); - authProvider.insertDeviceImei(request).then((value) { - }); + authProvider.insertDeviceImei(); } }); } @@ -50,7 +50,7 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future changeClinic(int clinicId, AuthViewModel authProvider) async { + Future changeClinic(int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); await getDoctorProfile(); ProfileReqModel docInfo = new ProfileReqModel( @@ -60,14 +60,11 @@ class DashboardViewModel extends BaseViewModel { projectID: doctorProfile.projectID, tokenID: '', languageID: 2); - - await authProvider.getDocProfiles(docInfo.toJson()).then((res) async { - sharedPref.setObj(DOCTOR_PROFILE, res['DoctorProfileList'][0]); - setState(ViewState.Idle); - }).catchError((err) { - error = err; - setState(ViewState.ErrorLocal); - }); + ClinicModel clinicModel = ClinicModel(doctorID:doctorProfile.doctorID,clinicID: doctorProfile.clinicID, projectID: doctorProfile.projectID,); + await authProvider.getDoctorProfileBasedOnClinic(clinicModel); + if(authProvider.state == ViewState.ErrorLocal) { + error = authProvider.error; + } } getPatientCount(DashboardModel inPatientCount) { diff --git a/lib/locator.dart b/lib/locator.dart index a2c77373..4cb18514 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,13 +1,6 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; -import 'package:doctor_app_flutter/core/service/dasboard_service.dart'; -import 'package:doctor_app_flutter/core/service/medical_file_service.dart'; -import 'package:doctor_app_flutter/core/service/patient_service.dart'; -import 'package:doctor_app_flutter/core/service/prescription_service.dart'; -import 'package:doctor_app_flutter/core/service/procedure_service.dart'; -import 'package:doctor_app_flutter/core/service/sickleave_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; @@ -15,7 +8,6 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; -import 'core/service/home/auth_service.dart'; import 'core/service/home/dasboard_service.dart'; import 'core/service/patient/DischargedPatientService.dart'; import 'core/service/patient/patient_service.dart'; diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 4edb0f44..0ec7f5ee 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -174,14 +174,14 @@ class _VerificationMethodsScreenState extends State { AppText( authenticationViewModel.user.editedOn != null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate( + ? AppDateUtils.getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate( authenticationViewModel.user .editedOn)) : authenticationViewModel.user.createdOn != null - ? DateUtils.getDayMonthYearDateFormatted( - DateUtils.convertStringToDate(authenticationViewModel.user + ? AppDateUtils.getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate(authenticationViewModel.user .createdOn)) : '--', textAlign: @@ -193,14 +193,14 @@ class _VerificationMethodsScreenState extends State { AppText( authenticationViewModel.user.editedOn != null - ? DateUtils.getHour( - DateUtils.convertStringToDate( + ? AppDateUtils.getHour( + AppDateUtils.convertStringToDate( authenticationViewModel.user .editedOn)) : authenticationViewModel.user.createdOn != null - ? DateUtils.getHour( - DateUtils.convertStringToDate(authenticationViewModel.user + ? AppDateUtils.getHour( + AppDateUtils.convertStringToDate(authenticationViewModel.user .createdOn)) : '--', textAlign: diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index b7125e21..2827a421 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -44,7 +44,6 @@ class HomeScreen extends StatefulWidget { } class _HomeScreenState extends State { - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); bool isLoading = false; ProjectViewModel projectsProvider; var _isInit = true; @@ -53,11 +52,11 @@ class _HomeScreenState extends State { bool isInpatient = false; int sliderActiveIndex = 0; var clinicId; + AuthenticationViewModel authenticationViewModel; @override Widget build(BuildContext context) { ProjectViewModel projectsProvider = Provider.of(context); - AuthViewModel authProvider = Provider.of(context); authenticationViewModel = Provider.of(context); FocusScopeNode currentFocus = FocusScope.of(context); @@ -67,7 +66,7 @@ class _HomeScreenState extends State { return BaseView( onModelReady: (model) async { - await model.setFirebaseNotification(projectsProvider, authProvider); + await model.setFirebaseNotification(projectsProvider, authenticationViewModel); await model.getDashboard(); }, builder: (_, model, w) => AppScaffold( @@ -178,7 +177,7 @@ class _HomeScreenState extends State { GifLoaderDialogUtils.showMyDialog( context); await model.changeClinic( - newValue, authProvider); + newValue, authenticationViewModel); GifLoaderDialogUtils.hideDialog( context); if (model.state == From d574dd0b160242689aa5cccdc3d467449f890d40 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 18 May 2021 11:31:47 +0300 Subject: [PATCH 048/241] return base app client --- lib/client/base_app_client.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 3914dce6..6677d305 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -31,14 +31,13 @@ class BaseAppClient { if (body['DoctorID'] == "") body['DoctorID'] = null; if (body['EditedBy'] == null) body['EditedBy'] = doctorProfile?.doctorID; - // if (body['ProjectID'] == null) { - // body['ProjectID'] = 15;//doctorProfile?.projectID; - // } + if (body['ProjectID'] == null) { + body['ProjectID'] = doctorProfile?.projectID; + } if (body['ClinicID'] == null) body['ClinicID'] = doctorProfile?.clinicID; } - body['ProjectID'] = 15; if (body['DoctorID'] == '') { body['DoctorID'] = null; } From fa830cf4da8302b76f3c5276e0b948d2f8d3d9c9 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 18 May 2021 13:21:15 +0300 Subject: [PATCH 049/241] changes --- lib/client/base_app_client.dart | 8 ++++---- lib/config/config.dart | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 718a3839..57814cf1 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -67,10 +67,10 @@ class BaseAppClient { await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); } - int projectID = await sharedPref.getInt(PROJECT_ID); - if (projectID == 2 || projectID == 3) - body['PatientOutSA'] = true; - else + // int projectID = await sharedPref.getInt(PROJECT_ID); + // if (projectID == 2 || projectID == 3) + // body['PatientOutSA'] = true; + // else body['PatientOutSA'] = false; body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; diff --git a/lib/config/config.dart b/lib/config/config.dart index 3e8bbcb5..83a28557 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = From 57fcd2cdeb84f6cb8c24894ffb9086f374414ecf Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 18 May 2021 14:40:54 +0300 Subject: [PATCH 050/241] fix home page design --- .../lab_order/labs_service.dart | 2 +- lib/core/viewModel/procedure_View_model.dart | 35 ------------------- lib/landing_page.dart | 4 +-- lib/screens/home/dashboard_swipe_widget.dart | 9 ++--- .../patient_profile_screen.dart | 7 ++-- lib/widgets/dashboard/activity_button.dart | 4 +-- lib/widgets/dashboard/out_patient_stack.dart | 8 ++--- 7 files changed, 18 insertions(+), 51 deletions(-) diff --git a/lib/core/service/patient_medical_file/lab_order/labs_service.dart b/lib/core/service/patient_medical_file/lab_order/labs_service.dart index 4eee522a..d7fc3aab 100644 --- a/lib/core/service/patient_medical_file/lab_order/labs_service.dart +++ b/lib/core/service/patient_medical_file/lab_order/labs_service.dart @@ -105,7 +105,7 @@ class LabsService extends BaseService { await baseAppClient.postPatient(url, patient: patient, onSuccess: (dynamic response, int statusCode) { - patientLabSpecialResult.clear(); + // patientLabSpecialResult.clear(); labResultList.clear(); if (isInpatient) { diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 32a40e7e..8e6f8989 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -257,41 +257,6 @@ class ProcedureViewModel extends BaseViewModel { } } - getPatientLabResult( - {PatientLabOrders patientLabOrder, PatiantInformtion patient}) async { - setState(ViewState.Busy); - await _labsService.getPatientLabResult( - patientLabOrder: patientLabOrder, patient: patient); - if (_labsService.hasError) { - error = _labsService.error; - setState(ViewState.Error); - } else { - _labsService.labResultList.forEach((element) { - List patientLabOrdersClinic = labResultLists - .where( - (elementClinic) => elementClinic.filterName == element.testCode) - .toList(); - - if (patientLabOrdersClinic.length != 0) { - var value = - labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])] - .patientLabResultList - .where((e) => - e.sampleCollectedOn == element.sampleCollectedOn && - e.resultValue == element.resultValue) - .toList(); - if (value.isEmpty) - labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])] - .patientLabResultList - .add(element); - } else { - labResultLists - .add(LabResultList(filterName: element.testCode, lab: element)); - } - }); - setState(ViewState.Idle); - } - } getPatientLabOrdersResults( {PatientLabOrders patientLabOrder, diff --git a/lib/landing_page.dart b/lib/landing_page.dart index 0e1e2c48..cd7a8171 100644 --- a/lib/landing_page.dart +++ b/lib/landing_page.dart @@ -62,9 +62,7 @@ class _LandingPageState extends State { physics: NeverScrollableScrollPhysics(), controller: pageController, children: [ - ShowCaseWidget( - builder: Builder(builder: (context) => HomeScreen()), - ), + HomeScreen(), MyScheduleScreen(), QrReaderScreen(), DoctorReplyScreen( diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart index a6dc12eb..de5cc05f 100644 --- a/lib/screens/home/dashboard_swipe_widget.dart +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -28,8 +29,8 @@ class _DashboardSwipeWidgetState extends State { @override Widget build(BuildContext context) { return Container( - // height: MediaQuery.of(context).size.height * 0.35, - height: 230, + height: MediaQuery.of(context).size.height * 0.35, + // height: 230, child: Swiper( onIndexChanged: (index) { if (mounted) { @@ -210,12 +211,12 @@ class _DashboardSwipeWidgetState extends State { widget.model .getPatientCount(dashboardItemList[2]) .toString(), - fontSize: 28, + fontSize: SizeConfig.textMultiplier * 3.0, fontWeight: FontWeight.bold, ) ], ), - top: MediaQuery.of(context).size.height * 0.12, + top: MediaQuery.of(context).size.height * 0.13, left: 0, right: 0) ]), diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 2424da36..7a0305e4 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -27,7 +27,7 @@ class _PatientProfileScreenState extends State PatiantInformtion patient; bool isFromSearch = false; - bool isFromLiveCare = true; + bool isFromLiveCare = false; bool isInpatient = false; @@ -73,6 +73,9 @@ class _PatientProfileScreenState extends State if (routeArgs.containsKey("isSearchAndOut")) { isSearchAndOut = routeArgs['isSearchAndOut']; } + if(routeArgs.containsKey("isFromLiveCare")) { + isFromLiveCare = routeArgs['isFromLiveCare']; + } if (isInpatient) _activeTab = 0; else @@ -287,7 +290,7 @@ class _PatientProfileScreenState extends State ), ], ), - ) : Container(), + ) : null, ), diff --git a/lib/widgets/dashboard/activity_button.dart b/lib/widgets/dashboard/activity_button.dart index a46fc334..ff9db962 100644 --- a/lib/widgets/dashboard/activity_button.dart +++ b/lib/widgets/dashboard/activity_button.dart @@ -9,12 +9,12 @@ class GetActivityButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - width: 110, + width: MediaQuery.of(context).size.height * 0.125, padding: EdgeInsets.all(5), margin: EdgeInsets.all(5), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(15), ), child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index 2b982e20..fe05d69d 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -14,7 +14,7 @@ class GetOutPatientStack extends StatelessWidget { var list = new List(); value.summaryoptions.forEach((result) => - {list.add(getStack(result, value.summaryoptions.first.value))}); + {list.add(getStack(result, value.summaryoptions.first.value,context))}); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -32,7 +32,7 @@ class GetOutPatientStack extends StatelessWidget { ); } - getStack(Summaryoptions value, max) { + getStack(Summaryoptions value, max,context) { return Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 2), @@ -55,7 +55,7 @@ class GetOutPatientStack extends StatelessWidget { child: Container( child: SizedBox(), padding: EdgeInsets.all(10), - height: max != 0 ? (150 * value.value) / max : 0, + height: max != 0 ? ((MediaQuery.of(context).size.height * 0.24 )* value.value) / max : 0, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Color(0x63D02127), @@ -63,7 +63,7 @@ class GetOutPatientStack extends StatelessWidget { ), ), Container( - height: 150, + height: (MediaQuery.of(context).size.height * 0.24 ), margin: EdgeInsets.only(left: 5, top: 5), padding: EdgeInsets.all(10), child: RotatedBox( From 066acc404a839f28599461826590c86cd8d18b5b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 18 May 2021 16:39:01 +0300 Subject: [PATCH 051/241] Procedure template service --- lib/client/base_app_client.dart | 14 +- lib/config/config.dart | 3 + .../procedure_template_details_model.dart | 84 +++++++ ...cedure_template_details_request_model.dart | 124 ++++++++++ .../procedure/procedure_service.dart | 37 ++- lib/core/viewModel/procedure_View_model.dart | 17 +- .../procedures/add-favourite-procedure.dart | 180 +++++++------- .../procedures/entity_list_fav_procedure.dart | 221 ++++++++---------- 8 files changed, 451 insertions(+), 229 deletions(-) create mode 100644 lib/core/model/procedure/procedure_template_details_model.dart create mode 100644 lib/core/model/procedure/procedure_template_details_request_model.dart diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index bd4b0cd4..0f2cf68c 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -43,7 +43,7 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = token ?? ''; + body['TokenID'] = "@dm!n" ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') body['LanguageID'] = 1; @@ -67,11 +67,11 @@ class BaseAppClient { await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); } - int projectID = await sharedPref.getInt(PROJECT_ID); - if(projectID ==2 || projectID == 3) - body['PatientOutSA'] = true; - else - body['PatientOutSA'] = false; + int projectID = await sharedPref.getInt(PROJECT_ID); + if (projectID == 2 || projectID == 3) + body['PatientOutSA'] = true; + else + body['PatientOutSA'] = false; body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; print("URL : $url"); @@ -196,7 +196,7 @@ class BaseAppClient { body['SessionID'] = SESSION_ID; //getSe int projectID = await sharedPref.getInt(PROJECT_ID); - if(projectID ==2 || projectID == 3) + if (projectID == 2 || projectID == 3) body['PatientOutSA'] = true; else body['PatientOutSA'] = false; diff --git a/lib/config/config.dart b/lib/config/config.dart index 5b9f594a..2410617c 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -286,6 +286,9 @@ const GET_MY_OUT_PATIENT = const GET_PROCEDURE_TEMPLETE = 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; +const GET_PROCEDURE_TEMPLETE_DETAILS = + "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ diff --git a/lib/core/model/procedure/procedure_template_details_model.dart b/lib/core/model/procedure/procedure_template_details_model.dart new file mode 100644 index 00000000..84f97b65 --- /dev/null +++ b/lib/core/model/procedure/procedure_template_details_model.dart @@ -0,0 +1,84 @@ +class ProcedureTempleteDetailsModel { + String setupID; + int projectID; + int clinicID; + int doctorID; + int templateID; + String procedureID; + bool isActive; + int createdBy; + String createdOn; + dynamic editedBy; + dynamic editedOn; + String procedureName; + String procedureNameN; + String alias; + String aliasN; + String categoryID; + String subGroupID; + dynamic riskCategoryID; + + ProcedureTempleteDetailsModel( + {this.setupID, + this.projectID, + this.clinicID, + this.doctorID, + this.templateID, + this.procedureID, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn, + this.procedureName, + this.procedureNameN, + this.alias, + this.aliasN, + this.categoryID, + this.subGroupID, + this.riskCategoryID}); + + ProcedureTempleteDetailsModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + templateID = json['TemplateID']; + procedureID = json['ProcedureID']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + alias = json['Alias']; + aliasN = json['AliasN']; + categoryID = json['CategoryID']; + subGroupID = json['SubGroupID']; + riskCategoryID = json['RiskCategoryID']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['TemplateID'] = this.templateID; + data['ProcedureID'] = this.procedureID; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['Alias'] = this.alias; + data['AliasN'] = this.aliasN; + data['CategoryID'] = this.categoryID; + data['SubGroupID'] = this.subGroupID; + data['RiskCategoryID'] = this.riskCategoryID; + return data; + } +} diff --git a/lib/core/model/procedure/procedure_template_details_request_model.dart b/lib/core/model/procedure/procedure_template_details_request_model.dart new file mode 100644 index 00000000..6df6fc73 --- /dev/null +++ b/lib/core/model/procedure/procedure_template_details_request_model.dart @@ -0,0 +1,124 @@ +class ProcedureTempleteDetailsRequestModel { + int doctorID; + String firstName; + int templateID; + String middleName; + String lastName; + String patientMobileNumber; + String patientIdentificationID; + int patientID; + String from; + String to; + int searchType; + String mobileNo; + String identificationNo; + int editedBy; + int projectID; + int clinicID; + String tokenID; + int languageID; + String stamp; + String iPAdress; + double versionID; + int channel; + String sessionID; + bool isLoginForDoctorApp; + bool patientOutSA; + String vidaAuthTokenID; + String vidaRefreshTokenID; + int deviceTypeID; + + ProcedureTempleteDetailsRequestModel( + {this.doctorID, + this.firstName, + this.templateID, + this.middleName, + this.lastName, + this.patientMobileNumber, + this.patientIdentificationID, + this.patientID, + this.from, + this.to, + this.searchType, + this.mobileNo, + this.identificationNo, + this.editedBy, + this.projectID, + this.clinicID, + this.tokenID, + this.languageID, + this.stamp, + this.iPAdress, + this.versionID, + this.channel, + this.sessionID, + this.isLoginForDoctorApp, + this.patientOutSA, + this.vidaAuthTokenID, + this.vidaRefreshTokenID, + this.deviceTypeID}); + + ProcedureTempleteDetailsRequestModel.fromJson(Map json) { + doctorID = json['DoctorID']; + firstName = json['FirstName']; + templateID = json['TemplateID']; + middleName = json['MiddleName']; + lastName = json['LastName']; + patientMobileNumber = json['PatientMobileNumber']; + patientIdentificationID = json['PatientIdentificationID']; + patientID = json['PatientID']; + from = json['From']; + to = json['To']; + searchType = json['SearchType']; + mobileNo = json['MobileNo']; + identificationNo = json['IdentificationNo']; + editedBy = json['EditedBy']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + tokenID = json['TokenID']; + languageID = json['LanguageID']; + stamp = json['stamp']; + iPAdress = json['IPAdress']; + versionID = json['VersionID']; + channel = json['Channel']; + sessionID = json['SessionID']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + patientOutSA = json['PatientOutSA']; + vidaAuthTokenID = json['VidaAuthTokenID']; + vidaRefreshTokenID = json['VidaRefreshTokenID']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['DoctorID'] = this.doctorID; + data['FirstName'] = this.firstName; + data['TemplateID'] = this.templateID; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['PatientID'] = this.patientID; + data['From'] = this.from; + data['To'] = this.to; + data['SearchType'] = this.searchType; + data['MobileNo'] = this.mobileNo; + data['IdentificationNo'] = this.identificationNo; + data['EditedBy'] = this.editedBy; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['TokenID'] = this.tokenID; + data['LanguageID'] = this.languageID; + data['stamp'] = this.stamp; + data['IPAdress'] = this.iPAdress; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['SessionID'] = this.sessionID; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['PatientOutSA'] = this.patientOutSA; + data['VidaAuthTokenID'] = this.vidaAuthTokenID; + data['VidaRefreshTokenID'] = this.vidaRefreshTokenID; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index d0d88f83..f31bcc73 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -6,6 +6,8 @@ import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_re import 'package:doctor_app_flutter/core/model/procedure/get_procedure_req_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/update_procedure_request_model.dart'; @@ -24,11 +26,17 @@ class ProcedureService extends BaseService { List _templateList = List(); List get templateList => _templateList; + List _templateDetailsList = List(); + List get templateDetailsList => + _templateDetailsList; + GetOrderedProcedureRequestModel _getOrderedProcedureRequestModel = GetOrderedProcedureRequestModel(); ProcedureTempleteRequestModel _procedureTempleteRequestModel = ProcedureTempleteRequestModel(); + ProcedureTempleteDetailsRequestModel _procedureTempleteDetailsRequestModel = + ProcedureTempleteDetailsRequestModel(); GetProcedureReqModel _getProcedureReqModel = GetProcedureReqModel( // clinicId: 17, @@ -56,7 +64,12 @@ class ProcedureService extends BaseService { Future getProcedureTemplate( {int doctorId, int projectId, int clinicId}) async { - _procedureTempleteRequestModel = ProcedureTempleteRequestModel(); + _procedureTempleteRequestModel = ProcedureTempleteRequestModel( + tokenID: "@dm!n", + patientID: 0, + searchType: 1, + editedBy: 208195, + ); hasError = false; //insuranceApprovalInPatient.clear(); @@ -69,7 +82,27 @@ class ProcedureService extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: Map()); + }, body: _procedureTempleteRequestModel.toJson()); + } + + Future getProcedureTemplateDetails( + {int doctorId, int projectId, int clinicId, int templateId}) async { + _procedureTempleteDetailsRequestModel = + ProcedureTempleteDetailsRequestModel(templateID: templateId); + hasError = false; + //insuranceApprovalInPatient.clear(); + + await baseAppClient.post(GET_PROCEDURE_TEMPLETE_DETAILS, + onSuccess: (dynamic response, int statusCode) { + //prescriptionsList.clear(); + response['HIS_ProcedureTemplateDetailsList'].forEach((template) { + _templateDetailsList + .add(ProcedureTempleteDetailsModel.fromJson(template)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _procedureTempleteDetailsRequestModel.toJson()); } Future getProcedure({int mrn}) async { diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index aca47f10..434e108e 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -8,6 +8,7 @@ import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dar import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/update_procedure_request_model.dart'; @@ -49,8 +50,10 @@ class ProcedureViewModel extends BaseViewModel { List get labOrdersResultsList => _labsService.labOrdersResultsList; - List get ProcedureTemplate => + List get procedureTemplate => _procedureService.templateList; + List get procedureTemplateDetails => + _procedureService.templateDetailsList; List _patientLabOrdersListClinic = List(); List _patientLabOrdersListHospital = List(); @@ -107,6 +110,18 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getProcedureTemplateDetails({int templateId}) async { + hasError = false; + //_insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _procedureService.getProcedureTemplateDetails(templateId: templateId); + if (_procedureService.hasError) { + error = _procedureService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + Future postProcedure( PostProcedureReqModel postProcedureReqModel, int mrn) async { hasError = false; diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index a424c961..ee128caa 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; @@ -5,7 +6,10 @@ 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/screens/procedures/entity_list_checkbox_search_widget.dart'; import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:flutter/cupertino.dart'; @@ -36,103 +40,91 @@ class _AddFavouriteProcedureState extends State { Container( height: MediaQuery.of(context).size.height * 0.070, ), - if (model.procedureList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: - // selectedCategory != null - // ? selectedCategory['categoryId'] == 02 || - // selectedCategory['categoryId'] == 03 - // ? - EntityListCheckboxSearchFavProceduresWidget( - model: widget.model, - masterList: widget.model.ProcedureTemplate, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); + if (model.procedureTemplate.length != 0) + Expanded( + child: NetworkBaseView( + baseViewModel: model, + child: + // selectedCategory != null + // ? selectedCategory['categoryId'] == 02 || + // selectedCategory['categoryId'] == 03 + // ? + EntityListCheckboxSearchFavProceduresWidget( + model: widget.model, + masterList: widget.model.procedureTemplate, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), + ) + // : ProcedureListWidget( + // model: widget.model, + // masterList: widget.model + // .categoriesList[0].entityList, + // removeHistory: (item) { + // setState(() { + // entityList.remove(item); + // }); + // }, + // addHistory: (history) { + // setState(() { + // entityList.add(history); + // }); + // }, + // addSelectedHistories: () { + // //TODO build your fun herr + // // widget.addSelectedHistories(); + // }, + // isEntityListSelected: (master) => + // isEntityListSelected(master), + // ) + // : null, + ), + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: TranslationBase.of(context).addSelectedProcedures, + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () { + //print(entityList.toString()); + onPressed: + if (entityList.isEmpty == true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .fillTheMandatoryProcedureDetails, + ); + return; + } + + Navigator.pop(context); + // postProcedure( + // orderType: selectedType.toString(), + // entityList: entityList, + // patient: patient, + // model: widget.model, + // remarks: remarksController.text); }, - isEntityListSelected: (master) => - isEntityListSelected(master), - ) - // : ProcedureListWidget( - // model: widget.model, - // masterList: widget.model - // .categoriesList[0].entityList, - // removeHistory: (item) { - // setState(() { - // entityList.remove(item); - // }); - // }, - // addHistory: (history) { - // setState(() { - // entityList.add(history); - // }); - // }, - // addSelectedHistories: () { - // //TODO build your fun herr - // // widget.addSelectedHistories(); - // }, - // isEntityListSelected: (master) => - // isEntityListSelected(master), - // ) - // : null, ), - SizedBox( - height: 15.0, + ], + ), ), - Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - // Container( - // child: Row( - // children: [ - // AppText( - // TranslationBase.of(context).orderType), - // Radio( - // activeColor: Color(0xFFB9382C), - // value: 1, - // groupValue: selectedType, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text('routine'), - // Radio( - // activeColor: Color(0xFFB9382C), - // groupValue: selectedType, - // value: 0, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text(TranslationBase.of(context).urgent), - // ], - // ), - // ), - // SizedBox( - // height: 15.0, - // ), - // TextFields( - // hintText: TranslationBase.of(context).remarks, - // controller: remarksController, - // minLines: 3, - // maxLines: 5, - // ), - SizedBox( - height: 100.0, - ), - ], - ) ], ), ), diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index 93f264ab..c052f789 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -49,6 +49,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState } List items = List(); + //List items = List(); List remarksList = List(); List typeList = List(); @@ -67,7 +68,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState NetworkBaseView( baseViewModel: widget.model, child: Container( - height: MediaQuery.of(context).size.height * 0.75, + height: MediaQuery.of(context).size.height * 0.65, child: Center( child: Container( margin: EdgeInsets.only(top: 15), @@ -77,12 +78,12 @@ class _EntityListCheckboxSearchFavProceduresWidgetState child: ListView( children: [ TextFields( - hintText: TranslationBase.of(context).searchProcedures, + hintText: 'Search Favourite templates', suffixIcon: EvaIcons.search, suffixIconColor: Color(0xff2B353E), - // onChanged: (value) { - // filterSearchResults(value); - // }, + onChanged: (value) { + filterSearchResults(value); + }, hasBorder: false, ), SizedBox( @@ -94,36 +95,37 @@ class _EntityListCheckboxSearchFavProceduresWidgetState return Column( children: [ ExpansionTile( - title: Row( - children: [ - Checkbox( - value: widget.isEntityListSelected( - historyInfo), - activeColor: Color(0xffD02127), - onChanged: (bool newValue) { - setState(() { - if (widget.isEntityListSelected( - historyInfo)) { - widget.removeHistory( - historyInfo); - } else { - widget - .addHistory(historyInfo); - } - }); - }), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 0), - child: AppText('sss', - fontSize: 14.0, - variant: "bodyText", - bold: true, - color: Color(0xff575757)), + title: InkWell( + onTap: () { + widget.model + .getProcedureTemplateDetails( + templateId: + historyInfo.templateID); + }, + child: Row( + children: [ + Icon( + Icons.folder, + size: 20, + color: Color(0xff575757), ), - ), - ], + Expanded( + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 10, + vertical: 0), + child: AppText( + "Procedures for " + + historyInfo.templateName, + fontSize: 16.0, + variant: "bodyText", + bold: true, + color: Color(0xff575757)), + ), + ), + ], + ), ), children: [ Container( @@ -140,60 +142,48 @@ class _EntityListCheckboxSearchFavProceduresWidgetState padding: const EdgeInsets .symmetric( horizontal: 11), - child: AppText( - TranslationBase.of( - context) - .orderType, - fontWeight: - FontWeight.w700, - color: Color(0xff2B353E), + child: Checkbox( + value: widget + .isEntityListSelected( + historyInfo), + activeColor: + Color(0xffD02127), + onChanged: + (bool newValue) { + setState(() { + if (widget + .isEntityListSelected( + historyInfo)) { + widget.removeHistory( + historyInfo); + } else { + widget.addHistory( + historyInfo); + } + }); + }), + ), + Expanded( + child: Padding( + padding: const EdgeInsets + .symmetric( + horizontal: 10, + vertical: 0), + child: AppText( + widget + .model + .procedureTemplate[ + 0] + .templateName, + fontSize: 14.0, + variant: "bodyText", + bold: true, + color: Color( + 0xff575757)), ), ), ], ), - // Row( - // children: [ - // Radio( - // activeColor: - // Color(0xFFD02127), - // value: 0, - // groupValue: selectedType, - // onChanged: (value) { - // historyInfo.type = - // setSelectedType(value) - // .toString(); - // - // historyInfo.type = - // value.toString(); - // }, - // ), - // AppText( - // 'routine', - // color: Color(0xff575757), - // fontWeight: FontWeight.w600, - // ), - // Radio( - // activeColor: - // Color(0xFFD02127), - // groupValue: selectedType, - // value: 1, - // onChanged: (value) { - // historyInfo.type = - // setSelectedType(value) - // .toString(); - // - // historyInfo.type = - // value.toString(); - // }, - // ), - // AppText( - // TranslationBase.of(context) - // .urgent, - // color: Color(0xff575757), - // fontWeight: FontWeight.w600, - // ), - // ], - // ), ], ), ), @@ -201,22 +191,6 @@ class _EntityListCheckboxSearchFavProceduresWidgetState SizedBox( height: 2.0, ), - // Padding( - // padding: EdgeInsets.symmetric( - // horizontal: 12, vertical: 12.0), - // child: TextFields( - // hintText: TranslationBase.of(context) - // .remarks, - // //controller: remarksController, - // onChanged: (value) { - // historyInfo.remarks = value; - // }, - // minLines: 3, - // maxLines: 5, - // borderWidth: 0.5, - // borderColor: Colors.grey[500], - // ), - // ), DividerWithSpacesAround(), ], ), @@ -235,34 +209,31 @@ class _EntityListCheckboxSearchFavProceduresWidgetState )), ), ), - SizedBox( - height: 10, - ), ], ), ); } -// void filterSearchResults(String query) { -// List dummySearchList = List(); -// dummySearchList.addAll(widget.masterList); -// if (query.isNotEmpty) { -// List dummyListData = List(); -// dummySearchList.forEach((item) { -// if (item.procedureName.toLowerCase().contains(query.toLowerCase())) { -// dummyListData.add(item); -// } -// }); -// setState(() { -// items.clear(); -// items.addAll(dummyListData); -// }); -// return; -// } else { -// setState(() { -// items.clear(); -// items.addAll(widget.masterList); -// }); -// } -// } + void filterSearchResults(String query) { + List dummySearchList = List(); + dummySearchList.addAll(widget.masterList); + if (query.isNotEmpty) { + List dummyListData = List(); + dummySearchList.forEach((item) { + if (item.templateName.toLowerCase().contains(query.toLowerCase())) { + dummyListData.add(item); + } + }); + setState(() { + items.clear(); + items.addAll(dummyListData); + }); + return; + } else { + setState(() { + items.clear(); + items.addAll(widget.masterList); + }); + } + } } From 623f2730e8651b4d943a68906a6ffcb78f6d6f61 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 18 May 2021 16:56:30 +0300 Subject: [PATCH 052/241] Procedure card design update --- lib/screens/procedures/ProcedureCard.dart | 109 +++++++++++++++++----- 1 file changed, 85 insertions(+), 24 deletions(-) diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index f18422ee..0c3d952f 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -1,4 +1,5 @@ //import 'package:doctor_app_flutter/client/base_app_client.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -32,7 +33,7 @@ class ProcedureCard extends StatelessWidget { return Container( width: double.maxFinite, - height: MediaQuery.of(context).size.height * .22, + //height: MediaQuery.of(context).size.height * .22, margin: EdgeInsets.all(10), padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), decoration: BoxDecoration( @@ -129,33 +130,93 @@ class ProcedureCard extends StatelessWidget { ), ], ), + // Row( + // children: [ + // AppText( + // TranslationBase.of(context).doctorName + ": ", + // //color: Colors.grey, + // fontSize: 12, + // color: Colors.grey, + // ), + // AppText( + // entityList.doctorName.toString(), + // fontSize: 12, + // bold: true, + // ), + // ], + // ), + // Row( + // children: [ + // AppText( + // TranslationBase.of(context).clinic + ": ", + // //color: Colors.grey, + // fontSize: 12, + // color: Colors.grey, + // ), + // AppText( + // entityList.clinicDescription ?? "", + // bold: true, + // fontSize: 12, + // ), + // ], + // ), Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppText( - TranslationBase.of(context).doctorName + ": ", - //color: Colors.grey, - fontSize: 12, - color: Colors.grey, - ), - AppText( - entityList.doctorName.toString(), - fontSize: 12, - bold: true, + Container( + margin: EdgeInsets.only(left: 10, right: 0), + child: Image.asset( + 'assets/images/patient/ic_ref_arrow_left.png', + height: 50, + width: 30, + ), ), - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).clinic + ": ", - //color: Colors.grey, - fontSize: 12, - color: Colors.grey, + Container( + margin: EdgeInsets.only( + left: 0, top: 25, right: 0, bottom: 0), + padding: EdgeInsets.only(left: 4.0, right: 4.0), + child: Container( + width: 40, + height: 40, + child: ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Image.network( + 'assets/images/male_avatar.png', + height: 25, + width: 30, + errorBuilder: (BuildContext context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + ))), ), - AppText( - entityList.clinicDescription ?? "", - bold: true, - fontSize: 12, + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.only( + left: 10, top: 25, right: 10, bottom: 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + entityList.doctorName, + fontFamily: 'Poppins', + fontWeight: FontWeight.w800, + fontSize: 1.7 * SizeConfig.textMultiplier, + color: Colors.black, + ), + if (entityList.clinicDescription != null) + AppText( + entityList.clinicDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ], + ), + ), ), ], ), From a97a331d87f6f092947f66632339e778526036e3 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 18 May 2021 17:46:32 +0300 Subject: [PATCH 053/241] fix bugs in change the clinic, login page when get the projects and add the special Result --- ios/Podfile.lock | 2 +- lib/core/viewModel/dashboard_view_model.dart | 9 +-- lib/screens/auth/login_screen.dart | 15 ++-- .../lab_result/laboratory_result_page.dart | 3 +- .../lab_result/laboratory_result_widget.dart | 73 ++++++++++++++++++- .../profile/lab_result/labs_home_page.dart | 2 +- ..._header_with_appointment_card_app_bar.dart | 23 +----- 7 files changed, 88 insertions(+), 39 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2f4607e0..878a1850 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -322,4 +322,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.1 diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index f37a8feb..a1f83293 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -53,14 +53,7 @@ class DashboardViewModel extends BaseViewModel { Future changeClinic(int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); await getDoctorProfile(); - ProfileReqModel docInfo = new ProfileReqModel( - doctorID: doctorProfile.doctorID, - clinicID: clinicId, - license: true, - projectID: doctorProfile.projectID, - tokenID: '', - languageID: 2); - ClinicModel clinicModel = ClinicModel(doctorID:doctorProfile.doctorID,clinicID: doctorProfile.clinicID, projectID: doctorProfile.projectID,); + ClinicModel clinicModel = ClinicModel(doctorID:doctorProfile.doctorID,clinicID: clinicId, projectID: doctorProfile.projectID,); await authProvider.getDoctorProfileBasedOnClinic(clinicModel); if(authProvider.state == ViewState.ErrorLocal) { error = authProvider.error; diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index 84517932..f3f03fe8 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -166,14 +166,14 @@ class _LoginScreenState extends State { value .trim(); }); - if(allowCallApi) { + // if(allowCallApi) { this.getProjects( authenticationViewModel.userInfo .userID); - setState(() { - allowCallApi = false; - }); - } + // setState(() { + // allowCallApi = false; + // }); + // } }, onClick: (){ @@ -280,10 +280,11 @@ class _LoginScreenState extends State { primaryFocus.unfocus(); } - + String memberID =""; getProjects(memberID)async { if (memberID != null && memberID != '') { - if (projectsList.length == 0) { + if (this.memberID !=memberID) { + this.memberID = memberID; await authenticationViewModel.getHospitalsList(memberID); if(authenticationViewModel.state == ViewState.Idle) { projectsList = authenticationViewModel.hospitals; diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 1c5104f8..e54a3782 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -52,7 +52,8 @@ class _LaboratoryResultPageState extends State { invoiceNO: widget.patientLabOrders.invoiceNo, ), baseViewModel: model, - body: Scaffold( + body: AppScaffold( + isShowAppBar: false, body: SingleChildScrollView( child: Column( children: [ diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart index 810f025f..bc6fcbcb 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart @@ -9,6 +9,7 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; import 'package:provider/provider.dart'; class LaboratoryResultWidget extends StatefulWidget { @@ -37,6 +38,7 @@ class LaboratoryResultWidget extends StatefulWidget { class _LaboratoryResultWidgetState extends State { bool _isShowMoreGeneral = true; + bool _isShowMore = true; ProjectViewModel projectViewModel; @override @@ -141,9 +143,76 @@ class _LaboratoryResultWidgetState extends State { ], ), ), - SizedBox( - height: 10, + SizedBox(height: 15,), + if(widget.details!=null && widget.details.isNotEmpty) + Column( + children: [ + InkWell( + onTap: () { + setState(() { + _isShowMore = !_isShowMore; + }); + }, + child: Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(5.0), + )), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only( + left: 10, right: 10), + child: AppText( + TranslationBase.of(context) + .specialResult, + bold: true, + ))), + Container( + width: 25, + height: 25, + child: Icon( + _isShowMore + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + color: Colors.grey[800], + size: 22, + ), + ) + ], + ), + ), + ), + if (_isShowMore) + AnimatedContainer( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(5.0), + bottomRight: Radius.circular(5.0), + )), + duration: Duration(milliseconds: 7000), + child: Container( + width: double.infinity, + child: Html( + data: widget.details ?? TranslationBase.of(context).noDataAvailable, + )), + ), + SizedBox( + height: 10, + ), + ], ), + + ], ), ], diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index f60e875a..5c65ceb4 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -199,7 +199,7 @@ class _LabsHomePageState extends State { clinic: model .patientLabOrdersList[index].clinicDescription, appointmentDate: - model.patientLabOrdersList[index].orderDate, + model.patientLabOrdersList[index].orderDate.add(Duration(days: 1)), orderNo: model.patientLabOrdersList[index].orderNo, isShowTime: false, ), diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart index 2e47b211..9093566b 100644 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart +++ b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart @@ -103,7 +103,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget margin: EdgeInsets.symmetric(horizontal: 4), child: InkWell( onTap: () { - launch("tel://" + patient.mobileNumber); + launch("tel://" + patient?.mobileNumber??""); }, child: Icon( Icons.phone, @@ -235,7 +235,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget style: TextStyle( fontSize: 12, fontFamily: 'Poppins')), new TextSpan( - text: patient.patientId.toString(), + text: patient?.patientId?.toString() ?? "", style: TextStyle( fontWeight: FontWeight.w700, fontFamily: 'Poppins', @@ -256,7 +256,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget ? ClipRRect( borderRadius: BorderRadius.circular(20.0), child: Image.network( - patient.nationalityFlagURL, + patient?.nationalityFlagURL??"", height: 25, width: 30, errorBuilder: (BuildContext context, @@ -355,7 +355,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget AppText('Invoice: ', color: Colors.grey[800], fontSize: 12), - AppText(invoiceNO, fontSize: 12) + AppText(invoiceNO??"", fontSize: 12) ], ), if (branch != null) @@ -449,22 +449,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget return newDate.toString(); } - isToday(date) { - DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == - DateFormat("yyyy-MM-dd").format(DateTime.now()); - } - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } @override Size get preferredSize => Size(double.maxFinite, 310); From deb126fdd5e2a824f5c2dd95b7011ec8b7db6c0c Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 19 May 2021 09:17:03 +0300 Subject: [PATCH 054/241] meical report changes --- lib/client/base_app_client.dart | 2 +- lib/config/config.dart | 1 + .../PatientMedicalReportService.dart | 24 +++ .../PatientMedicalReportViewModel.dart | 19 ++- .../MedicalReport/MedicalReportTemplate.dart | 60 ++++++++ .../AddVerifyMedicalReport.dart | 1 + .../medical_report/MedicalReportPage.dart | 140 ++++++++++-------- 7 files changed, 182 insertions(+), 65 deletions(-) create mode 100644 lib/models/patient/MedicalReport/MedicalReportTemplate.dart diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index f07dc533..79343dd8 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -47,7 +47,7 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = token ?? ''; + body['TokenID'] = body.containsKey('TokenID') ? body['TokenID'] : token ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') body['LanguageID'] = 1; diff --git a/lib/config/config.dart b/lib/config/config.dart index ca81dfeb..72e2db07 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -285,6 +285,7 @@ const GET_MY_OUT_PATIENT = const PATIENT_MEDICAL_REPORT_GET_LIST = "Services/Patients.svc/REST/DAPP_ListMedicalReport"; +const PATIENT_MEDICAL_REPORT_GET_TEMPLATE = "Services/Patients.svc/REST/DAPP_GetTemplateByID"; const PATIENT_MEDICAL_REPORT_INSERT = "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; const PATIENT_MEDICAL_REPORT_VERIFIED = "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 64cce97a..a3ba3f6d 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -1,10 +1,12 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/MedicalReport/MedicalReportTemplate.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; class PatientMedicalReportService extends BaseService { List medicalReportList = []; + List medicalReportTemplate = []; Future getMedicalReportList(PatiantInformtion patient) async { hasError = false; @@ -28,6 +30,28 @@ class PatientMedicalReportService extends BaseService { }, body: body, patient: patient); } + Future getMedicalReportTemplate() async { + hasError = false; + Map body = Map(); + body['TokenID'] = "@dm!n"; + body['SetupID'] = "91877"; + body['TemplateID'] = 43; + + await baseAppClient.post(PATIENT_MEDICAL_REPORT_GET_TEMPLATE, + onSuccess: (dynamic response, int statusCode) { + + medicalReportTemplate.clear(); + if (response['DAPP_GetTemplateByIDList'] != null) { + response['DAPP_GetTemplateByIDList'].forEach((v) { + medicalReportTemplate.add(MedicalReportTemplate.fromJson(v)); + }); + } + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error.toString(); + }, body: body); + } + Future insertMedicalReport(PatiantInformtion patient, String htmlText) async { hasError = false; Map body = Map(); diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index 8d7b5c63..9a41a253 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/models/patient/MedicalReport/MedicalReportTemplate.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -11,6 +12,9 @@ class PatientMedicalReportViewModel extends BaseViewModel { List get medicalReportList => _service.medicalReportList; + List get medicalReportTemplate => + _service.medicalReportTemplate; + Future getMedicalReportList(PatiantInformtion patient) async { setState(ViewState.Busy); await _service.getMedicalReportList(patient); @@ -21,7 +25,17 @@ class PatientMedicalReportViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future insertMedicalReport(PatiantInformtion patient, String htmlText)async { + Future getMedicalReportTemplate() async { + setState(ViewState.Busy); + await _service.getMedicalReportTemplate(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future insertMedicalReport(PatiantInformtion patient, String htmlText) async { setState(ViewState.Busy); await _service.insertMedicalReport(patient, htmlText); if (_service.hasError) { @@ -31,7 +45,8 @@ class PatientMedicalReportViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future verifyMedicalReport(PatiantInformtion patient, MedicalReportModel medicalReport) async { + Future verifyMedicalReport( + PatiantInformtion patient, MedicalReportModel medicalReport) async { setState(ViewState.Busy); await _service.verifyMedicalReport(patient, medicalReport); if (_service.hasError) { diff --git a/lib/models/patient/MedicalReport/MedicalReportTemplate.dart b/lib/models/patient/MedicalReport/MedicalReportTemplate.dart new file mode 100644 index 00000000..f00e84a0 --- /dev/null +++ b/lib/models/patient/MedicalReport/MedicalReportTemplate.dart @@ -0,0 +1,60 @@ +class MedicalReportTemplate { + String setupID; + int projectID; + int templateID; + String procedureID; + int reportType; + String templateName; + String templateNameN; + String templateText; + String templateTextN; + bool isActive; + String templateTextHtml; + String templateTextNHtml; + + MedicalReportTemplate( + {this.setupID, + this.projectID, + this.templateID, + this.procedureID, + this.reportType, + this.templateName, + this.templateNameN, + this.templateText, + this.templateTextN, + this.isActive, + this.templateTextHtml, + this.templateTextNHtml}); + + MedicalReportTemplate.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + templateID = json['TemplateID']; + procedureID = json['ProcedureID']; + reportType = json['ReportType']; + templateName = json['TemplateName']; + templateNameN = json['TemplateNameN']; + templateText = json['TemplateText']; + templateTextN = json['TemplateTextN']; + isActive = json['IsActive']; + templateTextHtml = json['TemplateTextHtml']; + templateTextNHtml = json['TemplateTextNHtml']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['TemplateID'] = this.templateID; + data['ProcedureID'] = this.procedureID; + data['ReportType'] = this.reportType; + data['TemplateName'] = this.templateName; + data['TemplateNameN'] = this.templateNameN; + data['TemplateText'] = this.templateText; + data['TemplateTextN'] = this.templateTextN; + data['IsActive'] = this.isActive; + data['TemplateTextHtml'] = this.templateTextHtml; + data['TemplateTextNHtml'] = this.templateTextNHtml; + return data; + } +} diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index f562f7b2..4fd6b7dc 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -66,6 +66,7 @@ class _AddVerifyMedicalReportState extends State { MedicalReportStatus status = routeArgs['status']; return BaseView( + onModelReady: (model) => model.getMedicalReportTemplate(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 1701feac..41fcc02e 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -11,6 +12,7 @@ import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-head 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/card_with_bg_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -23,8 +25,8 @@ class MedicalReportPage extends StatelessWidget { @override Widget build(BuildContext context) { final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatiantInformtion patient = routeArgs['patient']; - String patientType = routeArgs['patientType']; + PatiantInformtion patient = routeArgs['patient']; + String patientType = routeArgs['patientType']; String arrivalType = routeArgs['arrivalType']; ProjectViewModel projectViewModel = Provider.of(context); @@ -33,7 +35,11 @@ class MedicalReportPage extends StatelessWidget { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType,), + appBar: PatientProfileHeaderNewDesignAppBar( + patient, + patientType, + arrivalType, + ), body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( @@ -61,7 +67,8 @@ class MedicalReportPage extends StatelessWidget { ), AddNewOrder( onTap: () { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + Navigator.of(context) + .pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, @@ -70,69 +77,78 @@ class MedicalReportPage extends StatelessWidget { }, label: TranslationBase.of(context).createNewMedicalReport, ), - ...List.generate( - /*model.patientLabOrdersList.length,*/1, - (index) => CardWithBgWidget( - hasBorder: false, - bgColor: 0==0? Colors.red[700]:Colors.green[700], - widget: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText('On Hold',color: Colors.red,), - AppText( - "Jammal" ?? "", - fontSize: 15, - bold: true, - ), - ], - )), - Expanded( + if (model.state == ViewState.ErrorLocal) + Container( + child: ErrorMessage(error: model.error), + ), + if (model.state != ViewState.ErrorLocal) + ...List.generate( + /*model.patientLabOrdersList.length,*/ + 1, + (index) => CardWithBgWidget( + hasBorder: false, + bgColor: 0 == 0 ? Colors.red[700] : Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 14, - ), - AppText( - '${AppDateUtils.getHour(DateTime.now())}', - fontWeight: FontWeight.w600, - color: Colors.grey[700], - fontSize: 14, - ), - ], + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + 'On Hold', + color: Colors.red, ), - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - child: LargeAvatar( - name: "Jammal", - url: null, + AppText( + "Jammal" ?? "", + fontSize: 15, + bold: true, ), - width: 55, - height: 55, + ], + )), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 14, + ), + AppText( + '${AppDateUtils.getHour(DateTime.now())}', + fontWeight: FontWeight.w600, + color: Colors.grey[700], + fontSize: 14, + ), + ], ), - Expanded(child: AppText("")), - Icon( - EvaIcons.eye, - ) - ], - ), - ], - ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: LargeAvatar( + name: "Jammal", + url: null, + ), + width: 55, + height: 55, + ), + Expanded(child: AppText("")), + Icon( + EvaIcons.eye, + ) + ], + ), + ], ), - ) + ), + ), ], ), ), From 1cc55d809cd103a59bc0df75ade04636ca912972 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 19 May 2021 12:23:08 +0300 Subject: [PATCH 055/241] fix authentication service --- lib/client/base_app_client.dart | 2 +- lib/core/service/authentication_service.dart | 1 + .../viewModel/authentication_view_model.dart | 32 ++++++++++++---- lib/core/viewModel/base_view_model.dart | 6 +-- lib/screens/auth/login_screen.dart | 19 +++++----- .../auth/verification_methods_screen.dart | 37 +++++++++++-------- lib/screens/home/home_screen.dart | 3 ++ lib/widgets/shared/app_drawer_widget.dart | 4 +- 8 files changed, 67 insertions(+), 37 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index fad0e839..9965ad11 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -104,7 +104,7 @@ class BaseAppClient { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { - await Provider.of(AppGlobal.CONTEX, listen: false).logout(isSessionTimeout: true); + await Provider.of(AppGlobal.CONTEX, listen: false).logout(); Helpers.showErrorToast('Your session expired Please login again'); } if (isAllowAny) { diff --git a/lib/core/service/authentication_service.dart b/lib/core/service/authentication_service.dart index f033d4f7..49e89881 100644 --- a/lib/core/service/authentication_service.dart +++ b/lib/core/service/authentication_service.dart @@ -127,6 +127,7 @@ class AuthenticationService extends BaseService { Future insertDeviceImei(InsertIMEIDetailsModel insertIMEIDetailsModel)async { hasError = false; + // insertIMEIDetailsModel.tokenID = "@dm!n"; _insertDeviceImeiRes = {}; try { await baseAppClient.post(INSERT_DEVICE_IMEI, diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 223b303b..232d9619 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -72,6 +72,8 @@ class AuthenticationViewModel extends BaseViewModel { bool isLogin = false; bool unverified = false; + bool isFromLogin = false; + APP_STATUS app_status = APP_STATUS.LOADING; AuthenticationViewModel({bool checkDeviceInfo = false}) { getDeviceInfoFromFirebase(); @@ -386,27 +388,41 @@ class AuthenticationViewModel extends BaseViewModel { /// determine the status of the app APP_STATUS get status { if (state == ViewState.Busy) { - return APP_STATUS.LOADING; + app_status = APP_STATUS.LOADING; } else { - if (this.unverified) { - return APP_STATUS.UNVERIFIED; + if(this.doctorProfile !=null) + app_status = APP_STATUS.AUTHENTICATED; + else if (this.unverified) { + app_status = APP_STATUS.UNVERIFIED; } else if (this.isLogin) { - return APP_STATUS.AUTHENTICATED; + app_status = APP_STATUS.AUTHENTICATED; } else { - return APP_STATUS.UNAUTHENTICATED; + app_status = APP_STATUS.UNAUTHENTICATED; } } + return app_status; + } + setAppStatus(APP_STATUS status){ + this.app_status = status; + notifyListeners(); + } + + setUnverified(bool unverified,{bool isFromLogin = false}){ + this.unverified = unverified; + this.isFromLogin = isFromLogin; + notifyListeners(); } /// logout function - logout({bool isSessionTimeout = false}) async { + logout({bool isFromLogin = false}) async { DEVICE_TOKEN = ""; String lang = await sharedPref.getString(APP_Language); await Helpers.clearSharedPref(); + doctorProfile = null; sharedPref.setString(APP_Language, lang); deleteUser(); - if(isSessionTimeout) await getDeviceInfoFromFirebase(); + this.isFromLogin = isFromLogin; Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( @@ -419,7 +435,7 @@ class AuthenticationViewModel extends BaseViewModel { user = null; unverified = false; isLogin = false; - notifyListeners(); + // notifyListeners(); } } diff --git a/lib/core/viewModel/base_view_model.dart b/lib/core/viewModel/base_view_model.dart index fe4dbd22..9d4fe36d 100644 --- a/lib/core/viewModel/base_view_model.dart +++ b/lib/core/viewModel/base_view_model.dart @@ -47,8 +47,8 @@ class BaseViewModel extends ChangeNotifier { } } - setDoctorProfile(DoctorProfileModel doctorProfile){ - sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); - doctorProfile = doctorProfile; + setDoctorProfile(DoctorProfileModel doctorProfile)async { + await sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); + this.doctorProfile = doctorProfile; } } diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index f3f03fe8..9563b29c 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -259,15 +259,16 @@ class _LoginScreenState extends State { Helpers.showErrorToast(authenticationViewModel.error); } else { GifLoaderDialogUtils.hideDialog(context); - - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (BuildContext context) => - VerificationMethodsScreen( - password: authenticationViewModel.userInfo.password, - ), - ), - ); + authenticationViewModel.setUnverified(true,isFromLogin: true); + // Navigator.of(context).pushReplacement( + // MaterialPageRoute( + // builder: (BuildContext context) => + // VerificationMethodsScreen( + // password: authenticationViewModel.userInfo.password, + // isFromLogin: true, + // ), + // ), + // ); } } } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 0ec7f5ee..8257ebf0 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -13,6 +13,7 @@ import 'package:doctor_app_flutter/widgets/shared/app_loader_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/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/secondary_button.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -32,10 +33,13 @@ DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); class VerificationMethodsScreen extends StatefulWidget { - VerificationMethodsScreen({this.password}); + final password; + + VerificationMethodsScreen({this.password, }); + @override _VerificationMethodsScreenState createState() => _VerificationMethodsScreenState(); } @@ -72,9 +76,11 @@ class _VerificationMethodsScreenState extends State { SizedBox( height: 80, ), + if(authenticationViewModel.isFromLogin) InkWell( onTap: (){ - Navigator.of(context).pop(); + authenticationViewModel.setUnverified(false,isFromLogin: false); + authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); }, child: Icon(Icons.arrow_back_ios,color: Color(0xFF2B353E),) @@ -392,20 +398,21 @@ class _VerificationMethodsScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ - AppButton( - title: TranslationBase + SecondaryButton( + label: TranslationBase .of(context) .useAnotherAccount, - color: Color(0xFFD02127),fontWeight: FontWeight.w700, - onPressed: () { + color: Color(0xFFD02127), + //fontWeight: FontWeight.w700, + onTap: () { authenticationViewModel.deleteUser(); - - Navigator.pushAndRemoveUntil( - AppGlobal.CONTEX, - FadePage( - page: RootPage(), - ), - (r) => false); + authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); + // Navigator.pushAndRemoveUntil( + // AppGlobal.CONTEX, + // FadePage( + // page: RootPage(), + // ), + // (r) => false); // Navigator.of(context).pushNamed(LOGIN); }, ), @@ -425,13 +432,13 @@ class _VerificationMethodsScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); - await authenticationViewModel.sendActivationCodeForDoctorApp(authMethodType:authMethodType, password: widget.password ); + await authenticationViewModel.sendActivationCodeForDoctorApp(authMethodType:authMethodType, password: authenticationViewModel.userInfo.password ); if (authenticationViewModel.state == ViewState.ErrorLocal) { Helpers.showErrorToast(authenticationViewModel.error); GifLoaderDialogUtils.hideDialog(context); } else { authenticationViewModel.setDataAfterSendActivationSuccess(authenticationViewModel.activationCodeForDoctorAppRes); - sharedPref.setString(PASSWORD, widget.password); + sharedPref.setString(PASSWORD, authenticationViewModel.userInfo.password); GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 2827a421..1b864430 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; @@ -19,6 +20,7 @@ import 'package:doctor_app_flutter/screens/patients/patient_search/patient_searc import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/profile-welcome-widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -68,6 +70,7 @@ class _HomeScreenState extends State { onModelReady: (model) async { await model.setFirebaseNotification(projectsProvider, authenticationViewModel); await model.getDashboard(); + await model.getDoctorProfile(isGetProfile: true); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index e350e39d..64791b26 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/reschedule-leaves/add-rescheduleleave.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:provider/provider.dart'; @@ -172,7 +173,8 @@ class _AppDrawerState extends State { ), onTap: () async { Navigator.pop(context); - await authenticationViewModel.logout(); + GifLoaderDialogUtils.showMyDialog(context); + await authenticationViewModel.logout(isFromLogin: false); }, ), ], From 8cac9b6fe90b5eb123542dcfcbe5b857a178575c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 19 May 2021 13:58:48 +0300 Subject: [PATCH 056/241] add rich editor --- ios/Podfile.lock | 8 +- .../shared/text_fields/html_rich_editor.dart | 174 ++++++++++++++++++ pubspec.lock | 21 +++ pubspec.yaml | 5 + speech_to_text/example/pubspec.lock | 104 ++++------- speech_to_text/pubspec.lock | 71 +++---- 6 files changed, 263 insertions(+), 120 deletions(-) create mode 100644 lib/widgets/shared/text_fields/html_rich_editor.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 878a1850..1cf7499c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -58,6 +58,8 @@ PODS: - Flutter (1.0.0) - flutter_flexible_toast (0.0.1): - Flutter + - flutter_inappwebview (0.0.1): + - Flutter - flutter_plugin_android_lifecycle (0.0.1): - Flutter - GoogleDataTransport (7.5.1): @@ -151,6 +153,7 @@ DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`) + - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - imei_plugin (from `.symlinks/plugins/imei_plugin/ios`) @@ -218,6 +221,8 @@ EXTERNAL SOURCES: :path: Flutter flutter_flexible_toast: :path: ".symlinks/plugins/flutter_flexible_toast/ios" + flutter_inappwebview: + :path: ".symlinks/plugins/flutter_inappwebview/ios" flutter_plugin_android_lifecycle: :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" hexcolor: @@ -285,6 +290,7 @@ SPEC CHECKSUMS: FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a Flutter: 0e3d915762c693b495b44d77113d4970485de6ec flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143 + flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 @@ -322,4 +328,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/widgets/shared/text_fields/html_rich_editor.dart b/lib/widgets/shared/text_fields/html_rich_editor.dart new file mode 100644 index 00000000..1d87685b --- /dev/null +++ b/lib/widgets/shared/text_fields/html_rich_editor.dart @@ -0,0 +1,174 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:html_editor_enhanced/html_editor.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; +import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; +import '../speech-text-popup.dart'; + +class HtmlRichEditor extends StatefulWidget { + HtmlRichEditor({ + key, + this.hint = "Your text here...", + this.initialText, + this.height = 400, + this.decoration, + this.darkMode = false, + this.showBottomToolbar = false, + this.toolbar, + }) : super(key: key); + final String hint; + final String initialText; + final double height; + final BoxDecoration decoration; + final bool darkMode; + final bool showBottomToolbar; + final List toolbar; + + + @override + _HtmlRichEditorState createState() => _HtmlRichEditorState(); +} + +class _HtmlRichEditorState extends State { + ProjectViewModel projectViewModel; + stt.SpeechToText speech = stt.SpeechToText(); + var recognizedWord; + var event = RobotProvider(); + + + @override + void initState() { + requestPermissions(); + event.controller.stream.listen((p) { + if (p['startPopUp'] == 'true') { + if (this.mounted) { + initSpeechState().then((value) => {onVoiceText()}); + } + } + }); + super.initState(); + } + + + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + + return Stack( + children: [ + HtmlEditor( + hint: widget.hint, + height: widget.height, + initialText: widget.initialText, + showBottomToolbar: widget.showBottomToolbar, + darkMode: widget.darkMode, + decoration: widget.decoration ?? + BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.all( + Radius.circular(30.0), + ), + border: Border.all(color: Colors.grey[200], width: 0.5), + ), + toolbar: widget.toolbar ?? + const [ + // Style(), + Font(buttons: [ + FontButtons.bold, + FontButtons.underline, + FontButtons.clear + ]), + // ColorBar(buttons: [ColorButtons.color]), + Paragraph(buttons: [ + ParagraphButtons.ul, + ParagraphButtons.ol, + ParagraphButtons.paragraph + ]), + // Insert(buttons: [InsertButtons.link, InsertButtons.picture, InsertButtons.video, InsertButtons.table]), + // Misc(buttons: [MiscButtons.fullscreen, MiscButtons.codeview, MiscButtons.help]) + ], + ), + Positioned( + top: + 50, //MediaQuery.of(context).size.height * 0, + right: projectViewModel.isArabic + ? MediaQuery.of(context).size.width * 0.75 + : 15, + child: Column( + children: [ + IconButton( + icon: Icon(DoctorApp.speechtotext, + color: Colors.black, size: 35), + onPressed: () { + initSpeechState() + .then((value) => {onVoiceText()}); + }, + ), + ], + )) + ], + ); + } + + + onVoiceText() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speech.initialize( + onStatus: statusListener, onError: errorListener); + if (available) { + speech.listen( + onResult: resultListener, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + + void errorListener(SpeechRecognitionError error) { + event.setValue({"searchText": 'null'}); + //SpeechToText.closeAlertDialog(context); + print(error); + } + + void statusListener(String status) { + recognizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; + } + + void requestPermissions() async { + Map statuses = await [ + Permission.microphone, + ].request(); + } + + void resultListener(result)async { + recognizedWord = result.recognizedWords; + event.setValue({"searchText": recognizedWord}); + String txt = await HtmlEditor.getText(); + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speech.stop(); + HtmlEditor.setText(txt+recognizedWord); + }); + } else { + print(result.finalResult); + } + } + + Future initSpeechState() async { + bool hasSpeech = await speech.initialize( + onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } +} diff --git a/pubspec.lock b/pubspec.lock index ee31002d..980a4154 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -426,6 +426,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + flutter_inappwebview: + dependency: transitive + description: + name: flutter_inappwebview + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0+4" flutter_localizations: dependency: "direct main" description: flutter @@ -518,6 +525,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.14.0+4" + html_editor_enhanced: + dependency: "direct main" + description: + name: html_editor_enhanced + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" http: dependency: "direct main" description: @@ -1013,6 +1027,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1+3" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" vector_math: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 29c3f7b1..a5026871 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -90,6 +90,11 @@ dependencies: speech_to_text: path: speech_to_text + + + #Html Editor Enhanced + html_editor_enhanced: ^1.3.0 + dev_dependencies: flutter_test: sdk: flutter diff --git a/speech_to_text/example/pubspec.lock b/speech_to_text/example/pubspec.lock index e0e9b753..6809f75f 100644 --- a/speech_to_text/example/pubspec.lock +++ b/speech_to_text/example/pubspec.lock @@ -1,69 +1,48 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.5.0-nullsafety.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.0-nullsafety.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0-nullsafety.1" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" + version: "1.15.0-nullsafety.3" cupertino_icons: dependency: "direct main" description: @@ -71,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" flutter: dependency: "direct main" description: flutter @@ -81,13 +67,6 @@ packages: description: flutter source: sdk version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" json_annotation: dependency: transitive description: @@ -101,14 +80,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety.3" nested: dependency: transitive description: @@ -122,7 +101,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.8.0-nullsafety.1" permission_handler: dependency: "direct main" description: @@ -137,13 +116,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" plugin_platform_interface: dependency: transitive description: @@ -158,13 +130,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.3.1" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -176,7 +141,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0-nullsafety.2" speech_to_text: dependency: "direct dev" description: @@ -190,56 +155,49 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.19-nullsafety.2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0-nullsafety.3" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" + version: "2.1.0-nullsafety.3" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.10.0-110 <2.11.0" flutter: ">=1.16.0 <2.0.0" diff --git a/speech_to_text/pubspec.lock b/speech_to_text/pubspec.lock index 7877604f..efc63cc7 100644 --- a/speech_to_text/pubspec.lock +++ b/speech_to_text/pubspec.lock @@ -15,13 +15,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.39.13" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" args: dependency: transitive description: @@ -35,14 +28,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.5.0-nullsafety.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" build: dependency: transitive description: @@ -99,13 +92,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "7.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.0-nullsafety.1" checked_yaml: dependency: transitive description: @@ -119,7 +119,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0-nullsafety.1" code_builder: dependency: transitive description: @@ -133,7 +133,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0-nullsafety.3" convert: dependency: transitive description: @@ -168,7 +168,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0-nullsafety.1" fixnum: dependency: transitive description: @@ -221,13 +221,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" io: dependency: transitive description: @@ -269,14 +262,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -311,7 +304,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.8.0-nullsafety.1" pedantic: dependency: transitive description: @@ -319,13 +312,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" pool: dependency: transitive description: @@ -386,21 +372,21 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0-nullsafety.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0-nullsafety.1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0-nullsafety.1" stream_transform: dependency: transitive description: @@ -414,21 +400,21 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.19-nullsafety.2" timing: dependency: transitive description: @@ -442,14 +428,14 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0-nullsafety.3" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0-nullsafety.3" watcher: dependency: transitive description: @@ -464,13 +450,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" yaml: dependency: transitive description: @@ -479,5 +458,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.10.0-110 <2.11.0" flutter: ">=1.10.0" From e1d00b87ad34a67c31a2dcddf87a2c650649ea7c Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Wed, 19 May 2021 14:46:29 +0300 Subject: [PATCH 057/241] favourite template Procedure service --- .../procedure/procedure_service.dart | 4 +- lib/core/viewModel/procedure_View_model.dart | 2 + .../procedures/add-favourite-procedure.dart | 19 ++- .../procedures/entity_list_fav_procedure.dart | 129 ++++++++++-------- 4 files changed, 90 insertions(+), 64 deletions(-) diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index f31bcc73..9673b9bf 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -88,9 +88,11 @@ class ProcedureService extends BaseService { Future getProcedureTemplateDetails( {int doctorId, int projectId, int clinicId, int templateId}) async { _procedureTempleteDetailsRequestModel = - ProcedureTempleteDetailsRequestModel(templateID: templateId); + ProcedureTempleteDetailsRequestModel( + templateID: templateId, searchType: 1, patientID: 0); hasError = false; //insuranceApprovalInPatient.clear(); + _templateDetailsList.clear(); await baseAppClient.post(GET_PROCEDURE_TEMPLETE_DETAILS, onSuccess: (dynamic response, int statusCode) { diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 434e108e..bf790335 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -110,7 +110,9 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } + int tempId = 0; Future getProcedureTemplateDetails({int templateId}) async { + tempId = templateId; hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index ee128caa..89a382ad 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -27,11 +28,15 @@ class _AddFavouriteProcedureState extends State { _AddFavouriteProcedureState({this.patient, this.model}); ProcedureViewModel model; PatiantInformtion patient; - List entityList = List(); + List entityList = List(); @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getProcedureTemplate(), + onModelReady: (model) async { + if (model.procedureTemplate.length == 0) { + model.getProcedureTemplate(); + } + }, builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -52,12 +57,12 @@ class _AddFavouriteProcedureState extends State { EntityListCheckboxSearchFavProceduresWidget( model: widget.model, masterList: widget.model.procedureTemplate, - removeHistory: (item) { + removeFavProcedure: (item) { setState(() { entityList.remove(item); }); }, - addHistory: (history) { + addFavProcedure: (history) { setState(() { entityList.add(history); }); @@ -66,7 +71,7 @@ class _AddFavouriteProcedureState extends State { //TODO build your fun herr // widget.addSelectedHistories(); }, - isEntityListSelected: (master) => + isEntityFavListSelected: (master) => isEntityListSelected(master), ) // : ProcedureListWidget( @@ -131,8 +136,8 @@ class _AddFavouriteProcedureState extends State { ); } - bool isEntityListSelected(ProcedureTempleteModel masterKey) { - Iterable history = entityList + bool isEntityListSelected(ProcedureTempleteDetailsModel masterKey) { + Iterable history = entityList .where((element) => masterKey.templateID == element.templateID); if (history.length > 0) { return true; diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index c052f789..31b2a784 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; @@ -17,7 +18,12 @@ class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { final Function(ProcedureTempleteModel) addHistory; final Function(ProcedureTempleteModel) addRemarks; + final Function(ProcedureTempleteDetailsModel) removeFavProcedure; + final Function(ProcedureTempleteDetailsModel) addFavProcedure; + final Function(ProcedureTempleteDetailsModel) addProceduresRemarks; + final bool Function(ProcedureTempleteModel) isEntityListSelected; + final bool Function(ProcedureTempleteDetailsModel) isEntityFavListSelected; final List masterList; EntityListCheckboxSearchFavProceduresWidget( @@ -27,7 +33,11 @@ class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { this.removeHistory, this.masterList, this.addHistory, + this.addFavProcedure, + this.addProceduresRemarks, + this.removeFavProcedure, this.isEntityListSelected, + this.isEntityFavListSelected, this.addRemarks}) : super(key: key); @@ -49,7 +59,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState } List items = List(); - //List items = List(); + List itemsProcedure = List(); List remarksList = List(); List typeList = List(); @@ -128,65 +138,72 @@ class _EntityListCheckboxSearchFavProceduresWidgetState ), ), children: [ - Container( - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 12), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( + Column( + children: widget + .model.procedureTemplateDetails + .map((itemProcedure) { + return Container( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 12), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets - .symmetric( - horizontal: 11), - child: Checkbox( - value: widget - .isEntityListSelected( - historyInfo), - activeColor: - Color(0xffD02127), - onChanged: - (bool newValue) { - setState(() { - if (widget - .isEntityListSelected( - historyInfo)) { - widget.removeHistory( - historyInfo); - } else { - widget.addHistory( - historyInfo); - } - }); - }), - ), - Expanded( - child: Padding( - padding: const EdgeInsets - .symmetric( - horizontal: 10, - vertical: 0), - child: AppText( - widget - .model - .procedureTemplate[ - 0] - .templateName, - fontSize: 14.0, - variant: "bodyText", - bold: true, - color: Color( - 0xff575757)), - ), + Row( + children: [ + Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: 11), + child: Checkbox( + value: widget + .isEntityFavListSelected( + itemProcedure), + activeColor: Color( + 0xffD02127), + onChanged: (bool + newValue) { + setState(() { + if (widget + .isEntityFavListSelected( + itemProcedure)) { + widget.removeFavProcedure( + itemProcedure); + } else { + widget.addFavProcedure( + itemProcedure); + } + }); + }), + ), + Expanded( + child: Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: + 10, + vertical: 0), + child: AppText( + itemProcedure + .procedureName, + fontSize: 14.0, + variant: + "bodyText", + bold: true, + color: Color( + 0xff575757)), + ), + ), + ], ), ], ), - ], - ), - ), + ), + ); + }).toList(), ), SizedBox( height: 2.0, From f6539c82a6fc90e2cda935afc5e790506c7b2946 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 19 May 2021 15:06:47 +0300 Subject: [PATCH 058/241] add live care card in home page --- .../patient/LiveCarePatientServices.dart | 5 ++ .../viewModel/LiveCarePatientViewModel.dart | 6 ++ lib/locator.dart | 4 ++ lib/screens/home/home_screen.dart | 15 +++++ .../live_care/LiveCarePatientScreen.dart | 59 +++++++++++++++++++ lib/screens/live_care/end_call_screen.dart | 2 - 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 lib/core/service/patient/LiveCarePatientServices.dart create mode 100644 lib/core/viewModel/LiveCarePatientViewModel.dart create mode 100644 lib/screens/live_care/LiveCarePatientScreen.dart diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart new file mode 100644 index 00000000..31d3cf82 --- /dev/null +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -0,0 +1,5 @@ +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; + +class LiveCarePatientServices extends BaseService{ + +} \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart new file mode 100644 index 00000000..de185de6 --- /dev/null +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -0,0 +1,6 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; + +class LiveCarePatientViewModel extends BaseViewModel { + getPendingPatientERForDoctorApp() async {} +} diff --git a/lib/locator.dart b/lib/locator.dart index 4cb18514..1c369103 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -10,6 +10,7 @@ import 'package:get_it/get_it.dart'; import 'core/service/home/dasboard_service.dart'; import 'core/service/patient/DischargedPatientService.dart'; +import 'core/service/patient/LiveCarePatientServices.dart'; import 'core/service/patient/patient_service.dart'; import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; import 'core/service/patient/MyReferralPatientService.dart'; @@ -37,6 +38,7 @@ import 'core/service/patient/referred_patient_service.dart'; import 'core/service/home/schedule_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; +import 'core/viewModel/LiveCarePatientViewModel.dart'; import 'core/viewModel/PatientMuseViewModel.dart'; import 'core/viewModel/PatientSearchViewModel.dart'; import 'core/viewModel/SOAP_view_model.dart'; @@ -86,6 +88,7 @@ void setupLocator() { locator.registerLazySingleton(() => PatientInPatientService()); locator.registerLazySingleton(() => OutPatientService()); locator.registerLazySingleton(() => HospitalsService()); + locator.registerLazySingleton(() => LiveCarePatientServices()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -112,4 +115,5 @@ void setupLocator() { locator.registerFactory(() => DischargedPatientViewModel()); locator.registerFactory(() => PatientSearchViewModel()); locator.registerFactory(() => HospitalViewModel()); + locator.registerFactory(() => LiveCarePatientViewModel()); } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 1b864430..cd610c0b 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -289,6 +289,21 @@ class _HomeScreenState extends State { child: ListView( scrollDirection: Axis.horizontal, children: [ + HomePatientCard( + backgroundColor: Color(0xffD02127), + backgroundIconColor: Colors.white12, + cardIcon: DoctorApp.inpatient, + textColor: Colors.white, + text: "Live Care Patients", + onTap: () { + Navigator.push( + context, + FadePage( + page: PatientInPatientScreen(), + ), + ); + }, + ), HomePatientCard( backgroundColor: Color(0xffD02127), backgroundIconColor: Colors.white12, diff --git a/lib/screens/live_care/LiveCarePatientScreen.dart b/lib/screens/live_care/LiveCarePatientScreen.dart new file mode 100644 index 00000000..9f5e55ac --- /dev/null +++ b/lib/screens/live_care/LiveCarePatientScreen.dart @@ -0,0 +1,59 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.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:flutter/material.dart'; + +class LiveCarePatientScreen extends StatefulWidget { + @override + _LiveCarePatientScreenState createState() => _LiveCarePatientScreenState(); +} + +class _LiveCarePatientScreenState extends State { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) async {}, + 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( + "Live Care Patients", + fontSize: SizeConfig.textMultiplier * 2.8, + fontWeight: FontWeight.bold, + color: Color(0xFF2B353E), + ), + ), + ]), + ), + ), + Expanded( + child: Column( + children: [], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index b4a7c415..880c8fd8 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -11,8 +11,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; -import '../../routes.dart'; - class EndCallScreen extends StatefulWidget { final PatiantInformtion patient; From 342477beda7e6368eb01eaa5020e7ffb91b01d70 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 19 May 2021 15:06:57 +0300 Subject: [PATCH 059/241] add rich editor for MedicalReportPage --- .../AddVerifyMedicalReport.dart | 153 ++---------------- .../medical_report/MedicalReportPage.dart | 2 + .../shared/text_fields/html_rich_editor.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 16 insertions(+), 143 deletions(-) diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index a350544b..4c51e3d7 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -3,7 +3,7 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.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/dr_app_toast_msg.dart'; @@ -12,13 +12,13 @@ import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/html_rich_editor.dart'; import 'package:flutter/material.dart'; +import 'package:html_editor_enhanced/html_editor.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; -import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; class AddVerifyMedicalReport extends StatefulWidget { @override @@ -72,8 +72,6 @@ class _AddVerifyMedicalReportState extends State { ? routeArgs['medicalReport'] : null; - // model.medicalReportTemplate[0].templateTextHtml - return BaseView( onModelReady: (model) => model.getMedicalReportTemplate(), builder: (_, model, w) => AppScaffold( @@ -96,117 +94,9 @@ class _AddVerifyMedicalReportState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Stack( - children: [ - AppTextFieldCustom( - hintText: TranslationBase.of(context) - .historyPhysicalFinding, - controller: historyFindingController, - maxLines: 15, - minLines: 10, - hasBorder: true, - validationError: commentsError, - ), - Positioned( - top: -2, - //MediaQuery.of(context).size.height * 0, - right: projectViewModel.isArabic - ? MediaQuery.of(context) - .size - .width * - 0.75 - : 15, - child: Column( - children: [ - IconButton( - icon: Icon( - DoctorApp.speechtotext, - color: Colors.black, - size: 35), - onPressed: () { - initSpeechState().then( - (value) => - {onVoiceText()}); - }, - ), - ], - )), - ], - ), - Stack( - children: [ - AppTextFieldCustom( - hintText: TranslationBase.of(context) - .laboratoryPhysicalData, - controller: laboratoryDataController, - maxLines: 15, - minLines: 10, - hasBorder: true, - validationError: comments2Error, - ), - Positioned( - top: -2, - //MediaQuery.of(context).size.height * 0, - right: projectViewModel.isArabic - ? MediaQuery.of(context) - .size - .width * - 0.75 - : 15, - child: Column( - children: [ - IconButton( - icon: Icon( - DoctorApp.speechtotext, - color: Colors.black, - size: 35), - onPressed: () { - initSpeechState2().then( - (value) => - {onVoiceText2()}); - }, - ), - ], - )), - ], - ), - Stack( - children: [ - AppTextFieldCustom( - hintText: TranslationBase.of(context) - .impressionRecommendation, - controller: recommendationController, - maxLines: 15, - minLines: 10, - hasBorder: true, - validationError: comments3Error, - ), - Positioned( - top: -2, - //MediaQuery.of(context).size.height * 0, - right: projectViewModel.isArabic - ? MediaQuery.of(context) - .size - .width * - 0.75 - : 15, - child: Column( - children: [ - IconButton( - icon: Icon( - DoctorApp.speechtotext, - color: Colors.black, - size: 35), - onPressed: () { - initSpeechState3().then( - (value) => - {onVoiceText3()}); - }, - ), - ], - )), - ], - ), + HtmlRichEditor(initialText: model + .medicalReportTemplate[0] + .templateTextHtml, height: MediaQuery.of(context).size.height * 0.75,), ], ), ), @@ -231,32 +121,13 @@ class _AddVerifyMedicalReportState extends State { // disabled: progressNoteController.text.isEmpty, fontWeight: FontWeight.w700, onPressed: () async { - setState(() { - if (historyFindingController.text == "") { - commentsError = - TranslationBase.of(context).fieldRequired; - } else { - commentsError = null; - } - if (laboratoryDataController.text == "") { - comments2Error = - TranslationBase.of(context).fieldRequired; - } else { - comments2Error = null; - } - if (recommendationController.text == "") { - comments3Error = - TranslationBase.of(context).fieldRequired; - } else { - comments3Error = null; - } - }); - if (historyFindingController.text != "" && - laboratoryDataController.text != "" && - recommendationController.text != "") { + + String txtOfMedicalReport = await HtmlEditor.getText(); + + if (txtOfMedicalReport.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); - model.insertMedicalReport(patient, - "${historyFindingController.text}\n${laboratoryDataController.text}\n${recommendationController.text}"); + model.insertMedicalReport(patient,txtOfMedicalReport + ); GifLoaderDialogUtils.hideDialog(context); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index d986500e..4dad827c 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -36,6 +36,8 @@ class MedicalReportPage extends StatelessWidget { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: PatientProfileHeaderNewDesignAppBar( patient, patientType, diff --git a/lib/widgets/shared/text_fields/html_rich_editor.dart b/lib/widgets/shared/text_fields/html_rich_editor.dart index 1d87685b..71359604 100644 --- a/lib/widgets/shared/text_fields/html_rich_editor.dart +++ b/lib/widgets/shared/text_fields/html_rich_editor.dart @@ -82,8 +82,8 @@ class _HtmlRichEditorState extends State { // Style(), Font(buttons: [ FontButtons.bold, + FontButtons.italic, FontButtons.underline, - FontButtons.clear ]), // ColorBar(buttons: [ColorButtons.color]), Paragraph(buttons: [ diff --git a/pubspec.yaml b/pubspec.yaml index a5026871..2e4d7ce8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -92,7 +92,7 @@ dependencies: - #Html Editor Enhanced + # Html Editor Enhanced html_editor_enhanced: ^1.3.0 dev_dependencies: From c182928a5d902267904c3896196fd8d7f27c4e21 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Wed, 19 May 2021 17:17:09 +0300 Subject: [PATCH 060/241] favourite template Procedure service --- lib/client/base_app_client.dart | 12 +- lib/config/config.dart | 17 +- .../procedures/procedure_checkout_screen.dart | 227 ++++++++++++++++++ lib/screens/procedures/procedure_screen.dart | 14 +- 4 files changed, 254 insertions(+), 16 deletions(-) create mode 100644 lib/screens/procedures/procedure_checkout_screen.dart diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 7336db13..fe7db950 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -24,7 +24,7 @@ class BaseAppClient { bool isAllowAny = false}) async { String url = BASE_URL + endPoint; - bool callLog= true; + bool callLog = true; try { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); String token = await sharedPref.getString(TOKEN); @@ -48,7 +48,7 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = token ?? ''; + body['TokenID'] = "@dm!n" ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') body['LanguageID'] = 1; @@ -74,9 +74,9 @@ class BaseAppClient { //int projectID = await sharedPref.getInt(PROJECT_ID); //if (projectID == 2 || projectID == 3) - // body['PatientOutSA'] = true; + // body['PatientOutSA'] = true; //else - body['PatientOutSA'] = false; + body['PatientOutSA'] = false; body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; print("URL : $url"); @@ -104,7 +104,9 @@ class BaseAppClient { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { - await Provider.of(AppGlobal.CONTEX, listen: false).logout(); + await Provider.of(AppGlobal.CONTEX, + listen: false) + .logout(); Helpers.showErrorToast('Your session expired Please login again'); } if (isAllowAny) { diff --git a/lib/config/config.dart b/lib/config/config.dart index 0e8106bc..8464f720 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +//const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = @@ -283,11 +283,14 @@ const GET_SICK_LEAVE_PATIENT = "Services/Patients.svc/REST/GetPatientSickLeave"; const GET_MY_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GetMyOutPatient"; - -const PATIENT_MEDICAL_REPORT_GET_LIST = "Services/Patients.svc/REST/DAPP_ListMedicalReport"; -const PATIENT_MEDICAL_REPORT_GET_TEMPLATE = "Services/Patients.svc/REST/DAPP_GetTemplateByID"; -const PATIENT_MEDICAL_REPORT_INSERT = "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; -const PATIENT_MEDICAL_REPORT_VERIFIED = "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; +const PATIENT_MEDICAL_REPORT_GET_LIST = + "Services/Patients.svc/REST/DAPP_ListMedicalReport"; +const PATIENT_MEDICAL_REPORT_GET_TEMPLATE = + "Services/Patients.svc/REST/DAPP_GetTemplateByID"; +const PATIENT_MEDICAL_REPORT_INSERT = + "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; +const PATIENT_MEDICAL_REPORT_VERIFIED = + "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; const GET_PROCEDURE_TEMPLETE = 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart new file mode 100644 index 00000000..04bbaa3a --- /dev/null +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -0,0 +1,227 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_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/shared/TextFields.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/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ProcedureCheckOutScreen extends StatefulWidget { + @override + _ProcedureCheckOutScreenState createState() => + _ProcedureCheckOutScreenState(); +} + +class _ProcedureCheckOutScreenState extends State { + List items = List(); + List remarksList = List(); + List typeList = List(); + int selectedType = 0; + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + backgroundColor: Color(0xffF8F8F8).withOpacity(0.9), + isShowAppBar: false, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + color: Colors.white, + ), + Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Row( + //mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + child: Icon( + Icons.arrow_back_ios_sharp, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ), + SizedBox( + width: 5.0, + ), + AppText( + 'Add Procedure', + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ], + ), + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.022, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: ListView.builder( + scrollDirection: Axis.vertical, + physics: AlwaysScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: 1, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.all(Radius.circular(10.0))), + child: ExpansionTile( + initiallyExpanded: true, + title: Row( + children: [ + Icon( + Icons.check_box, + color: Color(0xffD02127), + size: 30.5, + ), + SizedBox( + width: 6.0, + ), + AppText('Procedure Name'), + ], + ), + children: [ + Container( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 11), + child: AppText( + TranslationBase.of(context).orderType, + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + ), + ), + ], + ), + Row( + children: [ + Radio( + activeColor: Color(0xFFD02127), + value: 0, + groupValue: selectedType, + onChanged: (value) { + // historyInfo.type = + // setSelectedType(value).toString(); + // + // historyInfo.type = value.toString(); + }, + ), + AppText( + 'routine', + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + Radio( + activeColor: Color(0xFFD02127), + groupValue: selectedType, + value: 1, + onChanged: (value) { + // historyInfo.type = + // setSelectedType(value).toString(); + // + // historyInfo.type = value.toString(); + }, + ), + AppText( + TranslationBase.of(context).urgent, + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + ], + ), + ], + ), + ), + ), + SizedBox( + height: 2.0, + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: 12, vertical: 15.0), + child: TextFields( + hintText: TranslationBase.of(context).remarks, + //controller: remarksController, + onChanged: (value) { + // historyInfo.remarks = value; + }, + minLines: 3, + maxLines: 5, + borderWidth: 0.5, + borderColor: Colors.grey[500], + ), + ), + SizedBox( + height: 19.0, + ), + //DividerWithSpacesAround(), + ], + ), + ); + }), + ), + ], + ), + bottomSheet: Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: TranslationBase.of(context).addSelectedProcedures, + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () { + //print(entityList.toString()); + onPressed: + // if (entityList.isEmpty == true) { + // DrAppToastMsg.showErrorToast( + // TranslationBase.of(context) + // .fillTheMandatoryProcedureDetails, + // ); + // return; + // } + + Navigator.pop(context); + // postProcedure( + // orderType: selectedType.toString(), + // entityList: entityList, + // patient: patient, + // model: widget.model, + // remarks: remarksController.text); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index b964392e..8d03f86c 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -7,6 +7,7 @@ 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/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; +import 'package:doctor_app_flutter/screens/procedures/procedure_checkout_screen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -102,13 +103,18 @@ class ProcedureScreen extends StatelessWidget { patient.patientStatusType == 43) InkWell( onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => AddProcedureHome( + // patient: patient, + // model: model, + // )), + // ); Navigator.push( context, MaterialPageRoute( - builder: (context) => AddProcedureHome( - patient: patient, - model: model, - )), + builder: (context) => ProcedureCheckOutScreen()), ); }, child: Container( From 40b4a83c6b3ae9890fbb05e073dd3ede9a13d30e Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 19 May 2021 17:20:14 +0300 Subject: [PATCH 061/241] Fix Expansion Procedure --- ios/Podfile.lock | 2 +- lib/client/base_app_client.dart | 3 +- lib/config/config.dart | 4 +- lib/core/viewModel/procedure_View_model.dart | 2 +- .../procedures/ExpansionProcedure.dart | 189 ++++++++++++++++++ .../procedures/add-favourite-procedure.dart | 45 +---- .../procedures/entity_list_fav_procedure.dart | 121 +---------- pubspec.lock | 6 +- 8 files changed, 215 insertions(+), 157 deletions(-) create mode 100644 lib/screens/procedures/ExpansionProcedure.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1cf7499c..59cdf14c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -328,4 +328,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.1 diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 7336db13..4b362e35 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -48,7 +48,8 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = token ?? ''; + body['TokenID'] = "@dm!n";// token ?? ''; + // body['TokenID'] = token ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') body['LanguageID'] = 1; diff --git a/lib/config/config.dart b/lib/config/config.dart index 0e8106bc..8d5459cc 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 4f9a7cf6..3bdd676f 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -115,7 +115,7 @@ class ProcedureViewModel extends BaseViewModel { tempId = templateId; hasError = false; //_insuranceCardService.clearInsuranceCard(); - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _procedureService.getProcedureTemplateDetails(templateId: templateId); if (_procedureService.hasError) { error = _procedureService.error; diff --git a/lib/screens/procedures/ExpansionProcedure.dart b/lib/screens/procedures/ExpansionProcedure.dart new file mode 100644 index 00000000..188f6634 --- /dev/null +++ b/lib/screens/procedures/ExpansionProcedure.dart @@ -0,0 +1,189 @@ +import 'package:doctor_app_flutter/client/base_app_client.dart'; +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_request_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ExpansionProcedure extends StatefulWidget { + final ProcedureTempleteModel procedureTempleteModel; + final ProcedureViewModel model; + final Function(ProcedureTempleteDetailsModel) removeFavProcedure; + final Function(ProcedureTempleteDetailsModel) addFavProcedure; + final Function(ProcedureTempleteDetailsModel) addProceduresRemarks; + + final bool Function(ProcedureTempleteModel) isEntityListSelected; + final bool Function(ProcedureTempleteDetailsModel) isEntityFavListSelected; + + const ExpansionProcedure( + {Key key, + this.procedureTempleteModel, + this.model, + this.removeFavProcedure, + this.addFavProcedure, + this.addProceduresRemarks, + this.isEntityListSelected, + this.isEntityFavListSelected}) + : super(key: key); + + @override + _ExpansionProcedureState createState() => _ExpansionProcedureState(); +} + +class _ExpansionProcedureState extends State { + bool _isShowMore = false; + List _templateDetailsList = List(); + BaseAppClient baseAppClient = BaseAppClient(); + @override + Widget build(BuildContext context) { + return Column( + children: [ + InkWell( + onTap: () async { + if (!_isShowMore && _templateDetailsList.isEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await getProcedureTemplateDetails(widget.procedureTempleteModel.templateID); + GifLoaderDialogUtils.hideDialog(context); + } + setState(() { + _isShowMore = !_isShowMore; + }); + }, + child: Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(5.0), + )), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + Icon( + Icons.folder, + size: 20, + color: Color(0xff575757), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 0), + child: AppText( + "Procedures for " + + widget.procedureTempleteModel.templateName, + fontSize: 16.0, + variant: "bodyText", + bold: true, + color: Color(0xff575757)), + ), + ), + ], + )), + Container( + width: 25, + height: 25, + child: Icon( + _isShowMore + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + color: Colors.grey[800], + size: 22, + ), + ) + ], + ), + ), + ), + if (_isShowMore) + AnimatedContainer( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(5.0), + bottomRight: Radius.circular(5.0), + )), + duration: Duration(milliseconds: 7000), + child: Column( + children: + _templateDetailsList.map((itemProcedure) { + return Container( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 11), + child: Checkbox( + value: widget + .isEntityFavListSelected(itemProcedure), + activeColor: Color(0xffD02127), + onChanged: (bool newValue) { + setState(() { + if (widget.isEntityFavListSelected(itemProcedure)) { + widget.removeFavProcedure(itemProcedure); + } else { + widget.addFavProcedure(itemProcedure); + } + }); + }), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 0), + child: AppText(itemProcedure.procedureName, + fontSize: 14.0, + variant: "bodyText", + bold: true, + color: Color(0xff575757)), + ), + ), + ], + ), + ], + ), + ), + ); + }).toList(), + ), + ), + SizedBox( + height: 10, + ), + ], + ); + } + + getProcedureTemplateDetails(templateId)async { + ProcedureTempleteDetailsRequestModel _procedureTempleteDetailsRequestModel = ProcedureTempleteDetailsRequestModel(templateID: templateId, searchType: 1, patientID: 0); + _templateDetailsList.clear(); + await baseAppClient.post(GET_PROCEDURE_TEMPLETE_DETAILS, + onSuccess: (dynamic response, int statusCode) { + response['HIS_ProcedureTemplateDetailsList'].forEach((template) { + setState(() { + _templateDetailsList.add(ProcedureTempleteDetailsModel.fromJson(template)); + }); + }); + }, onFailure: (String error, int statusCode) { + DrAppToastMsg.showErrorToast(error); + + }, body: _procedureTempleteDetailsRequestModel.toJson()); + } + +} diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index 89a382ad..fe95735d 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -20,15 +20,18 @@ class AddFavouriteProcedure extends StatefulWidget { const AddFavouriteProcedure({Key key, this.model, this.patient}) : super(key: key); + @override _AddFavouriteProcedureState createState() => _AddFavouriteProcedureState(); } class _AddFavouriteProcedureState extends State { _AddFavouriteProcedureState({this.patient, this.model}); + ProcedureViewModel model; PatiantInformtion patient; List entityList = List(); + @override Widget build(BuildContext context) { return BaseView( @@ -49,12 +52,7 @@ class _AddFavouriteProcedureState extends State { Expanded( child: NetworkBaseView( baseViewModel: model, - child: - // selectedCategory != null - // ? selectedCategory['categoryId'] == 02 || - // selectedCategory['categoryId'] == 03 - // ? - EntityListCheckboxSearchFavProceduresWidget( + child: EntityListCheckboxSearchFavProceduresWidget( model: widget.model, masterList: widget.model.procedureTemplate, removeFavProcedure: (item) { @@ -73,30 +71,7 @@ class _AddFavouriteProcedureState extends State { }, isEntityFavListSelected: (master) => isEntityListSelected(master), - ) - // : ProcedureListWidget( - // model: widget.model, - // masterList: widget.model - // .categoriesList[0].entityList, - // removeHistory: (item) { - // setState(() { - // entityList.remove(item); - // }); - // }, - // addHistory: (history) { - // setState(() { - // entityList.add(history); - // }); - // }, - // addSelectedHistories: () { - // //TODO build your fun herr - // // widget.addSelectedHistories(); - // }, - // isEntityListSelected: (master) => - // isEntityListSelected(master), - // ) - // : null, - ), + )), ), Container( margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), @@ -108,8 +83,6 @@ class _AddFavouriteProcedureState extends State { color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () { - //print(entityList.toString()); - onPressed: if (entityList.isEmpty == true) { DrAppToastMsg.showErrorToast( TranslationBase.of(context) @@ -119,12 +92,6 @@ class _AddFavouriteProcedureState extends State { } Navigator.pop(context); - // postProcedure( - // orderType: selectedType.toString(), - // entityList: entityList, - // patient: patient, - // model: widget.model, - // remarks: remarksController.text); }, ), ], @@ -138,7 +105,7 @@ class _AddFavouriteProcedureState extends State { bool isEntityListSelected(ProcedureTempleteDetailsModel masterKey) { Iterable history = entityList - .where((element) => masterKey.templateID == element.templateID); + .where((element) => masterKey.templateID == element.templateID && masterKey.procedureName == element.procedureName); if (history.length > 0) { return true; } diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index 31b2a784..1dac2f24 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -11,6 +11,8 @@ import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'ExpansionProcedure.dart'; + class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { final ProcedureViewModel model; final Function addSelectedHistories; @@ -70,6 +72,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState } TextEditingController remarksController = TextEditingController(); + @override Widget build(BuildContext context) { return Container( @@ -102,116 +105,14 @@ class _EntityListCheckboxSearchFavProceduresWidgetState items.length != 0 ? Column( children: items.map((historyInfo) { - return Column( - children: [ - ExpansionTile( - title: InkWell( - onTap: () { - widget.model - .getProcedureTemplateDetails( - templateId: - historyInfo.templateID); - }, - child: Row( - children: [ - Icon( - Icons.folder, - size: 20, - color: Color(0xff575757), - ), - Expanded( - child: Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 10, - vertical: 0), - child: AppText( - "Procedures for " + - historyInfo.templateName, - fontSize: 16.0, - variant: "bodyText", - bold: true, - color: Color(0xff575757)), - ), - ), - ], - ), - ), - children: [ - Column( - children: widget - .model.procedureTemplateDetails - .map((itemProcedure) { - return Container( - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 12), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Padding( - padding: - const EdgeInsets - .symmetric( - horizontal: 11), - child: Checkbox( - value: widget - .isEntityFavListSelected( - itemProcedure), - activeColor: Color( - 0xffD02127), - onChanged: (bool - newValue) { - setState(() { - if (widget - .isEntityFavListSelected( - itemProcedure)) { - widget.removeFavProcedure( - itemProcedure); - } else { - widget.addFavProcedure( - itemProcedure); - } - }); - }), - ), - Expanded( - child: Padding( - padding: - const EdgeInsets - .symmetric( - horizontal: - 10, - vertical: 0), - child: AppText( - itemProcedure - .procedureName, - fontSize: 14.0, - variant: - "bodyText", - bold: true, - color: Color( - 0xff575757)), - ), - ), - ], - ), - ], - ), - ), - ); - }).toList(), - ), - SizedBox( - height: 2.0, - ), - DividerWithSpacesAround(), - ], - ), - ], + return ExpansionProcedure( + procedureTempleteModel: historyInfo, + model: widget.model, + removeFavProcedure: widget.removeFavProcedure, + addFavProcedure: widget.addFavProcedure, + addProceduresRemarks: widget.addProceduresRemarks, + isEntityListSelected: widget.isEntityListSelected, + isEntityFavListSelected: widget.isEntityFavListSelected, ); }).toList(), ) diff --git a/pubspec.lock b/pubspec.lock index 613c2753..4b6a9b7a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 67e0cac7428cd36a677295cc6c566e18d30a1f02 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 19 May 2021 17:46:00 +0300 Subject: [PATCH 062/241] add livecare to home --- lib/config/config.dart | 2 + lib/core/service/home/dasboard_service.dart | 21 +- lib/core/viewModel/dashboard_view_model.dart | 29 +- lib/screens/home/home_screen.dart | 267 ++++++++++-------- .../AddVerifyMedicalReport.dart | 187 +----------- .../medical_report/MedicalReportPage.dart | 51 ++-- pubspec.lock | 8 +- 7 files changed, 247 insertions(+), 318 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 0e8106bc..1760caef 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -295,6 +295,8 @@ const GET_PROCEDURE_TEMPLETE = const GET_PROCEDURE_TEMPLETE_DETAILS = "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; +const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index 5a66e9eb..685646ee 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -6,7 +6,8 @@ class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; - // DashboardModel _dashboard = DashboardModel(); + bool hasVirtualClinic; + String sServiceID; Future getDashboard() async { hasError = false; @@ -28,4 +29,22 @@ class DashboardService extends BaseService { }, ); } + + Future checkDoctorHasLiveCare() async { + hasError = false; + await baseAppClient.post( + DOCTOR_CHECK_HAS_LIVE_CARE, + onSuccess: (dynamic response, int statusCode) { + hasVirtualClinic = response['HasVirtualClinic']; + sServiceID = response['SserviceID']; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "DoctorID": 9920 + }, + ); + } } diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index a1f83293..bbbef0b6 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -12,14 +12,18 @@ import 'authentication_view_model.dart'; import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { - final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); DashboardService _dashboardService = locator(); List get dashboardItemsList => _dashboardService.dashboardItemsList; - Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async{ + bool get hasVirtualClinic => _dashboardService.hasVirtualClinic; + + String get sServiceID => _dashboardService.sServiceID; + + Future setFirebaseNotification(ProjectViewModel projectsProvider, + AuthenticationViewModel authProvider) async { setState(ViewState.Busy); await projectsProvider.getDoctorClinicsList(); @@ -50,12 +54,27 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future changeClinic(int clinicId, AuthenticationViewModel authProvider) async { + Future checkDoctorHasLiveCare() async { + setState(ViewState.Busy); + await _dashboardService.checkDoctorHasLiveCare(); + if (_dashboardService.hasError) { + error = _dashboardService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future changeClinic( + int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); await getDoctorProfile(); - ClinicModel clinicModel = ClinicModel(doctorID:doctorProfile.doctorID,clinicID: clinicId, projectID: doctorProfile.projectID,); + ClinicModel clinicModel = ClinicModel( + doctorID: doctorProfile.doctorID, + clinicID: clinicId, + projectID: doctorProfile.projectID, + ); await authProvider.getDoctorProfileBasedOnClinic(clinicModel); - if(authProvider.state == ViewState.ErrorLocal) { + if (authProvider.state == ViewState.ErrorLocal) { error = authProvider.error; } } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 40277db9..f99dc727 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -33,7 +33,6 @@ import 'package:provider/provider.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; import '../../widgets/shared/app_texts_widget.dart'; -import 'home_page_card.dart'; class HomeScreen extends StatefulWidget { HomeScreen({Key key, this.title}) : super(key: key); @@ -55,6 +54,7 @@ class _HomeScreenState extends State { int sliderActiveIndex = 0; var clinicId; AuthenticationViewModel authenticationViewModel; + int colorIndex = 0; @override Widget build(BuildContext context) { @@ -68,9 +68,11 @@ class _HomeScreenState extends State { return BaseView( onModelReady: (model) async { - await model.setFirebaseNotification(projectsProvider, authenticationViewModel); + await model.setFirebaseNotification( + projectsProvider, authenticationViewModel); await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); + await model.checkDoctorHasLiveCare(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, @@ -289,117 +291,7 @@ class _HomeScreenState extends State { child: ListView( scrollDirection: Axis.horizontal, children: [ - HomePatientCard( - backgroundColor: Color(0xffD02127), - backgroundIconColor: Colors.white12, - cardIcon: DoctorApp.inpatient, - textColor: Colors.white, - text: "Live Care Patients", - onTap: () { - Navigator.push( - context, - FadePage( - page: PatientInPatientScreen(), - ), - ); - }, - ), - HomePatientCard( - backgroundColor: Color(0xffD02127), - backgroundIconColor: Colors.white12, - cardIcon: DoctorApp.inpatient, - textColor: Colors.white, - text: TranslationBase.of(context) - .myInPatient, - onTap: () { - Navigator.push( - context, - FadePage( - page: PatientInPatientScreen(), - ), - ); - }, - ), - HomePatientCard( - backgroundColor: Colors.grey[300], - backgroundIconColor: Colors.white38, - cardIcon: DoctorApp.arrival_patients, - textColor: Colors.black, - text: TranslationBase.of(context) - .myOutPatient_2lines, - onTap: () { - String date = - AppDateUtils.convertDateToFormat( - DateTime( - DateTime.now().year, - DateTime.now().month, - DateTime.now().day), - 'yyyy-MM-dd'); - - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => OutPatientsScreen( - patientSearchRequestModel: - PatientSearchRequestModel( - from: date, - to: date, - doctorID: - authenticationViewModel - .doctorProfile - .doctorID)), - )); - }, - ), - HomePatientCard( - backgroundColor: Color(0xff2B353E), - backgroundIconColor: Colors.white10, - cardIcon: DoctorApp.referral_1, - textColor: Colors.white, - text: TranslationBase.of(context) - .myPatientsReferral, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - PatientReferralScreen(), - ), - ); - }, - ), - HomePatientCard( - backgroundColor: Color(0xffD02127), - backgroundIconColor: Colors.white10, - cardIcon: DoctorApp.search, - textColor: Colors.white, - text: TranslationBase.of(context) - .searchPatientDashBoard, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - PatientSearchScreen(), - )); - }, - ), - HomePatientCard( - backgroundColor: Color(0xffC9C9C9), - backgroundIconColor: Colors.black12, - cardIcon: DoctorApp.search_medicines, - textColor: Color(0xff2B353E), - text: TranslationBase.of(context) - .searchMedicineDashboard, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - MedicineSearchScreen(), - )); - }, - ), + ...homePatientsCardsWidget(model), ])), SizedBox( height: 20, @@ -416,4 +308,153 @@ class _HomeScreenState extends State { ), ); } + + List homePatientsCardsWidget(DashboardViewModel model) { + colorIndex = 0; + + List backgroundColors = List(3); + backgroundColors[0] = Color(0xffD02127); + backgroundColors[1] = Colors.grey[300]; + backgroundColors[2] = Color(0xff2B353E); + List backgroundIconColors = List(3); + backgroundIconColors[0] = Colors.white12; + backgroundIconColors[1] = Colors.white38; + backgroundIconColors[2] = Colors.white10; + List textColors = List(3); + textColors[0] = Colors.white; + textColors[1] = Colors.black; + textColors[2] = Colors.white; + + List patientCards = List(); + + if (model.hasVirtualClinic) { + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.inpatient, + textColor: textColors[colorIndex], + text: + "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", + onTap: () { + Navigator.push( + context, + FadePage( + page: PatientInPatientScreen(), + ), + ); + }, + )); + changeColorIndex(); + } + + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.inpatient, + textColor: textColors[colorIndex], + text: TranslationBase.of(context).myInPatient, + onTap: () { + Navigator.push( + context, + FadePage( + page: PatientInPatientScreen(), + ), + ); + }, + )); + changeColorIndex(); + + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.arrival_patients, + textColor: textColors[colorIndex], + text: TranslationBase.of(context).myOutPatient_2lines, + onTap: () { + String date = AppDateUtils.convertDateToFormat( + DateTime( + DateTime.now().year, DateTime.now().month, DateTime.now().day), + 'yyyy-MM-dd'); + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => OutPatientsScreen( + patientSearchRequestModel: PatientSearchRequestModel( + from: date, + to: date, + doctorID: + authenticationViewModel.doctorProfile.doctorID)), + )); + }, + )); + changeColorIndex(); + + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.referral_1, + textColor: textColors[colorIndex], + text: TranslationBase.of(context) + .myPatientsReferral, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + PatientReferralScreen(), + ), + ); + }, + )); + changeColorIndex(); + + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.search, + textColor: textColors[colorIndex], + text: TranslationBase.of(context) + .searchPatientDashBoard, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + PatientSearchScreen(), + )); + }, + )); + changeColorIndex(); + + patientCards.add(HomePatientCard( + backgroundColor: backgroundColors[colorIndex], + backgroundIconColor: backgroundIconColors[colorIndex], + cardIcon: DoctorApp.search_medicines, + textColor: textColors[colorIndex], + text: TranslationBase.of(context) + .searchMedicineDashboard, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + MedicineSearchScreen(), + )); + }, + )); + changeColorIndex(); + + return [ + ...List.generate(patientCards.length, (index) => patientCards[index]) + .toList() + ]; + } + + changeColorIndex() { + colorIndex++; + if (colorIndex > 2) { + colorIndex = 0; + } + } } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 4c51e3d7..a3fa91e9 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -1,6 +1,4 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; @@ -11,14 +9,11 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; -import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/html_rich_editor.dart'; import 'package:flutter/material.dart'; import 'package:html_editor_enhanced/html_editor.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -import 'package:speech_to_text/speech_recognition_error.dart'; -import 'package:speech_to_text/speech_to_text.dart' as stt; class AddVerifyMedicalReport extends StatefulWidget { @override @@ -26,42 +21,6 @@ class AddVerifyMedicalReport extends StatefulWidget { } class _AddVerifyMedicalReportState extends State { - stt.SpeechToText speechHistoryFinding = stt.SpeechToText(); - stt.SpeechToText speechLaboratoryData = stt.SpeechToText(); - stt.SpeechToText speechRecommendation = stt.SpeechToText(); - var recognizedWord1; - var recognizedWord2; - var recognizedWord3; - var event = RobotProvider(); - - TextEditingController historyFindingController = TextEditingController(); - TextEditingController laboratoryDataController = TextEditingController(); - TextEditingController recommendationController = TextEditingController(); - String commentsError; - String comments2Error; - String comments3Error; - - @override - void initState() { - requestPermissions(); - event.controller.stream.listen((p) { - if (p['startPopUp'] == 'true') { - if (this.mounted) { - initSpeechState().then((value) { - onVoiceText(); - }); - initSpeechState2().then((value) { - onVoiceText2(); - }); - initSpeechState3().then((value) { - onVoiceText3(); - }); - } - } - }); - super.initState(); - } - @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -94,9 +53,15 @@ class _AddVerifyMedicalReportState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - HtmlRichEditor(initialText: model - .medicalReportTemplate[0] - .templateTextHtml, height: MediaQuery.of(context).size.height * 0.75,), + if (model.medicalReportTemplate.length > 0) + HtmlRichEditor( + initialText: model + .medicalReportTemplate[0] + .templateTextHtml, + height: + MediaQuery.of(context).size.height * + 0.75, + ), ], ), ), @@ -121,13 +86,13 @@ class _AddVerifyMedicalReportState extends State { // disabled: progressNoteController.text.isEmpty, fontWeight: FontWeight.w700, onPressed: () async { - - String txtOfMedicalReport = await HtmlEditor.getText(); + String txtOfMedicalReport = + await HtmlEditor.getText(); if (txtOfMedicalReport.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); - model.insertMedicalReport(patient,txtOfMedicalReport - ); + model.insertMedicalReport( + patient, txtOfMedicalReport); GifLoaderDialogUtils.hideDialog(context); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); @@ -166,137 +131,11 @@ class _AddVerifyMedicalReportState extends State { )); } - onVoiceText() async { - new SpeechToText(context: context).showAlertDialog(context); - var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speechHistoryFinding.initialize( - onStatus: statusListener, onError: errorListener); - if (available) { - speechHistoryFinding.listen( - onResult: resultListener, - listenMode: stt.ListenMode.confirmation, - localeId: lang == 'en' ? 'en-US' : 'ar-SA', - ); - } else { - print("The user has denied the use of speech recognition."); - } - } - - onVoiceText2() async { - new SpeechToText(context: context).showAlertDialog(context); - var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speechLaboratoryData.initialize( - onStatus: statusListener, onError: errorListener); - if (available) { - speechLaboratoryData.listen( - onResult: resultListener2, - listenMode: stt.ListenMode.confirmation, - localeId: lang == 'en' ? 'en-US' : 'ar-SA', - ); - } else { - print("The user has denied the use of speech recognition."); - } - } - - onVoiceText3() async { - new SpeechToText(context: context).showAlertDialog(context); - var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speechRecommendation.initialize( - onStatus: statusListener, onError: errorListener); - if (available) { - speechRecommendation.listen( - onResult: resultListener3, - listenMode: stt.ListenMode.confirmation, - localeId: lang == 'en' ? 'en-US' : 'ar-SA', - ); - } else { - print("The user has denied the use of speech recognition."); - } - } - - void errorListener(SpeechRecognitionError error) { - event.setValue({"searchText": 'null'}); - //SpeechToText.closeAlertDialog(context); - print(error); - } - - void statusListener(String status) { - recognizedWord1 = status == 'listening' ? 'Lisening...' : 'Sorry....'; - recognizedWord2 = status == 'listening' ? 'Lisening...' : 'Sorry....'; - recognizedWord3 = status == 'listening' ? 'Lisening...' : 'Sorry....'; - } - void requestPermissions() async { Map statuses = await [ Permission.microphone, ].request(); } - - void resultListener(result) { - recognizedWord1 = result.recognizedWords; - event.setValue({"searchText": recognizedWord1}); - - if (result.finalResult == true) { - setState(() { - SpeechToText.closeAlertDialog(context); - speechHistoryFinding.stop(); - historyFindingController.text += recognizedWord1 + '\n'; - }); - } else { - print(result.finalResult); - } - } - - void resultListener2(result) { - recognizedWord2 = result.recognizedWords; - event.setValue({"searchText": recognizedWord2}); - - if (result.finalResult == true) { - setState(() { - SpeechToText.closeAlertDialog(context); - speechLaboratoryData.stop(); - laboratoryDataController.text += recognizedWord2 + '\n'; - }); - } else { - print(result.finalResult); - } - } - - void resultListener3(result) { - recognizedWord3 = result.recognizedWords; - event.setValue({"searchText": recognizedWord3}); - - if (result.finalResult == true) { - setState(() { - SpeechToText.closeAlertDialog(context); - speechRecommendation.stop(); - recommendationController.text += recognizedWord3 + '\n'; - }); - } else { - print(result.finalResult); - } - } - - Future initSpeechState() async { - bool hasSpeech = await speechHistoryFinding.initialize( - onError: errorListener, onStatus: statusListener); - print(hasSpeech); - if (!mounted) return; - } - - Future initSpeechState2() async { - bool hasSpeech = await speechLaboratoryData.initialize( - onError: errorListener, onStatus: statusListener); - print(hasSpeech); - if (!mounted) return; - } - - Future initSpeechState3() async { - bool hasSpeech = await speechRecommendation.initialize( - onError: errorListener, onStatus: statusListener); - print(hasSpeech); - if (!mounted) return; - } } enum MedicalReportStatus { ADD, VERIFY } diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 4dad827c..5e71dbd6 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -6,6 +6,7 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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/date-utils.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; @@ -32,12 +33,16 @@ class MedicalReportPage extends StatelessWidget { ProjectViewModel projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getMedicalReportList(patient), + onModelReady: (model) async { + await model.getMedicalReportList(patient); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + }, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( patient, patientType, @@ -80,10 +85,10 @@ class MedicalReportPage extends StatelessWidget { }, label: TranslationBase.of(context).createNewMedicalReport, ), - if (model.state == ViewState.ErrorLocal) - Container( - child: ErrorMessage(error: model.error), - ), + // if (model.state == ViewState.ErrorLocal) + // Container( + // child: ErrorMessage(error: model.error), + // ), if (model.state != ViewState.ErrorLocal) ...List.generate( model.medicalReportList.length, @@ -150,22 +155,26 @@ class MedicalReportPage extends StatelessWidget { onTap: () { if (model.medicalReportList[index].status == 0) { - Navigator.of(context) - .pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'medicalReport' : model.medicalReportList[index] - }); + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_INSERT, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'type': MedicalReportStatus.ADD, + 'medicalReport': + model.medicalReportList[index] + }); } else { - Navigator.of(context) - .pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'medicalReport' : model.medicalReportList[index] - }); + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_DETAIL, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'medicalReport': + model.medicalReportList[index] + }); } }, child: Icon( diff --git a/pubspec.lock b/pubspec.lock index 613c2753..980a4154 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -587,7 +587,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.1" + version: "0.6.2" json_annotation: dependency: transitive description: @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From d50740b9b93c7fd5c1408aea367ec1f5316346c9 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Wed, 19 May 2021 19:09:42 +0300 Subject: [PATCH 063/241] Procedure template service --- lib/config/config.dart | 2 +- .../procedure_template_details_model.dart | 8 +- .../procedures/add-favourite-procedure.dart | 19 +++- .../procedures/add-procedure-form.dart | 2 +- .../procedures/procedure_checkout_screen.dart | 86 +++++++++++-------- lib/screens/procedures/procedure_screen.dart | 14 +-- pubspec.lock | 6 +- 7 files changed, 84 insertions(+), 53 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index d04497d4..8464f720 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,7 +5,7 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +//const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/model/procedure/procedure_template_details_model.dart b/lib/core/model/procedure/procedure_template_details_model.dart index 84f97b65..42a2517a 100644 --- a/lib/core/model/procedure/procedure_template_details_model.dart +++ b/lib/core/model/procedure/procedure_template_details_model.dart @@ -17,6 +17,9 @@ class ProcedureTempleteDetailsModel { String categoryID; String subGroupID; dynamic riskCategoryID; + String type = "1"; + String remarks; + int selectedType = 0; ProcedureTempleteDetailsModel( {this.setupID, @@ -36,7 +39,10 @@ class ProcedureTempleteDetailsModel { this.aliasN, this.categoryID, this.subGroupID, - this.riskCategoryID}); + this.riskCategoryID, + this.remarks, + this.type = "1", + this.selectedType = 0}); ProcedureTempleteDetailsModel.fromJson(Map json) { setupID = json['SetupID']; diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index fe95735d..be6e3451 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -5,14 +5,17 @@ import 'package:doctor_app_flutter/core/model/procedure/procedure_template_detai import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add_procedure_homeScreen.dart'; import 'package:doctor_app_flutter/screens/procedures/entity_list_checkbox_search_widget.dart'; import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; +import 'package:doctor_app_flutter/screens/procedures/procedure_checkout_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; class AddFavouriteProcedure extends StatefulWidget { final ProcedureViewModel model; @@ -91,7 +94,15 @@ class _AddFavouriteProcedureState extends State { return; } - Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ProcedureCheckOutScreen( + items: entityList, + model: model, + patient: widget.patient, + )), + ); }, ), ], @@ -104,8 +115,10 @@ class _AddFavouriteProcedureState extends State { } bool isEntityListSelected(ProcedureTempleteDetailsModel masterKey) { - Iterable history = entityList - .where((element) => masterKey.templateID == element.templateID && masterKey.procedureName == element.procedureName); + Iterable history = entityList.where( + (element) => + masterKey.templateID == element.templateID && + masterKey.procedureName == element.procedureName); if (history.length > 0) { return true; } diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index 2b62d2bf..b17f50ae 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -60,7 +60,7 @@ postProcedure( controlValue: element.remarks != null ? element.remarks : ""), ); controls.add( - Controls(code: "ordertype", controlValue: "0"), + Controls(code: "ordertype", controlValue: element.type ?? "1"), ); controlsProcedure.add(Procedures( category: element.categoryID, diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index 04bbaa3a..e3fc86be 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -1,7 +1,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -12,21 +15,20 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ProcedureCheckOutScreen extends StatefulWidget { + ProcedureCheckOutScreen({this.items, this.model, this.patient}); + final List items; + final ProcedureViewModel model; + final PatiantInformtion patient; + @override _ProcedureCheckOutScreenState createState() => _ProcedureCheckOutScreenState(); } class _ProcedureCheckOutScreenState extends State { - List items = List(); List remarksList = List(); + final TextEditingController remarksController = TextEditingController(); List typeList = List(); - int selectedType = 0; - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } @override Widget build(BuildContext context) { @@ -44,7 +46,7 @@ class _ProcedureCheckOutScreenState extends State { Container( color: Colors.white, child: Padding( - padding: const EdgeInsets.all(15.0), + padding: EdgeInsets.all(12.0), child: Row( //mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -69,18 +71,17 @@ class _ProcedureCheckOutScreenState extends State { ), ), ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.022, - ), Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.only( + left: 12.0, right: 12.0, bottom: 26.0, top: 10), child: ListView.builder( scrollDirection: Axis.vertical, physics: AlwaysScrollableScrollPhysics(), shrinkWrap: true, - itemCount: 1, + itemCount: widget.items.length, itemBuilder: (BuildContext context, int index) { return Container( + margin: EdgeInsets.only(bottom: 15.0), decoration: BoxDecoration( color: Colors.white, borderRadius: @@ -97,7 +98,9 @@ class _ProcedureCheckOutScreenState extends State { SizedBox( width: 6.0, ), - AppText('Procedure Name'), + Expanded( + child: + AppText(widget.items[index].procedureName)), ], ), children: [ @@ -125,12 +128,14 @@ class _ProcedureCheckOutScreenState extends State { Radio( activeColor: Color(0xFFD02127), value: 0, - groupValue: selectedType, + groupValue: + widget.items[index].selectedType, onChanged: (value) { - // historyInfo.type = - // setSelectedType(value).toString(); - // - // historyInfo.type = value.toString(); + widget.items[index].selectedType = 0; + setState(() { + widget.items[index].type = + value.toString(); + }); }, ), AppText( @@ -140,13 +145,15 @@ class _ProcedureCheckOutScreenState extends State { ), Radio( activeColor: Color(0xFFD02127), - groupValue: selectedType, + groupValue: + widget.items[index].selectedType, value: 1, onChanged: (value) { - // historyInfo.type = - // setSelectedType(value).toString(); - // - // historyInfo.type = value.toString(); + widget.items[index].selectedType = 1; + setState(() { + widget.items[index].type = + value.toString(); + }); }, ), AppText( @@ -168,9 +175,9 @@ class _ProcedureCheckOutScreenState extends State { horizontal: 12, vertical: 15.0), child: TextFields( hintText: TranslationBase.of(context).remarks, - //controller: remarksController, + controller: remarksController, onChanged: (value) { - // historyInfo.remarks = value; + widget.items[index].remarks = value; }, minLines: 3, maxLines: 5, @@ -198,7 +205,7 @@ class _ProcedureCheckOutScreenState extends State { title: TranslationBase.of(context).addSelectedProcedures, color: Color(0xff359846), fontWeight: FontWeight.w700, - onPressed: () { + onPressed: () async { //print(entityList.toString()); onPressed: // if (entityList.isEmpty == true) { @@ -208,14 +215,25 @@ class _ProcedureCheckOutScreenState extends State { // ); // return; // } - + List entityList = List(); + widget.items.forEach((element) { + entityList.add( + EntityList( + procedureId: element.procedureID, + remarks: element.remarks, + categoryID: element.categoryID, + type: element.type, + ), + ); + }); + Navigator.pop(context); + await postProcedure( + entityList: entityList, + patient: widget.patient, + model: widget.model, + remarks: remarksController.text); + Navigator.pop(context); Navigator.pop(context); - // postProcedure( - // orderType: selectedType.toString(), - // entityList: entityList, - // patient: patient, - // model: widget.model, - // remarks: remarksController.text); }, ), ], diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 8d03f86c..b964392e 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -7,7 +7,6 @@ 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/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; -import 'package:doctor_app_flutter/screens/procedures/procedure_checkout_screen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -103,18 +102,13 @@ class ProcedureScreen extends StatelessWidget { patient.patientStatusType == 43) InkWell( onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => AddProcedureHome( - // patient: patient, - // model: model, - // )), - // ); Navigator.push( context, MaterialPageRoute( - builder: (context) => ProcedureCheckOutScreen()), + builder: (context) => AddProcedureHome( + patient: patient, + model: model, + )), ); }, child: Container( diff --git a/pubspec.lock b/pubspec.lock index 4b6a9b7a..613c2753 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.4" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <2.11.0" + dart: ">=2.10.0 <=2.11.0-213.1.beta" flutter: ">=1.22.0 <2.0.0" From 33ceb01d67463d503f1644cd99c2591a258a0f84 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 09:52:21 +0300 Subject: [PATCH 064/241] first step from Live care patient list --- lib/config/config.dart | 1 + ...dingPatientERForDoctorAppRequestModel.dart | 22 ++++ .../patient/LiveCarePatientServices.dart | 23 ++++ .../viewModel/LiveCarePatientViewModel.dart | 28 ++++- lib/models/patient/patiant_info_model.dart | 10 +- lib/screens/home/home_screen.dart | 3 +- .../live_care/LiveCarePatientScreen.dart | 59 ---------- .../live_care/live_care_patient_screen.dart | 105 ++++++++++++++++++ lib/util/date-utils.dart | 8 +- lib/widgets/patients/PatientCard.dart | 17 +-- ...ent-profile-header-new-design-app-bar.dart | 7 +- 11 files changed, 205 insertions(+), 78 deletions(-) create mode 100644 lib/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart delete mode 100644 lib/screens/live_care/LiveCarePatientScreen.dart create mode 100644 lib/screens/live_care/live_care_patient_screen.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 0e8106bc..48248bb7 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -294,6 +294,7 @@ const GET_PROCEDURE_TEMPLETE = const GET_PROCEDURE_TEMPLETE_DETAILS = "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; +const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP ='Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; var selectedPatientType = 1; diff --git a/lib/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart b/lib/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart new file mode 100644 index 00000000..dc1f25b3 --- /dev/null +++ b/lib/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart @@ -0,0 +1,22 @@ +class PendingPatientERForDoctorAppRequestModel { + bool outSA; + int doctorID; + String sErServiceID; + + PendingPatientERForDoctorAppRequestModel( + {this.outSA, this.doctorID, this.sErServiceID}); + + PendingPatientERForDoctorAppRequestModel.fromJson(Map json) { + outSA = json['OutSA']; + doctorID = json['DoctorID']; + sErServiceID = json['SErServiceID']; + } + + Map toJson() { + final Map data = new Map(); + data['OutSA'] = this.outSA; + data['DoctorID'] = this.doctorID; + data['SErServiceID'] = this.sErServiceID; + return data; + } +} diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index 31d3cf82..a0c94af0 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -1,5 +1,28 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; class LiveCarePatientServices extends BaseService{ + List _patientList = []; + List get patientList => _patientList; + + Future getPendingPatientERForDoctorApp(PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async{ + hasError = false; + await baseAppClient.post( + GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP, + onSuccess: (dynamic response, int statusCode) { + _patientList.clear(); + response['List_PendingPatientList'].forEach((v) { + _patientList.add(PatiantInformtion.fromJson(v)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: pendingPatientERForDoctorAppRequestModel.toJson(), + ); + } } \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index de185de6..9c3c267f 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -1,6 +1,32 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +import '../../locator.dart'; class LiveCarePatientViewModel extends BaseViewModel { - getPendingPatientERForDoctorApp() async {} + List filterData = []; + + LiveCarePatientServices _liveCarePatientServices = + locator(); + + getPendingPatientERForDoctorApp() async { + setState(ViewState.BusyLocal); + //TODO Change it to dynamic + PendingPatientERForDoctorAppRequestModel + pendingPatientERForDoctorAppRequestModel = + PendingPatientERForDoctorAppRequestModel(doctorID: 9920,sErServiceID: "7,3", outSA: false); + await _liveCarePatientServices + .getPendingPatientERForDoctorApp(pendingPatientERForDoctorAppRequestModel); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + + setState(ViewState.ErrorLocal); + } else { + filterData = _liveCarePatientServices.patientList; + setState(ViewState.Idle); + } + } } diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 2dec82d1..0c189b86 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -130,7 +130,7 @@ class PatiantInformtion { projectId: json["ProjectID"] ?? json["projectID"], clinicId: json["ClinicID"] ?? json["clinicID"], doctorId: json["DoctorID"] ?? json["doctorID"], - patientId: json["PatientID"] ?? + patientId: json["PatientID"]!= null ?json["PatientID"] is String ? int.parse(json["PatientID"]):json["PatientID"]: json["patientID"] ?? json['patientMRN'] ?? json['PatientMRN'], @@ -142,10 +142,10 @@ class PatiantInformtion { firstNameN: json["FirstNameN"] ?? json["firstNameN"], middleNameN: json["MiddleNameN"] ?? json["middleNameN"], lastNameN: json["LastNameN"] ?? json["lastNameN"], - gender: json["Gender"] ?? json["gender"], - fullName: json["fullName"] ?? json["fullName"], - fullNameN: json["fullNameN"] ?? json["fullNameN"], - dateofBirth: json["DateofBirth"] ?? json["dob"], + gender: json["Gender"]!= null? json["Gender"]is String ?int.parse(json["Gender"]):json["Gender"] :json["gender"], + fullName: json["fullName"] ?? json["fullName"]??json["PatientName"], + fullNameN: json["fullNameN"] ?? json["fullNameN"]??json["PatientName"], + dateofBirth: json["DateofBirth"] ?? json["dob"]??json['DateOfBirth'], nationalityId: json["NationalityID"] ?? json["nationalityID"], mobileNumber: json["MobileNumber"] ?? json["mobileNumber"], emailAddress: json["EmailAddress"] ?? json["emailAddress"], diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 40277db9..c79c5b70 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -13,6 +13,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_swipe_widget.dart'; import 'package:doctor_app_flutter/screens/home/home_patient_card.dart'; +import 'package:doctor_app_flutter/screens/live_care/live_care_patient_screen.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/PatientsInPatientScreen.dart'; import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_screen.dart'; @@ -299,7 +300,7 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(), + page: LiveCarePatientScreen(), ), ); }, diff --git a/lib/screens/live_care/LiveCarePatientScreen.dart b/lib/screens/live_care/LiveCarePatientScreen.dart deleted file mode 100644 index 9f5e55ac..00000000 --- a/lib/screens/live_care/LiveCarePatientScreen.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.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:flutter/material.dart'; - -class LiveCarePatientScreen extends StatefulWidget { - @override - _LiveCarePatientScreenState createState() => _LiveCarePatientScreenState(); -} - -class _LiveCarePatientScreenState extends State { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) async {}, - 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( - "Live Care Patients", - fontSize: SizeConfig.textMultiplier * 2.8, - fontWeight: FontWeight.bold, - color: Color(0xFF2B353E), - ), - ), - ]), - ), - ), - Expanded( - child: Column( - children: [], - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart new file mode 100644 index 00000000..39c7cbb5 --- /dev/null +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -0,0 +1,105 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.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_loader_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/shared/errors/error_message.dart'; +import 'package:flutter/material.dart'; + +import '../../routes.dart'; + +class LiveCarePatientScreen extends StatefulWidget { + @override + _LiveCarePatientScreenState createState() => _LiveCarePatientScreenState(); +} + +class _LiveCarePatientScreenState extends State { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) async { + await model.getPendingPatientERForDoctorApp(); + + }, + 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( + "Live Care Patients", + fontSize: SizeConfig.textMultiplier * 2.8, + fontWeight: FontWeight.bold, + color: Color(0xFF2B353E), + ), + ), + ]), + ), + ), + model.state == ViewState.Idle ?Expanded( + child: Container( + child: model.filterData.isEmpty + ? Center( + child: ErrorMessage( + error: TranslationBase.of(context) + .youDontHaveAnyPatient, + ), + ) + : ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: model.filterData.length, + itemBuilder: (BuildContext ctxt, int index) { + return Padding( + padding: EdgeInsets.all(8.0), + child: PatientCard( + patientInfo: model.filterData[index], + patientType: "0", + arrivalType: "0", + isFromSearch: false, + isInpatient: false, + isFromLiveCare:true, + onTap: () { + // TODO change the parameter to daynamic + Navigator.of(context).pushNamed( + PATIENTS_PROFILE, + arguments: { + "patient": model.filterData[index], + "patientType": "0", + "isSearch": false, + "isInpatient": false, + "arrivalType": "0", + "isSearchAndOut": false, + }); + }, + // isFromSearch: widget.isSearch, + ), + ); + })), + ):Expanded(child: AppLoaderWidget()), + ], + ), + ), + ); + } +} diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 44e7bffe..adddc292 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -305,9 +305,13 @@ class AppDateUtils { return DateFormat('hh:mm a').format(dateTime); } - static String getAgeByBirthday(dynamic birthday, BuildContext context) { + static String getAgeByBirthday(dynamic birthday, BuildContext context, { bool isServerFormat = true}) { // https://leechy.dev/calculate-dates-diff-in-dart - DateTime birthDate = AppDateUtils.getDateTimeFromServerFormat(birthday); + DateTime birthDate; + if(isServerFormat){ birthDate = AppDateUtils.getDateTimeFromServerFormat(birthday); + }else{ + birthDate = DateTime.parse('1986-08-15'); + } final now = DateTime.now(); int years = now.year - birthDate.year; int months = now.month - birthDate.month; diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/PatientCard.dart index 179633e7..8515c115 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/PatientCard.dart @@ -1,4 +1,3 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -9,7 +8,6 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; class PatientCard extends StatelessWidget { final PatiantInformtion patientInfo; @@ -19,6 +17,7 @@ class PatientCard extends StatelessWidget { final bool isInpatient; final bool isMyPatient; final bool isFromSearch; + final bool isFromLiveCare; const PatientCard( {Key key, @@ -26,8 +25,12 @@ class PatientCard extends StatelessWidget { this.onTap, this.patientType, this.arrivalType, - this.isInpatient, this.isMyPatient = false, this.isFromSearch = false}) + this.isInpatient, + this.isMyPatient = false, + this.isFromSearch = false, + this.isFromLiveCare = false}) : super(key: key); + @override Widget build(BuildContext context) { return Container( @@ -43,7 +46,7 @@ class PatientCard extends StatelessWidget { marginLeft: (!isMyPatient && isInpatient)?0:10, marginSymmetric:isFromSearch ? 10 : 0.0, hasBorder: false, - bgColor:(isMyPatient && !isFromSearch)?Colors.green[500]: patientInfo.patientStatusType == 43 + bgColor:isFromLiveCare?Colors.white:(isMyPatient && !isFromSearch)?Colors.green[500]: patientInfo.patientStatusType == 43 ? Colors.green[500] :isMyPatient? Colors.green[500]:isInpatient?Colors.white:!isFromSearch?Colors.red[800]:Colors.white, widget: Container( @@ -103,7 +106,7 @@ class PatientCard extends StatelessWidget { fontSize: 10, ), ], - ): !isFromSearch && patientInfo.patientStatusType==null ? Row( + ): !isFromSearch&&!isFromLiveCare && patientInfo.patientStatusType==null ? Row( children: [ AppText( TranslationBase.of(context).notArrived, @@ -174,7 +177,7 @@ class PatientCard extends StatelessWidget { Expanded( // width: MediaQuery.of(context).size.width*0.51, child: AppText( - (Helpers.capitalize(patientInfo.firstName) + + isFromLiveCare? Helpers.capitalize(patientInfo.fullName): (Helpers.capitalize(patientInfo.firstName) + " " + Helpers.capitalize(patientInfo.lastName)), fontSize: 16, @@ -299,7 +302,7 @@ class PatientCard extends StatelessWidget { style: TextStyle(fontSize: 12)), new TextSpan( text: - "${AppDateUtils.getAgeByBirthday(patientInfo.dateofBirth, context)}", + "${AppDateUtils.getAgeByBirthday(patientInfo.dateofBirth, context, isServerFormat: !isFromLiveCare)}", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 13)), diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 07bfe8f7..795a01bf 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -60,7 +60,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ? (Helpers.capitalize(patient.firstName) + " " + Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails.fullName), + : Helpers.capitalize(patient.fullName??patient.patientDetails.fullName), fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.bold, fontFamily: 'Poppins', @@ -158,7 +158,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase.of(context).appointmentDate + + TranslationBase.of(context).appointmentDate + " : ", fontSize: 14, ), @@ -182,6 +182,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget SizedBox( width: 3.5, ), + Container( child: AppText( convertDateFormat2( @@ -260,7 +261,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget style: TextStyle(fontSize: 14)), new TextSpan( text: - "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth??"" : patient.dateofBirth??"", context)}", + "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth??"" : patient.dateofBirth??"", context,)}", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 14)), ], From 186461f3a87d2f7fd16a8ba28ed34d511e46fa5f Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 20 May 2021 10:41:44 +0300 Subject: [PATCH 065/241] hot fix --- lib/config/config.dart | 4 ++-- lib/core/service/home/dasboard_service.dart | 2 +- lib/screens/home/home_screen.dart | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 54a2d46e..a54bc613 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index 685646ee..a1072676 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -6,7 +6,7 @@ class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; - bool hasVirtualClinic; + bool hasVirtualClinic = false; String sServiceID; Future getDashboard() async { diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f99dc727..147ffd4d 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -240,10 +240,10 @@ class _HomeScreenState extends State { ), sliderActiveIndex == 1 ? DashboardSliderItemWidget( - model.dashboardItemsList[3]) + model.dashboardItemsList[6]) : sliderActiveIndex == 0 ? DashboardSliderItemWidget( - model.dashboardItemsList[6]) + model.dashboardItemsList[3]) : DashboardSliderItemWidget( model.dashboardItemsList[4]), ]))) From 5778a4a887acd323da2d2fba3b6913516e57acb2 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 11:21:34 +0300 Subject: [PATCH 066/241] view list of Live care patient --- lib/config/config.dart | 4 +- .../viewModel/LiveCarePatientViewModel.dart | 30 +++++++++- lib/screens/home/home_screen.dart | 6 +- .../live_care/live_care_patient_screen.dart | 56 ++++++++++++++++++- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 425403db..c5372a07 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 9c3c267f..611beac7 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -1,5 +1,6 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -12,12 +13,15 @@ class LiveCarePatientViewModel extends BaseViewModel { LiveCarePatientServices _liveCarePatientServices = locator(); + DashboardService _dashboardService = + locator(); + getPendingPatientERForDoctorApp() async { setState(ViewState.BusyLocal); //TODO Change it to dynamic PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel = - PendingPatientERForDoctorAppRequestModel(doctorID: 9920,sErServiceID: "7,3", outSA: false); + PendingPatientERForDoctorAppRequestModel(doctorID:9920 /*doctorProfile.doctorID*/,sErServiceID:"7,3" /*_dashboardService.sServiceID*/, outSA: false); await _liveCarePatientServices .getPendingPatientERForDoctorApp(pendingPatientERForDoctorAppRequestModel); if (_liveCarePatientServices.hasError) { @@ -29,4 +33,28 @@ class LiveCarePatientViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + searchData(String str) { + var strExist= str.length > 0 ? true : false; + if (strExist) { + filterData = []; + for (var i = 0; i < _liveCarePatientServices.patientList.length; i++) { + String fullName = + _liveCarePatientServices.patientList[i].fullName.toUpperCase(); + String patientID = + _liveCarePatientServices.patientList[i].patientId.toString(); + String mobile = + _liveCarePatientServices.patientList[i].mobileNumber.toUpperCase(); + + if (fullName.contains(str.toUpperCase()) || + patientID.contains(str)|| mobile.contains(str)) { + filterData.add(_liveCarePatientServices.patientList[i]); + } + } + notifyListeners(); + } else { + filterData = _liveCarePatientServices.patientList; + notifyListeners(); + } + } } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f99dc727..dde5ae2a 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -13,6 +13,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_swipe_widget.dart'; import 'package:doctor_app_flutter/screens/home/home_patient_card.dart'; +import 'package:doctor_app_flutter/screens/live_care/live_care_patient_screen.dart'; import 'package:doctor_app_flutter/screens/medicine/medicine_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/PatientsInPatientScreen.dart'; import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_screen.dart'; @@ -327,7 +328,8 @@ class _HomeScreenState extends State { List patientCards = List(); - if (model.hasVirtualClinic) { + //TODO: return back the right condition + if (true) { patientCards.add(HomePatientCard( backgroundColor: backgroundColors[colorIndex], backgroundIconColor: backgroundIconColors[colorIndex], @@ -339,7 +341,7 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(), + page: LiveCarePatientScreen(), ), ); }, diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 39c7cbb5..dfae66f2 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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'; @@ -8,6 +9,7 @@ import 'package:doctor_app_flutter/widgets/shared/app_loader_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/shared/errors/error_message.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; import 'package:flutter/material.dart'; import '../../routes.dart'; @@ -18,6 +20,8 @@ class LiveCarePatientScreen extends StatefulWidget { } class _LiveCarePatientScreenState extends State { + final _controller = TextEditingController(); + @override Widget build(BuildContext context) { return BaseView( @@ -56,7 +60,55 @@ class _LiveCarePatientScreenState extends State { ]), ), ), - model.state == ViewState.Idle ?Expanded( + SizedBox(height: 20,), + Center( + child: FractionallySizedBox( + widthFactor: .9, + child: Container( + width: double.maxFinite, + height: 75, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(6.0)), + border: Border.all( + width: 1.0, + color: Color(0xffCCCCCC), + ), + color: Colors.white), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + left: 10, top: 10), + child: AppText( + TranslationBase.of( + context) + .searchPatientName, + fontSize: 13, + )), + AppTextFormField( + // focusNode: focusProject, + controller: _controller, + borderColor: Colors.white, + prefix: IconButton( + icon: Icon( + DoctorApp.filter_1, + color: Colors.black, + ), + iconSize: 20, + padding: + EdgeInsets.only( + bottom: 30), + ), + onChanged: (String str) { + model.searchData(str); + }), + ])), + ), + ), + Expanded( child: Container( child: model.filterData.isEmpty ? Center( @@ -96,7 +148,7 @@ class _LiveCarePatientScreenState extends State { ), ); })), - ):Expanded(child: AppLoaderWidget()), + ), ], ), ), From 97a855ab70ec729a8171b01357e6fcf8e826d639 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 11:31:47 +0300 Subject: [PATCH 067/241] return condition in home page --- lib/screens/home/home_screen.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index dde5ae2a..60414976 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -328,8 +328,7 @@ class _HomeScreenState extends State { List patientCards = List(); - //TODO: return back the right condition - if (true) { + if (model.hasVirtualClinic) { patientCards.add(HomePatientCard( backgroundColor: backgroundColors[colorIndex], backgroundIconColor: backgroundIconColors[colorIndex], From 3557e87b75136c6b1b08d225f9cbd2b4d9b5e688 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 11:42:09 +0300 Subject: [PATCH 068/241] fix loading issue --- .../live_care/live_care_patient_screen.dart | 28 ++++++++++--------- lib/widgets/shared/app_loader_widget.dart | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index dfae66f2..faa5405e 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -108,18 +108,19 @@ class _LiveCarePatientScreenState extends State { ])), ), ), - Expanded( - child: Container( - child: model.filterData.isEmpty - ? Center( - child: ErrorMessage( - error: TranslationBase.of(context) - .youDontHaveAnyPatient, - ), - ) - : ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, + model.state == ViewState.Idle + ? Expanded( + child: Container( + child: model.filterData.isEmpty + ? Center( + child: ErrorMessage( + error: TranslationBase.of(context) + .youDontHaveAnyPatient, + ), + ) + : ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, itemCount: model.filterData.length, itemBuilder: (BuildContext ctxt, int index) { return Padding( @@ -148,7 +149,8 @@ class _LiveCarePatientScreenState extends State { ), ); })), - ), + ) : Expanded( + child: AppLoaderWidget(containerColor: Colors.transparent,)), ], ), ), diff --git a/lib/widgets/shared/app_loader_widget.dart b/lib/widgets/shared/app_loader_widget.dart index ef614209..4b6d753b 100644 --- a/lib/widgets/shared/app_loader_widget.dart +++ b/lib/widgets/shared/app_loader_widget.dart @@ -24,7 +24,7 @@ class _AppLoaderWidgetState extends State { child: Stack( children: [ Container( - color: Colors.grey.withOpacity(0.6), + color: widget.containerColor??Colors.grey.withOpacity(0.6), ), Container(child: GifLoaderContainer(), margin: EdgeInsets.only( bottom: MediaQuery.of(context).size.height * 0.09)) From 8e140abee9b3570585a0c027efff9c460ec8ee28 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 11:45:25 +0300 Subject: [PATCH 069/241] make pending service dynamic --- lib/core/viewModel/LiveCarePatientViewModel.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 611beac7..803ea92a 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -18,10 +18,9 @@ class LiveCarePatientViewModel extends BaseViewModel { getPendingPatientERForDoctorApp() async { setState(ViewState.BusyLocal); - //TODO Change it to dynamic PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel = - PendingPatientERForDoctorAppRequestModel(doctorID:9920 /*doctorProfile.doctorID*/,sErServiceID:"7,3" /*_dashboardService.sServiceID*/, outSA: false); + PendingPatientERForDoctorAppRequestModel(sErServiceID:_dashboardService.sServiceID, outSA: false); await _liveCarePatientServices .getPendingPatientERForDoctorApp(pendingPatientERForDoctorAppRequestModel); if (_liveCarePatientServices.hasError) { From d49d52458b8ae0455b7db4d0fbba1b437379c3b8 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 12:08:25 +0300 Subject: [PATCH 070/241] fix birthOfDate --- ios/Podfile.lock | 2 +- .../live_care/live_care_patient_screen.dart | 3 ++- .../patient_profile_screen.dart | 22 +++++++++---------- lib/util/date-utils.dart | 7 +++--- ...ent-profile-header-new-design-app-bar.dart | 22 +++++++++---------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 59cdf14c..1cf7499c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -328,4 +328,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index faa5405e..132cc214 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -131,7 +131,7 @@ class _LiveCarePatientScreenState extends State { arrivalType: "0", isFromSearch: false, isInpatient: false, - isFromLiveCare:true, + isFromLiveCare:true, onTap: () { // TODO change the parameter to daynamic Navigator.of(context).pushNamed( @@ -143,6 +143,7 @@ class _LiveCarePatientScreenState extends State { "isInpatient": false, "arrivalType": "0", "isSearchAndOut": false, + "isFromLiveCare":true }); }, // isFromSearch: widget.isSearch, diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 7a0305e4..dc4324ec 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -97,18 +97,16 @@ class _PatientProfileScreenState extends State Column( children: [ PatientProfileHeaderNewDesignAppBar( - patient, - arrivalType ?? '0', - patientType, - isInpatient: isInpatient, - height: (patient.patientStatusType != null && - patient.patientStatusType == 43) - ? 210 - : isDischargedPatient - ? 240 - : 0, - isDischargedPatient:isDischargedPatient - ), + patient, arrivalType ?? '0', patientType, + isInpatient: isInpatient, + isFromLiveCare: isFromLiveCare, + height: (patient.patientStatusType != null && + patient.patientStatusType == 43) + ? 210 + : isDischargedPatient + ? 240 + : 0, + isDischargedPatient: isDischargedPatient), Container( height: !isSearchAndOut ? isDischargedPatient diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index adddc292..fb68ab4e 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -305,12 +305,13 @@ class AppDateUtils { return DateFormat('hh:mm a').format(dateTime); } - static String getAgeByBirthday(dynamic birthday, BuildContext context, { bool isServerFormat = true}) { + static String getAgeByBirthday(String birthOfDate, BuildContext context, { bool isServerFormat = true}) { // https://leechy.dev/calculate-dates-diff-in-dart DateTime birthDate; - if(isServerFormat){ birthDate = AppDateUtils.getDateTimeFromServerFormat(birthday); + if(birthOfDate.contains("/Date")) { + birthDate = AppDateUtils.getDateTimeFromServerFormat(birthOfDate); }else{ - birthDate = DateTime.parse('1986-08-15'); + birthDate = DateTime.parse(birthOfDate); } final now = DateTime.now(); int years = now.year - birthDate.year; diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 795a01bf..995ac57a 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -19,9 +19,10 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final double height; final bool isInpatient; final bool isDischargedPatient; + final bool isFromLiveCare; PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false}); + this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); @override Widget build(BuildContext context) { @@ -152,7 +153,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget )) : SizedBox(), if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient") + "List_MyOutPatient" && !isFromLiveCare) Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, @@ -182,15 +183,14 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget SizedBox( width: 3.5, ), - - Container( - child: AppText( - convertDateFormat2( - patient.appointmentDate ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, + Container( + child: AppText( + convertDateFormat2( + patient.appointmentDate ?? ''), + fontSize: 1.5 * SizeConfig.textMultiplier, + fontWeight: FontWeight.bold, + ), ), - ), SizedBox( height: 0.5, ) @@ -261,7 +261,7 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget style: TextStyle(fontSize: 14)), new TextSpan( text: - "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth??"" : patient.dateofBirth??"", context,)}", + "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth??"" : patient.dateofBirth??"", context,isServerFormat: !isFromLiveCare)}", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 14)), ], From 0798057f31b646d79b1b099029d28101679de6f3 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 20 May 2021 13:55:59 +0300 Subject: [PATCH 071/241] change --- .../medical_report/PatientMedicalReportService.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 760c7dd5..6e00b890 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -11,8 +11,6 @@ class PatientMedicalReportService extends BaseService { Future getMedicalReportList(PatiantInformtion patient) async { hasError = false; Map body = Map(); - // body['TokenID'] = "@dm!n"; - body['SetupID'] = "91877"; body['AdmissionNo'] = patient.admissionNo; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, From 6d989e3fc3cc465b3814bd8899205681a856b335 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 14:19:30 +0300 Subject: [PATCH 072/241] finish new service for live care --- .../patient/LiveCarePatientServices.dart | 17 ++ .../viewModel/LiveCarePatientViewModel.dart | 24 ++ .../profile/in_patient_profile_screen.dart | 227 ------------------ .../patient_profile_screen.dart | 79 +++--- .../profile_gird_for_other.dart | 108 ++++++--- .../radiology/radiology_home_page.dart | 14 +- .../vital_sign/vital_sign_details_screen.dart | 36 +-- .../prescription/prescriptions_page.dart | 14 +- lib/screens/procedures/procedure_screen.dart | 15 +- .../profile/PatientProfileButton.dart | 5 +- 10 files changed, 198 insertions(+), 341 deletions(-) delete mode 100644 lib/screens/patients/profile/in_patient_profile_screen.dart diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index a0c94af0..e4443b9b 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -1,12 +1,18 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; class LiveCarePatientServices extends BaseService{ List _patientList = []; List get patientList => _patientList; + bool _isFinished = false; + bool get isFinished => _isFinished; + + var endCallResponse = {}; + Future getPendingPatientERForDoctorApp(PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async{ hasError = false; await baseAppClient.post( @@ -25,4 +31,15 @@ class LiveCarePatientServices extends BaseService{ ); } + Future endCall(EndCallReq endCallReq) async { + + await baseAppClient.post(END_CALL, onSuccess: (response, statusCode) async { + _isFinished = true; + endCallResponse = response; + }, onFailure: (String error, int statusCode) { + _isFinished = true; + throw error; + }, body: endCallReq.toJson()); + } + } \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 803ea92a..0cce5f86 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDocto import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import '../../locator.dart'; @@ -13,6 +14,8 @@ class LiveCarePatientViewModel extends BaseViewModel { LiveCarePatientServices _liveCarePatientServices = locator(); + bool get isFinished => _liveCarePatientServices.isFinished; + DashboardService _dashboardService = locator(); @@ -33,6 +36,27 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + Future endCall(request, isPatient, doctorID) async { + + EndCallReq endCallReq = new EndCallReq(); + endCallReq.doctorId = doctorID; //profile["DoctorID"]; + endCallReq.generalid = 'Cs2020@2016\$2958'; + endCallReq.vCID = request.vCID; //["VC_ID"]; + endCallReq.isDestroy = isPatient; + + setState(ViewState.BusyLocal); + await _liveCarePatientServices + .endCall(endCallReq); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + + setState(ViewState.ErrorLocal); + } else { + filterData = _liveCarePatientServices.patientList; + setState(ViewState.Idle); + } + } + searchData(String str) { var strExist= str.length > 0 ? true : false; if (strExist) { diff --git a/lib/screens/patients/profile/in_patient_profile_screen.dart b/lib/screens/patients/profile/in_patient_profile_screen.dart deleted file mode 100644 index 8b1c3b7e..00000000 --- a/lib/screens/patients/profile/in_patient_profile_screen.dart +++ /dev/null @@ -1,227 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/patient_view_model.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/profile/PatientProfileButton.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:flutter/material.dart'; -import '../../../routes.dart'; - - -class InPatientProfileScreen extends StatefulWidget { - @override - _InPatientProfileScreenState createState() => _InPatientProfileScreenState(); -} - -class _InPatientProfileScreenState extends Statewith SingleTickerProviderStateMixin { - PatiantInformtion patient; - - bool isFromSearch = false; - - bool isInpatient = false; - - bool isDischargedPatient = false; - String patientType; - String arrivalType; - String from; - String to; - - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - patient = routeArgs['patient']; - patientType = routeArgs['patientType']; - arrivalType = routeArgs['arrivalType']; - from = routeArgs['from']; - to = routeArgs['to']; - if (routeArgs.containsKey("isSearch")) { - isFromSearch = routeArgs['isSearch']; - } - if (routeArgs.containsKey("isInpatient")) { - isInpatient = routeArgs['isInpatient']; - } - if (routeArgs.containsKey("isDischargedPatient")) { - isDischargedPatient = routeArgs['isDischargedPatient']; - } - - } - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (_, patientViewModel, w) => AppScaffold( - baseViewModel: patientViewModel, - appBarTitle: TranslationBase.of(context).patientProfile, - isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient,arrivalType??'0',patientType), - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 15.0,horizontal: 15), - child: GridView.count( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1 / 1.0, - crossAxisCount: 3, - children: [ - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: TranslationBase.of(context).vital, - nameLine2: TranslationBase.of(context).signs, - route: VITAL_SIGN_DETAILS, - isInPatient: true, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: LAB_RESULT, - isInPatient: true, - nameLine1: TranslationBase.of(context).lab, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/lab_results.png'), - PatientProfileButton( - - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInPatient: isInpatient, - route: RADIOLOGY_PATIENT, - nameLine1: TranslationBase.of(context).radiology, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/health_summary.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PRESCRIPTION_NEW, - nameLine1: TranslationBase.of(context).patient, - nameLine2: TranslationBase.of(context).prescription, - icon: 'patient/order_prescription.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PROGRESS_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: TranslationBase.of(context).progress, - nameLine2: TranslationBase.of(context).note, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: "Order", //"Text", - nameLine2: - "Sheet", //TranslationBase.of(context).orders, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PROCEDURE, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).procedures, - icon: 'patient/Order_Procedures.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: HEALTH_SUMMARY, - nameLine1: "Health", - //TranslationBase.of(context).medicalReport, - nameLine2: "Summary", - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: HEALTH_SUMMARY, - nameLine1: "Medical", //Health - //TranslationBase.of(context).medicalReport, - nameLine2: "Report", //Report - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: REFER_IN_PATIENT_TO_DOCTOR, - isInPatient: true, - nameLine1: TranslationBase.of(context).referral, - nameLine2: TranslationBase.of(context).patient, - icon: 'patient/refer_patient.png'), - PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_INSURANCE_APPROVALS_NEW, - nameLine1: TranslationBase.of(context).insurance, - nameLine2: TranslationBase.of(context).approvals, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: null, - nameLine1: "Discharge", - nameLine2: "Summery", - icon: 'patient/patient_sick_leave.png'), - PatientProfileButton( - - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ADD_SICKLEAVE, - nameLine1: TranslationBase.of(context).patientSick, - nameLine2: TranslationBase.of(context).leave, - icon: 'patient/patient_sick_leave.png'), - ], - ), - ), - ), - ), - )); - } -} - -class AvatarWidget extends StatelessWidget { - final Widget avatarIcon; - - AvatarWidget(this.avatarIcon); - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Color.fromRGBO(0, 0, 0, 0.08), - offset: Offset(0.0, 5.0), - blurRadius: 16.0) - ], - borderRadius: BorderRadius.all(Radius.circular(35.0)), - color: Color(0xffCCCCCC), - ), - child: avatarIcon, - ); - } -} diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index dc4324ec..344c5394 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; @@ -85,9 +86,9 @@ class _PatientProfileScreenState extends State @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; - return BaseView( - builder: (_, patientViewModel, w) => AppScaffold( - baseViewModel: patientViewModel, + return BaseView( + builder: (_, model, w) => AppScaffold( + baseViewModel: model, appBarTitle: TranslationBase.of(context).patientProfile, isShowAppBar: false, body: Column( @@ -119,34 +120,35 @@ class _PatientProfileScreenState extends State child: isSearchAndOut ? ProfileGridForSearch( patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInpatient: isInpatient, - from: from, - to: to, - ) - : isInpatient - ? ProfileGridForInPatient( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInpatient: isInpatient, - from: from, - to: to, - isDischargedPatient: - isDischargedPatient, - isFromSearch: isFromSearch, - ) - : ProfileGridForOther( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInpatient: isInpatient, - from: from, - to: to, - ), - ), - SizedBox( + patientType: patientType, + arrivalType: arrivalType, + isInpatient: isInpatient, + from: from, + to: to, + ) + : isInpatient + ? ProfileGridForInPatient( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + isInpatient: isInpatient, + from: from, + to: to, + isDischargedPatient: + isDischargedPatient, + isFromSearch: isFromSearch, + ) + : ProfileGridForOther( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + isInpatient: isInpatient, + isFromLiveCare: isFromLiveCare, + from: from, + to: to, + ), + ), + SizedBox( height: MediaQuery.of(context).size.height * 0.05, ) ], @@ -270,14 +272,19 @@ class _PatientProfileScreenState extends State child: Center( child: AppButton( fontWeight: FontWeight.w700, - color: Colors.green[600], - title: TranslationBase + color: model.isFinished?Colors.red[600]:Colors.green[600], + title: model.isFinished?"End":TranslationBase .of(context) .initiateCall, onPressed: () async { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); + if(model.isFinished) { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); + } else { + // TODO Call initiateCall service + } + }, ), ), diff --git a/lib/screens/patients/profile/profile_screen/profile_gird_for_other.dart b/lib/screens/patients/profile/profile_screen/profile_gird_for_other.dart index 86ccd6d1..fee8b1e1 100644 --- a/lib/screens/patients/profile/profile_screen/profile_gird_for_other.dart +++ b/lib/screens/patients/profile/profile_screen/profile_gird_for_other.dart @@ -14,6 +14,7 @@ class ProfileGridForOther extends StatelessWidget { final String arrivalType; final double height; final bool isInpatient; + final bool isFromLiveCare; String from; String to; @@ -25,7 +26,8 @@ class ProfileGridForOther extends StatelessWidget { this.height, this.isInpatient, this.from, - this.to}) + this.to, + this.isFromLiveCare}) : super(key: key); @override @@ -74,41 +76,67 @@ class ProfileGridForOther extends StatelessWidget { 'patient/Order_Procedures.png', isInPatient: isInpatient), PatientProfileCardModel( - TranslationBase.of(context).insurance, - TranslationBase.of(context).service, + TranslationBase + .of(context) + .insurance, + TranslationBase + .of(context) + .service, PATIENT_INSURANCE_APPROVALS_NEW, 'patient/vital_signs.png', isInPatient: isInpatient), PatientProfileCardModel( - TranslationBase.of(context).patientSick, - TranslationBase.of(context).leave, + TranslationBase + .of(context) + .patientSick, + TranslationBase + .of(context) + .leave, ADD_SICKLEAVE, 'patient/patient_sick_leave.png', isInPatient: isInpatient), - if (patient.appointmentNo != null && patient.appointmentNo != 0) - PatientProfileCardModel( - TranslationBase.of(context).patient, - TranslationBase.of(context).ucaf, - PATIENT_UCAF_REQUEST, - 'patient/ucaf.png', - isInPatient: isInpatient, - isDisable: patient.patientStatusType != 43 ? true : false), - if (patient.appointmentNo != null && patient.appointmentNo != 0) - PatientProfileCardModel( - TranslationBase.of(context).referral, - TranslationBase.of(context).patient, - REFER_PATIENT_TO_DOCTOR, - 'patient/refer_patient.png', - isInPatient: isInpatient, - isDisable: patient.patientStatusType != 43 ? true : false), - if (patient.appointmentNo != null && patient.appointmentNo != 0) + if (isFromLiveCare || + (patient.appointmentNo != null && patient.appointmentNo != 0)) PatientProfileCardModel( - TranslationBase.of(context).admission, - TranslationBase.of(context).request, + TranslationBase + .of(context) + .patient, + TranslationBase + .of(context) + .ucaf, + PATIENT_UCAF_REQUEST, + 'patient/ucaf.png', + isInPatient: isInpatient, + isDisable: patient.patientStatusType != 43 || + patient.appointmentNo == null ? true : false), + if (isFromLiveCare || + (patient.appointmentNo != null && patient.appointmentNo != 0)) + PatientProfileCardModel( + TranslationBase + .of(context) + .referral, + TranslationBase + .of(context) + .patient, + REFER_PATIENT_TO_DOCTOR, + 'patient/refer_patient.png', + isInPatient: isInpatient, + isDisable: patient.patientStatusType != 43 || + patient.appointmentNo == null ? true : false), + if (isFromLiveCare || + (patient.appointmentNo != null && patient.appointmentNo != 0)) + PatientProfileCardModel( + TranslationBase + .of(context) + .admission, + TranslationBase + .of(context) + .request, PATIENT_ADMISSION_REQUEST, 'patient/admission_req.png', isInPatient: isInpatient, - isDisable: patient.patientStatusType != 43 ? true : false), + isDisable: patient.patientStatusType != 43 || + patient.appointmentNo == null ? true : false), ]; return Column( @@ -124,20 +152,22 @@ class ProfileGridForOther extends StatelessWidget { itemCount: cardsList.length, staggeredTileBuilder: (int index) => StaggeredTile.fit(1), itemBuilder: (BuildContext context, int index) => PatientProfileButton( - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: cardsList[index].nameLine1, - nameLine2: cardsList[index].nameLine2, - route: cardsList[index].route, - icon: cardsList[index].icon, - isInPatient: cardsList[index].isInPatient, - isDischargedPatient: cardsList[index].isDischargedPatient, - isDisable: cardsList[index].isDisable, - onTap: cardsList[index].onTap, - isLoading: cardsList[index].isLoading, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + from: from, + to: to, + nameLine1: cardsList[index].nameLine1, + nameLine2: cardsList[index].nameLine2, + route: cardsList[index].route, + icon: cardsList[index].icon, + isInPatient: cardsList[index].isInPatient, + isDischargedPatient: cardsList[index].isDischargedPatient, + isDisable: cardsList[index].isDisable, + onTap: cardsList[index].onTap, + isLoading: cardsList[index].isLoading, + isFromLiveCare: isFromLiveCare + ), ), ), diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 4b8d224e..7d70b677 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -25,6 +25,7 @@ class _RadiologyHomePageState extends State { PatiantInformtion patient; String arrivalType; bool isInpatient; + bool isFromLiveCare; @override void didChangeDependencies() { @@ -34,6 +35,7 @@ class _RadiologyHomePageState extends State { patientType = routeArgs['patientType']; arrivalType = routeArgs['arrivalType']; isInpatient = routeArgs['isInpatient']; + isFromLiveCare = routeArgs['isFromLiveCare']; print(arrivalType); } @@ -97,21 +99,25 @@ class _RadiologyHomePageState extends State { fontSize: 13, ), AppText( - TranslationBase.of(context).result, + TranslationBase + .of(context) + .result, bold: true, fontSize: 22, ), ], ), ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) + if ((patient.patientStatusType != null && + patient.patientStatusType == 43) || + (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddSelectedRadiologyOrder( + builder: (context) => + AddSelectedRadiologyOrder( patient: patient, model: model, )), diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index a6f36784..4f3deeb3 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -9,9 +9,9 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; class VitalSignDetailsScreen extends StatelessWidget { int appointmentNo; @@ -39,6 +39,7 @@ class VitalSignDetailsScreen extends StatelessWidget { builder: (_, mode, widget) => AppScaffold( baseViewModel: mode, isShowAppBar: true, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileHeaderNewDesignAppBar( patient, patientType, arrivalType), appBarTitle: TranslationBase.of(context).vitalSign, @@ -587,31 +588,18 @@ class VitalSignDetailsScreen extends StatelessWidget { ), ), ], - ), - ), - ), - ], - ) - : Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 100, - ), - Image.asset('assets/images/no-data.png'), - Padding( - padding: const EdgeInsets.all(8.0), - child: AppText( - TranslationBase.of(context).vitalSignEmptyMsg, - fontWeight: FontWeight.normal, - color: HexColor("#B8382B"), - fontSize: SizeConfig.textMultiplier * 2.5, - ), - ) - ], ), ), + ), + ], + ) + : Container( + color: Theme + .of(context) + .scaffoldBackgroundColor, + child: ErrorMessage(error: TranslationBase + .of(context) + .vitalSignEmptyMsg,)), ), ); } diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index a7367cf3..9bfd9b49 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -26,8 +26,8 @@ class PrescriptionsPage extends StatelessWidget { String patientType = routeArgs['patientType']; String arrivalType = routeArgs['arrivalType']; bool isInpatient = routeArgs['isInpatient']; + bool isFromLiveCare = routeArgs['isFromLiveCare']; bool isSelectInpatient = routeArgs['isSelectInpatient']; - ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => isSelectInpatient ? model.getPrescriptionsInPatient(patient) @@ -86,21 +86,25 @@ class PrescriptionsPage extends StatelessWidget { fontSize: 13, ), AppText( - TranslationBase.of(context).prescriptions, + TranslationBase + .of(context) + .prescriptions, bold: true, fontSize: 22, ), ], ), ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) + if ((patient.patientStatusType != null && + patient.patientStatusType == 43) || + (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { addPrescriptionForm(context, model, patient, model.prescriptionList); }, - label: TranslationBase.of(context) + label: TranslationBase + .of(context) .applyForNewPrescriptionsOrder, ), ...List.generate( diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index b964392e..1829957d 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -5,7 +5,6 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.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/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -14,6 +13,7 @@ import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-head import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; + import 'ProcedureCard.dart'; class ProcedureScreen extends StatelessWidget { @@ -31,6 +31,7 @@ class ProcedureScreen extends StatelessWidget { PatiantInformtion patient = routeArgs['patient']; String patientType = routeArgs['patientType']; String arrivalType = routeArgs['arrivalType']; + bool isFromLiveCare = routeArgs['isFromLiveCare']; bool isInpatient = routeArgs['isInpatient']; return BaseView( onModelReady: (model) => model.getProcedure( @@ -91,21 +92,25 @@ class ProcedureScreen extends StatelessWidget { fontSize: 13, ), AppText( - TranslationBase.of(context).procedure, + TranslationBase + .of(context) + .procedure, bold: true, fontSize: 22, ), ], ), ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) + if ((patient.patientStatusType != null && + patient.patientStatusType == 43) || + (isFromLiveCare && patient.appointmentNo != null)) InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddProcedureHome( + builder: (context) => + AddProcedureHome( patient: patient, model: model, )), diff --git a/lib/widgets/patients/profile/PatientProfileButton.dart b/lib/widgets/patients/profile/PatientProfileButton.dart index c5580568..ef285150 100644 --- a/lib/widgets/patients/profile/PatientProfileButton.dart +++ b/lib/widgets/patients/profile/PatientProfileButton.dart @@ -7,6 +7,7 @@ import 'package:doctor_app_flutter/widgets/shared/dr_app_circular_progress_Indei import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +// ignore: must_be_immutable class PatientProfileButton extends StatelessWidget { final String nameLine1; final String nameLine2; @@ -26,6 +27,7 @@ class PatientProfileButton extends StatelessWidget { final bool isSelectInpatient; final bool isDartIcon; final IconData dartIcon; + final bool isFromLiveCare; PatientProfileButton({ Key key, @@ -45,7 +47,7 @@ class PatientProfileButton extends StatelessWidget { this.isDischargedPatient = false, this.isSelectInpatient = false, this.isDartIcon = false, - this.dartIcon, + this.dartIcon, this.isFromLiveCare = false, }) : super(key: key); @override @@ -142,6 +144,7 @@ class PatientProfileButton extends StatelessWidget { 'isInpatient': isInPatient, 'isDischargedPatient': isDischargedPatient, 'isSelectInpatient': isSelectInpatient, + "isFromLiveCare":isFromLiveCare }); } } From 04c9a1168b607dd7bbbde0ad9007291f467d65ab Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 14:34:30 +0300 Subject: [PATCH 073/241] add VC_ID --- lib/models/patient/patiant_info_model.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 0c189b86..fc77af66 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -62,6 +62,8 @@ class PatiantInformtion { String startTimes; String dischargeDate; int status; + int vcId; + PatiantInformtion( {this.patientDetails, this.projectId, @@ -121,7 +123,7 @@ class PatiantInformtion { this.nationalityFlagURL, this.patientStatusType, this.visitTypeId, - this.startTimes,this.dischargeDate,this.status}); + this.startTimes,this.dischargeDate,this.status, this.vcId}); factory PatiantInformtion.fromJson(Map json) => PatiantInformtion( @@ -199,5 +201,6 @@ class PatiantInformtion { startTimes: json['StartTime'] ?? json['StartTime'], dischargeDate: json['DischargeDate'] , status: json['Status'] , + vcId: json['VC_ID'] , ); } From b6cb6362f606ca4f03bb56e62271f28826c171b2 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 20 May 2021 14:54:43 +0300 Subject: [PATCH 074/241] adding validation and voice speach to prescription form --- .../prescription/add_prescription_form.dart | 677 +++++++++++------- 1 file changed, 426 insertions(+), 251 deletions(-) diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index a3c6e589..e80534c1 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -5,10 +5,12 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/Prescriptions/post_prescrition_req_model.dart'; import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_model.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; +import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; @@ -23,12 +25,16 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hexcolor/hexcolor.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; +import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; addPrescriptionForm(context, PrescriptionViewModel model, PatiantInformtion patient, prescription) { @@ -102,6 +108,13 @@ class PrescriptionFormWidget extends StatefulWidget { } class _PrescriptionFormWidgetState extends State { + String routeError; + String frequencyError; + String doseTimeError; + String durationError; + String unitError; + String strengthError; + int selectedType; TextEditingController durationController = TextEditingController(); TextEditingController strengthController = TextEditingController(); @@ -124,6 +137,9 @@ class _PrescriptionFormWidgetState extends State { TextEditingController drugIdController = TextEditingController(); TextEditingController doseController = TextEditingController(); final searchController = TextEditingController(); + stt.SpeechToText speech = stt.SpeechToText(); + var event = RobotProvider(); + var reconizedWord; var notesList; var filteredNotesList; @@ -188,6 +204,60 @@ class _PrescriptionFormWidgetState extends State { }); } + onVoiceText() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speech.initialize( + onStatus: statusListener, onError: errorListener); + if (available) { + speech.listen( + onResult: resultListener, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + + void errorListener(SpeechRecognitionError error) { + event.setValue({"searchText": 'null'}); + //SpeechToText.closeAlertDialog(context); + print(error); + } + + void statusListener(String status) { + reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; + } + + void requestPermissions() async { + Map statuses = await [ + Permission.microphone, + ].request(); + } + + void resultListener(result) { + reconizedWord = result.recognizedWords; + event.setValue({"searchText": reconizedWord}); + + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speech.stop(); + indicationController.text += reconizedWord + '\n'; + }); + } else { + print(result.finalResult); + } + } + + Future initSpeechState() async { + bool hasSpeech = await speech.initialize( + onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } + @override Widget build(BuildContext context) { ListSelectDialog drugDialog; @@ -244,7 +314,7 @@ class _PrescriptionFormWidgetState extends State { (BuildContext context, ScrollController scrollController) { return SingleChildScrollView( child: Container( - height: MediaQuery.of(context).size.height * 1.45, + height: MediaQuery.of(context).size.height * 1.65, color: Color(0xffF8F8F8), child: Padding( padding: EdgeInsets.symmetric( @@ -437,11 +507,6 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: spaceBetweenTextFileds), Container( - //height: screenSize.height * 0.062, - height: MediaQuery.of(context) - .size - .height * - 0.0749, width: double.infinity, child: Row( children: [ @@ -451,44 +516,43 @@ class _PrescriptionFormWidgetState extends State { .size .width * 0.35, - child: TextField( - decoration: - textFieldSelectorDecorationStreangrh( - strengthController - .text, - 'Strength', //strengthController.text, - false), - enabled: true, - controller: - strengthController, - onChanged: - (String value) { - setState(() { - strengthChar = - value.length; - }); - if (strengthChar >= 5) { - DrAppToastMsg - .showErrorToast( - TranslationBase.of( - context) - .only5DigitsAllowedForStrength, - ); - } - }, - keyboardType: TextInputType - .numberWithOptions( - decimal: true, - )), + child: AppTextFieldCustom( + height: 40, + validationError: + strengthError, + hintText: 'Strength', + isTextFieldHasSuffix: false, + enabled: true, + controller: + strengthController, + onChanged: (String value) { + setState(() { + strengthChar = + value.length; + }); + if (strengthChar >= 5) { + DrAppToastMsg + .showErrorToast( + TranslationBase.of( + context) + .only5DigitsAllowedForStrength, + ); + } + }, + inputType: TextInputType + .numberWithOptions( + decimal: true, + ), + // keyboardType: TextInputType + // .numberWithOptions( + // decimal: true, + // ), + ), ), SizedBox( width: 5.0, ), Container( - // height: MediaQuery.of(context) - // .size - // .height * - // 0.06, color: Colors.white, width: MediaQuery.of(context) .size @@ -538,23 +602,23 @@ class _PrescriptionFormWidgetState extends State { ); } : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - 'Select', - model.itemMedicineListUnit - .length == - 1 - ? units = model - .itemMedicineListUnit[0] - [ - 'description'] - : units != - null - ? units['description'] - .toString() - : null, - true), + child: AppTextFieldCustom( + hintText: 'Select', + isTextFieldHasSuffix: + true, + dropDownText: model + .itemMedicineListUnit + .length == + 1 + ? units = model + .itemMedicineListUnit[0] + ['description'] + : units != null + ? units['description'] + .toString() + : null, + validationError: + unitError, enabled: false), ), ), @@ -564,7 +628,7 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, + //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( onTap: @@ -613,23 +677,44 @@ class _PrescriptionFormWidgetState extends State { ); } : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .route, - model.itemMedicineListRoute - .length == - 1 - ? model.itemMedicineListRoute[ - 0] - ['description'] - : route != null - ? route[ - 'description'] - : null, - true), + child: AppTextFieldCustom( + // decoration: + // textFieldSelectorDecoration( + // TranslationBase.of( + // context) + // .route, + // model.itemMedicineListRoute + // .length == + // 1 + // ? model.itemMedicineListRoute[ + // 0] + // ['description'] + // : route != null + // ? route[ + // 'description'] + // : null, + // true), + hintText: + TranslationBase.of(context) + .route, + dropDownText: model + .itemMedicineListRoute + .length == + 1 + ? model.itemMedicineListRoute[ + 0]['description'] + : route != null + ? route['description'] + : null, + isTextFieldHasSuffix: true, + //height: 45, + validationError: + model.itemMedicineListRoute + .length != + 1 + ? routeError + : null, + enabled: false, ), ), @@ -637,7 +722,7 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, + //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( onTap: @@ -704,23 +789,22 @@ class _PrescriptionFormWidgetState extends State { ); } : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .frequency, - model.itemMedicineList - .length == - 1 - ? model.itemMedicineList[ - 0] - ['description'] - : frequency != null - ? frequency[ - 'description'] - : null, - true), + child: AppTextFieldCustom( + isTextFieldHasSuffix: true, + hintText: + TranslationBase.of(context) + .frequency, + dropDownText: model + .itemMedicineList + .length == + 1 + ? model.itemMedicineList[0] + ['description'] + : frequency != null + ? frequency[ + 'description'] + : null, + validationError: frequencyError, enabled: false, ), ), @@ -728,7 +812,7 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, + //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( onTap: @@ -770,17 +854,18 @@ class _PrescriptionFormWidgetState extends State { ); } : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .doseTime, - doseTime != null - ? doseTime['nameEn'] - : null, - true), + child: AppTextFieldCustom( + hintText: + TranslationBase.of(context) + .doseTime, + isTextFieldHasSuffix: true, + dropDownText: doseTime != null + ? doseTime['nameEn'] + : null, + //height: 45, + enabled: false, + validationError: doseTimeError, ), ), ), @@ -894,7 +979,7 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, + //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( onTap: @@ -963,16 +1048,15 @@ class _PrescriptionFormWidgetState extends State { ); } : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .duration, - duration != null - ? duration['nameEn'] - : null, - true), + child: AppTextFieldCustom( + validationError: durationError, + isTextFieldHasSuffix: true, + dropDownText: duration != null + ? duration['nameEn'] + : null, + hintText: + TranslationBase.of(context) + .duration, enabled: false, ), ), @@ -1101,14 +1185,36 @@ class _PrescriptionFormWidgetState extends State { width: 1.0, color: HexColor("#CCCCCC"))), - child: TextFields( - maxLines: 6, - minLines: 4, - hintText: - TranslationBase.of(context) + child: Stack( + children: [ + TextFields( + maxLines: 6, + minLines: 4, + hintText: TranslationBase.of( + context) .instruction, - controller: instructionController, - //keyboardType: TextInputType.number, + controller: + instructionController, + //keyboardType: TextInputType.number, + ), + Positioned( + top: + 0, //MediaQuery.of(context).size.height * 0, + right: 15, + child: IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35, + ), + onPressed: () { + initSpeechState().then( + (value) => + {onVoiceText()}); + }, + ), + ), + ], ), ), SizedBox( @@ -1125,139 +1231,205 @@ class _PrescriptionFormWidgetState extends State { context) .addMedication, fontWeight: FontWeight.w600, - onPressed: () { - formKey.currentState.save(); - // Navigator.pop(context); - // openDrugToDrug(); - if (frequency == null || + onPressed: () async { + if (route != null && + duration != null && + doseTime != null && + frequency != null && + units != null && + selectedDate != null && strengthController - .text == - "" || - doseTime == null || - duration == null || - selectedDate == null) { - DrAppToastMsg.showErrorToast( - TranslationBase.of( - context) - .pleaseFillAllFields); - return; - } - if (_selectedMedication - .isNarcotic == - true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of( - context) - .narcoticMedicineCanOnlyBePrescribedFromVida); - Navigator.pop(context); - return; - } + .text != + "") { + if (_selectedMedication + .isNarcotic == + true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of( + context) + .narcoticMedicineCanOnlyBePrescribedFromVida); + Navigator.pop(context); + return; + } - if (double.parse( - strengthController - .text) > - 1000.0) { - DrAppToastMsg.showErrorToast( - "1000 is the MAX for the strength"); - return; - } - if (double.parse( - strengthController - .text) < - 0.0) { - DrAppToastMsg.showErrorToast( - "strength can't be zero"); - return; - } + if (double.parse( + strengthController + .text) > + 1000.0) { + DrAppToastMsg + .showErrorToast( + "1000 is the MAX for the strength"); + return; + } + if (double.parse( + strengthController + .text) < + 0.0) { + DrAppToastMsg + .showErrorToast( + "strength can't be zero"); + return; + } - if (formKey.currentState - .validate()) { - Navigator.pop(context); - openDrugToDrug(model); - { - // postProcedure( - // icdCode: model - // .patientAssessmentList - // .isNotEmpty - // ? model - // .patientAssessmentList[ - // 0] - // .icdCode10ID - // .isEmpty - // ? "test" - // : model - // .patientAssessmentList[ - // 0] - // .icdCode10ID - // .toString() - // : "test", - // // icdCode: model - // // .patientAssessmentList - // // .map((value) => value - // // .icdCode10ID - // // .trim()) - // // .toList() - // // .join(' '), - // dose: strengthController - // .text, - // doseUnit: model - // .itemMedicineListUnit - // .length == - // 1 - // ? model - // .itemMedicineListUnit[ - // 0][ - // 'parameterCode'] - // .toString() - // : units['parameterCode'] - // .toString(), - // patient: widget.patient, - // doseTimeIn: - // doseTime['id'] - // .toString(), - // model: widget.model, - // duration: duration['id'] - // .toString(), - // frequency: model - // .itemMedicineList - // .length == - // 1 - // ? model - // .itemMedicineList[ - // 0][ - // 'parameterCode'] - // .toString() - // : frequency[ - // 'parameterCode'] - // .toString(), - // route: model.itemMedicineListRoute - // .length == - // 1 - // ? model - // .itemMedicineListRoute[ - // 0][ - // 'parameterCode'] - // .toString() - // : route['parameterCode'] - // .toString(), - // drugId: - // _selectedMedication - // .itemId - // .toString(), - // strength: - // strengthController - // .text, - // indication: - // indicationController - // .text, - // instruction: - // instructionController - // .text, - // doseTime: selectedDate, - // ); + if (formKey.currentState + .validate()) { + Navigator.pop(context); + openDrugToDrug(model); + { + // postProcedure( + // icdCode: model + // .patientAssessmentList + // .isNotEmpty + // ? model + // .patientAssessmentList[ + // 0] + // .icdCode10ID + // .isEmpty + // ? "test" + // : model + // .patientAssessmentList[ + // 0] + // .icdCode10ID + // .toString() + // : "test", + // // icdCode: model + // // .patientAssessmentList + // // .map((value) => value + // // .icdCode10ID + // // .trim()) + // // .toList() + // // .join(' '), + // dose: strengthController + // .text, + // doseUnit: model + // .itemMedicineListUnit + // .length == + // 1 + // ? model + // .itemMedicineListUnit[ + // 0][ + // 'parameterCode'] + // .toString() + // : units['parameterCode'] + // .toString(), + // patient: widget.patient, + // doseTimeIn: + // doseTime['id'] + // .toString(), + // model: widget.model, + // duration: duration['id'] + // .toString(), + // frequency: model + // .itemMedicineList + // .length == + // 1 + // ? model + // .itemMedicineList[ + // 0][ + // 'parameterCode'] + // .toString() + // : frequency[ + // 'parameterCode'] + // .toString(), + // route: model.itemMedicineListRoute + // .length == + // 1 + // ? model + // .itemMedicineListRoute[ + // 0][ + // 'parameterCode'] + // .toString() + // : route['parameterCode'] + // .toString(), + // drugId: + // _selectedMedication + // .itemId + // .toString(), + // strength: + // strengthController + // .text, + // indication: + // indicationController + // .text, + // instruction: + // instructionController + // .text, + // doseTime: selectedDate, + // ); + } } + } else { + setState(() { + if (duration == null) { + durationError = + TranslationBase.of( + context) + .fieldRequired; + } else { + durationError = null; + } + if (doseTime == null) { + doseTimeError = + TranslationBase.of( + context) + .fieldRequired; + } else { + doseTimeError = null; + } + if (route == null) { + routeError = + TranslationBase.of( + context) + .fieldRequired; + } else { + routeError = null; + } + if (frequency == null) { + frequencyError = + TranslationBase.of( + context) + .fieldRequired; + } else { + frequencyError = null; + } + if (units == null) { + unitError = + TranslationBase.of( + context) + .fieldRequired; + } else { + unitError = null; + } + if (strengthController + .text == + "") { + strengthError = + TranslationBase.of( + context) + .fieldRequired; + } else { + strengthError = null; + } + }); } + formKey.currentState.save(); + // Navigator.pop(context); + // openDrugToDrug(); + // if (frequency == null || + // strengthController + // .text == + // "" || + // doseTime == null || + // duration == null || + // selectedDate == null) { + // DrAppToastMsg.showErrorToast( + // TranslationBase.of( + // context) + // .pleaseFillAllFields); + // return; + // } + { // Navigator.push( // context, @@ -1430,17 +1602,20 @@ class _PrescriptionFormWidgetState extends State { // .join(' '), dose: strengthController.text, doseUnit: model.itemMedicineListUnit.length == 1 - ? model.itemMedicineListUnit[0]['parameterCode'].toString() + ? model.itemMedicineListUnit[0]['parameterCode'] + .toString() : units['parameterCode'].toString(), patient: widget.patient, doseTimeIn: doseTime['id'].toString(), model: widget.model, duration: duration['id'].toString(), frequency: model.itemMedicineList.length == 1 - ? model.itemMedicineList[0]['parameterCode'].toString() + ? model.itemMedicineList[0]['parameterCode'] + .toString() : frequency['parameterCode'].toString(), route: model.itemMedicineListRoute.length == 1 - ? model.itemMedicineListRoute[0]['parameterCode'].toString() + ? model.itemMedicineListRoute[0]['parameterCode'] + .toString() : route['parameterCode'].toString(), drugId: _selectedMedication.itemId.toString(), strength: strengthController.text, From 0ed0dbb5aaf9344f7db9f845ed7a8fde2044ce2e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 20 May 2021 15:10:21 +0300 Subject: [PATCH 075/241] livecare changes --- lib/config/localized_values.dart | 1 + lib/screens/live_care/end_call_screen.dart | 48 ++++---- .../live-care_transfer_to_admin.dart | 108 ++++++++++++++++++ lib/util/helpers.dart | 51 ++++++++- lib/util/translations_delegate_base.dart | 2 + 5 files changed, 184 insertions(+), 26 deletions(-) create mode 100644 lib/screens/live_care/live-care_transfer_to_admin.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index dcc4aa1f..f8d6a510 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1,6 +1,7 @@ const Map> localizedValues = { 'dashboardScreenToolbarTitle': {'ar': 'الرئيسة', 'en': 'Home'}, 'settings': {'en': 'Settings', 'ar': 'الاعدادات'}, + 'areYouSureYouWantTo': {'en': 'Are you sure you want to', 'ar': 'هل انت متاكد من انك تريد أن'}, 'language': {'en': 'App Language', 'ar': 'لغة التطبيق'}, 'lanEnglish': {'en': 'English', 'ar': 'English'}, 'lanArabic': {'en': 'العربية', 'ar': 'العربية'}, diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 880c8fd8..dff46923 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/PatientProfileCardModel.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/PatientProfileButton.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -35,18 +36,24 @@ class _EndCallScreenState extends State { final List cardsList = [ PatientProfileCardModel(TranslationBase.of(context).resume, TranslationBase.of(context).theCall, '', 'patient/vital_signs.png', - isInPatient: isInpatient, onTap: () {}, isDartIcon: true, + isInPatient: isInpatient, + onTap: () {}, + isDartIcon: true, dartIcon: DoctorApp.call), PatientProfileCardModel( TranslationBase.of(context).endLC, TranslationBase.of(context).consultation, '', 'patient/vital_signs.png', - isInPatient: isInpatient, - onTap: () {}, - isDartIcon: true, - dartIcon: DoctorApp.end_consultaion - ), + isInPatient: isInpatient, onTap: () { + Helpers.showConfirmationDialog( + context, + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).endLC} ${TranslationBase.of(context).consultation} ?", + () { + Navigator.of(context).pop(); + + }); + }, isDartIcon: true, dartIcon: DoctorApp.end_consultaion), PatientProfileCardModel( TranslationBase.of(context).sendLC, TranslationBase.of(context).instruction, @@ -55,19 +62,13 @@ class _EndCallScreenState extends State { onTap: () {}, isInPatient: isInpatient, isDartIcon: true, - dartIcon: DoctorApp.send_instruction - ), - PatientProfileCardModel( - TranslationBase.of(context).transferTo, - TranslationBase.of(context).admin, - '', - 'patient/health_summary.png', + dartIcon: DoctorApp.send_instruction), + PatientProfileCardModel(TranslationBase.of(context).transferTo, + TranslationBase.of(context).admin, '', 'patient/health_summary.png', onTap: () {}, - isInPatient: isInpatient, - - isDartIcon: true, - dartIcon: DoctorApp.transfer_to_admin - ), + isInPatient: isInpatient, + isDartIcon: true, + dartIcon: DoctorApp.transfer_to_admin), ]; return AppScaffold( @@ -93,8 +94,8 @@ class _EndCallScreenState extends State { child: ListView( children: [ Padding( - padding: const EdgeInsets.symmetric( - vertical: 15.0, horizontal: 15), + padding: + const EdgeInsets.symmetric(vertical: 15.0, horizontal: 15), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -103,11 +104,14 @@ class _EndCallScreenState extends State { fontSize: 14, fontWeight: FontWeight.w500, ), - AppText(TranslationBase.of(context).endcall, + AppText( + TranslationBase.of(context).endcall, fontSize: 26, fontWeight: FontWeight.bold, ), - SizedBox(height: 10,), + SizedBox( + height: 10, + ), StaggeredGridView.countBuilder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart new file mode 100644 index 00000000..f6e3798f --- /dev/null +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -0,0 +1,108 @@ +import 'dart:html'; + +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; +import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; + +class LivaCareTransferToAdmin extends StatefulWidget { + + final PatiantInformtion patient; + + const LivaCareTransferToAdmin({Key key, this.patient}) : super(key: key); + + @override + _LivaCareTransferToAdminState createState() => _LivaCareTransferToAdminState(); +} + +class _LivaCareTransferToAdminState extends State { + + stt.SpeechToText speech = stt.SpeechToText(); + var reconizedWord; + var event = RobotProvider(); + ProjectViewModel projectViewModel; + + TextEditingController noteController = TextEditingController(); + + void initState() { + requestPermissions(); + event.controller.stream.listen((p) { + if (p['startPopUp'] == 'true') { + if (this.mounted) { + initSpeechState().then((value) => {onVoiceText()}); + } + } + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + + return Container( + + ); + } + + onVoiceText() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speech.initialize( + onStatus: statusListener, onError: errorListener); + if (available) { + speech.listen( + onResult: resultListener, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + + void errorListener(SpeechRecognitionError error) { + event.setValue({"searchText": 'null'}); + //SpeechToText.closeAlertDialog(context); + print(error); + } + + void statusListener(String status) { + reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; + } + + void requestPermissions() async { + Map statuses = await [ + Permission.microphone, + ].request(); + } + + void resultListener(result) { + reconizedWord = result.recognizedWords; + event.setValue({"searchText": reconizedWord}); + + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speech.stop(); + noteController.text += reconizedWord + '\n'; + }); + } else { + print(result.finalResult); + } + } + + Future initSpeechState() async { + bool hasSpeech = await speech.initialize( + onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } +} diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 53f81ef2..7f72435f 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -8,6 +8,8 @@ import 'package:doctor_app_flutter/models/doctor/list_doctor_working_hours_table import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -24,7 +26,47 @@ class Helpers { static int cupertinoPickerIndex = 0; get currentLanguage => null; - static showCupertinoPicker(context, List items, decKey, onSelectFun, AuthenticationViewModel model) { + + static showConfirmationDialog( + BuildContext context, String message, Function okFunction) { + return showDialog( + context: context, + barrierDismissible: false, // user must tap button! + builder: (_) { + return Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AlertDialog( + title: null, + content: Container( + child: AppText(message), + ), + actions: [ + AppButton( + onPressed: okFunction, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + AppButton( + onPressed: (){ + Navigator.of(context).pop(); + }, + title: TranslationBase.of(context).cancel, + fontColor: Colors.white, + color: Colors.red[600], + ), + ], + ), + ], + ), + ); + }); + } + + static showCupertinoPicker(context, List items, + decKey, onSelectFun, AuthenticationViewModel model) { showModalBottomSheet( isDismissible: false, context: context, @@ -64,8 +106,8 @@ class Helpers { Container( height: SizeConfig.realScreenHeight * 0.3, color: Color(0xfff7f7f7), - child: - buildPickerItems(context, items, decKey, onSelectFun, model)) + child: buildPickerItems( + context, items, decKey, onSelectFun, model)) ], ), ); @@ -75,7 +117,8 @@ class Helpers { static TextStyle textStyle(context) => TextStyle(color: Theme.of(context).primaryColor); - static buildPickerItems(context, List items, decKey, onSelectFun, model) { + static buildPickerItems(context, List items, + decKey, onSelectFun, model) { return CupertinoPicker( magnification: 1.5, scrollController: diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index ac805956..4f5a128b 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -18,6 +18,8 @@ class TranslationBase { String get settings => localizedValues['settings'][locale.languageCode]; + String get areYouSureYouWantTo => localizedValues['areYouSureYouWantTo'][locale.languageCode]; + String get language => localizedValues['language'][locale.languageCode]; String get lanEnglish => localizedValues['lanEnglish'][locale.languageCode]; From 5d5f9f692839d2dd76a275756c19d58e031b24db Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 20 May 2021 15:45:37 +0300 Subject: [PATCH 076/241] Fix issues on the add procedure --- lib/models/doctor/doctor_profile_model.dart | 2 +- lib/screens/live_care/video_call.dart | 2 +- .../procedures/add-procedure-form.dart | 38 +-- .../procedures/procedure_checkout_screen.dart | 303 +++++++++--------- 4 files changed, 163 insertions(+), 182 deletions(-) diff --git a/lib/models/doctor/doctor_profile_model.dart b/lib/models/doctor/doctor_profile_model.dart index 17625968..c2f5b0dd 100644 --- a/lib/models/doctor/doctor_profile_model.dart +++ b/lib/models/doctor/doctor_profile_model.dart @@ -7,7 +7,7 @@ class DoctorProfileModel { Null clinicDescriptionN; Null licenseExpiry; int employmentType; - Null setupID; + dynamic setupID; int projectID; String projectName; String nationalityID; diff --git a/lib/screens/live_care/video_call.dart b/lib/screens/live_care/video_call.dart index 961654cc..321a7e0f 100644 --- a/lib/screens/live_care/video_call.dart +++ b/lib/screens/live_care/video_call.dart @@ -76,7 +76,7 @@ class _VideoCallPageState extends State { }); }, onCallNotRespond: (SessionStatusModel sessionStatusModel) { - //TODO handling onCalcallNotRespondlEnd + //TODO handling onCalNotRespondEnd WidgetsBinding.instance.addPostFrameCallback((_) { changeRoute(context); }); diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index b17f50ae..db249da7 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -13,13 +13,11 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; import 'entity_list_checkbox_search_widget.dart'; -import 'entity_list_procedure_widget.dart'; valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, List entityList) async { @@ -139,9 +137,7 @@ class _AddSelectedProcedureState extends State { @override Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; return BaseView( - //onModelReady: (model) => model.getCategory(), builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -218,21 +214,23 @@ class _AddSelectedProcedureState extends State { width: MediaQuery.of(context).size.width * 0.02, ), - InkWell( - onTap: () { - if (procedureName.text.isNotEmpty && - procedureName.text.length >= 3) - model.getProcedureCategory( - categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .atLeastThreeCharacters, - ); - }, - child: Icon( - Icons.search, - size: 25.0, + Expanded( + child: InkWell( + onTap: () { + if (procedureName.text.isNotEmpty && + procedureName.text.length >= 3) + model.getProcedureCategory( + categoryName: procedureName.text); + else + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .atLeastThreeCharacters, + ); + }, + child: Icon( + Icons.search, + size: 25.0, + ), ), ), ], @@ -429,8 +427,6 @@ class _AddSelectedProcedureState extends State { color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () { - //print(entityList.toString()); - onPressed: if (entityList.isEmpty == true) { DrAppToastMsg.showErrorToast( TranslationBase.of(context) diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index e3fc86be..f5b6dcb7 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -10,7 +10,6 @@ import 'package:doctor_app_flutter/widgets/shared/TextFields.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -37,164 +36,159 @@ class _ProcedureCheckOutScreenState extends State { AppScaffold( backgroundColor: Color(0xffF8F8F8).withOpacity(0.9), isShowAppBar: false, - body: Column( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.070, - color: Colors.white, - ), - Container( - color: Colors.white, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Row( - //mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - InkWell( - child: Icon( - Icons.arrow_back_ios_sharp, - size: 24.0, + body: SingleChildScrollView( + child: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + color: Colors.white, + ), + Container( + color: Colors.white, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Row( + //mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + child: Icon( + Icons.arrow_back_ios_sharp, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, ), - onTap: () { - Navigator.pop(context); - }, - ), - SizedBox( - width: 5.0, - ), - AppText( - 'Add Procedure', - fontWeight: FontWeight.w700, - fontSize: 20, - ), - ], + SizedBox( + width: 5.0, + ), + AppText( + 'Add Procedure', + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ], + ), ), ), - ), - Padding( - padding: const EdgeInsets.only( - left: 12.0, right: 12.0, bottom: 26.0, top: 10), - child: ListView.builder( - scrollDirection: Axis.vertical, - physics: AlwaysScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: widget.items.length, - itemBuilder: (BuildContext context, int index) { - return Container( - margin: EdgeInsets.only(bottom: 15.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: - BorderRadius.all(Radius.circular(10.0))), - child: ExpansionTile( - initiallyExpanded: true, - title: Row( + SizedBox(height: 30,), + ...List.generate(widget.items.length, (index) => Container( + margin: EdgeInsets.only(bottom: 15.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.all(Radius.circular(10.0))), + child: ExpansionTile( + initiallyExpanded: true, + title: Row( + children: [ + Icon( + Icons.check_box, + color: Color(0xffD02127), + size: 30.5, + ), + SizedBox( + width: 6.0, + ), + Expanded( + child: + AppText(widget.items[index].procedureName)), + ], + ), + children: [ + Container( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon( - Icons.check_box, - color: Color(0xffD02127), - size: 30.5, + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 11), + child: AppText( + TranslationBase.of(context).orderType, + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + ), + ), + ], ), - SizedBox( - width: 6.0, + Row( + children: [ + Radio( + activeColor: Color(0xFFD02127), + value: 0, + groupValue: + widget.items[index].selectedType, + onChanged: (value) { + widget.items[index].selectedType = 0; + setState(() { + widget.items[index].type = + value.toString(); + }); + }, + ), + AppText( + 'routine', + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + Radio( + activeColor: Color(0xFFD02127), + groupValue: + widget.items[index].selectedType, + value: 1, + onChanged: (value) { + widget.items[index].selectedType = 1; + setState(() { + widget.items[index].type = + value.toString(); + }); + }, + ), + AppText( + TranslationBase.of(context).urgent, + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + ], ), - Expanded( - child: - AppText(widget.items[index].procedureName)), ], ), - children: [ - Container( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 11), - child: AppText( - TranslationBase.of(context).orderType, - fontWeight: FontWeight.w700, - color: Color(0xff2B353E), - ), - ), - ], - ), - Row( - children: [ - Radio( - activeColor: Color(0xFFD02127), - value: 0, - groupValue: - widget.items[index].selectedType, - onChanged: (value) { - widget.items[index].selectedType = 0; - setState(() { - widget.items[index].type = - value.toString(); - }); - }, - ), - AppText( - 'routine', - color: Color(0xff575757), - fontWeight: FontWeight.w600, - ), - Radio( - activeColor: Color(0xFFD02127), - groupValue: - widget.items[index].selectedType, - value: 1, - onChanged: (value) { - widget.items[index].selectedType = 1; - setState(() { - widget.items[index].type = - value.toString(); - }); - }, - ), - AppText( - TranslationBase.of(context).urgent, - color: Color(0xff575757), - fontWeight: FontWeight.w600, - ), - ], - ), - ], - ), - ), - ), - SizedBox( - height: 2.0, - ), - Padding( - padding: EdgeInsets.symmetric( - horizontal: 12, vertical: 15.0), - child: TextFields( - hintText: TranslationBase.of(context).remarks, - controller: remarksController, - onChanged: (value) { - widget.items[index].remarks = value; - }, - minLines: 3, - maxLines: 5, - borderWidth: 0.5, - borderColor: Colors.grey[500], - ), - ), - SizedBox( - height: 19.0, - ), - //DividerWithSpacesAround(), - ], ), - ); - }), - ), - ], + ), + SizedBox( + height: 2.0, + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: 12, vertical: 15.0), + child: TextFields( + hintText: TranslationBase.of(context).remarks, + controller: remarksController, + onChanged: (value) { + widget.items[index].remarks = value; + }, + minLines: 3, + maxLines: 5, + borderWidth: 0.5, + borderColor: Colors.grey[500], + ), + ), + SizedBox( + height: 19.0, + ), + //DividerWithSpacesAround(), + ], + ), + )), + SizedBox(height: 90,), + + + ], + ), ), bottomSheet: Container( margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), @@ -206,15 +200,6 @@ class _ProcedureCheckOutScreenState extends State { color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () async { - //print(entityList.toString()); - onPressed: - // if (entityList.isEmpty == true) { - // DrAppToastMsg.showErrorToast( - // TranslationBase.of(context) - // .fillTheMandatoryProcedureDetails, - // ); - // return; - // } List entityList = List(); widget.items.forEach((element) { entityList.add( From 1367f2bebb7fb8b706b884784e6afda244c9d994 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 15:47:13 +0300 Subject: [PATCH 077/241] add translation --- lib/config/localized_values.dart | 1 + .../profile/profile_screen/patient_profile_screen.dart | 4 +++- lib/util/translations_delegate_base.dart | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index dcc4aa1f..e8309d70 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -996,4 +996,5 @@ const Map> localizedValues = { "impressionRecommendation": {"en": "Impression and Recommendation", "ar": "الانطباع والتوصية"}, "onHold": {"en": "'On Hold'", "ar": "قيد الانتظار"}, "verified": {"en": "'Verified'", "ar": "Verified"}, + "endCall": {"en": "'End'", "ar": "انهاء"}, }; diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 344c5394..0ec0cf0e 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -273,7 +273,9 @@ class _PatientProfileScreenState extends State child: AppButton( fontWeight: FontWeight.w700, color: model.isFinished?Colors.red[600]:Colors.green[600], - title: model.isFinished?"End":TranslationBase + title: model.isFinished?TranslationBase + .of(context) + .endCall:TranslationBase .of(context) .initiateCall, onPressed: () async { diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index ac805956..9cf6e024 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1337,6 +1337,8 @@ class TranslationBase { String get medicalReportVerify => localizedValues['medicalReportVerify'][locale.languageCode]; String get comments => localizedValues['comments'][locale.languageCode]; String get initiateCall => localizedValues['initiateCall '][locale.languageCode]; + String get endCall => localizedValues['endCall '][locale.languageCode]; + String get transferTo => localizedValues['transferTo'][locale.languageCode]; String get admin => localizedValues['admin'][locale.languageCode]; String get instructions => localizedValues['instructions'][locale.languageCode]; From 8b2c7f1a059e5153d0508afccc9401e877938fef Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 20 May 2021 15:49:35 +0300 Subject: [PATCH 078/241] livecare --- .../patient/LiveCarePatientServices.dart | 16 ++ .../viewModel/LiveCarePatientViewModel.dart | 13 + lib/screens/live_care/end_call_screen.dart | 241 ++++++++++-------- .../live-care_transfer_to_admin.dart | 21 +- .../patient_profile_screen.dart | 8 +- 5 files changed, 179 insertions(+), 120 deletions(-) diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index e4443b9b..36ca2c7e 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -42,4 +42,20 @@ class LiveCarePatientServices extends BaseService{ }, body: endCallReq.toJson()); } + Future endCallWithCharge(int vcID) async{ + hasError = false; + await baseAppClient.post( + END_CALL_WITH_CHARGE, + onSuccess: (dynamic response, int statusCode) { + endCallResponse = response; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "VC_ID": vcID, + }, + ); + } } \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 0cce5f86..8c7587a4 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -57,6 +57,19 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + Future endCallWithCharge(int vcID) async { + setState(ViewState.BusyLocal); + await _liveCarePatientServices + .endCallWithCharge(vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + await getPendingPatientERForDoctorApp(); + setState(ViewState.Idle); + } + } + searchData(String str) { var strExist= str.length > 0 ? true : false; if (strExist) { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index dff46923..b7657d31 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -1,6 +1,11 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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/screens/live_care/live-care_transfer_to_admin.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/PatientProfileCardModel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/PatientProfileButton.dart'; @@ -8,6 +13,7 @@ import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-head 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/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -31,6 +37,8 @@ class _EndCallScreenState extends State { String from; String to; + LiveCarePatientViewModel liveCareModel; + @override Widget build(BuildContext context) { final List cardsList = [ @@ -46,13 +54,17 @@ class _EndCallScreenState extends State { '', 'patient/vital_signs.png', isInPatient: isInpatient, onTap: () { - Helpers.showConfirmationDialog( - context, + Helpers.showConfirmationDialog(context, "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).endLC} ${TranslationBase.of(context).consultation} ?", - () { - Navigator.of(context).pop(); - - }); + () async { + Navigator.of(context).pop(); + GifLoaderDialogUtils.showMyDialog(context); + liveCareModel.endCallWithCharge(0); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } + }); }, isDartIcon: true, dartIcon: DoctorApp.end_consultaion), PatientProfileCardModel( TranslationBase.of(context).sendLC, @@ -65,122 +77,133 @@ class _EndCallScreenState extends State { dartIcon: DoctorApp.send_instruction), PatientProfileCardModel(TranslationBase.of(context).transferTo, TranslationBase.of(context).admin, '', 'patient/health_summary.png', - onTap: () {}, + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + LivaCareTransferToAdmin(patient:widget.patient))); + }, isInPatient: isInpatient, isDartIcon: true, dartIcon: DoctorApp.transfer_to_admin), ]; - return AppScaffold( - appBarTitle: TranslationBase.of(context).patientProfile, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( - widget.patient, arrivalType ?? '7', '1', - isInpatient: isInpatient, - height: (widget.patient.patientStatusType != null && - widget.patient.patientStatusType == 43) - ? 210 - : isDischargedPatient - ? 240 - : 0, - isDischargedPatient: isDischargedPatient), - body: Container( - height: !isSearchAndOut - ? isDischargedPatient - ? MediaQuery.of(context).size.height * 0.64 - : MediaQuery.of(context).size.height * 0.65 - : MediaQuery.of(context).size.height * 0.69, - child: ListView( - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15.0, horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).patient, - fontSize: 14, - fontWeight: FontWeight.w500, - ), - AppText( - TranslationBase.of(context).endcall, - fontSize: 26, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 10, - ), - StaggeredGridView.countBuilder( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - crossAxisCount: 3, - itemCount: cardsList.length, - staggeredTileBuilder: (int index) => StaggeredTile.fit(1), - itemBuilder: (BuildContext context, int index) => - PatientProfileButton( - patient: widget.patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: cardsList[index].nameLine1, - nameLine2: cardsList[index].nameLine2, - route: cardsList[index].route, - icon: cardsList[index].icon, - isInPatient: cardsList[index].isInPatient, - isDischargedPatient: cardsList[index].isDischargedPatient, - isDisable: cardsList[index].isDisable, - onTap: cardsList[index].onTap, - isLoading: cardsList[index].isLoading, - isDartIcon: cardsList[index].isDartIcon, - dartIcon: cardsList[index].dartIcon, + return BaseView( + onModelReady: (model) { + liveCareModel = model; + }, + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + appBarTitle: TranslationBase.of(context).patientProfile, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + isShowAppBar: true, + appBar: PatientProfileHeaderNewDesignAppBar( + widget.patient, arrivalType ?? '7', '1', + isInpatient: isInpatient, + height: (widget.patient.patientStatusType != null && + widget.patient.patientStatusType == 43) + ? 210 + : isDischargedPatient + ? 240 + : 0, + isDischargedPatient: isDischargedPatient), + body: Container( + height: !isSearchAndOut + ? isDischargedPatient + ? MediaQuery.of(context).size.height * 0.64 + : MediaQuery.of(context).size.height * 0.65 + : MediaQuery.of(context).size.height * 0.69, + child: ListView( + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 15.0, horizontal: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).patient, + fontSize: 14, + fontWeight: FontWeight.w500, ), - ), - ], + AppText( + TranslationBase.of(context).endcall, + fontSize: 26, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 10, + ), + StaggeredGridView.countBuilder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + crossAxisCount: 3, + itemCount: cardsList.length, + staggeredTileBuilder: (int index) => StaggeredTile.fit(1), + itemBuilder: (BuildContext context, int index) => + PatientProfileButton( + patient: widget.patient, + patientType: patientType, + arrivalType: arrivalType, + from: from, + to: to, + nameLine1: cardsList[index].nameLine1, + nameLine2: cardsList[index].nameLine2, + route: cardsList[index].route, + icon: cardsList[index].icon, + isInPatient: cardsList[index].isInPatient, + isDischargedPatient: + cardsList[index].isDischargedPatient, + isDisable: cardsList[index].isDisable, + onTap: cardsList[index].onTap, + isLoading: cardsList[index].isLoading, + isDartIcon: cardsList[index].isDartIcon, + dartIcon: cardsList[index].dartIcon, + ), + ), + ], + ), ), - ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.05, - ) - ], - ), - ), - bottomSheet: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(0.0), + SizedBox( + height: MediaQuery.of(context).size.height * 0.05, + ) + ], ), - border: Border.all(color: HexColor('#707070'), width: 0), ), - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - child: Column( - children: [ - SizedBox( - height: 10, + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(0.0), ), - Container( - child: FractionallySizedBox( - widthFactor: .80, - child: Center( - child: AppButton( - fontWeight: FontWeight.w700, - color: Colors.red[600], - title: "Close", //TranslationBase.of(context).close, - onPressed: () async {}, + border: Border.all(color: HexColor('#707070'), width: 0), + ), + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + child: Column( + children: [ + SizedBox( + height: 10, + ), + Container( + child: FractionallySizedBox( + widthFactor: .80, + child: Center( + child: AppButton( + fontWeight: FontWeight.w700, + color: Colors.red[600], + title: "Close", //TranslationBase.of(context).close, + onPressed: () async {}, + ), ), ), ), - ), - SizedBox( - height: 5, - ), - ], + SizedBox( + height: 5, + ), + ], + ), ), ), ); diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart index f6e3798f..33f55c95 100644 --- a/lib/screens/live_care/live-care_transfer_to_admin.dart +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -1,10 +1,11 @@ -import 'dart:html'; - import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -13,17 +14,16 @@ import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; class LivaCareTransferToAdmin extends StatefulWidget { - final PatiantInformtion patient; const LivaCareTransferToAdmin({Key key, this.patient}) : super(key: key); @override - _LivaCareTransferToAdminState createState() => _LivaCareTransferToAdminState(); + _LivaCareTransferToAdminState createState() => + _LivaCareTransferToAdminState(); } class _LivaCareTransferToAdminState extends State { - stt.SpeechToText speech = stt.SpeechToText(); var reconizedWord; var event = RobotProvider(); @@ -47,8 +47,15 @@ class _LivaCareTransferToAdminState extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); - return Container( - + return BaseView( + onModelReady: (model) {}, + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + appBarTitle: "${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin}", + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + isShowAppBar: true, + body: Container(), + ), ); } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 344c5394..a2aa07e3 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -277,13 +277,13 @@ class _PatientProfileScreenState extends State .of(context) .initiateCall, onPressed: () async { - if(model.isFinished) { + // if(model.isFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); - } else { - // TODO Call initiateCall service - } + // } else { + // // TODO Call initiateCall service + // } }, ), From e313722743ec02a0905cc755ebf274cc8f69c80e Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 20 May 2021 15:59:25 +0300 Subject: [PATCH 079/241] fix bug when logout --- lib/core/viewModel/authentication_view_model.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 232d9619..a6e9eaeb 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -421,8 +421,9 @@ class AuthenticationViewModel extends BaseViewModel { doctorProfile = null; sharedPref.setString(APP_Language, lang); deleteUser(); - await getDeviceInfoFromFirebase(); + await getDeviceInfoFromFirebase(); this.isFromLogin = isFromLogin; + setState(ViewState.Idle); Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, FadePage( From 269c8e21f6de3a46543b27721a1afe8ee3f1cfb0 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 20 May 2021 16:26:20 +0300 Subject: [PATCH 080/241] hot fix --- lib/screens/prescription/add_prescription_form.dart | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index e80534c1..fc4609f3 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -618,7 +618,11 @@ class _PrescriptionFormWidgetState extends State { .toString() : null, validationError: - unitError, + model.itemMedicineListUnit + .length != + 1 + ? unitError + : null, enabled: false), ), ), @@ -804,7 +808,12 @@ class _PrescriptionFormWidgetState extends State { ? frequency[ 'description'] : null, - validationError: frequencyError, + validationError: model + .itemMedicineList + .length != + 1 + ? frequencyError + : null, enabled: false, ), ), From 0cd7fa0cb2530d811dc1bd7691f99662b17c59ba Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 20 May 2021 17:07:50 +0300 Subject: [PATCH 081/241] working on livecare --- .../patient/LiveCarePatientServices.dart | 20 +++++ .../viewModel/LiveCarePatientViewModel.dart | 13 +++ lib/screens/live_care/end_call_screen.dart | 5 +- .../live-care_transfer_to_admin.dart | 86 ++++++++++++++++++- .../shared/buttons/button_bottom_sheet.dart | 38 ++++---- 5 files changed, 142 insertions(+), 20 deletions(-) diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index 36ca2c7e..0a8c4894 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -12,6 +12,7 @@ class LiveCarePatientServices extends BaseService{ bool get isFinished => _isFinished; var endCallResponse = {}; + var transferToAdminResponse = {}; Future getPendingPatientERForDoctorApp(PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async{ hasError = false; @@ -58,4 +59,23 @@ class LiveCarePatientServices extends BaseService{ }, ); } + + Future transferToAdmin(int vcID, String notes) async{ + hasError = false; + await baseAppClient.post( + TRANSFERT_TO_ADMIN, + onSuccess: (dynamic response, int statusCode) { + transferToAdminResponse = response; + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "VC_ID": vcID, + "IsOutKsa": false, + "Notes": notes, + }, + ); + } } \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 8c7587a4..e8b07cba 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -70,6 +70,19 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + Future transferToAdmin(int vcID, String notes) async { + setState(ViewState.BusyLocal); + await _liveCarePatientServices + .transferToAdmin(vcID, notes); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + await getPendingPatientERForDoctorApp(); + setState(ViewState.Idle); + } + } + searchData(String str) { var strExist= str.length > 0 ? true : false; if (strExist) { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index b7657d31..e33d476c 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -59,10 +59,13 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - liveCareModel.endCallWithCharge(0); + liveCareModel.endCallWithCharge(widget.patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); + } else { + Navigator.of(context).pop(); + Navigator.of(context).pop(); } }); }, isDartIcon: true, dartIcon: DoctorApp.end_consultaion), diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart index 33f55c95..c5bcf304 100644 --- a/lib/screens/live_care/live-care_transfer_to_admin.dart +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -1,12 +1,19 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/button_bottom_sheet.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; @@ -30,6 +37,7 @@ class _LivaCareTransferToAdminState extends State { ProjectViewModel projectViewModel; TextEditingController noteController = TextEditingController(); + String noteError; void initState() { requestPermissions(); @@ -51,10 +59,84 @@ class _LivaCareTransferToAdminState extends State { onModelReady: (model) {}, builder: (_, model, w) => AppScaffold( baseViewModel: model, - appBarTitle: "${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin}", + appBarTitle: + "${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin}", backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, - body: Container(), + body: Container( + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + color: Colors.white, + margin: EdgeInsets.all(16), + child: Stack( + children: [ + AppTextFieldCustom( + hintText: TranslationBase.of(context).notes, + //TranslationBase.of(context).addProgressNote, + controller: noteController, + maxLines: 35, + minLines: 25, + hasBorder: true, + validationError: noteError, + ), + Positioned( + top: -2, //MediaQuery.of(context).size.height * 0, + right: projectViewModel.isArabic + ? MediaQuery.of(context).size.width * 0.75 + : 15, + child: Column( + children: [ + IconButton( + icon: Icon(DoctorApp.speechtotext, + color: Colors.black, size: 35), + onPressed: () { + initSpeechState() + .then((value) => {onVoiceText()}); + }, + ), + ], + )) + ], + ), + ), + ), + ), + ButtonBottomSheet( + title: + "${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin}", + onPressed: () { + setState(() { + if (noteController.text.isEmpty) { + noteError = TranslationBase.of(context).emptyMessage; + } else { + noteError = null; + } + if (noteController.text.isNotEmpty) { + Helpers.showConfirmationDialog(context, + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin} ?", + () async { + Navigator.of(context).pop(); + GifLoaderDialogUtils.showMyDialog(context); + model.endCallWithCharge(widget.patient.vcId); + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } + }); + } + }); + }, + ) + ], + ), + ), ), ); } diff --git a/lib/widgets/shared/buttons/button_bottom_sheet.dart b/lib/widgets/shared/buttons/button_bottom_sheet.dart index 9db662d2..3c5cc32d 100644 --- a/lib/widgets/shared/buttons/button_bottom_sheet.dart +++ b/lib/widgets/shared/buttons/button_bottom_sheet.dart @@ -42,23 +42,27 @@ class ButtonBottomSheet extends StatelessWidget { Widget build(BuildContext context) { return Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: AppButton( - title: title, - onPressed: onPressed, - fontWeight: fontWeight, - color: color, - fontSize: fontSize, - padding: padding, - disabled: disabled, - radius: radius, - hasBorder: hasBorder, - fontColor: fontColor, - icon: icon, - iconData: iconData, - hPadding: hPadding, - vPadding: vPadding, - borderColor: borderColor, - loading: loading, + child: Column( + children: [ + AppButton( + title: title, + onPressed: onPressed, + fontWeight: fontWeight, + color: color, + fontSize: fontSize, + padding: padding, + disabled: disabled, + radius: radius, + hasBorder: hasBorder, + fontColor: fontColor, + icon: icon, + iconData: iconData, + hPadding: hPadding, + vPadding: vPadding, + borderColor: borderColor, + loading: loading, + ), + ], ), ); } From 401516403f198a9ecb226e34a802537dba7163ba Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Thu, 20 May 2021 17:13:52 +0300 Subject: [PATCH 082/241] first step from show Video call --- .../patient/LiveCarePatientServices.dart | 27 +++++++++++++--- .../viewModel/LiveCarePatientViewModel.dart | 31 +++++++++++++++++-- lib/screens/live_care/panding_list.dart | 14 ++++----- lib/screens/live_care/video_call.dart | 16 ++++++---- .../patient_profile_screen.dart | 17 +++++++++- 5 files changed, 85 insertions(+), 20 deletions(-) diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index e4443b9b..deff406e 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -2,17 +2,25 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -class LiveCarePatientServices extends BaseService{ +class LiveCarePatientServices extends BaseService { List _patientList = []; + List get patientList => _patientList; bool _isFinished = false; - bool get isFinished => _isFinished; + + bool get isFinished => _isFinished; + var endCallResponse = {}; + StartCallRes _startCallRes; + StartCallRes get startCallRes => _startCallRes; + Future getPendingPatientERForDoctorApp(PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async{ hasError = false; await baseAppClient.post( @@ -32,14 +40,25 @@ class LiveCarePatientServices extends BaseService{ } Future endCall(EndCallReq endCallReq) async { - + hasError = false; await baseAppClient.post(END_CALL, onSuccess: (response, statusCode) async { _isFinished = true; endCallResponse = response; }, onFailure: (String error, int statusCode) { _isFinished = true; - throw error; + hasError = true; + super.error = error; }, body: endCallReq.toJson()); } + Future startCall(StartCallReq startCallReq) async { + hasError = false; + await baseAppClient.post(START_LIVECARE_CALL, + onSuccess: (response, statusCode) async { + _startCallRes = StartCallRes.fromJson(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: startCallReq.toJson()); + } } \ No newline at end of file diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 0cce5f86..f5d089b4 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -4,6 +4,8 @@ import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import '../../locator.dart'; @@ -15,6 +17,7 @@ class LiveCarePatientViewModel extends BaseViewModel { locator(); bool get isFinished => _liveCarePatientServices.isFinished; + StartCallRes get startCallRes => _liveCarePatientServices.startCallRes; DashboardService _dashboardService = locator(); @@ -49,14 +52,38 @@ class LiveCarePatientViewModel extends BaseViewModel { .endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; - setState(ViewState.ErrorLocal); } else { - filterData = _liveCarePatientServices.patientList; setState(ViewState.Idle); } } + + Future startCall({int vCID, bool isReCall}) async { + StartCallReq startCallReq = new StartCallReq(); + await getDoctorProfile(); + startCallReq.clinicId = super.doctorProfile.clinicID; + startCallReq.vCID = vCID; //["VC_ID"]; + startCallReq.isrecall = isReCall; + startCallReq.doctorId = doctorProfile.doctorID; + startCallReq.isOutKsa = false; //["IsOutKSA"]; + startCallReq.projectName = doctorProfile.projectName; + startCallReq.docotrName = doctorProfile.doctorName; + startCallReq.clincName = doctorProfile.clinicDescription; + startCallReq.docSpec = doctorProfile.doctorTitleForProfile; + startCallReq.generalid = 'Cs2020@2016\$2958'; + + setState(ViewState.BusyLocal); + await _liveCarePatientServices + .startCall(startCallReq); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + + } searchData(String str) { var strExist= str.length > 0 ? true : false; if (strExist) { diff --git a/lib/screens/live_care/panding_list.dart b/lib/screens/live_care/panding_list.dart index 8c9851db..f081479c 100644 --- a/lib/screens/live_care/panding_list.dart +++ b/lib/screens/live_care/panding_list.dart @@ -204,13 +204,13 @@ class _LiveCarePandingListState extends State { // .pushNamed( // VIDEO_CALL, // item) - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - VideoCallPage( - item, - context))) + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => + // VideoCallPage( + // item, + // context))) }, ), ) diff --git a/lib/screens/live_care/video_call.dart b/lib/screens/live_care/video_call.dart index 961654cc..e3b05871 100644 --- a/lib/screens/live_care/video_call.dart +++ b/lib/screens/live_care/video_call.dart @@ -1,10 +1,12 @@ import 'dart:async'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/livecare_view_model.dart'; import 'package:doctor_app_flutter/models/livecare/get_pending_res_list.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -13,9 +15,10 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class VideoCallPage extends StatefulWidget { - final LiveCarePendingListResponse patientData; + final PatiantInformtion patientData; final listContext; - VideoCallPage(this.patientData, this.listContext); + final LiveCarePatientViewModel model; + VideoCallPage({this.patientData, this.listContext, this.model}); @override _VideoCallPageState createState() => _VideoCallPageState(); @@ -41,7 +44,8 @@ class _VideoCallPageState extends State { super.didChangeDependencies(); if (_isInit) { _liveCareProvider = Provider.of(context); - startCall(false); + connectOpenTok(widget.model.startCallRes); + // widget.model.startCall(vCID: widget.patientData.vcId, isReCall: false); } _isInit = false; } @@ -61,7 +65,7 @@ class _VideoCallPageState extends State { kSessionId: tokenData.openSessionID, //'1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', kApiKey: '46209962', - vcId: widget.patientData.vCID, + vcId: widget.patientData.vcId, tokenID: token, //"hfkjshdf347r8743", generalId: "Cs2020@2016\$2958", doctorId: doctorprofile['DoctorID'], @@ -130,7 +134,7 @@ class _VideoCallPageState extends State { height: MediaQuery.of(context).size.height * 0.02, ), Text( - widget.patientData.patientName, + widget.patientData.fullName, style: TextStyle( color: Colors.deepPurpleAccent, fontWeight: FontWeight.w900, @@ -319,7 +323,7 @@ class _VideoCallPageState extends State { endCallWithCharge() { _liveCareProvider - .endCallWithCharge(widget.patientData.vCID, doctorprofile['DoctorID']) + .endCallWithCharge(widget.patientData.vcId, doctorprofile['DoctorID']) .then((result) { closeRoute(); print('end callwith charge'); diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 0ec0cf0e..f90e9f33 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; @@ -5,9 +6,11 @@ import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.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/screens/live_care/end_call_screen.dart'; +import 'package:doctor_app_flutter/screens/live_care/video_call.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -278,13 +281,25 @@ class _PatientProfileScreenState extends State .endCall:TranslationBase .of(context) .initiateCall, + disabled: model.state == ViewState.BusyLocal, onPressed: () async { if(model.isFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); } else { - // TODO Call initiateCall service + GifLoaderDialogUtils.showMyDialog(context); + await model.startCall( isReCall : false, vCID: patient.vcId); + if(model.state == ViewState.ErrorLocal) { + // + GifLoaderDialogUtils.hideDialog(context); + Helpers.showErrorToast(model.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + VideoCallPage(patientData: patient,listContext: "dfd",model: model,))); + } } }, From f26d870d5b74d6c0436e724d297162a2f11057c8 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 20 May 2021 18:17:06 +0300 Subject: [PATCH 083/241] procedure changes --- lib/client/base_app_client.dart | 4 +- lib/config/config.dart | 4 +- .../get_ordered_procedure_model.dart | 6 ++- lib/screens/procedures/ProcedureCard.dart | 42 +++++++++++-------- .../procedures/add-procedure-form.dart | 2 +- .../procedures/add_procedure_homeScreen.dart | 12 +++--- lib/screens/procedures/procedure_screen.dart | 6 +-- lib/screens/procedures/update-procedure.dart | 2 +- 8 files changed, 44 insertions(+), 34 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index f73d4068..7a8baa56 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -48,8 +48,8 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = "@dm!n";// token ?? ''; - // body['TokenID'] = "@dm!n" ?? ''; + body['TokenID'] = token ?? ''; + // body['TokenID'] = "@dm!n" ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') body['LanguageID'] = 1; diff --git a/lib/config/config.dart b/lib/config/config.dart index 8464f720..93d38947 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL = 'https://hmgwebservices.com/'; -//const BASE_URL = 'https://uat.hmgwebservices.com/'; +//const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/model/procedure/get_ordered_procedure_model.dart b/lib/core/model/procedure/get_ordered_procedure_model.dart index b7185711..c3c7718f 100644 --- a/lib/core/model/procedure/get_ordered_procedure_model.dart +++ b/lib/core/model/procedure/get_ordered_procedure_model.dart @@ -53,6 +53,7 @@ class EntityList { String remarks; String status; String template; + int doctorID; EntityList( {this.achiCode, @@ -78,10 +79,12 @@ class EntityList { this.procedureName, this.remarks, this.status, - this.template}); + this.template, + this.doctorID}); EntityList.fromJson(Map json) { achiCode = json['achiCode']; + doctorID = json['doctorID']; appointmentDate = json['appointmentDate']; appointmentNo = json['appointmentNo']; categoryID = json['categoryID']; @@ -110,6 +113,7 @@ class EntityList { Map toJson() { final Map data = new Map(); data['achiCode'] = this.achiCode; + data['doctorID'] = this.doctorID; data['appointmentDate'] = this.appointmentDate; data['appointmentNo'] = this.appointmentNo; data['categoryID'] = this.categoryID; diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index 0c3d952f..3448d0be 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -16,7 +17,7 @@ class ProcedureCard extends StatelessWidget { final String categoryName; final int categoryID; final PatiantInformtion patient; - final String doctorName; + final int doctorID; const ProcedureCard({ Key key, @@ -25,7 +26,7 @@ class ProcedureCard extends StatelessWidget { this.categoryID, this.categoryName, this.patient, - this.doctorName, + this.doctorID, }) : super(key: key); @override Widget build(BuildContext context) { @@ -241,22 +242,27 @@ class ProcedureCard extends StatelessWidget { ), ), ),*/ - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // AppText( - // entityList.remarks.toString() ?? '', - // fontSize: 12, - // ), - // if (entityList.categoryID == 2 || - // entityList.categoryID == 4 && - // doctorName == entityList.doctorName) - // InkWell( - // child: Icon(DoctorApp.edit), - // onTap: onTap, - // ) - // ], - // ) + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: AppText( + entityList.remarks.toString() ?? '', + fontSize: 12, + ), + ), + if (entityList.categoryID == 2 || + entityList.categoryID == 4 && + doctorID == entityList.doctorID) + InkWell( + child: Icon(DoctorApp.edit), + onTap: onTap, + ) + ], + ), + ) ], ), //onTap: onTap, diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index b17f50ae..830b5a5e 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -186,7 +186,7 @@ class _AddSelectedProcedureState extends State { children: [ Container( width: MediaQuery.of(context).size.width * - 0.81, + 0.79, child: AppTextFieldCustom( hintText: TranslationBase.of(context) .searchProcedureHere, diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/add_procedure_homeScreen.dart index de242cd7..4a4d8242 100644 --- a/lib/screens/procedures/add_procedure_homeScreen.dart +++ b/lib/screens/procedures/add_procedure_homeScreen.dart @@ -125,12 +125,12 @@ class _AddProcedureHomeState extends State tabWidget( screenSize, _activeTab == 0, - 'All Procedures', + "Favorite Templates", ), tabWidget( screenSize, _activeTab == 1, - "Favorite Templates", + 'All Procedures', ), ], ), @@ -144,14 +144,14 @@ class _AddProcedureHomeState extends State physics: BouncingScrollPhysics(), controller: _tabController, children: [ - AddSelectedProcedure( - model: model, - patient: patient, - ), AddFavouriteProcedure( patient: patient, model: model, ), + AddSelectedProcedure( + model: model, + patient: patient, + ), ], ), ), diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index b964392e..bcc7c291 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -17,12 +17,12 @@ import 'package:flutter/material.dart'; import 'ProcedureCard.dart'; class ProcedureScreen extends StatelessWidget { - String doctorNameP; + int doctorNameP; void initState() async { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); - doctorNameP = doctorProfile.doctorName; + doctorNameP = doctorProfile.doctorID; } @override @@ -187,7 +187,7 @@ class ProcedureScreen extends StatelessWidget { // 'You Cant Update This Procedure'); }, patient: patient, - doctorName: doctorNameP, + doctorID: doctorNameP, ), ), if (model.state == ViewState.ErrorLocal || diff --git a/lib/screens/procedures/update-procedure.dart b/lib/screens/procedures/update-procedure.dart index 6190e92e..24c4ea41 100644 --- a/lib/screens/procedures/update-procedure.dart +++ b/lib/screens/procedures/update-procedure.dart @@ -100,7 +100,7 @@ class _UpdateProcedureWidgetState extends State { baseViewModel: model, child: SingleChildScrollView( child: Container( - height: MediaQuery.of(context).size.height * 0.65, + height: MediaQuery.of(context).size.height * 0.9, child: Form( child: Padding( padding: From 17cca30b17678de20abd38126907c83caa307663 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Thu, 20 May 2021 18:18:39 +0300 Subject: [PATCH 084/241] procedure changes --- lib/config/config.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index c5372a07..f1d642eb 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -297,9 +297,11 @@ const GET_PROCEDURE_TEMPLETE = const GET_PROCEDURE_TEMPLETE_DETAILS = "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; -const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP ='Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; +const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = + 'Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; -const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; +const DOCTOR_CHECK_HAS_LIVE_CARE = + "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; var selectedPatientType = 1; From 2a448406660dcff15c861c907f4e4b5088f1271b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 23 May 2021 09:34:09 +0300 Subject: [PATCH 085/241] hot fix --- lib/models/doctor/doctor_profile_model.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/doctor/doctor_profile_model.dart b/lib/models/doctor/doctor_profile_model.dart index 17625968..c2f5b0dd 100644 --- a/lib/models/doctor/doctor_profile_model.dart +++ b/lib/models/doctor/doctor_profile_model.dart @@ -7,7 +7,7 @@ class DoctorProfileModel { Null clinicDescriptionN; Null licenseExpiry; int employmentType; - Null setupID; + dynamic setupID; int projectID; String projectName; String nationalityID; From 69eca869b4a7afe7899b932e79ec2c94bf9a882b Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 23 May 2021 10:12:08 +0300 Subject: [PATCH 086/241] fix error after merge --- .../patients/profile/profile_screen/patient_profile_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e3d5ef64..f90e9f33 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -283,7 +283,7 @@ class _PatientProfileScreenState extends State .initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - // if(model.isFinished) { + if(model.isFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); From 764578f28e673d34fac963c2f7ea3fb386b7808e Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 23 May 2021 14:34:25 +0300 Subject: [PATCH 087/241] procedure changes --- lib/core/viewModel/procedure_View_model.dart | 3 ++- lib/screens/procedures/ProcedureCard.dart | 7 ++++--- lib/screens/procedures/procedure_screen.dart | 11 ++++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 3bdd676f..4411f7b5 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -60,6 +60,8 @@ class ProcedureViewModel extends BaseViewModel { Future getProcedure({int mrn, String patientType}) async { hasError = false; + await getDoctorProfile(); + doctorProfile.doctorID; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); await _procedureService.getProcedure(mrn: mrn); @@ -289,7 +291,6 @@ class ProcedureViewModel extends BaseViewModel { } } - getPatientLabOrdersResults( {PatientLabOrders patientLabOrder, String procedure, diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index 3448d0be..d998ca58 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -28,6 +28,7 @@ class ProcedureCard extends StatelessWidget { this.patient, this.doctorID, }) : super(key: key); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -253,9 +254,9 @@ class ProcedureCard extends StatelessWidget { fontSize: 12, ), ), - if (entityList.categoryID == 2 || - entityList.categoryID == 4 && - doctorID == entityList.doctorID) + if ((entityList.categoryID == 2 || + entityList.categoryID == 4) && + doctorID == entityList.doctorID) InkWell( child: Icon(DoctorApp.edit), onTap: onTap, diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index 986d3cc1..b6bd705a 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -92,9 +92,7 @@ class ProcedureScreen extends StatelessWidget { fontSize: 13, ), AppText( - TranslationBase - .of(context) - .procedure, + TranslationBase.of(context).procedure, bold: true, fontSize: 22, ), @@ -102,15 +100,14 @@ class ProcedureScreen extends StatelessWidget { ), ), if ((patient.patientStatusType != null && - patient.patientStatusType == 43) || + patient.patientStatusType == 43) || (isFromLiveCare && patient.appointmentNo != null)) InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => - AddProcedureHome( + builder: (context) => AddProcedureHome( patient: patient, model: model, )), @@ -192,7 +189,7 @@ class ProcedureScreen extends StatelessWidget { // 'You Cant Update This Procedure'); }, patient: patient, - doctorID: doctorNameP, + doctorID: model.doctorProfile.doctorID, ), ), if (model.state == ViewState.ErrorLocal || From 73cf681e9dbc94a6b2b054bb3013773991af52d9 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 23 May 2021 17:18:23 +0300 Subject: [PATCH 088/241] lab-result-special --- lib/config/config.dart | 4 ++-- .../lab_order/labs_service.dart | 7 +++++-- .../PatientMedicalReportService.dart | 2 ++ .../lab_result/laboratory_result_page.dart | 16 ++++++++++------ .../lab_result/laboratory_result_widget.dart | 8 ++++---- lib/widgets/shared/doctor_card.dart | 9 ++++++--- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index f1d642eb..638ff134 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/core/service/patient_medical_file/lab_order/labs_service.dart b/lib/core/service/patient_medical_file/lab_order/labs_service.dart index d7fc3aab..c7bb9a78 100644 --- a/lib/core/service/patient_medical_file/lab_order/labs_service.dart +++ b/lib/core/service/patient_medical_file/lab_order/labs_service.dart @@ -105,13 +105,16 @@ class LabsService extends BaseService { await baseAppClient.postPatient(url, patient: patient, onSuccess: (dynamic response, int statusCode) { - // patientLabSpecialResult.clear(); - labResultList.clear(); + patientLabSpecialResult = []; + labResultList = []; if (isInpatient) { response['List_GetLabNormal'].forEach((hospital) { labResultList.add(LabResult.fromJson(hospital)); }); + response['List_GetLabSpecial'].forEach((hospital) { + patientLabSpecialResult.add(PatientLabSpecialResult.fromJson(hospital)); + }); } else { response['ListPLR'].forEach((lab) { labResultList.add(LabResult.fromJson(lab)); diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 6e00b890..aa81e8a6 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -11,7 +11,9 @@ class PatientMedicalReportService extends BaseService { Future getMedicalReportList(PatiantInformtion patient) async { hasError = false; Map body = Map(); + await getDoctorProfile(); body['AdmissionNo'] = patient.admissionNo; + body['SetupID'] = doctorProfile.setupID; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, onSuccess: (dynamic response, int statusCode) { diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index e54a3782..4670e2d1 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -30,13 +30,17 @@ class _LaboratoryResultPageState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getLaboratoryResult( - invoiceNo: widget.patientLabOrders.invoiceNo, - clinicID: widget.patientLabOrders.clinicID, - projectID: widget.patientLabOrders.projectID, - orderNo: widget.patientLabOrders.orderNo, + // onModelReady: (model) => model.getLaboratoryResult( + // invoiceNo: widget.patientLabOrders.invoiceNo, + // clinicID: widget.patientLabOrders.clinicID, + // projectID: widget.patientLabOrders.projectID, + // orderNo: widget.patientLabOrders.orderNo, + // patient: widget.patient, + // isInpatient: widget.patientType == "1"), + onModelReady: (model) => model.getPatientLabResult( + patientLabOrder: widget.patientLabOrders, patient: widget.patient, - isInpatient: widget.patientType == "1"), + isInpatient: widget.patientType =="1"), builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBar: PatientProfileHeaderWhitAppointmentAppBar( diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart index bc6fcbcb..1bdc49cf 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart @@ -45,10 +45,10 @@ class _LaboratoryResultWidgetState extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); return BaseView( - onModelReady: (model) => model.getPatientLabResult( - patientLabOrder: widget.patientLabOrder, - patient: widget.patient, - isInpatient: widget.isInpatient), + // onModelReady: (model) => model.getPatientLabResult( + // patientLabOrder: widget.patientLabOrder, + // patient: widget.patient, + // isInpatient: widget.isInpatient), builder: (_, model, w) => NetworkBaseView( baseViewModel: model, child: Container( diff --git a/lib/widgets/shared/doctor_card.dart b/lib/widgets/shared/doctor_card.dart index 2a98a381..faa4379a 100644 --- a/lib/widgets/shared/doctor_card.dart +++ b/lib/widgets/shared/doctor_card.dart @@ -139,6 +139,7 @@ class DoctorCard extends StatelessWidget { ), if (clinic != null) Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( TranslationBase.of(context).clinic + @@ -146,9 +147,11 @@ class DoctorCard extends StatelessWidget { color: Colors.grey[500], fontSize: 14, ), - AppText( - clinic, - fontSize: 14, + Expanded( + child: AppText( + clinic, + fontSize: 14, + ), ) ], ), From ac701c98064a6612ee286de875872454365f5fd0 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Sun, 23 May 2021 17:22:37 +0300 Subject: [PATCH 089/241] fix live care issues --- ios/Podfile.lock | 2 +- lib/config/localized_values.dart | 6 +- .../patient/LiveCarePatientServices.dart | 10 ++- .../viewModel/LiveCarePatientViewModel.dart | 18 +++-- lib/screens/live_care/end_call_screen.dart | 75 ++++++++++++++++--- .../patient_profile_screen.dart | 65 ++++++++++++---- lib/util/translations_delegate_base.dart | 4 +- 7 files changed, 138 insertions(+), 42 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1cf7499c..59cdf14c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -328,4 +328,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.1 diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 6c0e0d83..64a353fd 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -982,7 +982,7 @@ const Map> localizedValues = { "medicalReportAdd": {"en": "Add Medical Report", "ar": "إضافة تقرير طبي"}, "medicalReportVerify": {"en": "Verify Medical Report", "ar": "تحقق من التقرير الطبي"}, "comments": {"en": "Comments", "ar": "تعليقات"}, - "initiateCall ": {"en": "Initiate Call ", "ar": "بدء الاتصال"}, + "initiateCall": {"en": "Initiate Call ", "ar": "بدء الاتصال"}, "transferTo": {"en": "Transfer To ", "ar": "حول إلى"}, "admin": {"en": "Admin", "ar": "مشرف"}, "instructions": {"en": "Instructions", "ar": "تعليمات"}, @@ -996,6 +996,6 @@ const Map> localizedValues = { "laboratoryPhysicalData": {"en": "Laboratory and Physical Data", "ar": "المعامل والبيانات الفيزيائية"}, "impressionRecommendation": {"en": "Impression and Recommendation", "ar": "الانطباع والتوصية"}, "onHold": {"en": "'On Hold'", "ar": "قيد الانتظار"}, - "verified": {"en": "'Verified'", "ar": "Verified"}, - "endCall": {"en": "'End'", "ar": "انهاء"}, + "verified": {"en": "Verified", "ar": "Verified"}, + "endCall": {"en": "End Call", "ar": "انهاء"}, }; diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index cb8cf61d..27dd666f 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -15,6 +15,10 @@ class LiveCarePatientServices extends BaseService { bool get isFinished => _isFinished; + setFinished(bool isFinished){ + _isFinished = isFinished; + } + var endCallResponse = {}; var transferToAdminResponse = {}; @@ -43,10 +47,10 @@ class LiveCarePatientServices extends BaseService { Future endCall(EndCallReq endCallReq) async { hasError = false; await baseAppClient.post(END_CALL, onSuccess: (response, statusCode) async { - _isFinished = true; + endCallResponse = response; }, onFailure: (String error, int statusCode) { - _isFinished = true; + hasError = true; super.error = error; }, body: endCallReq.toJson()); @@ -74,7 +78,7 @@ class LiveCarePatientServices extends BaseService { super.error = error; }, body: { - "VC_ID": vcID, + "VC_ID": vcID,"generalid":"Cs2020@2016\$2958", }, ); } diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index a7e0024f..59706429 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; @@ -16,7 +17,7 @@ class LiveCarePatientViewModel extends BaseViewModel { LiveCarePatientServices _liveCarePatientServices = locator(); - bool get isFinished => _liveCarePatientServices.isFinished; + StartCallRes get startCallRes => _liveCarePatientServices.startCallRes; DashboardService _dashboardService = @@ -39,12 +40,12 @@ class LiveCarePatientViewModel extends BaseViewModel { } } - Future endCall(request, isPatient, doctorID) async { - + Future endCall(int vCID, bool isPatient) async { + await getDoctorProfile(isGetProfile: true); EndCallReq endCallReq = new EndCallReq(); - endCallReq.doctorId = doctorID; //profile["DoctorID"]; + endCallReq.doctorId = doctorProfile.doctorID; endCallReq.generalid = 'Cs2020@2016\$2958'; - endCallReq.vCID = request.vCID; //["VC_ID"]; + endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; setState(ViewState.BusyLocal); @@ -58,6 +59,10 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + getToken()async{ + String token = await sharedPref.getString(TOKEN); + return token; + } Future startCall({int vCID, bool isReCall}) async { StartCallReq startCallReq = new StartCallReq(); @@ -74,8 +79,7 @@ class LiveCarePatientViewModel extends BaseViewModel { startCallReq.generalid = 'Cs2020@2016\$2958'; setState(ViewState.BusyLocal); - await _liveCarePatientServices - .startCall(startCallReq); + await _liveCarePatientServices.startCall(startCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index e33d476c..d4e9120e 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -1,10 +1,13 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.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/screens/live_care/live-care_transfer_to_admin.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/PatientProfileCardModel.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -44,10 +47,51 @@ class _EndCallScreenState extends State { final List cardsList = [ PatientProfileCardModel(TranslationBase.of(context).resume, TranslationBase.of(context).theCall, '', 'patient/vital_signs.png', - isInPatient: isInpatient, - onTap: () {}, - isDartIcon: true, - dartIcon: DoctorApp.call), + isInPatient: isInpatient, onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + await liveCareModel + .startCall(isReCall: false, vCID: widget.patient.vcId) + .then((value) async{ + await liveCareModel.getDoctorProfile(); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + }else + await VideoChannel.openVideoCallScreen( + kToken: liveCareModel.startCallRes.openTokenID, + kSessionId: liveCareModel.startCallRes.openSessionID, + kApiKey: '46209962', + vcId: widget.patient.vcId, + tokenID: await liveCareModel.getToken(), + generalId: GENERAL_ID, + doctorId: liveCareModel.doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + }, + onCallEnd: () async{ + GifLoaderDialogUtils.showMyDialog(context); + GifLoaderDialogUtils.showMyDialog(context); + await liveCareModel.endCall(widget.patient.vcId, false,); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) async{ + GifLoaderDialogUtils.showMyDialog(context); + GifLoaderDialogUtils.showMyDialog(context); + await liveCareModel.endCall(widget.patient.vcId, sessionStatusModel.sessionStatus == 3,); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } + }); + }); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } + }, isDartIcon: true, dartIcon: DoctorApp.call), PatientProfileCardModel( TranslationBase.of(context).endLC, TranslationBase.of(context).consultation, @@ -59,7 +103,7 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - liveCareModel.endCallWithCharge(widget.patient.vcId); + await liveCareModel.endCallWithCharge(widget.patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); @@ -77,14 +121,19 @@ class _EndCallScreenState extends State { onTap: () {}, isInPatient: isInpatient, isDartIcon: true, + isDisable: true, dartIcon: DoctorApp.send_instruction), - PatientProfileCardModel(TranslationBase.of(context).transferTo, - TranslationBase.of(context).admin, '', 'patient/health_summary.png', - onTap: () { - Navigator.push(context, MaterialPageRoute( + PatientProfileCardModel( + TranslationBase.of(context).transferTo, + TranslationBase.of(context).admin, + '', + 'patient/health_summary.png', onTap: () { + Navigator.push( + context, + MaterialPageRoute( builder: (BuildContext context) => - LivaCareTransferToAdmin(patient:widget.patient))); - }, + LivaCareTransferToAdmin(patient: widget.patient))); + }, isInPatient: isInpatient, isDartIcon: true, dartIcon: DoctorApp.transfer_to_admin), @@ -197,7 +246,9 @@ class _EndCallScreenState extends State { fontWeight: FontWeight.w700, color: Colors.red[600], title: "Close", //TranslationBase.of(context).close, - onPressed: () async {}, + onPressed: () { + Navigator.of(context).pop(); + }, ), ), ), diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index f90e9f33..ae5406d5 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,15 +1,17 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.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/screens/live_care/end_call_screen.dart'; -import 'package:doctor_app_flutter/screens/live_care/video_call.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -34,7 +36,7 @@ class _PatientProfileScreenState extends State bool isFromLiveCare = false; bool isInpatient = false; - + bool isCallFinished = false; bool isDischargedPatient = false; bool isSearchAndOut = false; String patientType; @@ -275,15 +277,13 @@ class _PatientProfileScreenState extends State child: Center( child: AppButton( fontWeight: FontWeight.w700, - color: model.isFinished?Colors.red[600]:Colors.green[600], - title: model.isFinished?TranslationBase - .of(context) - .endCall:TranslationBase - .of(context) - .initiateCall, + color: isCallFinished?Colors.red[600]:Colors.green[600], + title: isCallFinished? + TranslationBase.of(context).endCall: + TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - if(model.isFinished) { + if(isCallFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); @@ -291,14 +291,51 @@ class _PatientProfileScreenState extends State GifLoaderDialogUtils.showMyDialog(context); await model.startCall( isReCall : false, vCID: patient.vcId); if(model.state == ViewState.ErrorLocal) { - // GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { + await model.getDoctorProfile(); GifLoaderDialogUtils.hideDialog(context); - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - VideoCallPage(patientData: patient,listContext: "dfd",model: model,))); + await VideoChannel.openVideoCallScreen( + kToken: model.startCallRes.openTokenID, + kSessionId: model.startCallRes.openSessionID, + kApiKey: '46209962', + vcId: patient.vcId, + tokenID: await model.getToken(), + generalId: GENERAL_ID, + doctorId: model.doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + }, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + + }); + }); } } diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index a4ecc977..9ed00146 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1338,8 +1338,8 @@ class TranslationBase { String get medicalReportAdd => localizedValues['medicalReportAdd'][locale.languageCode]; String get medicalReportVerify => localizedValues['medicalReportVerify'][locale.languageCode]; String get comments => localizedValues['comments'][locale.languageCode]; - String get initiateCall => localizedValues['initiateCall '][locale.languageCode]; - String get endCall => localizedValues['endCall '][locale.languageCode]; + String get initiateCall => localizedValues['initiateCall'][locale.languageCode]; + String get endCall => localizedValues['endCall'][locale.languageCode]; String get transferTo => localizedValues['transferTo'][locale.languageCode]; String get admin => localizedValues['admin'][locale.languageCode]; From 1391799101af955215ebc6a0969aacb78c265c68 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Sun, 23 May 2021 17:26:39 +0300 Subject: [PATCH 090/241] fix live care user --- lib/core/service/home/dasboard_service.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index a1072676..ba836287 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -32,6 +32,7 @@ class DashboardService extends BaseService { Future checkDoctorHasLiveCare() async { hasError = false; + await getDoctorProfile(isGetProfile: true); await baseAppClient.post( DOCTOR_CHECK_HAS_LIVE_CARE, onSuccess: (dynamic response, int statusCode) { @@ -43,7 +44,7 @@ class DashboardService extends BaseService { super.error = error; }, body: { - "DoctorID": 9920 + "DoctorID": doctorProfile.doctorID// test user 9920 }, ); } From 41515b311cea8987c983e2462960a349b5e4004f Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 24 May 2021 12:45:07 +0300 Subject: [PATCH 091/241] lab-result-fixes --- lib/config/config.dart | 4 +- lib/config/localized_values.dart | 4 +- .../PatientMedicalReportService.dart | 1 + lib/core/viewModel/labs_view_model.dart | 33 +- .../admission-request-detail-screen.dart | 307 ------------------ .../admission-request-first-screen.dart | 14 - .../lab_result/laboratory_result_page.dart | 23 +- .../lab_result/laboratory_result_widget.dart | 152 +++++---- .../medical_report/MedicalReportPage.dart | 21 +- lib/util/helpers.dart | 7 +- 10 files changed, 136 insertions(+), 430 deletions(-) delete mode 100644 lib/screens/patients/profile/admission-request/admission-request-detail-screen.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 638ff134..f1d642eb 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,8 +4,8 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 6c0e0d83..20bcd1d7 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -995,7 +995,7 @@ const Map> localizedValues = { "historyPhysicalFinding": {"en": "History and Physical Finding", "ar": "التاريخ والاكتشاف المادي"}, "laboratoryPhysicalData": {"en": "Laboratory and Physical Data", "ar": "المعامل والبيانات الفيزيائية"}, "impressionRecommendation": {"en": "Impression and Recommendation", "ar": "الانطباع والتوصية"}, - "onHold": {"en": "'On Hold'", "ar": "قيد الانتظار"}, - "verified": {"en": "'Verified'", "ar": "Verified"}, + "onHold": {"en": "On Hold", "ar": "قيد الانتظار"}, + "verified": {"en": "Verified", "ar": "تم التحقق"}, "endCall": {"en": "'End'", "ar": "انهاء"}, }; diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index aa81e8a6..94933d7d 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -14,6 +14,7 @@ class PatientMedicalReportService extends BaseService { await getDoctorProfile(); body['AdmissionNo'] = patient.admissionNo; body['SetupID'] = doctorProfile.setupID; + body['ProjectID'] = doctorProfile.projectID; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, onSuccess: (dynamic response, int statusCode) { diff --git a/lib/core/viewModel/labs_view_model.dart b/lib/core/viewModel/labs_view_model.dart index 90e9b327..5b4b7e4c 100644 --- a/lib/core/viewModel/labs_view_model.dart +++ b/lib/core/viewModel/labs_view_model.dart @@ -128,25 +128,28 @@ class LabsViewModel extends BaseViewModel { error = _labsService.error; setState(ViewState.Error); } else { - _labsService.labResultList.forEach((element) { - List patientLabOrdersClinic = labResultLists - .where( - (elementClinic) => elementClinic.filterName == element.testCode) - .toList(); - - if (patientLabOrdersClinic.length != 0) { - labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])] - .patientLabResultList - .add(element); - } else { - labResultLists - .add(LabResultList(filterName: element.testCode, lab: element)); - } - }); setState(ViewState.Idle); } } + void setLabResultDependOnFilterName(){ + _labsService.labResultList.forEach((element) { + List patientLabOrdersClinic = labResultLists + .where( + (elementClinic) => elementClinic.filterName == element.testCode) + .toList(); + + if (patientLabOrdersClinic.length != 0) { + labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])] + .patientLabResultList + .add(element); + } else { + labResultLists + .add(LabResultList(filterName: element.testCode, lab: element)); + } + }); + } + getPatientLabOrdersResults( {PatientLabOrders patientLabOrder, String procedure, diff --git a/lib/screens/patients/profile/admission-request/admission-request-detail-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-detail-screen.dart deleted file mode 100644 index bbc968b0..00000000 --- a/lib/screens/patients/profile/admission-request/admission-request-detail-screen.dart +++ /dev/null @@ -1,307 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/date-utils.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-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/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:provider/provider.dart'; - -import '../../../../routes.dart'; - -class AdmissionRequestDetailScreen extends StatefulWidget { - @override - _AdmissionRequestDetailScreenState createState() => - _AdmissionRequestDetailScreenState(); -} - -class _AdmissionRequestDetailScreenState - extends State { - DateTime selectedDate; - dynamic _selectedSpeciality; - dynamic _selectedDoctor; - - @override - Widget build(BuildContext context) { - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatiantInformtion patient = routeArgs['patient']; - final screenSize = MediaQuery.of(context).size; - ProjectViewModel projectViewModel = Provider.of(context); - - return BaseView( - onModelReady: (model) => model.getSpecialityList(), - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - appBarTitle: TranslationBase.of(context).admissionRequest, - body: model.doctorsList != null - ? Column( - children: [ - Expanded( - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - PatientPageHeaderWidget(patient), - Container( - margin: EdgeInsets.symmetric( - vertical: 16, horizontal: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 16, - ), - AppText( - TranslationBase.of(context).patientDetails, - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.5, - ), - SizedBox( - height: 10, - ), - Container( - decoration: - Helpers.containerBorderDecoration( - Color(0xFFEEEEEE), - Color(0xFFCCCCCC), - borderWidth: 0.0), - height: screenSize.height * 0.070, - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - "Pre Admission Number :01", - null, - false), - enabled: false, - // controller: _remarksController, - keyboardType: TextInputType.text, - )), - SizedBox( - height: 10, - ), - Container( - height: screenSize.height * 0.070, - child: InkWell( - onTap: () => _selectDate(context, model), - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - TranslationBase.of(context).date, - selectedDate != null - ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" - : null, - true, - suffixIcon: Icon( - Icons.calendar_today, - color: Colors.black, - )), - enabled: false, - ), - ), - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .specialityAndDoctorDetail, - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.5, - ), - SizedBox( - height: 10, - ), - Container( - height: screenSize.height * 0.070, - child: InkWell( - onTap: () { - ListSelectDialog dialog = - ListSelectDialog( - list: model.speciality, - attributeName: - projectViewModel.isArabic - ? 'nameAr' - : 'nameEn', - attributeValueId: 'id', - okText: - TranslationBase.of(context) - .ok, - okFunction: (selectedValue) { - setState(() { - _selectedSpeciality = - selectedValue; - }); - }); - showDialog( - barrierDismissible: false, - context: context, - builder: (BuildContext context) { - return dialog; - }, - ); - }, - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - TranslationBase.of(context) - .speciality, - _selectedSpeciality != null - ? projectViewModel.isArabic - ? _selectedSpeciality[ - 'nameAr'] - : _selectedSpeciality[ - 'nameEn'] - : null, - true), - enabled: false, - ), - ), - ), - SizedBox( - height: 10, - ), - Container( - height: screenSize.height * 0.070, - child: InkWell( - onTap: model.doctorsList != null && - model.doctorsList.length > 0 - ? () { - ListSelectDialog dialog = - ListSelectDialog( - list: model.doctorsList, - attributeName: 'DoctorName', - attributeValueId: 'DoctorID', - usingSearch: true, - hintSearchText: - TranslationBase.of(context) - .doctorSearch, - okText: - TranslationBase.of(context) - .ok, - okFunction: (selectedValue) { - setState(() { - _selectedDoctor = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: false, - context: context, - builder: (BuildContext context) { - return dialog; - }, - ); - } - : null, - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - TranslationBase.of(context) - .doctor, - _selectedDoctor != null - ? _selectedDoctor[ - 'DoctorName'] - : null, - true), - enabled: false, - ), - ), - ), - SizedBox( - height: 10, - ), - Container( - height: screenSize.height * 0.070, - decoration: Helpers.containerBorderDecoration( - Color(0xFFEEEEEE), Color(0xFFCCCCCC), - borderWidth: 0.0), - child: InkWell( - onTap: () => null, - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - TranslationBase.of(context) - .referringDate, - null, - true, - suffixIcon: Icon( - Icons.calendar_today, - color: Color(0xFFCCCCCC), - )), - enabled: false, - ), - ), - ), - SizedBox( - height: 10, - ), - Container( - decoration: - Helpers.containerBorderDecoration( - Color(0xFFEEEEEE), - Color(0xFFCCCCCC), - borderWidth: 0.0), - height: screenSize.height * 0.070, - child: TextField( - decoration: - Helpers.textFieldSelectorDecoration( - TranslationBase.of(context) - .referringDoctor, - null, - true, - dropDownColor: Color(0xFFCCCCCC)), - enabled: false, - // controller: _remarksController, - keyboardType: TextInputType.text, - )), - ], - ), - ), - ], - ), - ), - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: AppButton( - title: TranslationBase.of(context).next, - color: HexColor("#B8382B"), - onPressed: () { - Navigator.of(context).pushNamed( - PATIENT_ADMISSION_REQUEST_2, - arguments: {'patient': patient}); - }, - ), - ), - ], - ) - : Container(), - ), - ); - } - - _selectDate(BuildContext context, AdmissionRequestViewModel model) async { - selectedDate = DateTime.now(); - final DateTime picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart index d23397da..08a69907 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart @@ -453,20 +453,6 @@ class _AdmissionRequestThirdScreenState ); } - Future _selectDate(BuildContext context, DateTime dateTime, - Function(DateTime picked) updateDate) async { - final DateTime picked = await showDatePicker( - context: context, - initialDate: dateTime, - firstDate: DateTime.now(), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != dateTime) { - updateDate(picked); - } - } - void openListDialogField(String attributeName, String attributeValueId, List list, Function(dynamic selectedValue) okFunction) { ListSelectDialog dialog = ListSelectDialog( diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 4670e2d1..3aae6e69 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -61,18 +61,17 @@ class _LaboratoryResultPageState extends State { body: SingleChildScrollView( child: Column( children: [ - ...List.generate( - model.patientLabSpecialResult.length, - (index) => LaboratoryResultWidget( - onTap: () async {}, - billNo: widget.patientLabOrders.invoiceNo, - details: model - .patientLabSpecialResult[index].resultDataHTML, - orderNo: widget.patientLabOrders.orderNo, - patientLabOrder: widget.patientLabOrders, - patient: widget.patient, - isInpatient: widget.patientType == "1", - )), + LaboratoryResultWidget( + onTap: () async {}, + billNo: widget.patientLabOrders.invoiceNo, + details: model + .patientLabSpecialResult.length > 0 ? model + .patientLabSpecialResult[0].resultDataHTML : null, + orderNo: widget.patientLabOrders.orderNo, + patientLabOrder: widget.patientLabOrders, + patient: widget.patient, + isInpatient: widget.patientType == "1", + ), ], ), ), diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart index 1bdc49cf..08c247ee 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_widget.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/screens/patients/profile/lab_result/LabResultWidget.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; @@ -45,7 +46,8 @@ class _LaboratoryResultWidgetState extends State { Widget build(BuildContext context) { projectViewModel = Provider.of(context); return BaseView( - // onModelReady: (model) => model.getPatientLabResult( + onModelReady: (model) => model.setLabResultDependOnFilterName(), + // model.getPatientLabResult( // patientLabOrder: widget.patientLabOrder, // patient: widget.patient, // isInpatient: widget.isInpatient), @@ -130,8 +132,11 @@ class _LaboratoryResultWidgetState extends State { model.labResultLists.length, (index) => LabResultWidget( patientLabOrder: widget.patientLabOrder, - filterName: model.labResultLists[index].filterName, - patientLabResultList: model.labResultLists[index].patientLabResultList, + filterName: model + .labResultLists[index].filterName, + patientLabResultList: model + .labResultLists[index] + .patientLabResultList, patient: widget.patient, isInpatient: widget.isInpatient, ), @@ -143,76 +148,85 @@ class _LaboratoryResultWidgetState extends State { ], ), ), - SizedBox(height: 15,), - if(widget.details!=null && widget.details.isNotEmpty) - Column( - children: [ - InkWell( - onTap: () { - setState(() { - _isShowMore = !_isShowMore; - }); - }, - child: Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(5.0), - )), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only( - left: 10, right: 10), - child: AppText( - TranslationBase.of(context) - .specialResult, - bold: true, - ))), - Container( - width: 25, - height: 25, - child: Icon( - _isShowMore - ? Icons.keyboard_arrow_up - : Icons.keyboard_arrow_down, - color: Colors.grey[800], - size: 22, - ), - ) - ], + SizedBox( + height: 15, + ), + if (widget.details != null && widget.details.isNotEmpty) + Column( + children: [ + InkWell( + onTap: () { + setState(() { + _isShowMore = !_isShowMore; + }); + }, + child: Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(5.0), + )), + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only( + left: 10, right: 10), + child: AppText( + TranslationBase.of(context) + .specialResult, + bold: true, + ))), + Container( + width: 25, + height: 25, + child: Icon( + _isShowMore + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + color: Colors.grey[800], + size: 22, + ), + ) + ], + ), ), ), - ), - if (_isShowMore) - AnimatedContainer( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.white, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(5.0), - bottomRight: Radius.circular(5.0), - )), - duration: Duration(milliseconds: 7000), - child: Container( + if (_isShowMore) + AnimatedContainer( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(5.0), + bottomRight: Radius.circular(5.0), + )), + duration: Duration(milliseconds: 7000), + child: Container( width: double.infinity, - child: Html( - data: widget.details ?? TranslationBase.of(context).noDataAvailable, - )), + child: !Helpers.isTextHtml(widget.details) + ? AppText( + widget.details ?? + TranslationBase.of(context) + .noDataAvailable, + ) + : Html( + data: widget.details ?? + TranslationBase.of(context) + .noDataAvailable, + ), + ), + ), + SizedBox( + height: 10, ), - SizedBox( - height: 10, - ), - ], - ), - - + ], + ), ], ), ], diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 5e71dbd6..b54d4837 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -14,7 +14,6 @@ import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-head 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/card_with_bg_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -94,7 +93,7 @@ class MedicalReportPage extends StatelessWidget { model.medicalReportList.length, (index) => CardWithBgWidget( hasBorder: false, - bgColor: model.medicalReportList[index].status == 0 + bgColor: model.medicalReportList[index].status == 1 ? Colors.red[700] : Colors.green[700], widget: Column( @@ -106,10 +105,12 @@ class MedicalReportPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - model.medicalReportList[index].status == 0 + model.medicalReportList[index].status == 1 ? TranslationBase.of(context).onHold : TranslationBase.of(context).verified, - color: Colors.red, + color: model.medicalReportList[index].status == 1 + ? Colors.red[700] + : Colors.green[700], ), AppText( "Jammal" ?? "", @@ -123,13 +124,17 @@ class MedicalReportPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(DateTime.now(), isArabic: projectViewModel.isArabic)}', + '${AppDateUtils.convertDateFromServerFormat( + model.medicalReportList[index].editedOn, + "dd/MM/yyyy")}', color: Colors.black, fontWeight: FontWeight.w600, fontSize: 14, ), AppText( - '${AppDateUtils.getHour(DateTime.now())}', + '${AppDateUtils.convertDateFromServerFormat( + model.medicalReportList[index].editedOn, + "hh:mm a")}', fontWeight: FontWeight.w600, color: Colors.grey[700], fontSize: 14, @@ -154,7 +159,7 @@ class MedicalReportPage extends StatelessWidget { InkWell( onTap: () { if (model.medicalReportList[index].status == - 0) { + 1) { Navigator.of(context).pushNamed( PATIENT_MEDICAL_REPORT_INSERT, arguments: { @@ -178,7 +183,7 @@ class MedicalReportPage extends StatelessWidget { } }, child: Icon( - model.medicalReportList[index].status == 0 + model.medicalReportList[index].status == 1 ? EvaIcons.eye : DoctorApp.edit_1, ), diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 7f72435f..634abd02 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -50,7 +50,7 @@ class Helpers { color: Colors.green[600], ), AppButton( - onPressed: (){ + onPressed: () { Navigator.of(context).pop(); }, title: TranslationBase.of(context).cancel, @@ -265,4 +265,9 @@ class Helpers { return str; } } + + static bool isTextHtml(String text) { + var htmlRegex = RegExp("<(“[^”]*”|'[^’]*’|[^'”>])*>"); + return htmlRegex.hasMatch(text); + } } From 281a807ec8b35ec40e4f4673bc4c9c22860fde86 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 24 May 2021 16:37:57 +0300 Subject: [PATCH 092/241] fix live care --- lib/client/base_app_client.dart | 8 ++++++-- lib/config/config.dart | 3 ++- lib/config/localized_values.dart | 2 +- lib/core/service/patient/LiveCarePatientServices.dart | 10 +++++----- lib/core/viewModel/livecare_view_model.dart | 2 +- lib/models/patient/patiant_info_model.dart | 6 +++--- lib/util/VideoChannel.dart | 2 +- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 7a8baa56..824b8189 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -21,8 +21,12 @@ class BaseAppClient { {Map body, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, - bool isAllowAny = false}) async { - String url = BASE_URL + endPoint; + bool isAllowAny = false,bool isLiveCare = false}) async { + String url; + if(isLiveCare) + url = BASE_URL_LIVE_CARE + endPoint; + else + url = BASE_URL + endPoint; bool callLog = true; try { diff --git a/lib/config/config.dart b/lib/config/config.dart index 638ff134..86c42f8d 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,6 +4,7 @@ const MAX_SMALL_SCREEN = 660; const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; +const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; const BASE_URL = 'https://hmgwebservices.com/'; // const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; @@ -47,7 +48,7 @@ const GET_RADIOLOGY = 'Services/DoctorApplication.svc/REST/GetPatientRadResult'; const GET_LIVECARE_PENDINGLIST = 'Services/DoctorApplication.svc/REST/GetPendingPatientER'; -const START_LIVECARE_CALL = 'LiveCareApi/DoctorApp/CallPatient'; +const START_LIVE_CARE_CALL = 'LiveCareApi/DoctorApp/CallPatient'; const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL = "Lists.svc/REST/DashBoard_GetLiveCareDoctorsStatsticsForCertainDoctor"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 64a353fd..0bb783d9 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -774,7 +774,7 @@ const Map> localizedValues = { 'appointmentDate': {'en': "Appointment Date", 'ar': "تاريخ الموعد"}, 'arrived_p': {'en': "Arrived", 'ar': "وصل"}, 'details': {'en': 'Details', 'ar': 'التفاصيل'}, - "liveCare": {"en": "Live Care", "ar": "لايف كير"}, + "liveCare": {"en": "LiveCare", "ar": "لايف كير"}, "out-patient": {"en": "OutPatient", "ar": "عيادات خارجية"}, "BillNo": {"en": "Bill No :", "ar": "رقم الفاتورة"}, "labResults": {"en": "Lab Result", "ar": "نتيجة المختبر"}, diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index 27dd666f..4fc25094 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -53,18 +53,18 @@ class LiveCarePatientServices extends BaseService { hasError = true; super.error = error; - }, body: endCallReq.toJson()); + }, body: endCallReq.toJson(),isLiveCare: true); } Future startCall(StartCallReq startCallReq) async { hasError = false; - await baseAppClient.post(START_LIVECARE_CALL, + await baseAppClient.post(START_LIVE_CARE_CALL, onSuccess: (response, statusCode) async { _startCallRes = StartCallRes.fromJson(response); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: startCallReq.toJson()); + }, body: startCallReq.toJson(),isLiveCare: true); } Future endCallWithCharge(int vcID) async{ hasError = false; @@ -79,7 +79,7 @@ class LiveCarePatientServices extends BaseService { }, body: { "VC_ID": vcID,"generalid":"Cs2020@2016\$2958", - }, + },isLiveCare: true ); } @@ -98,7 +98,7 @@ class LiveCarePatientServices extends BaseService { "VC_ID": vcID, "IsOutKsa": false, "Notes": notes, - }, + },isLiveCare: true ); } } \ No newline at end of file diff --git a/lib/core/viewModel/livecare_view_model.dart b/lib/core/viewModel/livecare_view_model.dart index f6ef42e7..de586e1e 100644 --- a/lib/core/viewModel/livecare_view_model.dart +++ b/lib/core/viewModel/livecare_view_model.dart @@ -66,7 +66,7 @@ class LiveCareViewModel with ChangeNotifier { newRequest.docSpec = profile["DoctorTitleForProfile"]; newRequest.generalid = 'Cs2020@2016\$2958'; isFinished = false; - await baseAppClient.post(START_LIVECARE_CALL, + await baseAppClient.post(START_LIVE_CARE_CALL, onSuccess: (response, statusCode) async { isFinished = true; inCallResponse = StartCallRes.fromJson(response); diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index fc77af66..1fcce8eb 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -5,8 +5,8 @@ class PatiantInformtion { int genderInt; dynamic age; String appointmentDate; - int appointmentNo; - String appointmentType; + dynamic appointmentNo; + dynamic appointmentType; int appointmentTypeId; String arrivedOn; int clinicGroupId; @@ -23,7 +23,7 @@ class PatiantInformtion { String nationality; int projectId; int clinicId; - int patientId; + dynamic patientId; String doctorName; String doctorNameN; String firstName; diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index bf255b54..a0962010 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -20,7 +20,7 @@ class VideoChannel{ "kSessionId": kSessionId, "kToken": kToken, "appLang": "en", - "baseUrl": BASE_URL, + "baseUrl": BASE_URL_LIVE_CARE,//TODO change it to live "VC_ID": vcId, "TokenID": tokenID, "generalId": generalId, From da45f8c4b6c5536fc9b07826cfada444370526cc Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 24 May 2021 16:47:11 +0300 Subject: [PATCH 093/241] prescription refactoring --- .../prescription/add_prescription_form.dart | 1191 +++-------------- .../prescription/prescription_text_filed.dart | 76 ++ .../prescription/prescriptions_page.dart | 15 +- lib/util/date-utils.dart | 106 +- .../text_fields/app-textfield-custom.dart | 61 +- .../shared/text_fields/text_field_error.dart | 17 +- 6 files changed, 384 insertions(+), 1082 deletions(-) create mode 100644 lib/screens/prescription/prescription_text_filed.dart diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index fc4609f3..894d7c33 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -6,7 +6,6 @@ import 'package:doctor_app_flutter/core/model/Prescriptions/post_prescrition_req import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_model.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; - import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -15,6 +14,7 @@ import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.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/screens/prescription/drugtodrug.dart'; +import 'package:doctor_app_flutter/screens/prescription/prescription_text_filed.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -23,7 +23,6 @@ import 'package:doctor_app_flutter/widgets/medicine/medicine_item_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; @@ -36,8 +35,7 @@ import 'package:provider/provider.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; -addPrescriptionForm(context, PrescriptionViewModel model, - PatiantInformtion patient, prescription) { +addPrescriptionForm(context, PrescriptionViewModel model, PatiantInformtion patient, prescription) { showModalBottomSheet( isScrollControlled: true, context: context, @@ -46,7 +44,7 @@ addPrescriptionForm(context, PrescriptionViewModel model, }); } -postProcedure( +postPrescription( {String duration, String doseTimeIn, String dose, @@ -62,16 +60,15 @@ postProcedure( String icdCode, PatiantInformtion patient, String patientType}) async { - PostPrescriptionReqModel postProcedureReqModel = - new PostPrescriptionReqModel(); - List sss = List(); + PostPrescriptionReqModel postProcedureReqModel = new PostPrescriptionReqModel(); + List prescriptionList = List(); postProcedureReqModel.appointmentNo = patient.appointmentNo; postProcedureReqModel.clinicID = patient.clinicId; postProcedureReqModel.episodeID = patient.episodeNo; postProcedureReqModel.patientMRN = patient.patientMRN; - sss.add(PrescriptionRequestModel( + prescriptionList.add(PrescriptionRequestModel( covered: true, dose: double.parse(dose), itemId: drugId.isEmpty ? 1 : int.parse(drugId), @@ -84,9 +81,7 @@ postProcedure( doseTime: doseTimeIn.isEmpty ? 1 : int.parse(doseTimeIn), duration: duration.isEmpty ? 1 : int.parse(duration), doseStartDate: doseTime.toIso8601String())); - postProcedureReqModel.prescriptionRequestModel = sss; - //postProcedureReqModel.procedures = controlsProcedure; - + postProcedureReqModel.prescriptionRequestModel = prescriptionList; await model.postPrescription(postProcedureReqModel, patient.patientMRN); if (model.state == ViewState.ErrorLocal) { @@ -99,8 +94,9 @@ postProcedure( class PrescriptionFormWidget extends StatefulWidget { final PrescriptionViewModel model; - PatiantInformtion patient; - List prescriptionList; + final PatiantInformtion patient; + final List prescriptionList; + PrescriptionFormWidget(this.model, this.patient, this.prescriptionList); @override @@ -116,10 +112,8 @@ class _PrescriptionFormWidgetState extends State { String strengthError; int selectedType; - TextEditingController durationController = TextEditingController(); + TextEditingController strengthController = TextEditingController(); - TextEditingController routeController = TextEditingController(); - TextEditingController frequencyController = TextEditingController(); TextEditingController indicationController = TextEditingController(); TextEditingController instructionController = TextEditingController(); @@ -128,11 +122,9 @@ class _PrescriptionFormWidgetState extends State { final myController = TextEditingController(); DateTime selectedDate; - dynamic selectedDrug; int strengthChar; GetMedicationResponseModel _selectedMedication; - GlobalKey key = - new GlobalKey>(); + GlobalKey key = new GlobalKey>(); TextEditingController drugIdController = TextEditingController(); TextEditingController doseController = TextEditingController(); @@ -141,15 +133,8 @@ class _PrescriptionFormWidgetState extends State { var event = RobotProvider(); var reconizedWord; - var notesList; - var filteredNotesList; - String textSeartch = "Amoxicillin"; - final GlobalKey formKey = GlobalKey(); final double spaceBetweenTextFileds = 12; - List referToList; - dynamic type; - dynamic strength; dynamic route; dynamic frequency; dynamic duration; @@ -161,41 +146,12 @@ class _PrescriptionFormWidgetState extends State { dynamic x; List indicationList; - String routeInatial = 'By Mouth'; - //PatiantInformtion patient; @override void initState() { super.initState(); selectedType = 1; - referToList = List(); - indicationList = List(); - - dynamic indication1 = {"id": 545, "name": "Gingival Hyperplasia"}; - dynamic indication2 = {"id": 546, "name": "Mild Drowsiness"}; - dynamic indication3 = {"id": 547, "name": "Hypertrichosis"}; - dynamic indication4 = {"id": 548, "name": "Mild Dizziness"}; - dynamic indication5 = {"id": 549, "name": "Enlargement of Facial Features"}; - dynamic indication6 = { - "id": 550, - "name": "Phenytoin Hypersensitivity Syndrome" - }; - dynamic indication7 = {"id": 551, "name": "Asterixis"}; - dynamic indication8 = {"id": 552, "name": "Bullous Dermatitis"}; - dynamic indication9 = {"id": 554, "name": "Purpuric Dermatitis"}; - dynamic indication10 = {"id": 555, "name": "Systemic Lupus Erythematosus"}; - - indicationList.add(indication1); - indicationList.add(indication2); - indicationList.add(indication3); - indicationList.add(indication4); - indicationList.add(indication5); - indicationList.add(indication6); - indicationList.add(indication7); - indicationList.add(indication8); - indicationList.add(indication9); - indicationList.add(indication10); } setSelectedType(int val) { @@ -207,8 +163,7 @@ class _PrescriptionFormWidgetState extends State { onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speech.initialize( - onStatus: statusListener, onError: errorListener); + bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, @@ -222,7 +177,6 @@ class _PrescriptionFormWidgetState extends State { void errorListener(SpeechRecognitionError error) { event.setValue({"searchText": 'null'}); - //SpeechToText.closeAlertDialog(context); print(error); } @@ -252,21 +206,15 @@ class _PrescriptionFormWidgetState extends State { } Future initSpeechState() async { - bool hasSpeech = await speech.initialize( - onError: errorListener, onStatus: statusListener); + bool hasSpeech = await speech.initialize(onError: errorListener, onStatus: statusListener); print(hasSpeech); if (!mounted) return; } @override Widget build(BuildContext context) { - ListSelectDialog drugDialog; final screenSize = MediaQuery.of(context).size; ProjectViewModel projectViewModel = Provider.of(context); - - // final routeArgs = ModalRoute.of(context).settings.arguments as Map; - // patient = routeArgs['patient']; - return BaseView( onModelReady: (model) async { x = model.patientAssessmentList.map((element) { @@ -278,22 +226,16 @@ class _PrescriptionFormWidgetState extends State { editedBy: '', doctorID: '', appointmentNo: widget.patient.appointmentNo); - //await model.getMedicationList(); if (model.medicationStrengthList.length == 0) { await model.getMedicationStrength(); } - //await model.getPrescription(mrn: widget.patient.patientMRN); if (model.medicationDurationList.length == 0) { await model.getMedicationDuration(); } - //await model.getMedicationRoute(); - //await model.getMedicationFrequency(); if (model.medicationDoseTimeList.length == 0) { await model.getMedicationDoseTime(); } - //await model.getMedicationIndications(); await model.getPatientAssessment(getAssessmentReqModel); - //await model.getItem(); }, builder: ( BuildContext context, @@ -310,18 +252,14 @@ class _PrescriptionFormWidgetState extends State { initialChildSize: 0.98, maxChildSize: 0.98, minChildSize: 0.9, - builder: - (BuildContext context, ScrollController scrollController) { + builder: (BuildContext context, ScrollController scrollController) { return SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height * 1.65, color: Color(0xffF8F8F8), child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 12.0, vertical: 10.0), + padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0), child: Column( - //crossAxisAlignment: CrossAxisAlignment.start, - //mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Column( children: [ @@ -329,12 +267,10 @@ class _PrescriptionFormWidgetState extends State { height: 15, ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - TranslationBase.of(context) - .newPrescriptionOrder, + TranslationBase.of(context).newPrescriptionOrder, fontWeight: FontWeight.w700, fontSize: 20, ), @@ -358,17 +294,13 @@ class _PrescriptionFormWidgetState extends State { child: Form( key: formKey, child: Column( - //mainAxisAlignment: MainAxisAlignment.end, children: [ FractionallySizedBox( widthFactor: 0.9, child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"))), + borderRadius: BorderRadius.all(Radius.circular(6.0)), + border: Border.all(width: 1.0, color: HexColor("#CCCCCC"))), padding: EdgeInsets.all(10), child: AppTextFormField( onTap: () { @@ -376,8 +308,7 @@ class _PrescriptionFormWidgetState extends State { visbiltySearch = true; }, borderColor: Colors.white, - hintText: TranslationBase.of(context) - .searchMedicineNameHere, + hintText: TranslationBase.of(context).searchMedicineNameHere, controller: myController, onSaved: (value) {}, onFieldSubmitted: (value) { @@ -403,12 +334,9 @@ class _PrescriptionFormWidgetState extends State { children: [ // TODO change it secondary button and add loading AppButton( - title: TranslationBase.of( - context) - .search, + title: TranslationBase.of(context).search, onPressed: () async { - await searchMedicine( - context, model); + await searchMedicine(context, model); }, ), ], @@ -417,50 +345,25 @@ class _PrescriptionFormWidgetState extends State { ), if (myController.text != '') Container( - height: MediaQuery.of(context) - .size - .height * - 0.5, + height: MediaQuery.of(context).size.height * 0.5, child: ListView.builder( - padding: const EdgeInsets.only( - top: 20), + padding: const EdgeInsets.only(top: 20), scrollDirection: Axis.vertical, // shrinkWrap: true, - itemCount: - model.allMedicationList == - null - ? 0 - : model - .allMedicationList - .length, - itemBuilder: - (BuildContext context, - int index) { + itemCount: model.allMedicationList == null + ? 0 + : model.allMedicationList.length, + itemBuilder: (BuildContext context, int index) { return InkWell( child: MedicineItemWidget( - label: model - .allMedicationList[ - index] - .description - // url: model - // .pharmacyItemsList[ - // index]["ImageSRCUrl"], - ), + label: model.allMedicationList[index].description), onTap: () { - model.getItem( - itemID: model - .allMedicationList[ - index] - .itemId); - visbiltyPrescriptionForm = - true; + model.getItem(itemID: model.allMedicationList[index].itemId); + visbiltyPrescriptionForm = true; visbiltySearch = false; - _selectedMedication = - model.allMedicationList[ - index]; - uom = _selectedMedication - .uom; + _selectedMedication = model.allMedicationList[index]; + uom = _selectedMedication.uom; }, ); }, @@ -479,409 +382,134 @@ class _PrescriptionFormWidgetState extends State { child: Column( children: [ AppText( - _selectedMedication?.description ?? - "", + _selectedMedication?.description ?? "", bold: true, ), Container( child: Row( children: [ AppText( - TranslationBase.of(context) - .orderType, + TranslationBase.of(context).orderType, fontWeight: FontWeight.w600, ), Radio( - activeColor: - Color(0xFFB9382C), + activeColor: Color(0xFFB9382C), value: 1, groupValue: selectedType, onChanged: (value) { setSelectedType(value); }, ), - Text('Regular'), + Text(TranslationBase.of(context).regular), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( width: double.infinity, child: Row( children: [ Container( - color: Colors.white, - width: MediaQuery.of(context) - .size - .width * - 0.35, + width: MediaQuery.of(context).size.width * 0.35, child: AppTextFieldCustom( height: 40, - validationError: - strengthError, + validationError: strengthError, hintText: 'Strength', isTextFieldHasSuffix: false, enabled: true, - controller: - strengthController, + controller: strengthController, onChanged: (String value) { setState(() { - strengthChar = - value.length; + strengthChar = value.length; }); if (strengthChar >= 5) { - DrAppToastMsg - .showErrorToast( - TranslationBase.of( - context) - .only5DigitsAllowedForStrength, + DrAppToastMsg.showErrorToast( + TranslationBase.of(context).only5DigitsAllowedForStrength, ); } }, - inputType: TextInputType - .numberWithOptions( + inputType: TextInputType.numberWithOptions( decimal: true, ), - // keyboardType: TextInputType - // .numberWithOptions( - // decimal: true, - // ), ), ), SizedBox( width: 5.0, ), - Container( - color: Colors.white, - width: MediaQuery.of(context) - .size - .width * - 0.560, - child: InkWell( - onTap: - model.itemMedicineListUnit != - null - ? () { - Helpers - .hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineListUnit, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState( - () { - units = - selectedValue; - units['isDefault'] = - true; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: - context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: AppTextFieldCustom( - hintText: 'Select', - isTextFieldHasSuffix: - true, - dropDownText: model - .itemMedicineListUnit - .length == - 1 - ? units = model - .itemMedicineListUnit[0] - ['description'] - : units != null - ? units['description'] - .toString() - : null, - validationError: - model.itemMedicineListUnit - .length != - 1 - ? unitError - : null, - enabled: false), - ), + PrescriptionTextFiled( + width: MediaQuery.of(context).size.width * 0.560, + element: units, + elementError: unitError, + keyName: 'description', + keyId: 'parameterCode', + hintText: 'Select', + elementList: model.itemMedicineListUnit, + okFunction: (selectedValue) { + setState(() { + units = selectedValue; + units['isDefault'] = true; + }); + }, ), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), - Container( - //height: screenSize.height * 0.070, - color: Colors.white, - child: InkWell( - onTap: - model.itemMedicineListRoute != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineListRoute, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - route = - selectedValue; - route['isDefault'] = - true; - }); - if (route == - null) { - Helpers.showErrorToast( - 'plase fill'); - } - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: AppTextFieldCustom( - // decoration: - // textFieldSelectorDecoration( - // TranslationBase.of( - // context) - // .route, - // model.itemMedicineListRoute - // .length == - // 1 - // ? model.itemMedicineListRoute[ - // 0] - // ['description'] - // : route != null - // ? route[ - // 'description'] - // : null, - // true), - hintText: - TranslationBase.of(context) - .route, - dropDownText: model - .itemMedicineListRoute - .length == - 1 - ? model.itemMedicineListRoute[ - 0]['description'] - : route != null - ? route['description'] - : null, - isTextFieldHasSuffix: true, - //height: 45, - validationError: - model.itemMedicineListRoute - .length != - 1 - ? routeError - : null, - - enabled: false, - ), - ), - ), - SizedBox( - height: spaceBetweenTextFileds), - Container( - //height: screenSize.height * 0.070, - color: Colors.white, - child: InkWell( - onTap: - model.itemMedicineList != null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineList, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - frequency = - selectedValue; - frequency[ - 'isDefault'] = - true; - if (_selectedMedication != null && - duration != - null && - frequency != - null && - strengthController - .text != - null) { - model.getBoxQuantity( - freq: frequency[ - 'parameterCode'], - duration: - duration[ - 'id'], - itemCode: - _selectedMedication - .itemId, - strength: - double.parse( - strengthController.text)); - - return; - } - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: AppTextFieldCustom( - isTextFieldHasSuffix: true, - hintText: - TranslationBase.of(context) - .frequency, - dropDownText: model - .itemMedicineList - .length == - 1 - ? model.itemMedicineList[0] - ['description'] - : frequency != null - ? frequency[ - 'description'] - : null, - validationError: model - .itemMedicineList - .length != - 1 - ? frequencyError - : null, - enabled: false, - ), - ), - ), - SizedBox( - height: spaceBetweenTextFileds), - Container( - //height: screenSize.height * 0.070, - color: Colors.white, - child: InkWell( - onTap: - model.medicationDoseTimeList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .medicationDoseTimeList, - attributeName: - 'nameEn', - attributeValueId: - 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - doseTime = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: AppTextFieldCustom( - hintText: - TranslationBase.of(context) - .doseTime, - isTextFieldHasSuffix: true, - dropDownText: doseTime != null - ? doseTime['nameEn'] - : null, - //height: 45, - - enabled: false, - validationError: doseTimeError, - ), - ), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + elementList: model.itemMedicineListRoute, + element: route, + elementError: routeError, + keyId: 'parameterCode', + keyName: 'description', + okFunction: (selectedValue) { + setState(() { + route = selectedValue; + route['isDefault'] = true; + }); + }, + hintText: TranslationBase.of(context).route, ), - SizedBox( - height: spaceBetweenTextFileds), - if (model - .patientAssessmentList.isNotEmpty) + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + hintText: TranslationBase.of(context).frequency, + elementError: frequencyError, + element: frequencyError, + elementList: model.itemMedicineList, + keyId: 'parameterCode', + keyName: 'description', + okFunction: (selectedValue) { + setState(() { + frequency = selectedValue; + frequency['isDefault'] = true; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text)); + + return; + } + }); + }), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + hintText: TranslationBase.of(context).doseTime, + elementError: doseTimeError, + element: doseTime, + elementList: model.medicationDoseTimeList, + keyId: 'id', + keyName: 'nameEn', + okFunction: (selectedValue) { + setState(() { + doseTime = selectedValue; + }); + }), + SizedBox(height: spaceBetweenTextFileds), + if (model.patientAssessmentList.isNotEmpty) Container( height: screenSize.height * 0.070, width: double.infinity, @@ -889,326 +517,121 @@ class _PrescriptionFormWidgetState extends State { child: Row( children: [ Container( - width: - MediaQuery.of(context) - .size - .width * - 0.29, - child: InkWell( - onTap: - indicationList != null - ? () { - Helpers.hideKeyboard( - context); - } - : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - model - .patientAssessmentList[ - 0] - .icdCode10ID - .toString(), - indication != - null - ? indication[ - 'name'] - : null, - false), - enabled: true, - readOnly: true, - ), + width: MediaQuery.of(context).size.width * 0.29, + child: TextField( + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].icdCode10ID.toString(), + indication != null ? indication['name'] : null, + false), + enabled: true, + readOnly: true, ), ), Container( - width: - MediaQuery.of(context) - .size - .width * - 0.65, + width: MediaQuery.of(context).size.width * 0.65, color: Colors.white, - child: InkWell( - onTap: - indicationList != null - ? () { - Helpers.hideKeyboard( - context); - } - : null, - child: TextField( - maxLines: 5, - decoration: - textFieldSelectorDecoration( - model - .patientAssessmentList[ - 0] - .asciiDesc - .toString(), - indication != - null - ? indication[ - 'name'] - : null, - false), - enabled: true, - readOnly: true, - ), + child: TextField( + maxLines: 5, + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].asciiDesc.toString(), + indication != null ? indication['name'] : null, + false), + enabled: true, + readOnly: true, ), ), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: () => selectDate( - context, widget.model), + onTap: () => selectDate(context, widget.model), child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .date, - selectedDate != null - ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" - : null, - true, - suffixIcon: Icon( - Icons.calendar_today, - color: Colors.black, - )), + decoration: textFieldSelectorDecoration( + TranslationBase.of(context).date, + selectedDate != null + ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" + : null, + true, + suffixIcon: Icon( + Icons.calendar_today, + color: Colors.black, + )), enabled: false, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), - Container( - //height: screenSize.height * 0.070, - color: Colors.white, - child: InkWell( - onTap: - model.medicationDurationList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .medicationDurationList, - attributeName: - 'nameEn', - attributeValueId: - 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - duration = - selectedValue; - if (_selectedMedication != null && - duration != - null && - frequency != - null && - strengthController - .text != - null) { - model - .getBoxQuantity( - freq: frequency[ - 'parameterCode'], - duration: - duration[ - 'id'], - itemCode: - _selectedMedication - .itemId, - strength: double.parse( - strengthController - .text), - ); - box = model - .boxQuintity; + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + element: duration, + elementError: durationError, + hintText: TranslationBase.of(context).duration, + elementList: model.medicationDurationList, + keyName: 'nameEn', + keyId: 'id', + okFunction: (selectedValue) { + setState(() { + duration = selectedValue; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text), + ); + box = model.boxQuintity; - return; - } - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: AppTextFieldCustom( - validationError: durationError, - isTextFieldHasSuffix: true, - dropDownText: duration != null - ? duration['nameEn'] - : null, - hintText: - TranslationBase.of(context) - .duration, - enabled: false, - ), - ), + return; + } + }); + }, ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, color: Colors.white, - child: InkWell( - onTap: model.allMedicationList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog dialog = - ListSelectDialog( - list: model - .allMedicationList, - attributeName: 'nameEn', - attributeValueId: 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - duration = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: (BuildContext - context) { - return dialog; - }, - ); - } - : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - "UOM", - uom != null - ? uom - : null, - false), - //enabled: false, - readOnly: true, - ), + child: AppTextFieldCustom( + hintText: "UOM", + isTextFieldHasSuffix: false, + dropDownText: uom != null ? uom : null, + enabled: false, ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( - height: screenSize.height * 0.070, color: Colors.white, - child: InkWell( - onTap: model.allMedicationList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog dialog = - ListSelectDialog( - list: model - .allMedicationList, - attributeName: 'nameEn', - attributeValueId: 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - duration = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: (BuildContext - context) { - return dialog; - }, - ); - } + child: AppTextFieldCustom( + hintText: TranslationBase.of(context).boxQuantity, + isTextFieldHasSuffix: false, + dropDownText: box != null + ? TranslationBase.of(context).boxQuantity + + ": " + + model.boxQuintity.toString() : null, - child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .boxQuantity, - box != null - ? TranslationBase.of( - context) - .boxQuantity + - ": " + - model - .boxQuintity - .toString() - : null, - false), - //enabled: false, - readOnly: true, - ), + enabled: false, ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: - HexColor("#CCCCCC"))), + borderRadius: BorderRadius.all(Radius.circular(6.0)), + border: Border.all(width: 1.0, color: HexColor("#CCCCCC"))), child: Stack( children: [ TextFields( maxLines: 6, minLines: 4, - hintText: TranslationBase.of( - context) - .instruction, - controller: - instructionController, + hintText: TranslationBase.of(context).instruction, + controller: instructionController, //keyboardType: TextInputType.number, ), Positioned( - top: - 0, //MediaQuery.of(context).size.height * 0, + top: 0, right: 15, child: IconButton( icon: Icon( @@ -1217,28 +640,22 @@ class _PrescriptionFormWidgetState extends State { size: 35, ), onPressed: () { - initSpeechState().then( - (value) => - {onVoiceText()}); + initSpeechState().then((value) => {onVoiceText()}); }, ), ), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( - margin: EdgeInsets.all( - SizeConfig.widthMultiplier * 5), + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), child: Wrap( alignment: WrapAlignment.center, children: [ AppButton( color: Color(0xff359846), - title: TranslationBase.of( - context) - .addMedication, + title: TranslationBase.of(context).addMedication, fontWeight: FontWeight.w600, onPressed: () async { if (route != null && @@ -1247,41 +664,25 @@ class _PrescriptionFormWidgetState extends State { frequency != null && units != null && selectedDate != null && - strengthController - .text != - "") { - if (_selectedMedication - .isNarcotic == - true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of( - context) - .narcoticMedicineCanOnlyBePrescribedFromVida); + strengthController.text != "") { + if (_selectedMedication.isNarcotic == true) { + DrAppToastMsg.showErrorToast(TranslationBase.of(context) + .narcoticMedicineCanOnlyBePrescribedFromVida); Navigator.pop(context); return; } - if (double.parse( - strengthController - .text) > - 1000.0) { - DrAppToastMsg - .showErrorToast( - "1000 is the MAX for the strength"); + if (double.parse(strengthController.text) > 1000.0) { + DrAppToastMsg.showErrorToast( + "1000 is the MAX for the strength"); return; } - if (double.parse( - strengthController - .text) < - 0.0) { - DrAppToastMsg - .showErrorToast( - "strength can't be zero"); + if (double.parse(strengthController.text) < 0.0) { + DrAppToastMsg.showErrorToast("strength can't be zero"); return; } - if (formKey.currentState - .validate()) { + if (formKey.currentState.validate()) { Navigator.pop(context); openDrugToDrug(model); { @@ -1370,52 +771,32 @@ class _PrescriptionFormWidgetState extends State { } else { setState(() { if (duration == null) { - durationError = - TranslationBase.of( - context) - .fieldRequired; + durationError = TranslationBase.of(context).fieldRequired; } else { durationError = null; } if (doseTime == null) { - doseTimeError = - TranslationBase.of( - context) - .fieldRequired; + doseTimeError = TranslationBase.of(context).fieldRequired; } else { doseTimeError = null; } if (route == null) { - routeError = - TranslationBase.of( - context) - .fieldRequired; + routeError = TranslationBase.of(context).fieldRequired; } else { routeError = null; } if (frequency == null) { - frequencyError = - TranslationBase.of( - context) - .fieldRequired; + frequencyError = TranslationBase.of(context).fieldRequired; } else { frequencyError = null; } if (units == null) { - unitError = - TranslationBase.of( - context) - .fieldRequired; + unitError = TranslationBase.of(context).fieldRequired; } else { unitError = null; } - if (strengthController - .text == - "") { - strengthError = - TranslationBase.of( - context) - .fieldRequired; + if (strengthController.text == "") { + strengthError = TranslationBase.of(context).fieldRequired; } else { strengthError = null; } @@ -1423,30 +804,6 @@ class _PrescriptionFormWidgetState extends State { } formKey.currentState.save(); - // Navigator.pop(context); - // openDrugToDrug(); - // if (frequency == null || - // strengthController - // .text == - // "" || - // doseTime == null || - // duration == null || - // selectedDate == null) { - // DrAppToastMsg.showErrorToast( - // TranslationBase.of( - // context) - // .pleaseFillAllFields); - // return; - // } - - { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => - // NewPrescriptionScreen()), - // ); - } }, ), ], @@ -1489,8 +846,7 @@ class _PrescriptionFormWidgetState extends State { } } - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, + InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, {Icon suffixIcon}) { return InputDecoration( focusedBorder: OutlineInputBorder( @@ -1530,48 +886,6 @@ class _PrescriptionFormWidgetState extends State { ); } - InputDecoration textFieldSelectorDecorationStreangrh( - String hintText, String selectedText, bool isDropDown, - {Icon suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.keyboard_arrow_down_sharp, - color: Color(0xff2E303A), - ) - : null, - hintStyle: TextStyle( - fontSize: 13, - color: Color(0xff2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ), - hintText: selectedText == null || selectedText == "" ? hintText : null, - labelText: - selectedText != null && selectedText != "" ? '\n$selectedText' : null, - labelStyle: TextStyle( - fontSize: 15, - color: Color(0xff2E303A), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ), - ); - } - openDrugToDrug(model) { showModalBottomSheet( context: context, @@ -1583,9 +897,7 @@ class _PrescriptionFormWidgetState extends State { child: Column( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - DrugToDrug( - widget.patient, - getPriscriptionforDrug(widget.prescriptionList, model), + DrugToDrug(widget.patient, getPriscriptionforDrug(widget.prescriptionList, model), model.patientAssessmentList), Container( margin: EdgeInsets.all(SizeConfig.widthMultiplier * 3), @@ -1594,37 +906,25 @@ class _PrescriptionFormWidgetState extends State { onPressed: () { Navigator.pop(context); - postProcedure( + postPrescription( icdCode: model.patientAssessmentList.isNotEmpty - ? model.patientAssessmentList[0].icdCode10ID - .isEmpty + ? model.patientAssessmentList[0].icdCode10ID.isEmpty ? "test" - : model.patientAssessmentList[0].icdCode10ID - .toString() + : model.patientAssessmentList[0].icdCode10ID.toString() : "test", - // icdCode: model - // .patientAssessmentList - // .map((value) => value - // .icdCode10ID - // .trim()) - // .toList() - // .join(' '), dose: strengthController.text, doseUnit: model.itemMedicineListUnit.length == 1 - ? model.itemMedicineListUnit[0]['parameterCode'] - .toString() + ? model.itemMedicineListUnit[0]['parameterCode'].toString() : units['parameterCode'].toString(), patient: widget.patient, doseTimeIn: doseTime['id'].toString(), model: widget.model, duration: duration['id'].toString(), frequency: model.itemMedicineList.length == 1 - ? model.itemMedicineList[0]['parameterCode'] - .toString() + ? model.itemMedicineList[0]['parameterCode'].toString() : frequency['parameterCode'].toString(), route: model.itemMedicineListRoute.length == 1 - ? model.itemMedicineListRoute[0]['parameterCode'] - .toString() + ? model.itemMedicineListRoute[0]['parameterCode'].toString() : route['parameterCode'].toString(), drugId: _selectedMedication.itemId.toString(), strength: strengthController.text, @@ -1632,36 +932,6 @@ class _PrescriptionFormWidgetState extends State { instruction: instructionController.text, doseTime: selectedDate, ); - - // postProcedure( - // icdCode: model.patientAssessmentList.isNotEmpty - // ? model.patientAssessmentList[0].icdCode10ID - // .isEmpty - // ? "test" - // : model.patientAssessmentList[0].icdCode10ID - // .toString() - // : "test", - // // icdCode: model - // // .patientAssessmentList - // // .map((value) => value - // // .icdCode10ID - // // .trim()) - // // .toList() - // // .join(' '), - // dose: strengthController.text, - // doseUnit: units['parameterCode'].toString(), - // patient: widget.patient, - // doseTimeIn: doseTime['id'].toString(), - // model: widget.model, - // duration: duration['id'].toString(), - // frequency: frequency['parameterCode'].toString(), - // route: route['parameterCode'].toString(), - // drugId: _selectedMedication.itemId.toString(), - // strength: strengthController.text, - // indication: indicationController.text, - // instruction: instructionController.text, - // doseTime: selectedDate, - // ); }, )) ], @@ -1673,17 +943,7 @@ class _PrescriptionFormWidgetState extends State { }); } - // selectedValue(itemMdeicationList,key){ - // // String selected = ""; - // // units[key]=itemMdeicationList.length==1? itemMdeicationList[0][key]:units[key].toString(); - // // - // // selected = units[key]; - // // - // // return selected; - // // } - - getPriscriptionforDrug( - List prescriptionList, MedicineViewModel model) { + getPriscriptionforDrug(List prescriptionList, MedicineViewModel model) { var prescriptionDetails = []; if (prescriptionList.length > 0) { prescriptionList[0].entityList.forEach((element) { @@ -1728,19 +988,10 @@ class _PrescriptionFormWidgetState extends State { searchMedicine(context, MedicineViewModel model) async { FocusScope.of(context).unfocus(); - // if (myController.text.isEmpty()) { - // Helpers.showErrorToast(TranslationBase.of(context).typeMedicineName); - // //"Type Medicine Name") - // return; - // } if (myController.text.length < 3) { Helpers.showErrorToast(TranslationBase.of(context).moreThan3Letter); return; } - - //GifLoaderDialogUtils.showMyDialog(context); - await model.getMedicationList(drug: myController.text); - //GifLoaderDialogUtils.hideDialog(context); } } diff --git a/lib/screens/prescription/prescription_text_filed.dart b/lib/screens/prescription/prescription_text_filed.dart new file mode 100644 index 00000000..56020ca3 --- /dev/null +++ b/lib/screens/prescription/prescription_text_filed.dart @@ -0,0 +1,76 @@ +import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionTextFiled extends StatefulWidget { + dynamic element; + final String elementError; + final List elementList; + final String keyName; + final String keyId; + final String hintText; + final double width; + final Function(dynamic) okFunction; + + PrescriptionTextFiled( + {Key key, + @required this.element, + @required this.elementError, + this.width, + this.elementList, + this.keyName, + this.keyId, + this.hintText, + this.okFunction}) + : super(key: key); + + @override + _PrescriptionTextFiledState createState() => _PrescriptionTextFiledState(); +} + +class _PrescriptionTextFiledState extends State { + @override + Widget build(BuildContext context) { + return Container( + width: widget.width ?? null, + child: InkWell( + onTap: widget.elementList != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: widget.elementList, + attributeName: '${widget.keyName}', + attributeValueId: '${widget.keyId}', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) => + widget.okFunction(selectedValue), + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + child: AppTextFieldCustom( + hintText: widget.hintText, + dropDownText: widget.elementList.length == 1 + ? widget.elementList[0]['${widget.keyName}'] + : widget.element != null + ? widget.element['${widget.keyName}'] + : null, + isTextFieldHasSuffix: true, + validationError: + widget.elementList.length != 1 ? widget.elementError : null, + enabled: false, + ), + ), + ); + } +} diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 9bfd9b49..81c8760f 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -1,5 +1,4 @@ import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/screens/prescription/add_prescription_form.dart'; @@ -16,7 +15,6 @@ import 'package:doctor_app_flutter/widgets/shared/user-guid/in_patient_doctor_ca import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class PrescriptionsPage extends StatelessWidget { @override @@ -86,9 +84,7 @@ class PrescriptionsPage extends StatelessWidget { fontSize: 13, ), AppText( - TranslationBase - .of(context) - .prescriptions, + TranslationBase.of(context).prescriptions, bold: true, fontSize: 22, ), @@ -96,15 +92,14 @@ class PrescriptionsPage extends StatelessWidget { ), ), if ((patient.patientStatusType != null && - patient.patientStatusType == 43) || + patient.patientStatusType == 43) || (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { addPrescriptionForm(context, model, patient, model.prescriptionList); }, - label: TranslationBase - .of(context) + label: TranslationBase.of(context) .applyForNewPrescriptionsOrder, ), ...List.generate( @@ -132,7 +127,7 @@ class PrescriptionsPage extends StatelessWidget { .clinicDescription, isPrescriptions: true, appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( + AppDateUtils.getDateTimeFromServerFormat( model.prescriptionsList[index] .appointmentDate, ), @@ -201,7 +196,7 @@ class PrescriptionsPage extends StatelessWidget { clinic: 'basheer', isPrescriptions: true, appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( + AppDateUtils.getDateTimeFromServerFormat( model.inPatientPrescription[index] .prescriptionDatetime, ), diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index fb68ab4e..9ce078ed 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -7,7 +7,7 @@ class AppDateUtils { return DateFormat(dateFormat).format(dateTime); } - static DateTime convertISOStringToDateTime(String date){ + static DateTime convertISOStringToDateTime(String date) { DateTime newDate; newDate = DateTime.parse(date); @@ -27,22 +27,20 @@ class AppDateUtils { } static DateTime getDateTimeFromServerFormat(String str) { - DateTime date= DateTime.now(); - if (str!=null) { + DateTime date = DateTime.now(); + if (str != null) { const start = "/Date("; const end = "+0300)"; - if(str.contains("/Date")){ - final startIndex = str.indexOf(start); + if (str.contains("/Date")) { + final startIndex = str.indexOf(start); - final endIndex = str.indexOf(end, startIndex + start.length); - - date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(str.substring(startIndex + start.length, endIndex))); - } else { - date = DateTime.now(); - } + final endIndex = str.indexOf(end, startIndex + start.length); + date = new DateTime.fromMillisecondsSinceEpoch(int.parse(str.substring(startIndex + start.length, endIndex))); + } else { + date = DateTime.now(); + } } else { date = DateTime.parse(str); } @@ -50,8 +48,7 @@ class AppDateUtils { return date; } - static String differenceBetweenDateAndCurrentInYearMonthDay( - DateTime firstDate, BuildContext context) { + static String differenceBetweenDateAndCurrentInYearMonthDay(DateTime firstDate, BuildContext context) { DateTime now = DateTime.now(); // now = now.add(Duration(days: 400, minutes: 0)); var difference = firstDate.difference(now); @@ -71,15 +68,13 @@ class AppDateUtils { return "$days ${TranslationBase.of(context).days}, $months ${TranslationBase.of(context).months}, $years ${TranslationBase.of(context).years}"; } - static String differenceBetweenDateAndCurrent( - DateTime firstDate, BuildContext context) { + static String differenceBetweenDateAndCurrent(DateTime firstDate, BuildContext context) { DateTime now = DateTime.now(); // DateTime now = nows.add(Duration(days: 400, minutes: 25, hours: 0)); var difference = now.difference(firstDate); int minutesInDays = difference.inMinutes; - int hoursInDays = - minutesInDays ~/ 60; // ~/ : truncating division to make the result int + int hoursInDays = minutesInDays ~/ 60; // ~/ : truncating division to make the result int int minutes = minutesInDays % 60; int days = hoursInDays ~/ 24; int hours = hoursInDays % 24; @@ -89,8 +84,7 @@ class AppDateUtils { return "$days ${TranslationBase.of(context).days}, $hours ${TranslationBase.of(context).hr}, $minutes ${TranslationBase.of(context).min}"; } - static String differenceBetweenServerDateAndCurrent( - String str, BuildContext context) { + static String differenceBetweenServerDateAndCurrent(String str, BuildContext context) { const start = "/Date("; const end = "+0300)"; @@ -99,8 +93,7 @@ class AppDateUtils { final endIndex = str.indexOf(end, startIndex + start.length); - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(str.substring(startIndex + start.length, endIndex))); + var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(str.substring(startIndex + start.length, endIndex))); return differenceBetweenDateAndCurrent(date, context); } @@ -246,7 +239,10 @@ class AppDateUtils { final startIndex = date.indexOf(start); final endIndex = date.indexOf(end, startIndex + start.length); DateTime newDate = DateTime.fromMillisecondsSinceEpoch( - int.parse(date.substring(startIndex + start.length, endIndex),),); + int.parse( + date.substring(startIndex + start.length, endIndex), + ), + ); return newDate; } else return DateTime.now(); @@ -256,35 +252,30 @@ class AppDateUtils { /// [dateTime] convert DateTime to data formatted Arabic static String getMonthDayYearDateFormattedAr(DateTime dateTime) { if (dateTime != null) - return getMonthArabic(dateTime.month) + - " " + - dateTime.day.toString() + - ", " + - dateTime.year.toString(); + return getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); else return ""; } /// get data formatted like Apr 26,2020 /// [dateTime] convert DateTime to data formatted - static String getMonthDayYearDateFormatted(DateTime dateTime,{bool isArabic = false}) { + static String getMonthDayYearDateFormatted(DateTime dateTime, {bool isArabic = false}) { if (dateTime != null) - return isArabic? getMonthArabic(dateTime.month): getMonth(dateTime.month) + - " " + - dateTime.day.toString() + - ", " + - dateTime.year.toString(); + return isArabic + ? getMonthArabic(dateTime.month) + : getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString(); else return ""; } /// get data formatted like 26 Apr 2020 /// [dateTime] convert DateTime to data formatted - static String getDayMonthYearDateFormatted(DateTime dateTime,{bool isArabic = false}) { + static String getDayMonthYearDateFormatted(DateTime dateTime, {bool isArabic = false}) { if (dateTime != null) - return dateTime.day.toString()+" "+ "${isArabic? getMonthArabic(dateTime.month): getMonth(dateTime.month) }"+ + return dateTime.day.toString() + + " " + + "${isArabic ? getMonthArabic(dateTime.month) : getMonth(dateTime.month)}" + " " + - dateTime.year.toString(); else return ""; @@ -292,9 +283,9 @@ class AppDateUtils { /// get data formatted like 26/4/2020 /// [dateTime] convert DateTime to data formatted - static String getDayMonthYearDate(DateTime dateTime,{bool isArabic = false}) { + static String getDayMonthYearDate(DateTime dateTime, {bool isArabic = false}) { if (dateTime != null) - return dateTime.day.toString()+"/"+ "${dateTime.month}"+ "/" + dateTime.year.toString(); + return dateTime.day.toString() + "/" + "${dateTime.month}" + "/" + dateTime.year.toString(); else return ""; } @@ -302,15 +293,15 @@ class AppDateUtils { /// get data formatted like 10:45 PM /// [dateTime] convert DateTime to data formatted static String getHour(DateTime dateTime) { - return DateFormat('hh:mm a').format(dateTime); + return DateFormat('hh:mm a').format(dateTime); } - static String getAgeByBirthday(String birthOfDate, BuildContext context, { bool isServerFormat = true}) { + static String getAgeByBirthday(String birthOfDate, BuildContext context, {bool isServerFormat = true}) { // https://leechy.dev/calculate-dates-diff-in-dart DateTime birthDate; - if(birthOfDate.contains("/Date")) { + if (birthOfDate.contains("/Date")) { birthDate = AppDateUtils.getDateTimeFromServerFormat(birthOfDate); - }else{ + } else { birthDate = DateTime.parse(birthOfDate); } final now = DateTime.now(); @@ -328,24 +319,18 @@ class AppDateUtils { return "$years ${TranslationBase.of(context).years} $months ${TranslationBase.of(context).months} $days ${TranslationBase.of(context).days}"; } - static bool isToday(DateTime dateTime){ - + static bool isToday(DateTime dateTime) { DateTime todayDate = DateTime.now().toUtc(); - if(dateTime.day == todayDate.day && dateTime.month == todayDate.month && dateTime.year == todayDate.year) { + if (dateTime.day == todayDate.day && dateTime.month == todayDate.month && dateTime.year == todayDate.year) { return true; } return false; - } static String getDate(DateTime dateTime) { print(dateTime); if (dateTime != null) - return getMonth(dateTime.month) + - " " + - dateTime.day.toString() + - "," + - dateTime.year.toString(); + return getMonth(dateTime.month) + " " + dateTime.day.toString() + "," + dateTime.year.toString(); else return ""; } @@ -353,28 +338,23 @@ class AppDateUtils { static String getDateFormatted(DateTime dateTime) { print(dateTime); if (dateTime != null) - return dateTime.day.toString() + - "/" + - dateTime.month.toString() + - "/" + - dateTime.year.toString(); + return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString(); else return ""; } - static String getTimeHHMMA(DateTime dateTime){ + static String getTimeHHMMA(DateTime dateTime) { return DateFormat('hh:mm a').format(dateTime); } - static String getTimeHHMMA2 (DateTime dateTime){ + static String getTimeHHMMA2(DateTime dateTime) { return DateFormat('hh:mm').format(dateTime); } - static String getStartTime(String dateTime){ - String time=dateTime; + static String getStartTime(String dateTime) { + String time = dateTime; - if(dateTime.length>7) - time = dateTime.substring(0,5); + if (dateTime.length > 7) time = dateTime.substring(0, 5); return time; } diff --git a/lib/widgets/shared/text_fields/app-textfield-custom.dart b/lib/widgets/shared/text_fields/app-textfield-custom.dart index 7e13f411..fc7df189 100644 --- a/lib/widgets/shared/text_fields/app-textfield-custom.dart +++ b/lib/widgets/shared/text_fields/app-textfield-custom.dart @@ -105,37 +105,36 @@ class _AppTextFieldCustomState extends State { ? widget.height - 22 : null, child: TextField( - textAlign: projectViewModel.isArabic - ? TextAlign.right - : TextAlign.left, - decoration: TextFieldsUtils - .textFieldSelectorDecoration( - widget.hintText, null, true), - style: TextStyle( - fontSize: SizeConfig.textMultiplier * 1.7, - fontFamily: 'Poppins', - color: Color(0xFF575757), - ), - controller: widget.controller, - keyboardType: widget.inputType ?? - (widget.maxLines == 1 - ? TextInputType.text - : TextInputType.multiline), - enabled: widget.enabled, - minLines: widget.minLines, - maxLines: widget.maxLines, - inputFormatters: - widget.inputFormatters != null - ? widget.inputFormatters - : [], - onChanged: (value) { - setState(() {}); - if (widget.onChanged != null) { - widget.onChanged(value); - } - }, - obscureText: widget.isSecure - ), + textAlign: projectViewModel.isArabic + ? TextAlign.right + : TextAlign.left, + decoration: TextFieldsUtils + .textFieldSelectorDecoration( + widget.hintText, null, true), + style: TextStyle( + fontSize: SizeConfig.textMultiplier * 1.7, + fontFamily: 'Poppins', + color: Color(0xFF575757), + ), + controller: widget.controller, + keyboardType: widget.inputType ?? + (widget.maxLines == 1 + ? TextInputType.text + : TextInputType.multiline), + enabled: widget.enabled, + minLines: widget.minLines, + maxLines: widget.maxLines, + inputFormatters: + widget.inputFormatters != null + ? widget.inputFormatters + : [], + onChanged: (value) { + setState(() {}); + if (widget.onChanged != null) { + widget.onChanged(value); + } + }, + obscureText: widget.isSecure), ) : AppText( widget.dropDownText, diff --git a/lib/widgets/shared/text_fields/text_field_error.dart b/lib/widgets/shared/text_fields/text_field_error.dart index ee22a6a4..9c781db0 100644 --- a/lib/widgets/shared/text_fields/text_field_error.dart +++ b/lib/widgets/shared/text_fields/text_field_error.dart @@ -7,12 +7,11 @@ import '../app_texts_widget.dart'; class TextFieldsError extends StatelessWidget { const TextFieldsError({ Key key, - @required this.error, + @required this.error, }) : super(key: key); final String error; - @override Widget build(BuildContext context) { return Container( @@ -27,12 +26,14 @@ class TextFieldsError extends StatelessWidget { SizedBox( width: 12, ), - AppText( - error, - fontFamily: 'Poppins', - fontSize: SizeConfig.textMultiplier * 1.7, - color: Colors.red.shade700, - fontWeight: FontWeight.w700, + Expanded( + child: AppText( + error, + fontFamily: 'Poppins', + fontSize: SizeConfig.textMultiplier * 1.7, + color: Colors.red.shade700, + fontWeight: FontWeight.w700, + ), ), ], ), From e068009527534c702e6483feec1e15ad5f01cfcd Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 24 May 2021 17:36:33 +0300 Subject: [PATCH 094/241] prescription form --- lib/config/config.dart | 285 ++---- .../prescription/add_prescription_form.dart | 961 ++++++------------ pubspec.lock | 2 +- 3 files changed, 406 insertions(+), 842 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 86c42f8d..36f4f88d 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,304 +5,215 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +//const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; -const PATIENT_PROGRESS_NOTE_URL = - "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; -const PATIENT_INSURANCE_APPROVALS_URL = - "Services/DoctorApplication.svc/REST/GetApprovalStatusForInpatient"; -const PATIENT_ORDERS_URL = - "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; -const PATIENT_REFER_TO_DOCTOR_URL = - "Services/DoctorApplication.svc/REST/ReferToDoctor"; -const PATIENT_GET_DOCTOR_BY_CLINIC_URL = - "Services/DoctorApplication.svc/REST/GetDoctorsByClinicID"; - -const PATIENT_GET_DOCTOR_BY_CLINIC_Hospital = - "Services/Doctors.svc/REST/SearchDoctorsByTime"; - -const GET_CLINICS_FOR_DOCTOR = - 'Services/DoctorApplication.svc/REST/GetClinicsForDoctor'; -const PATIENT_GET_LIST_REFERAL_URL = - "Services/Lists.svc/REST/GetList_STPReferralFrequency"; -const PATIENT_GET_CLINIC_BY_PROJECT_URL = - "Services/DoctorApplication.svc/REST/GetClinicsByProjectID"; +const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; +const PATIENT_INSURANCE_APPROVALS_URL = "Services/DoctorApplication.svc/REST/GetApprovalStatusForInpatient"; +const PATIENT_ORDERS_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; +const PATIENT_REFER_TO_DOCTOR_URL = "Services/DoctorApplication.svc/REST/ReferToDoctor"; +const PATIENT_GET_DOCTOR_BY_CLINIC_URL = "Services/DoctorApplication.svc/REST/GetDoctorsByClinicID"; + +const PATIENT_GET_DOCTOR_BY_CLINIC_Hospital = "Services/Doctors.svc/REST/SearchDoctorsByTime"; + +const GET_CLINICS_FOR_DOCTOR = 'Services/DoctorApplication.svc/REST/GetClinicsForDoctor'; +const PATIENT_GET_LIST_REFERAL_URL = "Services/Lists.svc/REST/GetList_STPReferralFrequency"; +const PATIENT_GET_CLINIC_BY_PROJECT_URL = "Services/DoctorApplication.svc/REST/GetClinicsByProjectID"; const PROJECT_GET_INFO = "Services/DoctorApplication.svc/REST/GetProjectInfo"; const GET_CLINICS = "Services/DoctorApplication.svc/REST/GetClinics"; -const GET_REFERRAL_FACILITIES = - 'Services/DoctorApplication.svc/REST/GetReferralFacilities'; +const GET_REFERRAL_FACILITIES = 'Services/DoctorApplication.svc/REST/GetReferralFacilities'; const GET_PROJECTS = 'Services/DoctorApplication.svc/REST/GetProjectInfo'; -const GET_PATIENT_VITAL_SIGN = - 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; -const GET_PATIENT_VITAL_SIGN_DATA = - 'Services/DoctorApplication.svc/REST/GetVitalSigns'; -const GET_PATIENT_LAB_OREDERS = - 'Services/DoctorApplication.svc/REST/GetPatientLabOreders'; +const GET_PATIENT_VITAL_SIGN = 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; +const GET_PATIENT_VITAL_SIGN_DATA = 'Services/DoctorApplication.svc/REST/GetVitalSigns'; +const GET_PATIENT_LAB_OREDERS = 'Services/DoctorApplication.svc/REST/GetPatientLabOreders'; const GET_PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; const GET_RADIOLOGY = 'Services/DoctorApplication.svc/REST/GetPatientRadResult'; -const GET_LIVECARE_PENDINGLIST = - 'Services/DoctorApplication.svc/REST/GetPendingPatientER'; +const GET_LIVECARE_PENDINGLIST = 'Services/DoctorApplication.svc/REST/GetPendingPatientER'; const START_LIVE_CARE_CALL = 'LiveCareApi/DoctorApp/CallPatient'; const LIVE_CARE_STATISTICS_FOR_CERTAIN_DOCTOR_URL = "Lists.svc/REST/DashBoard_GetLiveCareDoctorsStatsticsForCertainDoctor"; -const GET_PRESCRIPTION_REPORT = - 'Services/Patients.svc/REST/GetPrescriptionReport'; +const GET_PRESCRIPTION_REPORT = 'Services/Patients.svc/REST/GetPrescriptionReport'; -const GT_MY_PATIENT_QUESTION = - 'Services/DoctorApplication.svc/REST/GtMyPatientsQuestions'; +const GT_MY_PATIENT_QUESTION = 'Services/DoctorApplication.svc/REST/GtMyPatientsQuestions'; -const PRM_SEARCH_PATIENT = - 'Services/Patients.svc/REST/GetPatientInformation_PRM'; +const PRM_SEARCH_PATIENT = 'Services/Patients.svc/REST/GetPatientInformation_PRM'; const GET_PATIENT = 'Services/DoctorApplication.svc/REST/'; -const GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT = - 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; +const GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT = 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; -const GET_MY_REFERRAL_PATIENT = - 'Services/DoctorApplication.svc/REST/GtMyReferralPatient'; +const GET_MY_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferralPatient'; const REFER_TO_DOCTOR = 'Services/DoctorApplication.svc/REST/ReferToDoctor'; -const ADD_REFERRED_DOCTOR_REMARKS = - 'Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks'; +const ADD_REFERRED_DOCTOR_REMARKS = 'Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks'; -const GET_MY_REFERRED_PATIENT = - 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; +const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; -const GET_PENDING_REFERRAL_PATIENT = - 'Services/DoctorApplication.svc/REST/PendingReferrals'; +const GET_PENDING_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/PendingReferrals'; -const CREATE_REFERRAL_PATIENT = - 'Services/DoctorApplication.svc/REST/CreateReferral'; +const CREATE_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/CreateReferral'; -const RESPONSE_PENDING_REFERRAL_PATIENT = - 'Services/DoctorApplication.svc/REST/RespondReferral'; +const RESPONSE_PENDING_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/RespondReferral'; const GET_PATIENT_REFERRAL = 'Services/DoctorApplication.svc/REST/GetRefferal'; const POST_UCAF = 'Services/DoctorApplication.svc/REST/PostUCAF'; -const GET_DOCTOR_WORKING_HOURS_TABLE = - 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable'; +const GET_DOCTOR_WORKING_HOURS_TABLE = 'Services/Doctors.svc/REST/GetDoctorWorkingHoursTable'; -const GET_PATIENT_LAB_RESULTS = - 'Services/DoctorApplication.svc/REST/GetPatientLabResults'; +const GET_PATIENT_LAB_RESULTS = 'Services/DoctorApplication.svc/REST/GetPatientLabResults'; const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New'; -const INSERT_DEVICE_IMEI = - 'Services/DoctorApplication.svc/REST/DoctorApp_InsertOrUpdateDeviceDetails'; +const INSERT_DEVICE_IMEI = 'Services/DoctorApplication.svc/REST/DoctorApp_InsertOrUpdateDeviceDetails'; // 'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI'; // const SELECT_DEVICE_IMEI = // 'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI'; -const SELECT_DEVICE_IMEI = - 'Services/DoctorApplication.svc/REST/DoctorApp_GetDeviceDetailsByIMEI'; +const SELECT_DEVICE_IMEI = 'Services/DoctorApplication.svc/REST/DoctorApp_GetDeviceDetailsByIMEI'; const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE = 'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType'; -const SEND_ACTIVATION_CODE_FOR_DOCTOR_APP = - 'Services/DoctorApplication.svc/REST/SendActivationCodeForDoctorApp'; +const SEND_ACTIVATION_CODE_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/REST/SendActivationCodeForDoctorApp'; -const SEND_ACTIVATION_CODE_FOR_VERIFICATION_SCREEN = - 'Services/DoctorApplication.svc/REST/SendVerificationCode'; -const MEMBER_CHECK_ACTIVATION_CODE_NEW = - 'Services/Sentry.svc/REST/MemberCheckActivationCode_New'; +const SEND_ACTIVATION_CODE_FOR_VERIFICATION_SCREEN = 'Services/DoctorApplication.svc/REST/SendVerificationCode'; +const MEMBER_CHECK_ACTIVATION_CODE_NEW = 'Services/Sentry.svc/REST/MemberCheckActivationCode_New'; -const CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP = - 'Services/DoctorApplication.svc/REST/CheckActivationCodeForDoctorApp'; +const CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/REST/CheckActivationCodeForDoctorApp'; const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; const TRANSFERT_TO_ADMIN = 'LiveCareApi/DoctorApp/TransferToAdmin'; const END_CALL = 'LiveCareApi/DoctorApp/EndCall'; const END_CALL_WITH_CHARGE = 'LiveCareApi/DoctorApp/CompleteCallWithCharge'; -const GET_DASHBOARD = - 'Services/DoctorApplication.svc/REST/GetDoctorDashboardKPI'; -const GET_SICKLEAVE_STATISTIC = - 'Services/DoctorApplication.svc/REST/PreSickLeaveStatistics'; -const ARRIVED_PATIENT_URL = - 'Services/DoctorApplication.svc/REST/PatientArrivalList'; +const GET_DASHBOARD = 'Services/DoctorApplication.svc/REST/GetDoctorDashboardKPI'; +const GET_SICKLEAVE_STATISTIC = 'Services/DoctorApplication.svc/REST/PreSickLeaveStatistics'; +const ARRIVED_PATIENT_URL = 'Services/DoctorApplication.svc/REST/PatientArrivalList'; const ADD_SICK_LEAVE = 'Services/DoctorApplication.svc/REST/PostSickLeave'; const GET_SICK_LEAVE = 'Services/Patients.svc/REST/GetPatientSickLeave'; const EXTEND_SICK_LEAVE = 'Services/DoctorApplication.svc/REST/ExtendSickLeave'; const GET_OFFTIME = 'Services/DoctorApplication.svc/REST/GetMasterLookUpList'; -const GET_COVERING_DOCTORS = - 'Services/DoctorApplication.svc/REST/GetCoveringDoctor'; +const GET_COVERING_DOCTORS = 'Services/DoctorApplication.svc/REST/GetCoveringDoctor'; const ADD_RESCHDEULE = 'Services/DoctorApplication.svc/REST/PostRequisition'; -const UPDATE_RESCHDEULE = - 'Services/DoctorApplication.svc/REST/PatchRequisition'; -const GET_RESCHEDULE_LEAVE = - 'Services/DoctorApplication.svc/REST/GetRequisition'; -const GET_PRESCRIPTION_LIST = - 'Services/DoctorApplication.svc/REST/GetPrescription'; - -const POST_PRESCRIPTION_LIST = - 'Services/DoctorApplication.svc/REST/PostPrescription'; -const GET_PROCEDURE_LIST = - 'Services/DoctorApplication.svc/REST/GetOrderedProcedure'; +const UPDATE_RESCHDEULE = 'Services/DoctorApplication.svc/REST/PatchRequisition'; +const GET_RESCHEDULE_LEAVE = 'Services/DoctorApplication.svc/REST/GetRequisition'; +const GET_PRESCRIPTION_LIST = 'Services/DoctorApplication.svc/REST/GetPrescription'; + +const POST_PRESCRIPTION_LIST = 'Services/DoctorApplication.svc/REST/PostPrescription'; +const GET_PROCEDURE_LIST = 'Services/DoctorApplication.svc/REST/GetOrderedProcedure'; const POST_PROCEDURE_LIST = 'Services/DoctorApplication.svc/REST/PostProcedure'; -const GET_PATIENT_ARRIVAL_LIST = - 'Services/DoctorApplication.svc/REST/PatientArrivalList'; +const GET_PATIENT_ARRIVAL_LIST = 'Services/DoctorApplication.svc/REST/PatientArrivalList'; -const GET_PATIENT_IN_PATIENT_LIST = - 'Services/DoctorApplication.svc/REST/GetMyInPatient'; +const GET_PATIENT_IN_PATIENT_LIST = 'Services/DoctorApplication.svc/REST/GetMyInPatient'; -const Verify_Referral_Doctor_Remarks = - 'Services/DoctorApplication.svc/REST/VerifyReferralDoctorRemarks'; +const Verify_Referral_Doctor_Remarks = 'Services/DoctorApplication.svc/REST/VerifyReferralDoctorRemarks'; ///Lab Order const GET_Patient_LAB_ORDERS = 'Services/Patients.svc/REST/GetPatientLabOrders'; -const GET_Patient_LAB_SPECIAL_RESULT = - 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; -const SEND_LAB_RESULT_EMAIL = - 'Services/Notifications.svc/REST/SendLabReportEmail'; -const GET_Patient_LAB_RESULT = - 'Services/Patients.svc/REST/GetPatientLabResults'; -const GET_Patient_LAB_ORDERS_RESULT = - 'Services/Patients.svc/REST/GetPatientLabOrdersResults'; +const GET_Patient_LAB_SPECIAL_RESULT = 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; +const SEND_LAB_RESULT_EMAIL = 'Services/Notifications.svc/REST/SendLabReportEmail'; +const GET_Patient_LAB_RESULT = 'Services/Patients.svc/REST/GetPatientLabResults'; +const GET_Patient_LAB_ORDERS_RESULT = 'Services/Patients.svc/REST/GetPatientLabOrdersResults'; // SOAP const GET_ALLERGIES = 'Services/DoctorApplication.svc/REST/GetAllergies'; -const GET_MASTER_LOOKUP_LIST = - 'Services/DoctorApplication.svc/REST/GetMasterLookUpList'; +const GET_MASTER_LOOKUP_LIST = 'Services/DoctorApplication.svc/REST/GetMasterLookUpList'; const POST_EPISODE = 'Services/DoctorApplication.svc/REST/PostEpisode'; const POST_ALLERGY = 'Services/DoctorApplication.svc/REST/PostAllergies'; const POST_HISTORY = 'Services/DoctorApplication.svc/REST/PostHistory'; -const POST_CHIEF_COMPLAINT = - 'Services/DoctorApplication.svc/REST/PostChiefcomplaint'; -const POST_PHYSICAL_EXAM = - 'Services/DoctorApplication.svc/REST/PostPhysicalExam'; -const POST_PROGRESS_NOTE = - '/Services/DoctorApplication.svc/REST/PostProgressNote'; +const POST_CHIEF_COMPLAINT = 'Services/DoctorApplication.svc/REST/PostChiefcomplaint'; +const POST_PHYSICAL_EXAM = 'Services/DoctorApplication.svc/REST/PostPhysicalExam'; +const POST_PROGRESS_NOTE = '/Services/DoctorApplication.svc/REST/PostProgressNote'; const POST_ASSESSMENT = 'Services/DoctorApplication.svc/REST/PostAssessment'; const PATCH_ALLERGY = 'Services/DoctorApplication.svc/REST/PatchAllergies'; const PATCH_HISTORY = 'Services/DoctorApplication.svc/REST/PatchHistory'; -const PATCH_CHIEF_COMPLAINT = - 'Services/DoctorApplication.svc/REST/PatchChiefcomplaint'; +const PATCH_CHIEF_COMPLAINT = 'Services/DoctorApplication.svc/REST/PatchChiefcomplaint'; -const PATCH_PHYSICAL_EXAM = - 'Services/DoctorApplication.svc/REST/PatchPhysicalExam'; -const PATCH_PROGRESS_NOTE = - 'Services/DoctorApplication.svc/REST/PatchProgressNote'; +const PATCH_PHYSICAL_EXAM = 'Services/DoctorApplication.svc/REST/PatchPhysicalExam'; +const PATCH_PROGRESS_NOTE = 'Services/DoctorApplication.svc/REST/PatchProgressNote'; const PATCH_ASSESSMENT = 'Services/DoctorApplication.svc/REST/PatchAssessment'; const GET_ALLERGY = 'Services/DoctorApplication.svc/REST/GetAllergies'; const GET_HISTORY = 'Services/DoctorApplication.svc/REST/GetHistory'; -const GET_CHIEF_COMPLAINT = - 'Services/DoctorApplication.svc/REST/GetChiefcomplaint'; +const GET_CHIEF_COMPLAINT = 'Services/DoctorApplication.svc/REST/GetChiefcomplaint'; const GET_PHYSICAL_EXAM = 'Services/DoctorApplication.svc/REST/GetPhysicalExam'; const GET_PROGRESS_NOTE = 'Services/DoctorApplication.svc/REST/GetProgressNote'; const GET_ASSESSMENT = 'Services/DoctorApplication.svc/REST/GetAssessment'; -const GET_ORDER_PROCEDURE = - 'Services/DoctorApplication.svc/REST/GetOrderedProcedure'; +const GET_ORDER_PROCEDURE = 'Services/DoctorApplication.svc/REST/GetOrderedProcedure'; -const GET_LIST_CATEGORISE = - 'Services/DoctorApplication.svc/REST/GetProcedureCategories'; +const GET_LIST_CATEGORISE = 'Services/DoctorApplication.svc/REST/GetProcedureCategories'; -const GET_CATEGORISE_PROCEDURE = - 'Services/DoctorApplication.svc/REST/GetProcedure'; +const GET_CATEGORISE_PROCEDURE = 'Services/DoctorApplication.svc/REST/GetProcedure'; const UPDATE_PROCEDURE = 'Services/DoctorApplication.svc/REST/PatchProcedure'; -const UPDATE_PRESCRIPTION = - 'Services/DoctorApplication.svc/REST/PatchPrescription'; +const UPDATE_PRESCRIPTION = 'Services/DoctorApplication.svc/REST/PatchPrescription'; const SEARCH_DRUG = 'Services/DoctorApplication.svc/REST/GetMedicationList'; -const DRUG_TO_DRUG = - 'Services/DoctorApplication.svc/REST/DrugToDrugInteraction'; +const DRUG_TO_DRUG = 'Services/DoctorApplication.svc/REST/DrugToDrugInteraction'; const GET_MEDICAL_FILE = 'Services/DoctorApplication.svc/REST/GetMedicalFile'; const GET_FLOORS = 'Services/DoctorApplication.svc/REST/GetFloors'; const GET_WARDS = 'Services/DoctorApplication.svc/REST/GetWards'; -const GET_ROOM_CATEGORIES = - 'Services/DoctorApplication.svc/REST/GetRoomCategories'; -const GET_DIAGNOSIS_TYPES = - 'Services/DoctorApplication.svc/REST/DiagnosisTypes'; +const GET_ROOM_CATEGORIES = 'Services/DoctorApplication.svc/REST/GetRoomCategories'; +const GET_DIAGNOSIS_TYPES = 'Services/DoctorApplication.svc/REST/DiagnosisTypes'; const GET_DIET_TYPES = 'Services/DoctorApplication.svc/REST/DietTypes'; const GET_ICD_CODES = 'Services/DoctorApplication.svc/REST/GetICDCodes'; -const POST_ADMISSION_REQUEST = - 'Services/DoctorApplication.svc/REST/PostAdmissionRequest'; -const GET_ITEM_BY_MEDICINE = - 'Services/DoctorApplication.svc/REST/GetItemByMedicineCode'; +const POST_ADMISSION_REQUEST = 'Services/DoctorApplication.svc/REST/PostAdmissionRequest'; +const GET_ITEM_BY_MEDICINE = 'Services/DoctorApplication.svc/REST/GetItemByMedicineCode'; -const GET_PROCEDURE_VALIDATION = - 'Services/DoctorApplication.svc/REST/ValidateProcedures'; -const GET_BOX_QUANTITY = - 'Services/DoctorApplication.svc/REST/CalculateBoxQuantity'; +const GET_PROCEDURE_VALIDATION = 'Services/DoctorApplication.svc/REST/ValidateProcedures'; +const GET_BOX_QUANTITY = 'Services/DoctorApplication.svc/REST/CalculateBoxQuantity'; ///GET ECG const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; -const GET_MY_REFERRAL_INPATIENT = - "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; +const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; -const GET_MY_DISCHARGE_PATIENT = - "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; -const GET_DISCHARGE_PATIENT = - "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; +const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; +const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; -const GET_PAtIENTS_INSURANCE_APPROVALS = - "Services/Patients.svc/REST/GetApprovalStatus"; +const GET_PAtIENTS_INSURANCE_APPROVALS = "Services/Patients.svc/REST/GetApprovalStatus"; const GET_RAD_IMAGE_URL = 'Services/Patients.svc/Rest/GetRadImageURL'; const GET_PATIENT_ORDERS = 'Services/Patients.svc/REST/GetPatientRadOrders'; -const GET_IN_PATIENT_ORDERS = - 'Services/DoctorApplication.svc/REST/GetPatientRadResult'; +const GET_IN_PATIENT_ORDERS = 'Services/DoctorApplication.svc/REST/GetPatientRadResult'; ///Prescriptions const PRESCRIPTIONS = 'Services/Patients.svc/REST/GetPrescriptionApptList'; -const GET_PRESCRIPTIONS_ALL_ORDERS = - 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; -const GET_PRESCRIPTION_REPORT_NEW = - 'Services/Patients.svc/REST/INP_GetPrescriptionReport'; -const SEND_PRESCRIPTION_EMAIL = - 'Services/Notifications.svc/REST/SendPrescriptionEmail'; -const GET_PRESCRIPTION_REPORT_ENH = - 'Services/Patients.svc/REST/GetPrescriptionReport_enh'; +const GET_PRESCRIPTIONS_ALL_ORDERS = 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +const GET_PRESCRIPTION_REPORT_NEW = 'Services/Patients.svc/REST/INP_GetPrescriptionReport'; +const SEND_PRESCRIPTION_EMAIL = 'Services/Notifications.svc/REST/SendPrescriptionEmail'; +const GET_PRESCRIPTION_REPORT_ENH = 'Services/Patients.svc/REST/GetPrescriptionReport_enh'; const GET_PHARMACY_LIST = "Services/Patients.svc/REST/GetPharmcyList"; -const UPDATE_PROGRESS_NOTE_FOR_INPATIENT = - "Services/DoctorApplication.svc/REST/UpdateProgressNoteForInPatient"; -const CREATE_PROGRESS_NOTE_FOR_INPATIENT = - "Services/DoctorApplication.svc/REST/CreateProgressNoteForInPatient"; +const UPDATE_PROGRESS_NOTE_FOR_INPATIENT = "Services/DoctorApplication.svc/REST/UpdateProgressNoteForInPatient"; +const CREATE_PROGRESS_NOTE_FOR_INPATIENT = "Services/DoctorApplication.svc/REST/CreateProgressNoteForInPatient"; -const GET_PRESCRIPTION_IN_PATIENT = - 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; +const GET_PRESCRIPTION_IN_PATIENT = 'Services/DoctorApplication.svc/REST/GetPrescriptionReportForInPatient'; -const GET_INSURANCE_IN_PATIENT = - "Services/DoctorApplication.svc/REST/GetApprovalStatusForInpatient"; +const GET_INSURANCE_IN_PATIENT = "Services/DoctorApplication.svc/REST/GetApprovalStatusForInpatient"; const GET_SICK_LEAVE_PATIENT = "Services/Patients.svc/REST/GetPatientSickLeave"; -const GET_MY_OUT_PATIENT = - "Services/DoctorApplication.svc/REST/GetMyOutPatient"; - -const PATIENT_MEDICAL_REPORT_GET_LIST = - "Services/Patients.svc/REST/DAPP_ListMedicalReport"; -const PATIENT_MEDICAL_REPORT_GET_TEMPLATE = - "Services/Patients.svc/REST/DAPP_GetTemplateByID"; -const PATIENT_MEDICAL_REPORT_INSERT = - "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; -const PATIENT_MEDICAL_REPORT_VERIFIED = - "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; - -const GET_PROCEDURE_TEMPLETE = - 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; - -const GET_PROCEDURE_TEMPLETE_DETAILS = - "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; -const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = - 'Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; - -const DOCTOR_CHECK_HAS_LIVE_CARE = - "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; +const GET_MY_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GetMyOutPatient"; + +const PATIENT_MEDICAL_REPORT_GET_LIST = "Services/Patients.svc/REST/DAPP_ListMedicalReport"; +const PATIENT_MEDICAL_REPORT_GET_TEMPLATE = "Services/Patients.svc/REST/DAPP_GetTemplateByID"; +const PATIENT_MEDICAL_REPORT_INSERT = "Services/Patients.svc/REST/DAPP_InsertMedicalReport"; +const PATIENT_MEDICAL_REPORT_VERIFIED = "Services/Patients.svc/REST/DAPP_VerifiedMedicalReport"; + +const GET_PROCEDURE_TEMPLETE = 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; + +const GET_PROCEDURE_TEMPLETE_DETAILS = "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; +const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; + +const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; var selectedPatientType = 1; diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index fc4609f3..d03e8f13 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -36,8 +36,7 @@ import 'package:provider/provider.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; -addPrescriptionForm(context, PrescriptionViewModel model, - PatiantInformtion patient, prescription) { +addPrescriptionForm(context, PrescriptionViewModel model, PatiantInformtion patient, prescription) { showModalBottomSheet( isScrollControlled: true, context: context, @@ -62,8 +61,7 @@ postProcedure( String icdCode, PatiantInformtion patient, String patientType}) async { - PostPrescriptionReqModel postProcedureReqModel = - new PostPrescriptionReqModel(); + PostPrescriptionReqModel postProcedureReqModel = new PostPrescriptionReqModel(); List sss = List(); postProcedureReqModel.appointmentNo = patient.appointmentNo; @@ -131,8 +129,7 @@ class _PrescriptionFormWidgetState extends State { dynamic selectedDrug; int strengthChar; GetMedicationResponseModel _selectedMedication; - GlobalKey key = - new GlobalKey>(); + GlobalKey key = new GlobalKey>(); TextEditingController drugIdController = TextEditingController(); TextEditingController doseController = TextEditingController(); @@ -177,10 +174,7 @@ class _PrescriptionFormWidgetState extends State { dynamic indication3 = {"id": 547, "name": "Hypertrichosis"}; dynamic indication4 = {"id": 548, "name": "Mild Dizziness"}; dynamic indication5 = {"id": 549, "name": "Enlargement of Facial Features"}; - dynamic indication6 = { - "id": 550, - "name": "Phenytoin Hypersensitivity Syndrome" - }; + dynamic indication6 = {"id": 550, "name": "Phenytoin Hypersensitivity Syndrome"}; dynamic indication7 = {"id": 551, "name": "Asterixis"}; dynamic indication8 = {"id": 552, "name": "Bullous Dermatitis"}; dynamic indication9 = {"id": 554, "name": "Purpuric Dermatitis"}; @@ -207,8 +201,7 @@ class _PrescriptionFormWidgetState extends State { onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speech.initialize( - onStatus: statusListener, onError: errorListener); + bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, @@ -252,8 +245,7 @@ class _PrescriptionFormWidgetState extends State { } Future initSpeechState() async { - bool hasSpeech = await speech.initialize( - onError: errorListener, onStatus: statusListener); + bool hasSpeech = await speech.initialize(onError: errorListener, onStatus: statusListener); print(hasSpeech); if (!mounted) return; } @@ -310,15 +302,13 @@ class _PrescriptionFormWidgetState extends State { initialChildSize: 0.98, maxChildSize: 0.98, minChildSize: 0.9, - builder: - (BuildContext context, ScrollController scrollController) { + builder: (BuildContext context, ScrollController scrollController) { return SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height * 1.65, color: Color(0xffF8F8F8), child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 12.0, vertical: 10.0), + padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0), child: Column( //crossAxisAlignment: CrossAxisAlignment.start, //mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -329,12 +319,10 @@ class _PrescriptionFormWidgetState extends State { height: 15, ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - TranslationBase.of(context) - .newPrescriptionOrder, + TranslationBase.of(context).newPrescriptionOrder, fontWeight: FontWeight.w700, fontSize: 20, ), @@ -364,11 +352,8 @@ class _PrescriptionFormWidgetState extends State { widthFactor: 0.9, child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: HexColor("#CCCCCC"))), + borderRadius: BorderRadius.all(Radius.circular(6.0)), + border: Border.all(width: 1.0, color: HexColor("#CCCCCC"))), padding: EdgeInsets.all(10), child: AppTextFormField( onTap: () { @@ -376,8 +361,7 @@ class _PrescriptionFormWidgetState extends State { visbiltySearch = true; }, borderColor: Colors.white, - hintText: TranslationBase.of(context) - .searchMedicineNameHere, + hintText: TranslationBase.of(context).searchMedicineNameHere, controller: myController, onSaved: (value) {}, onFieldSubmitted: (value) { @@ -403,12 +387,9 @@ class _PrescriptionFormWidgetState extends State { children: [ // TODO change it secondary button and add loading AppButton( - title: TranslationBase.of( - context) - .search, + title: TranslationBase.of(context).search, onPressed: () async { - await searchMedicine( - context, model); + await searchMedicine(context, model); }, ), ], @@ -417,50 +398,29 @@ class _PrescriptionFormWidgetState extends State { ), if (myController.text != '') Container( - height: MediaQuery.of(context) - .size - .height * - 0.5, + height: MediaQuery.of(context).size.height * 0.5, child: ListView.builder( - padding: const EdgeInsets.only( - top: 20), + padding: const EdgeInsets.only(top: 20), scrollDirection: Axis.vertical, // shrinkWrap: true, - itemCount: - model.allMedicationList == - null - ? 0 - : model - .allMedicationList - .length, - itemBuilder: - (BuildContext context, - int index) { + itemCount: model.allMedicationList == null + ? 0 + : model.allMedicationList.length, + itemBuilder: (BuildContext context, int index) { return InkWell( child: MedicineItemWidget( - label: model - .allMedicationList[ - index] - .description + label: model.allMedicationList[index].description // url: model // .pharmacyItemsList[ // index]["ImageSRCUrl"], ), onTap: () { - model.getItem( - itemID: model - .allMedicationList[ - index] - .itemId); - visbiltyPrescriptionForm = - true; + model.getItem(itemID: model.allMedicationList[index].itemId); + visbiltyPrescriptionForm = true; visbiltySearch = false; - _selectedMedication = - model.allMedicationList[ - index]; - uom = _selectedMedication - .uom; + _selectedMedication = model.allMedicationList[index]; + uom = _selectedMedication.uom; }, ); }, @@ -479,21 +439,18 @@ class _PrescriptionFormWidgetState extends State { child: Column( children: [ AppText( - _selectedMedication?.description ?? - "", + _selectedMedication?.description ?? "", bold: true, ), Container( child: Row( children: [ AppText( - TranslationBase.of(context) - .orderType, + TranslationBase.of(context).orderType, fontWeight: FontWeight.w600, ), Radio( - activeColor: - Color(0xFFB9382C), + activeColor: Color(0xFFB9382C), value: 1, groupValue: selectedType, onChanged: (value) { @@ -504,43 +461,32 @@ class _PrescriptionFormWidgetState extends State { ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( width: double.infinity, child: Row( children: [ Container( color: Colors.white, - width: MediaQuery.of(context) - .size - .width * - 0.35, + width: MediaQuery.of(context).size.width * 0.35, child: AppTextFieldCustom( height: 40, - validationError: - strengthError, - hintText: 'Strength', + validationError: strengthError, + hintText: 'Strength' + "*", isTextFieldHasSuffix: false, enabled: true, - controller: - strengthController, + controller: strengthController, onChanged: (String value) { setState(() { - strengthChar = - value.length; + strengthChar = value.length; }); if (strengthChar >= 5) { - DrAppToastMsg - .showErrorToast( - TranslationBase.of( - context) - .only5DigitsAllowedForStrength, + DrAppToastMsg.showErrorToast( + TranslationBase.of(context).only5DigitsAllowedForStrength, ); } }, - inputType: TextInputType - .numberWithOptions( + inputType: TextInputType.numberWithOptions( decimal: true, ), // keyboardType: TextInputType @@ -554,133 +500,80 @@ class _PrescriptionFormWidgetState extends State { ), Container( color: Colors.white, - width: MediaQuery.of(context) - .size - .width * - 0.560, + width: MediaQuery.of(context).size.width * 0.560, child: InkWell( - onTap: - model.itemMedicineListUnit != - null - ? () { - Helpers - .hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineListUnit, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState( - () { - units = - selectedValue; - units['isDefault'] = - true; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: - context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, + onTap: model.itemMedicineListUnit != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.itemMedicineListUnit, + attributeName: 'description', + attributeValueId: 'parameterCode', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + units = selectedValue; + units['isDefault'] = true; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, child: AppTextFieldCustom( hintText: 'Select', - isTextFieldHasSuffix: - true, - dropDownText: model - .itemMedicineListUnit - .length == - 1 - ? units = model - .itemMedicineListUnit[0] - ['description'] + isTextFieldHasSuffix: true, + dropDownText: model.itemMedicineListUnit.length == 1 + ? units = model.itemMedicineListUnit[0]['description'] : units != null - ? units['description'] - .toString() + ? units['description'].toString() : null, validationError: - model.itemMedicineListUnit - .length != - 1 - ? unitError - : null, + model.itemMedicineListUnit.length != 1 ? unitError : null, enabled: false), ), ), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: - model.itemMedicineListRoute != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineListRoute, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - route = - selectedValue; - route['isDefault'] = - true; - }); - if (route == - null) { - Helpers.showErrorToast( - 'plase fill'); - } - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, + onTap: model.itemMedicineListRoute != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.itemMedicineListRoute, + attributeName: 'description', + attributeValueId: 'parameterCode', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + route = selectedValue; + route['isDefault'] = true; + }); + if (route == null) { + Helpers.showErrorToast('plase fill'); + } + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, child: AppTextFieldCustom( // decoration: // textFieldSelectorDecoration( @@ -698,179 +591,108 @@ class _PrescriptionFormWidgetState extends State { // 'description'] // : null, // true), - hintText: - TranslationBase.of(context) - .route, - dropDownText: model - .itemMedicineListRoute - .length == - 1 - ? model.itemMedicineListRoute[ - 0]['description'] + hintText: TranslationBase.of(context).route + "*", + dropDownText: model.itemMedicineListRoute.length == 1 + ? model.itemMedicineListRoute[0]['description'] : route != null ? route['description'] : null, isTextFieldHasSuffix: true, //height: 45, validationError: - model.itemMedicineListRoute - .length != - 1 - ? routeError - : null, + model.itemMedicineListRoute.length != 1 ? routeError : null, enabled: false, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: - model.itemMedicineList != null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .itemMedicineList, - attributeName: - 'description', - attributeValueId: - 'parameterCode', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - frequency = - selectedValue; - frequency[ - 'isDefault'] = - true; - if (_selectedMedication != null && - duration != - null && - frequency != - null && - strengthController - .text != - null) { - model.getBoxQuantity( - freq: frequency[ - 'parameterCode'], - duration: - duration[ - 'id'], - itemCode: - _selectedMedication - .itemId, - strength: - double.parse( - strengthController.text)); + onTap: model.itemMedicineList != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.itemMedicineList, + attributeName: 'description', + attributeValueId: 'parameterCode', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + frequency = selectedValue; + frequency['isDefault'] = true; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text)); - return; - } - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, + return; + } + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, child: AppTextFieldCustom( isTextFieldHasSuffix: true, - hintText: - TranslationBase.of(context) - .frequency, - dropDownText: model - .itemMedicineList - .length == - 1 - ? model.itemMedicineList[0] - ['description'] + hintText: TranslationBase.of(context).frequency + "*", + dropDownText: model.itemMedicineList.length == 1 + ? model.itemMedicineList[0]['description'] : frequency != null - ? frequency[ - 'description'] + ? frequency['description'] : null, - validationError: model - .itemMedicineList - .length != - 1 - ? frequencyError - : null, + validationError: + model.itemMedicineList.length != 1 ? frequencyError : null, enabled: false, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: - model.medicationDoseTimeList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .medicationDoseTimeList, - attributeName: - 'nameEn', - attributeValueId: - 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - doseTime = - selectedValue; - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, + onTap: model.medicationDoseTimeList != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.medicationDoseTimeList, + attributeName: 'nameEn', + attributeValueId: 'id', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + doseTime = selectedValue; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, child: AppTextFieldCustom( - hintText: - TranslationBase.of(context) - .doseTime, + hintText: TranslationBase.of(context).doseTime + "*", isTextFieldHasSuffix: true, - dropDownText: doseTime != null - ? doseTime['nameEn'] - : null, + dropDownText: doseTime != null ? doseTime['nameEn'] : null, //height: 45, enabled: false, @@ -878,10 +700,8 @@ class _PrescriptionFormWidgetState extends State { ), ), ), - SizedBox( - height: spaceBetweenTextFileds), - if (model - .patientAssessmentList.isNotEmpty) + SizedBox(height: spaceBetweenTextFileds), + if (model.patientAssessmentList.isNotEmpty) Container( height: screenSize.height * 0.070, width: double.infinity, @@ -889,68 +709,38 @@ class _PrescriptionFormWidgetState extends State { child: Row( children: [ Container( - width: - MediaQuery.of(context) - .size - .width * - 0.29, + width: MediaQuery.of(context).size.width * 0.29, child: InkWell( - onTap: - indicationList != null - ? () { - Helpers.hideKeyboard( - context); - } - : null, + onTap: indicationList != null + ? () { + Helpers.hideKeyboard(context); + } + : null, child: TextField( - decoration: - textFieldSelectorDecoration( - model - .patientAssessmentList[ - 0] - .icdCode10ID - .toString(), - indication != - null - ? indication[ - 'name'] - : null, - false), + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].icdCode10ID.toString(), + indication != null ? indication['name'] : null, + false), enabled: true, readOnly: true, ), ), ), Container( - width: - MediaQuery.of(context) - .size - .width * - 0.65, + width: MediaQuery.of(context).size.width * 0.65, color: Colors.white, child: InkWell( - onTap: - indicationList != null - ? () { - Helpers.hideKeyboard( - context); - } - : null, + onTap: indicationList != null + ? () { + Helpers.hideKeyboard(context); + } + : null, child: TextField( maxLines: 5, - decoration: - textFieldSelectorDecoration( - model - .patientAssessmentList[ - 0] - .asciiDesc - .toString(), - indication != - null - ? indication[ - 'name'] - : null, - false), + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].asciiDesc.toString(), + indication != null ? indication['name'] : null, + false), enabled: true, readOnly: true, ), @@ -959,152 +749,101 @@ class _PrescriptionFormWidgetState extends State { ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: () => selectDate( - context, widget.model), + onTap: () => selectDate(context, widget.model), child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .date, - selectedDate != null - ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" - : null, - true, - suffixIcon: Icon( - Icons.calendar_today, - color: Colors.black, - )), + decoration: textFieldSelectorDecoration( + TranslationBase.of(context).date + "*", + selectedDate != null + ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" + : null, + true, + suffixIcon: Icon( + Icons.calendar_today, + color: Colors.black, + )), enabled: false, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( //height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: - model.medicationDurationList != - null - ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog - dialog = - ListSelectDialog( - list: model - .medicationDurationList, - attributeName: - 'nameEn', - attributeValueId: - 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { - setState(() { - duration = - selectedValue; - if (_selectedMedication != null && - duration != - null && - frequency != - null && - strengthController - .text != - null) { - model - .getBoxQuantity( - freq: frequency[ - 'parameterCode'], - duration: - duration[ - 'id'], - itemCode: - _selectedMedication - .itemId, - strength: double.parse( - strengthController - .text), - ); - box = model - .boxQuintity; + onTap: model.medicationDurationList != null + ? () { + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.medicationDurationList, + attributeName: 'nameEn', + attributeValueId: 'id', + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { + setState(() { + duration = selectedValue; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text), + ); + box = model.boxQuintity; - return; - } - }); - }, - ); - showDialog( - barrierDismissible: - false, - context: context, - builder: - (BuildContext - context) { - return dialog; - }, - ); - } - : null, + return; + } + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, child: AppTextFieldCustom( validationError: durationError, isTextFieldHasSuffix: true, - dropDownText: duration != null - ? duration['nameEn'] - : null, - hintText: - TranslationBase.of(context) - .duration, + dropDownText: duration != null ? duration['nameEn'] : null, + hintText: TranslationBase.of(context).duration + "*", enabled: false, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: model.allMedicationList != - null + onTap: model.allMedicationList != null ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog dialog = - ListSelectDialog( - list: model - .allMedicationList, + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.allMedicationList, attributeName: 'nameEn', attributeValueId: 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { setState(() { - duration = - selectedValue; + duration = selectedValue; }); }, ); showDialog( - barrierDismissible: - false, + barrierDismissible: false, context: context, - builder: (BuildContext - context) { + builder: (BuildContext context) { return dialog; }, ); @@ -1112,103 +851,70 @@ class _PrescriptionFormWidgetState extends State { : null, child: TextField( decoration: - textFieldSelectorDecoration( - "UOM", - uom != null - ? uom - : null, - false), + textFieldSelectorDecoration("UOM", uom != null ? uom : null, false), //enabled: false, readOnly: true, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( height: screenSize.height * 0.070, color: Colors.white, child: InkWell( - onTap: model.allMedicationList != - null + onTap: model.allMedicationList != null ? () { - Helpers.hideKeyboard( - context); - ListSelectDialog dialog = - ListSelectDialog( - list: model - .allMedicationList, + Helpers.hideKeyboard(context); + ListSelectDialog dialog = ListSelectDialog( + list: model.allMedicationList, attributeName: 'nameEn', attributeValueId: 'id', - okText: - TranslationBase.of( - context) - .ok, - okFunction: - (selectedValue) { + okText: TranslationBase.of(context).ok, + okFunction: (selectedValue) { setState(() { - duration = - selectedValue; + duration = selectedValue; }); }, ); showDialog( - barrierDismissible: - false, + barrierDismissible: false, context: context, - builder: (BuildContext - context) { + builder: (BuildContext context) { return dialog; }, ); } : null, child: TextField( - decoration: - textFieldSelectorDecoration( - TranslationBase.of( - context) - .boxQuantity, - box != null - ? TranslationBase.of( - context) - .boxQuantity + - ": " + - model - .boxQuintity - .toString() - : null, - false), + decoration: textFieldSelectorDecoration( + TranslationBase.of(context).boxQuantity, + box != null + ? TranslationBase.of(context).boxQuantity + + ": " + + model.boxQuintity.toString() + : null, + false), //enabled: false, readOnly: true, ), ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(6.0)), - border: Border.all( - width: 1.0, - color: - HexColor("#CCCCCC"))), + borderRadius: BorderRadius.all(Radius.circular(6.0)), + border: Border.all(width: 1.0, color: HexColor("#CCCCCC"))), child: Stack( children: [ TextFields( maxLines: 6, minLines: 4, - hintText: TranslationBase.of( - context) - .instruction, - controller: - instructionController, + hintText: TranslationBase.of(context).instruction, + controller: instructionController, //keyboardType: TextInputType.number, ), Positioned( - top: - 0, //MediaQuery.of(context).size.height * 0, + top: 0, //MediaQuery.of(context).size.height * 0, right: 15, child: IconButton( icon: Icon( @@ -1217,28 +923,22 @@ class _PrescriptionFormWidgetState extends State { size: 35, ), onPressed: () { - initSpeechState().then( - (value) => - {onVoiceText()}); + initSpeechState().then((value) => {onVoiceText()}); }, ), ), ], ), ), - SizedBox( - height: spaceBetweenTextFileds), + SizedBox(height: spaceBetweenTextFileds), Container( - margin: EdgeInsets.all( - SizeConfig.widthMultiplier * 5), + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), child: Wrap( alignment: WrapAlignment.center, children: [ AppButton( color: Color(0xff359846), - title: TranslationBase.of( - context) - .addMedication, + title: TranslationBase.of(context).addMedication, fontWeight: FontWeight.w600, onPressed: () async { if (route != null && @@ -1247,41 +947,25 @@ class _PrescriptionFormWidgetState extends State { frequency != null && units != null && selectedDate != null && - strengthController - .text != - "") { - if (_selectedMedication - .isNarcotic == - true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of( - context) - .narcoticMedicineCanOnlyBePrescribedFromVida); + strengthController.text != "") { + if (_selectedMedication.isNarcotic == true) { + DrAppToastMsg.showErrorToast(TranslationBase.of(context) + .narcoticMedicineCanOnlyBePrescribedFromVida); Navigator.pop(context); return; } - if (double.parse( - strengthController - .text) > - 1000.0) { - DrAppToastMsg - .showErrorToast( - "1000 is the MAX for the strength"); + if (double.parse(strengthController.text) > 1000.0) { + DrAppToastMsg.showErrorToast( + "1000 is the MAX for the strength"); return; } - if (double.parse( - strengthController - .text) < - 0.0) { - DrAppToastMsg - .showErrorToast( - "strength can't be zero"); + if (double.parse(strengthController.text) < 0.0) { + DrAppToastMsg.showErrorToast("strength can't be zero"); return; } - if (formKey.currentState - .validate()) { + if (formKey.currentState.validate()) { Navigator.pop(context); openDrugToDrug(model); { @@ -1370,52 +1054,32 @@ class _PrescriptionFormWidgetState extends State { } else { setState(() { if (duration == null) { - durationError = - TranslationBase.of( - context) - .fieldRequired; + durationError = TranslationBase.of(context).fieldRequired; } else { durationError = null; } if (doseTime == null) { - doseTimeError = - TranslationBase.of( - context) - .fieldRequired; + doseTimeError = TranslationBase.of(context).fieldRequired; } else { doseTimeError = null; } if (route == null) { - routeError = - TranslationBase.of( - context) - .fieldRequired; + routeError = TranslationBase.of(context).fieldRequired; } else { routeError = null; } if (frequency == null) { - frequencyError = - TranslationBase.of( - context) - .fieldRequired; + frequencyError = TranslationBase.of(context).fieldRequired; } else { frequencyError = null; } if (units == null) { - unitError = - TranslationBase.of( - context) - .fieldRequired; + unitError = TranslationBase.of(context).fieldRequired; } else { unitError = null; } - if (strengthController - .text == - "") { - strengthError = - TranslationBase.of( - context) - .fieldRequired; + if (strengthController.text == "") { + strengthError = TranslationBase.of(context).fieldRequired; } else { strengthError = null; } @@ -1489,8 +1153,7 @@ class _PrescriptionFormWidgetState extends State { } } - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, + InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, {Icon suffixIcon}) { return InputDecoration( focusedBorder: OutlineInputBorder( @@ -1530,8 +1193,7 @@ class _PrescriptionFormWidgetState extends State { ); } - InputDecoration textFieldSelectorDecorationStreangrh( - String hintText, String selectedText, bool isDropDown, + InputDecoration textFieldSelectorDecorationStreangrh(String hintText, String selectedText, bool isDropDown, {Icon suffixIcon}) { return InputDecoration( focusedBorder: OutlineInputBorder( @@ -1561,8 +1223,7 @@ class _PrescriptionFormWidgetState extends State { fontWeight: FontWeight.w600, ), hintText: selectedText == null || selectedText == "" ? hintText : null, - labelText: - selectedText != null && selectedText != "" ? '\n$selectedText' : null, + labelText: selectedText != null && selectedText != "" ? '\n$selectedText' : null, labelStyle: TextStyle( fontSize: 15, color: Color(0xff2E303A), @@ -1583,9 +1244,7 @@ class _PrescriptionFormWidgetState extends State { child: Column( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - DrugToDrug( - widget.patient, - getPriscriptionforDrug(widget.prescriptionList, model), + DrugToDrug(widget.patient, getPriscriptionforDrug(widget.prescriptionList, model), model.patientAssessmentList), Container( margin: EdgeInsets.all(SizeConfig.widthMultiplier * 3), @@ -1596,11 +1255,9 @@ class _PrescriptionFormWidgetState extends State { postProcedure( icdCode: model.patientAssessmentList.isNotEmpty - ? model.patientAssessmentList[0].icdCode10ID - .isEmpty + ? model.patientAssessmentList[0].icdCode10ID.isEmpty ? "test" - : model.patientAssessmentList[0].icdCode10ID - .toString() + : model.patientAssessmentList[0].icdCode10ID.toString() : "test", // icdCode: model // .patientAssessmentList @@ -1611,20 +1268,17 @@ class _PrescriptionFormWidgetState extends State { // .join(' '), dose: strengthController.text, doseUnit: model.itemMedicineListUnit.length == 1 - ? model.itemMedicineListUnit[0]['parameterCode'] - .toString() + ? model.itemMedicineListUnit[0]['parameterCode'].toString() : units['parameterCode'].toString(), patient: widget.patient, doseTimeIn: doseTime['id'].toString(), model: widget.model, duration: duration['id'].toString(), frequency: model.itemMedicineList.length == 1 - ? model.itemMedicineList[0]['parameterCode'] - .toString() + ? model.itemMedicineList[0]['parameterCode'].toString() : frequency['parameterCode'].toString(), route: model.itemMedicineListRoute.length == 1 - ? model.itemMedicineListRoute[0]['parameterCode'] - .toString() + ? model.itemMedicineListRoute[0]['parameterCode'].toString() : route['parameterCode'].toString(), drugId: _selectedMedication.itemId.toString(), strength: strengthController.text, @@ -1682,8 +1336,7 @@ class _PrescriptionFormWidgetState extends State { // // return selected; // // } - getPriscriptionforDrug( - List prescriptionList, MedicineViewModel model) { + getPriscriptionforDrug(List prescriptionList, MedicineViewModel model) { var prescriptionDetails = []; if (prescriptionList.length > 0) { prescriptionList[0].entityList.forEach((element) { diff --git a/pubspec.lock b/pubspec.lock index ad16d0c2..613c2753 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -587,7 +587,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" + version: "0.6.3-nullsafety.1" json_annotation: dependency: transitive description: From 280f87e51487ca19b4bf0a3d9ce3b3795bc5eed3 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 24 May 2021 17:45:44 +0300 Subject: [PATCH 095/241] fix live care issues --- lib/core/viewModel/authentication_view_model.dart | 1 + lib/models/patient/patiant_info_model.dart | 2 +- lib/screens/live_care/live_care_patient_screen.dart | 2 +- .../patients/profile/vital_sign/vital_sign_details_screen.dart | 2 +- .../patient_profile_header_with_appointment_card_app_bar.dart | 2 +- lib/widgets/shared/app_drawer_widget.dart | 1 + 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a6e9eaeb..4e8217d3 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -423,6 +423,7 @@ class AuthenticationViewModel extends BaseViewModel { deleteUser(); await getDeviceInfoFromFirebase(); this.isFromLogin = isFromLogin; + app_status = APP_STATUS.UNAUTHENTICATED; setState(ViewState.Idle); Navigator.pushAndRemoveUntil( AppGlobal.CONTEX, diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 1fcce8eb..61fb4a2f 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -154,7 +154,7 @@ class PatiantInformtion { patientIdentificationNo: json["PatientIdentificationNo"] ?? json["patientIdentificationNo"], //TODO make 7 dynamic when the backend retrun it in patient arrival - patientType: json["PatientType"] ?? json["patientType"]??7, + patientType: json["PatientType"] ?? json["patientType"]??1, admissionNo: json["AdmissionNo"] ?? json["admissionNo"], admissionDate: json["AdmissionDate"] ?? json["admissionDate"], createdOn: json["CreatedOn"] ?? json["CreatedOn"], diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 132cc214..abe8cf58 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -143,7 +143,7 @@ class _LiveCarePatientScreenState extends State { "isInpatient": false, "arrivalType": "0", "isSearchAndOut": false, - "isFromLiveCare":true + "isFromLiveCare":true, }); }, // isFromSearch: widget.isSearch, diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index 4f3deeb3..33f9a1cb 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -57,7 +57,7 @@ class VitalSignDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient.patientDetails.firstName}'s", + "${patient.firstName ?? patient.patientDetails?.firstName??''}'s", fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart index 9093566b..5d46e745 100644 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart +++ b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart @@ -84,7 +84,7 @@ class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget ? (Helpers.capitalize(patient.firstName) + " " + Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails.fullName), + : Helpers.capitalize(patient.fullName??patient?.patientDetails?.fullName??""), fontSize: SizeConfig.textMultiplier * 2.2, fontWeight: FontWeight.bold, fontFamily: 'Poppins', diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index 64791b26..8f8c0108 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -175,6 +175,7 @@ class _AppDrawerState extends State { Navigator.pop(context); GifLoaderDialogUtils.showMyDialog(context); await authenticationViewModel.logout(isFromLogin: false); + // GifLoaderDialogUtils.showMyDialog(context); }, ), ], From 6620c79478270252333094d5f92515ac5864a263 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 26 May 2021 10:33:21 +0300 Subject: [PATCH 096/241] fix ui issues --- lib/config/config.dart | 4 +-- .../procedure_template_details_model.dart | 25 +++++++++++++++++++ lib/core/viewModel/procedure_View_model.dart | 2 +- lib/screens/procedures/add_lab_orders.dart | 5 ++-- lib/screens/procedures/procedure_screen.dart | 2 +- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 36f4f88d..08dd8562 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -//const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/model/procedure/procedure_template_details_model.dart b/lib/core/model/procedure/procedure_template_details_model.dart index 42a2517a..c566a539 100644 --- a/lib/core/model/procedure/procedure_template_details_model.dart +++ b/lib/core/model/procedure/procedure_template_details_model.dart @@ -4,6 +4,7 @@ class ProcedureTempleteDetailsModel { int clinicID; int doctorID; int templateID; + String templateName; String procedureID; bool isActive; int createdBy; @@ -16,6 +17,9 @@ class ProcedureTempleteDetailsModel { String aliasN; String categoryID; String subGroupID; + String categoryDescription; + String categoryDescriptionN; + String categoryAlias; dynamic riskCategoryID; String type = "1"; String remarks; @@ -40,6 +44,10 @@ class ProcedureTempleteDetailsModel { this.categoryID, this.subGroupID, this.riskCategoryID, + this.templateName, + this.categoryDescription, + this.categoryDescriptionN, + this.categoryAlias, this.remarks, this.type = "1", this.selectedType = 0}); @@ -63,6 +71,10 @@ class ProcedureTempleteDetailsModel { categoryID = json['CategoryID']; subGroupID = json['SubGroupID']; riskCategoryID = json['RiskCategoryID']; + templateName = json['TemplateName']; + categoryDescription = json['CategoryDescription']; + categoryDescriptionN = json['CategoryDescriptionN']; + categoryAlias = json['CategoryAlias']; } Map toJson() { @@ -85,6 +97,19 @@ class ProcedureTempleteDetailsModel { data['CategoryID'] = this.categoryID; data['SubGroupID'] = this.subGroupID; data['RiskCategoryID'] = this.riskCategoryID; + data['TemplateName'] = this.templateName; + data['CategoryDescription'] = this.categoryDescription; + data['CategoryDescriptionN'] = this.categoryDescriptionN; + data['CategoryAlias'] = this.categoryAlias; return data; } } +class ProcedureTempleteDetailsModelList { + List procedureTemplate; + String templateName; + + ProcedureTempleteDetailsModelList( + {this.templateName, ProcedureTempleteDetailsModel template}) { + procedureTemplate.add(template); + } +} diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 4411f7b5..29b4b0e4 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -61,7 +61,7 @@ class ProcedureViewModel extends BaseViewModel { Future getProcedure({int mrn, String patientType}) async { hasError = false; await getDoctorProfile(); - doctorProfile.doctorID; + //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); await _procedureService.getProcedure(mrn: mrn); diff --git a/lib/screens/procedures/add_lab_orders.dart b/lib/screens/procedures/add_lab_orders.dart index 4a20dbaa..cd3205df 100644 --- a/lib/screens/procedures/add_lab_orders.dart +++ b/lib/screens/procedures/add_lab_orders.dart @@ -159,15 +159,14 @@ class _AddSelectedLabOrderState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( TranslationBase.of(context).applyForNewLabOrder, fontWeight: FontWeight.w700, fontSize: 20, ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.48, - ), + InkWell( child: Icon( Icons.close, diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index b6bd705a..f6752c4a 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -189,7 +189,7 @@ class ProcedureScreen extends StatelessWidget { // 'You Cant Update This Procedure'); }, patient: patient, - doctorID: model.doctorProfile.doctorID, + doctorID: model?.doctorProfile?.doctorID, ), ), if (model.state == ViewState.ErrorLocal || From f75ac64cad8c4468b8ce4fdfc5ae70a044bf2743 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 26 May 2021 14:47:27 +0300 Subject: [PATCH 097/241] procedure get template --- lib/client/base_app_client.dart | 4 ++- lib/config/config.dart | 2 ++ .../procedure_template_details_model.dart | 5 +-- .../procedure/procedure_service.dart | 17 +++++---- lib/core/viewModel/procedure_View_model.dart | 36 +++++++++++++++++-- .../procedures/add-favourite-procedure.dart | 8 +++-- 6 files changed, 57 insertions(+), 15 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 824b8189..b4e5f810 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -52,7 +52,9 @@ class BaseAppClient { if (body['EditedBy'] == '') { body.remove("EditedBy"); } - body['TokenID'] = token ?? ''; + if(body['TokenID'] == null){ + body['TokenID'] = token ?? ''; + } // body['TokenID'] = "@dm!n" ?? ''; String lang = await sharedPref.getString(APP_Language); if (lang != null && lang == 'ar') diff --git a/lib/config/config.dart b/lib/config/config.dart index 08dd8562..c8af8ad9 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -210,6 +210,8 @@ const PATIENT_MEDICAL_REPORT_VERIFIED = "Services/Patients.svc/REST/DAPP_Verifie const GET_PROCEDURE_TEMPLETE = 'Services/Doctors.svc/REST/DAPP_ProcedureTemplateGet'; +const GET_TEMPLETE_LIST = 'Services/Doctors.svc/REST/DAPP_TemplateGet'; + const GET_PROCEDURE_TEMPLETE_DETAILS = "Services/Doctors.svc/REST/DAPP_ProcedureTemplateDetailsGet"; const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/REST/GetPendingPatientERForDoctorApp'; diff --git a/lib/core/model/procedure/procedure_template_details_model.dart b/lib/core/model/procedure/procedure_template_details_model.dart index c566a539..1fc797ae 100644 --- a/lib/core/model/procedure/procedure_template_details_model.dart +++ b/lib/core/model/procedure/procedure_template_details_model.dart @@ -105,11 +105,12 @@ class ProcedureTempleteDetailsModel { } } class ProcedureTempleteDetailsModelList { - List procedureTemplate; + List procedureTemplate = List(); String templateName; + int templateId; ProcedureTempleteDetailsModelList( - {this.templateName, ProcedureTempleteDetailsModel template}) { + {this.templateName, this.templateId, ProcedureTempleteDetailsModel template}) { procedureTemplate.add(template); } } diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index 9673b9bf..756044ca 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -23,8 +23,9 @@ class ProcedureService extends BaseService { List procedureslist = List(); List categoryList = []; - List _templateList = List(); - List get templateList => _templateList; + // List _templateList = List(); + // List get templateList => _templateList; + List templateList = List(); List _templateDetailsList = List(); List get templateDetailsList => @@ -68,17 +69,19 @@ class ProcedureService extends BaseService { tokenID: "@dm!n", patientID: 0, searchType: 1, - editedBy: 208195, ); hasError = false; //insuranceApprovalInPatient.clear(); - await baseAppClient.post(GET_PROCEDURE_TEMPLETE, + await baseAppClient.post(GET_TEMPLETE_LIST/*GET_PROCEDURE_TEMPLETE*/, onSuccess: (dynamic response, int statusCode) { - //prescriptionsList.clear(); - response['HIS_ProcedureTemplateList'].forEach((template) { - _templateList.add(ProcedureTempleteModel.fromJson(template)); + templateList.clear(); + response['DAPP_TemplateGetList'].forEach((template) { + templateList.add(ProcedureTempleteDetailsModel.fromJson(template)); }); + // response['HIS_ProcedureTemplateList'].forEach((template) { + // _templateList.add(ProcedureTempleteModel.fromJson(template)); + // }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 29b4b0e4..6ff78fd0 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -26,17 +26,22 @@ class ProcedureViewModel extends BaseViewModel { FilterType filterType = FilterType.Clinic; bool hasError = false; ProcedureService _procedureService = locator(); + List get procedureList => _procedureService.procedureList; + List get valadteProcedureList => _procedureService.valadteProcedureList; + List get categoriesList => _procedureService.categoriesList; + List get categoryList => _procedureService.categoryList; RadiologyService _radiologyService = locator(); LabsService _labsService = locator(); List _finalRadiologyListClinic = List(); List _finalRadiologyListHospital = List(); + List get finalRadiologyList => filterType == FilterType.Clinic ? _finalRadiologyListClinic @@ -50,8 +55,11 @@ class ProcedureViewModel extends BaseViewModel { List get labOrdersResultsList => _labsService.labOrdersResultsList; - List get procedureTemplate => + + List get procedureTemplate => _procedureService.templateList; + List templateList = List(); + List get procedureTemplateDetails => _procedureService.templateDetailsList; @@ -108,11 +116,35 @@ class ProcedureViewModel extends BaseViewModel { if (_procedureService.hasError) { error = _procedureService.error; setState(ViewState.ErrorLocal); - } else + } else { + setTemplateListDependOnId(); setState(ViewState.Idle); + } + } + + setTemplateListDependOnId() { + procedureTemplate.forEach((element) { + List templateListData = templateList + .where((elementTemplate) => + elementTemplate.templateId == element.templateID) + .toList(); + + if (templateListData.length != 0) { + templateList[templateList.indexOf(templateListData[0])] + .procedureTemplate + .add(element); + } else { + templateList.add(ProcedureTempleteDetailsModelList( + templateName: element.templateName, + templateId: element.templateID, + template: element)); + } + }); + print(templateList.length.toString()); } int tempId = 0; + Future getProcedureTemplateDetails({int templateId}) async { tempId = templateId; hasError = false; diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index be6e3451..f520a226 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -39,13 +39,15 @@ class _AddFavouriteProcedureState extends State { Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { - if (model.procedureTemplate.length == 0) { + // TODO mosa_change + // if (model.procedureTemplate.length == 0) { model.getProcedureTemplate(); - } + // } }, builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, + baseViewModel: model, body: Column( children: [ Container( @@ -57,7 +59,7 @@ class _AddFavouriteProcedureState extends State { baseViewModel: model, child: EntityListCheckboxSearchFavProceduresWidget( model: widget.model, - masterList: widget.model.procedureTemplate, + // masterList: widget.model.procedureTemplate, removeFavProcedure: (item) { setState(() { entityList.remove(item); From 390a34dd818f5000b801441f70d91297eaa9a95d Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 26 May 2021 15:07:37 +0300 Subject: [PATCH 098/241] procedure hot fix --- .../procedure/procedure_service.dart | 13 ++++++++++--- lib/core/viewModel/procedure_View_model.dart | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index 756044ca..9e3d4297 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -64,20 +64,27 @@ class ProcedureService extends BaseService { ); Future getProcedureTemplate( - {int doctorId, int projectId, int clinicId}) async { + {int doctorId, int projectId, int clinicId, String categoryID}) async { _procedureTempleteRequestModel = ProcedureTempleteRequestModel( tokenID: "@dm!n", patientID: 0, searchType: 1, ); hasError = false; - //insuranceApprovalInPatient.clear(); await baseAppClient.post(GET_TEMPLETE_LIST/*GET_PROCEDURE_TEMPLETE*/, onSuccess: (dynamic response, int statusCode) { templateList.clear(); response['DAPP_TemplateGetList'].forEach((template) { - templateList.add(ProcedureTempleteDetailsModel.fromJson(template)); + ProcedureTempleteDetailsModel templateElement = ProcedureTempleteDetailsModel.fromJson(template); + if(categoryID != null){ + if(categoryID == templateElement.categoryID){ + templateList.add(templateElement); + } + } else { + templateList.add(templateElement); + } + }); // response['HIS_ProcedureTemplateList'].forEach((template) { // _templateList.add(ProcedureTempleteModel.fromJson(template)); diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 6ff78fd0..fe370800 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -108,11 +108,11 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getProcedureTemplate() async { + Future getProcedureTemplate({String categoryID}) async { hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _procedureService.getProcedureTemplate(); + await _procedureService.getProcedureTemplate(categoryID: categoryID); if (_procedureService.hasError) { error = _procedureService.error; setState(ViewState.ErrorLocal); From 725c87fe8b148e8b287909a5a463a2734608576e Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 26 May 2021 15:27:52 +0300 Subject: [PATCH 099/241] Add favorite procedure templates for lab and radiology --- lib/core/service/home/dasboard_service.dart | 2 +- lib/core/viewModel/procedure_View_model.dart | 1 + lib/screens/home/home_screen.dart | 6 +- .../live_care/live_care_patient_screen.dart | 2 +- .../insurance_approval_screen_patient.dart | 2 +- .../radiology/radiology_home_page.dart | 3 +- .../procedures/ExpansionProcedure.dart | 39 +-- .../procedures/add-favourite-procedure.dart | 69 ++--- .../procedures/add-procedure-form.dart | 158 +----------- .../procedures/add_lab_home_screen.dart | 218 ++++++++++++++++ lib/screens/procedures/add_lab_orders.dart | 6 +- .../procedures/add_procedure_homeScreen.dart | 2 + .../procedures/add_radiology_order.dart | 5 +- .../procedures/add_radiology_screen.dart | 219 ++++++++++++++++ .../procedures/entity_list_fav_procedure.dart | 3 +- .../procedures/procedure_checkout_screen.dart | 237 +++++++++--------- 16 files changed, 635 insertions(+), 337 deletions(-) create mode 100644 lib/screens/procedures/add_lab_home_screen.dart create mode 100644 lib/screens/procedures/add_radiology_screen.dart diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index ba836287..b35d24f2 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -44,7 +44,7 @@ class DashboardService extends BaseService { super.error = error; }, body: { - "DoctorID": doctorProfile.doctorID// test user 9920 + "DoctorID": doctorProfile?.doctorID// test user 9920 }, ); } diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 29b4b0e4..823ca2b4 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -23,6 +23,7 @@ import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:flutter/cupertino.dart'; class ProcedureViewModel extends BaseViewModel { + //TODO Hussam clean it FilterType filterType = FilterType.Clinic; bool hasError = false; ProcedureService _procedureService = locator(); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index b2020abe..c305b752 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -241,12 +241,12 @@ class _HomeScreenState extends State { ), sliderActiveIndex == 1 ? DashboardSliderItemWidget( - model.dashboardItemsList[6]) + model.dashboardItemsList[4]) : sliderActiveIndex == 0 ? DashboardSliderItemWidget( model.dashboardItemsList[3]) : DashboardSliderItemWidget( - model.dashboardItemsList[4]), + model.dashboardItemsList[6]), ]))) : SizedBox(), FractionallySizedBox( @@ -332,7 +332,7 @@ class _HomeScreenState extends State { patientCards.add(HomePatientCard( backgroundColor: backgroundColors[colorIndex], backgroundIconColor: backgroundIconColors[colorIndex], - cardIcon: DoctorApp.inpatient, + cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index abe8cf58..6bef6d5f 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -51,7 +51,7 @@ class _LiveCarePatientScreenState extends State { ), Expanded( child: AppText( - "Live Care Patients", + "LiveCare Patients", fontSize: SizeConfig.textMultiplier * 2.8, fontWeight: FontWeight.bold, color: Color(0xFF2B353E), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 2e4645ae..2bffdda5 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -39,7 +39,7 @@ class _InsuranceApprovalScreenNewState ? (model) => model.getInsuranceInPatient(mrn: patient.patientId) : patient.appointmentNo != null ? (model) => model.getInsuranceApproval(patient, - appointmentNo: patient.appointmentNo, + appointmentNo: patient?.appointmentNo, projectId: patient.projectId) : (model) => model.getInsuranceApproval(patient), builder: (BuildContext context, InsuranceViewModel model, Widget child) => diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 7d70b677..4e969793 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -4,6 +4,7 @@ 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/screens/patients/profile/radiology/radiology_details_page.dart'; import 'package:doctor_app_flutter/screens/procedures/add_radiology_order.dart'; +import 'package:doctor_app_flutter/screens/procedures/add_radiology_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -117,7 +118,7 @@ class _RadiologyHomePageState extends State { context, MaterialPageRoute( builder: (context) => - AddSelectedRadiologyOrder( + AddRadiologyScreen( patient: patient, model: model, )), diff --git a/lib/screens/procedures/ExpansionProcedure.dart b/lib/screens/procedures/ExpansionProcedure.dart index 188f6634..cdad16da 100644 --- a/lib/screens/procedures/ExpansionProcedure.dart +++ b/lib/screens/procedures/ExpansionProcedure.dart @@ -11,7 +11,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ExpansionProcedure extends StatefulWidget { - final ProcedureTempleteModel procedureTempleteModel; + final ProcedureTempleteDetailsModelList procedureTempleteModel; final ProcedureViewModel model; final Function(ProcedureTempleteDetailsModel) removeFavProcedure; final Function(ProcedureTempleteDetailsModel) addFavProcedure; @@ -37,19 +37,14 @@ class ExpansionProcedure extends StatefulWidget { class _ExpansionProcedureState extends State { bool _isShowMore = false; - List _templateDetailsList = List(); BaseAppClient baseAppClient = BaseAppClient(); + @override Widget build(BuildContext context) { return Column( children: [ InkWell( onTap: () async { - if (!_isShowMore && _templateDetailsList.isEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - await getProcedureTemplateDetails(widget.procedureTempleteModel.templateID); - GifLoaderDialogUtils.hideDialog(context); - } setState(() { _isShowMore = !_isShowMore; }); @@ -116,8 +111,8 @@ class _ExpansionProcedureState extends State { )), duration: Duration(milliseconds: 7000), child: Column( - children: - _templateDetailsList.map((itemProcedure) { + children: widget.procedureTempleteModel.procedureTemplate + .map((itemProcedure) { return Container( child: Padding( padding: EdgeInsets.symmetric(horizontal: 12), @@ -135,8 +130,10 @@ class _ExpansionProcedureState extends State { activeColor: Color(0xffD02127), onChanged: (bool newValue) { setState(() { - if (widget.isEntityFavListSelected(itemProcedure)) { - widget.removeFavProcedure(itemProcedure); + if (widget.isEntityFavListSelected( + itemProcedure)) { + widget + .removeFavProcedure(itemProcedure); } else { widget.addFavProcedure(itemProcedure); } @@ -145,8 +142,7 @@ class _ExpansionProcedureState extends State { ), Expanded( child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 0), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), child: AppText(itemProcedure.procedureName, fontSize: 14.0, variant: "bodyText", @@ -169,21 +165,4 @@ class _ExpansionProcedureState extends State { ], ); } - - getProcedureTemplateDetails(templateId)async { - ProcedureTempleteDetailsRequestModel _procedureTempleteDetailsRequestModel = ProcedureTempleteDetailsRequestModel(templateID: templateId, searchType: 1, patientID: 0); - _templateDetailsList.clear(); - await baseAppClient.post(GET_PROCEDURE_TEMPLETE_DETAILS, - onSuccess: (dynamic response, int statusCode) { - response['HIS_ProcedureTemplateDetailsList'].forEach((template) { - setState(() { - _templateDetailsList.add(ProcedureTempleteDetailsModel.fromJson(template)); - }); - }); - }, onFailure: (String error, int statusCode) { - DrAppToastMsg.showErrorToast(error); - - }, body: _procedureTempleteDetailsRequestModel.toJson()); - } - } diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index be6e3451..7e43f934 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -20,9 +20,17 @@ import 'package:flutter/material.dart'; class AddFavouriteProcedure extends StatefulWidget { final ProcedureViewModel model; final PatiantInformtion patient; + final String categoryID; + final String addButtonTitle; + final String toolbarTitle; - const AddFavouriteProcedure({Key key, this.model, this.patient}) - : super(key: key); + AddFavouriteProcedure( + {Key key, + this.model, + this.patient, + this.categoryID, + @required this.addButtonTitle, + @required this.toolbarTitle}); @override _AddFavouriteProcedureState createState() => _AddFavouriteProcedureState(); @@ -46,6 +54,7 @@ class _AddFavouriteProcedureState extends State { builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, + baseViewModel: model, body: Column( children: [ Container( @@ -54,27 +63,25 @@ class _AddFavouriteProcedureState extends State { if (model.procedureTemplate.length != 0) Expanded( child: NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchFavProceduresWidget( - model: widget.model, - masterList: widget.model.procedureTemplate, - removeFavProcedure: (item) { - setState(() { - entityList.remove(item); - }); - }, - addFavProcedure: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityFavListSelected: (master) => - isEntityListSelected(master), - )), + baseViewModel: model, + child: EntityListCheckboxSearchFavProceduresWidget( + model: widget.model, + masterList: widget.model.procedureTemplate, + //TODO change it to the new model + removeFavProcedure: (item) { + setState(() { + entityList.remove(item); + }); + }, + addFavProcedure: (history) { + setState(() { + entityList.add(history); + }); + }, + isEntityFavListSelected: (master) => + isEntityListSelected(master), + ), + ), ), Container( margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), @@ -82,7 +89,8 @@ class _AddFavouriteProcedureState extends State { alignment: WrapAlignment.center, children: [ AppButton( - title: TranslationBase.of(context).addSelectedProcedures, + title: widget.addButtonTitle ?? + TranslationBase.of(context).addSelectedProcedures, color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () { @@ -97,11 +105,14 @@ class _AddFavouriteProcedureState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => ProcedureCheckOutScreen( - items: entityList, - model: model, - patient: widget.patient, - )), + builder: (context) => ProcedureCheckOutScreen( + items: entityList, + model: model, + patient: widget.patient, + addButtonTitle: widget.addButtonTitle, + toolbarTitle: widget.toolbarTitle, + ), + ), ); }, ), diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index 4e08a73d..844ff246 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -111,6 +111,7 @@ class AddSelectedProcedure extends StatefulWidget { const AddSelectedProcedure({Key key, this.model, this.patient}) : super(key: key); + @override _AddSelectedProcedureState createState() => _AddSelectedProcedureState(patient: patient, model: model); @@ -120,7 +121,9 @@ class _AddSelectedProcedureState extends State { int selectedType; ProcedureViewModel model; PatiantInformtion patient; + _AddSelectedProcedureState({this.patient, this.model}); + TextEditingController procedureController = TextEditingController(); TextEditingController remarksController = TextEditingController(); List entityList = List(); @@ -220,7 +223,8 @@ class _AddSelectedProcedureState extends State { if (procedureName.text.isNotEmpty && procedureName.text.length >= 3) model.getProcedureCategory( - categoryName: procedureName.text); + categoryName: + procedureName.text); else DrAppToastMsg.showErrorToast( TranslationBase.of(context) @@ -235,90 +239,11 @@ class _AddSelectedProcedureState extends State { ), ], ), - // SizedBox( - // width: MediaQuery.of(context).size.width * 0.29, - // ), - // InkWell( - // child: Icon( - // Icons.close, - // size: 24.0, - // ), - // onTap: () { - // Navigator.pop(context); - // }, - // ), - // ], - // ), - // SizedBox( - // height: 10.0, - // ), - // Container( - // height: screenSize.height * 0.070, - // child: InkWell( - // onTap: model.categoryList != null && - // model.categoryList.length > 0 - // ? () { - // ListSelectDialog dialog = - // ListSelectDialog( - // list: model.categoryList, - // attributeName: 'categoryName', - // attributeValueId: 'categoryId', - // okText: TranslationBase.of(context).ok, - // okFunction: (selectedValue) { - // setState(() { - // selectedCategory = selectedValue; - // model.getProcedureCategory( - // categoryName: selectedCategory[ - // 'categoryName'], - // categoryID: selectedCategory[ - // 'categoryId'] <= - // 9 - // ? "0" + - // selectedCategory[ - // 'categoryId'] - // .toString() - // : selectedCategory[ - // 'categoryId'] - // .toString()); - // }); - // }, - // ); - // showDialog( - // barrierDismissible: false, - // context: context, - // builder: (BuildContext context) { - // return dialog; - // }, - // ); - // //model.getProcedureCategory(); - // } - // : null, - // child: TextField( - // decoration: textFieldSelectorDecoration( - // TranslationBase.of(context) - // .procedureCategorise, - // selectedCategory != null - // ? selectedCategory['categoryName'] - // : null, - // true, - // suffixIcon: Icon( - // Icons.search, - // color: Colors.black, - // )), - // enabled: false, - // ), - // ), - // ), if (procedureName.text.isNotEmpty && model.procedureList.length != 0) NetworkBaseView( baseViewModel: model, - child: - // selectedCategory != null - // ? selectedCategory['categoryId'] == 02 || - // selectedCategory['categoryId'] == 03 - // ? - EntityListCheckboxSearchWidget( + child: EntityListCheckboxSearchWidget( model: widget.model, masterList: widget .model.categoriesList[0].entityList, @@ -338,77 +263,10 @@ class _AddSelectedProcedureState extends State { }, isEntityListSelected: (master) => isEntityListSelected(master), - ) - // : ProcedureListWidget( - // model: widget.model, - // masterList: widget.model - // .categoriesList[0].entityList, - // removeHistory: (item) { - // setState(() { - // entityList.remove(item); - // }); - // }, - // addHistory: (history) { - // setState(() { - // entityList.add(history); - // }); - // }, - // addSelectedHistories: () { - // //TODO build your fun herr - // // widget.addSelectedHistories(); - // }, - // isEntityListSelected: (master) => - // isEntityListSelected(master), - // ) - // : null, - ), + )), SizedBox( - height: 15.0, + height: 115.0, ), - Column( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - // Container( - // child: Row( - // children: [ - // AppText( - // TranslationBase.of(context).orderType), - // Radio( - // activeColor: Color(0xFFB9382C), - // value: 1, - // groupValue: selectedType, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text('routine'), - // Radio( - // activeColor: Color(0xFFB9382C), - // groupValue: selectedType, - // value: 0, - // onChanged: (value) { - // setSelectedType(value); - // }, - // ), - // Text(TranslationBase.of(context).urgent), - // ], - // ), - // ), - // SizedBox( - // height: 15.0, - // ), - // TextFields( - // hintText: TranslationBase.of(context).remarks, - // controller: remarksController, - // minLines: 3, - // maxLines: 5, - // ), - SizedBox( - height: 100.0, - ), - ], - ) ], ), ), diff --git a/lib/screens/procedures/add_lab_home_screen.dart b/lib/screens/procedures/add_lab_home_screen.dart new file mode 100644 index 00000000..d86c4ecd --- /dev/null +++ b/lib/screens/procedures/add_lab_home_screen.dart @@ -0,0 +1,218 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; +import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'add_lab_orders.dart'; + +class AddLabHomeScreen extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + const AddLabHomeScreen({Key key, this.model, this.patient}) : super(key: key); + @override + _AddLabHomeScreenState createState() => + _AddLabHomeScreenState(patient: patient, model: model); +} + +class _AddLabHomeScreenState extends State + with SingleTickerProviderStateMixin { + _AddLabHomeScreenState({this.patient, this.model}); + ProcedureViewModel model; + PatiantInformtion patient; + TabController _tabController; + int _activeTab = 0; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + _tabController.addListener(_handleTabSelection); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + _handleTabSelection() { + setState(() { + _activeTab = _tabController.index; + }); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return BaseView( + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: NetworkBaseView( + baseViewModel: model, + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: + (BuildContext context, ScrollController scrollController) { + return Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText( + 'Add Procedure', + fontWeight: FontWeight.w700, + fontSize: 20, + ), + InkWell( + child: Icon( + Icons.close, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ) + ]), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + Expanded( + child: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight( + MediaQuery.of(context).size.height * 0.070), + child: Container( + height: + MediaQuery.of(context).size.height * 0.070, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5), //width: 0.7 + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorColor: Colors.transparent, + indicatorWeight: 1.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only( + top: 0, left: 0, right: 0, bottom: 0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + tabWidget( + screenSize, + _activeTab == 0, + "Favorite Templates", + ), + tabWidget( + screenSize, + _activeTab == 1, + 'All Lab', + ), + ], + ), + ), + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + AddFavouriteProcedure( + patient: patient, + model: model, + addButtonTitle: TranslationBase.of(context).addLabOrder, + toolbarTitle: TranslationBase.of(context).applyForNewLabOrder, + categoryID: "02", + ), + AddSelectedLabOrder( + model: model, + patient: patient, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }), + ), + ), + ); + } + + Widget tabWidget(Size screenSize, bool isActive, String title, + {int counter = -1}) { + return 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: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + title, + fontSize: SizeConfig.textMultiplier * 1.5, + color: isActive ? Colors.white : Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + if (counter != -1) + Container( + margin: EdgeInsets.all(4), + width: 15, + height: 15, + decoration: BoxDecoration( + color: isActive ? Colors.white : Color(0xFFD02127), + shape: BoxShape.circle, + ), + child: Center( + child: FittedBox( + child: AppText( + "$counter", + fontSize: SizeConfig.textMultiplier * 1.5, + color: !isActive ? Colors.white : Color(0xFFD02127), + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/procedures/add_lab_orders.dart b/lib/screens/procedures/add_lab_orders.dart index cd3205df..a4cb4e68 100644 --- a/lib/screens/procedures/add_lab_orders.dart +++ b/lib/screens/procedures/add_lab_orders.dart @@ -218,14 +218,10 @@ class _AddSelectedLabOrderState extends State { alignment: WrapAlignment.center, children: [ AppButton( - title: TranslationBase.of(context) - .addLabOrder, //TranslationBase.of(context) + title: TranslationBase.of(context).addLabOrder, fontWeight: FontWeight.w700, - //.addSelectedProcedures, color: Color(0xff359846), onPressed: () { - //print(entityList.toString()); - onPressed: if (entityList.isEmpty == true) { DrAppToastMsg.showErrorToast( TranslationBase.of(context) diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/add_procedure_homeScreen.dart index 4a4d8242..39ed4b25 100644 --- a/lib/screens/procedures/add_procedure_homeScreen.dart +++ b/lib/screens/procedures/add_procedure_homeScreen.dart @@ -147,6 +147,8 @@ class _AddProcedureHomeState extends State AddFavouriteProcedure( patient: patient, model: model, + addButtonTitle: TranslationBase.of(context).addSelectedProcedures, + toolbarTitle: 'Add Procedure', ), AddSelectedProcedure( model: model, diff --git a/lib/screens/procedures/add_radiology_order.dart b/lib/screens/procedures/add_radiology_order.dart index 3f19e7f9..78e91ba8 100644 --- a/lib/screens/procedures/add_radiology_order.dart +++ b/lib/screens/procedures/add_radiology_order.dart @@ -110,6 +110,7 @@ class AddSelectedRadiologyOrder extends StatefulWidget { const AddSelectedRadiologyOrder({Key key, this.model, this.patient}) : super(key: key); + @override _AddSelectedRadiologyOrderState createState() => _AddSelectedRadiologyOrderState(patient: patient, model: model); @@ -119,7 +120,9 @@ class _AddSelectedRadiologyOrderState extends State { int selectedType; ProcedureViewModel model; PatiantInformtion patient; + _AddSelectedRadiologyOrderState({this.patient, this.model}); + TextEditingController procedureController = TextEditingController(); TextEditingController remarksController = TextEditingController(); List entityList = List(); @@ -221,8 +224,6 @@ class _AddSelectedRadiologyOrderState extends State { color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () { - //print(entityList.toString()); - onPressed: if (entityList.isEmpty == true) { DrAppToastMsg.showErrorToast(TranslationBase.of(context) .fillTheMandatoryProcedureDetails); diff --git a/lib/screens/procedures/add_radiology_screen.dart b/lib/screens/procedures/add_radiology_screen.dart new file mode 100644 index 00000000..ac21e7d9 --- /dev/null +++ b/lib/screens/procedures/add_radiology_screen.dart @@ -0,0 +1,219 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; +import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'add_lab_orders.dart'; +import 'add_radiology_order.dart'; + +class AddRadiologyScreen extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + const AddRadiologyScreen({Key key, this.model, this.patient}) : super(key: key); + @override + _AddRadiologyScreenState createState() => + _AddRadiologyScreenState(patient: patient, model: model); +} + +class _AddRadiologyScreenState extends State + with SingleTickerProviderStateMixin { + _AddRadiologyScreenState({this.patient, this.model}); + ProcedureViewModel model; + PatiantInformtion patient; + TabController _tabController; + int _activeTab = 0; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + _tabController.addListener(_handleTabSelection); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + _handleTabSelection() { + setState(() { + _activeTab = _tabController.index; + }); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return BaseView( + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: NetworkBaseView( + baseViewModel: model, + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: + (BuildContext context, ScrollController scrollController) { + return Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppText( + TranslationBase.of(context).addLabOrder, + fontWeight: FontWeight.w700, + fontSize: 20, + ), + InkWell( + child: Icon( + Icons.close, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ) + ]), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + Expanded( + child: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight( + MediaQuery.of(context).size.height * 0.070), + child: Container( + height: + MediaQuery.of(context).size.height * 0.070, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5), //width: 0.7 + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorColor: Colors.transparent, + indicatorWeight: 1.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only( + top: 0, left: 0, right: 0, bottom: 0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + tabWidget( + screenSize, + _activeTab == 0, + "Favorite Templates", + ), + tabWidget( + screenSize, + _activeTab == 1, + 'All Radiology', + ), + ], + ), + ), + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + AddFavouriteProcedure( + patient: patient, + model: model, + addButtonTitle: TranslationBase.of(context).addLabOrder, + toolbarTitle: TranslationBase.of(context).applyForNewLabOrder, + categoryID: "03", + ), + AddSelectedRadiologyOrder( + model: model, + patient: patient, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }), + ), + ), + ); + } + + Widget tabWidget(Size screenSize, bool isActive, String title, + {int counter = -1}) { + return 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: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + title, + fontSize: SizeConfig.textMultiplier * 1.5, + color: isActive ? Colors.white : Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + if (counter != -1) + Container( + margin: EdgeInsets.all(4), + width: 15, + height: 15, + decoration: BoxDecoration( + color: isActive ? Colors.white : Color(0xFFD02127), + shape: BoxShape.circle, + ), + child: Center( + child: FittedBox( + child: AppText( + "$counter", + fontSize: SizeConfig.textMultiplier * 1.5, + color: !isActive ? Colors.white : Color(0xFFD02127), + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index 1dac2f24..c5189a48 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -61,6 +61,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState } List items = List(); + List itemss = List(); List itemsProcedure = List(); List remarksList = List(); List typeList = List(); @@ -104,7 +105,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState ), items.length != 0 ? Column( - children: items.map((historyInfo) { + children: itemss.map((historyInfo) { return ExpansionProcedure( procedureTempleteModel: historyInfo, model: widget.model, diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index f5b6dcb7..76d6cf6f 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -14,10 +14,14 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ProcedureCheckOutScreen extends StatefulWidget { - ProcedureCheckOutScreen({this.items, this.model, this.patient}); final List items; final ProcedureViewModel model; final PatiantInformtion patient; + final String addButtonTitle; + final String toolbarTitle; + + ProcedureCheckOutScreen( + {this.items, this.model, this.patient,@required this.addButtonTitle,@required this.toolbarTitle}); @override _ProcedureCheckOutScreenState createState() => @@ -63,7 +67,7 @@ class _ProcedureCheckOutScreenState extends State { width: 5.0, ), AppText( - 'Add Procedure', + widget.toolbarTitle ?? 'Add Procedure', fontWeight: FontWeight.w700, fontSize: 20, ), @@ -71,122 +75,129 @@ class _ProcedureCheckOutScreenState extends State { ), ), ), - SizedBox(height: 30,), - ...List.generate(widget.items.length, (index) => Container( - margin: EdgeInsets.only(bottom: 15.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: - BorderRadius.all(Radius.circular(10.0))), - child: ExpansionTile( - initiallyExpanded: true, - title: Row( - children: [ - Icon( - Icons.check_box, - color: Color(0xffD02127), - size: 30.5, - ), - SizedBox( - width: 6.0, - ), - Expanded( - child: - AppText(widget.items[index].procedureName)), - ], - ), - children: [ - Container( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 11), + SizedBox( + height: 30, + ), + ...List.generate( + widget.items.length, + (index) => Container( + margin: EdgeInsets.only(bottom: 15.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.all(Radius.circular(10.0))), + child: ExpansionTile( + initiallyExpanded: true, + title: Row( + children: [ + Icon( + Icons.check_box, + color: Color(0xffD02127), + size: 30.5, + ), + SizedBox( + width: 6.0, + ), + Expanded( child: AppText( - TranslationBase.of(context).orderType, - fontWeight: FontWeight.w700, - color: Color(0xff2B353E), - ), + widget.items[index].procedureName)), + ], + ), + children: [ + Container( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 11), + child: AppText( + TranslationBase.of(context) + .orderType, + fontWeight: FontWeight.w700, + color: Color(0xff2B353E), + ), + ), + ], + ), + Row( + children: [ + Radio( + activeColor: Color(0xFFD02127), + value: 0, + groupValue: + widget.items[index].selectedType, + onChanged: (value) { + widget.items[index].selectedType = + 0; + setState(() { + widget.items[index].type = + value.toString(); + }); + }, + ), + AppText( + 'routine', + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + Radio( + activeColor: Color(0xFFD02127), + groupValue: + widget.items[index].selectedType, + value: 1, + onChanged: (value) { + widget.items[index].selectedType = + 1; + setState(() { + widget.items[index].type = + value.toString(); + }); + }, + ), + AppText( + TranslationBase.of(context).urgent, + color: Color(0xff575757), + fontWeight: FontWeight.w600, + ), + ], + ), + ], ), - ], + ), ), - Row( - children: [ - Radio( - activeColor: Color(0xFFD02127), - value: 0, - groupValue: - widget.items[index].selectedType, - onChanged: (value) { - widget.items[index].selectedType = 0; - setState(() { - widget.items[index].type = - value.toString(); - }); - }, - ), - AppText( - 'routine', - color: Color(0xff575757), - fontWeight: FontWeight.w600, - ), - Radio( - activeColor: Color(0xFFD02127), - groupValue: - widget.items[index].selectedType, - value: 1, - onChanged: (value) { - widget.items[index].selectedType = 1; - setState(() { - widget.items[index].type = - value.toString(); - }); - }, - ), - AppText( - TranslationBase.of(context).urgent, - color: Color(0xff575757), - fontWeight: FontWeight.w600, - ), - ], + SizedBox( + height: 2.0, + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: 12, vertical: 15.0), + child: TextFields( + hintText: TranslationBase.of(context).remarks, + controller: remarksController, + onChanged: (value) { + widget.items[index].remarks = value; + }, + minLines: 3, + maxLines: 5, + borderWidth: 0.5, + borderColor: Colors.grey[500], + ), ), + SizedBox( + height: 19.0, + ), + //DividerWithSpacesAround(), ], ), - ), - ), - SizedBox( - height: 2.0, - ), - Padding( - padding: EdgeInsets.symmetric( - horizontal: 12, vertical: 15.0), - child: TextFields( - hintText: TranslationBase.of(context).remarks, - controller: remarksController, - onChanged: (value) { - widget.items[index].remarks = value; - }, - minLines: 3, - maxLines: 5, - borderWidth: 0.5, - borderColor: Colors.grey[500], - ), - ), - SizedBox( - height: 19.0, - ), - //DividerWithSpacesAround(), - ], - ), - )), - SizedBox(height: 90,), - - + )), + SizedBox( + height: 90, + ), ], ), ), @@ -196,7 +207,7 @@ class _ProcedureCheckOutScreenState extends State { alignment: WrapAlignment.center, children: [ AppButton( - title: TranslationBase.of(context).addSelectedProcedures, + title: widget.addButtonTitle ?? TranslationBase.of(context).addSelectedProcedures, color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () async { From b16dc2092b5499774a54f3c1cbd149eccefacf7b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 26 May 2021 16:22:35 +0300 Subject: [PATCH 100/241] liveCare cahnges --- .../viewModel/LiveCarePatientViewModel.dart | 44 ++- lib/models/patient/patiant_info_model.dart | 82 +++- .../live_care/live_care_patient_screen.dart | 22 ++ lib/widgets/patients/PatientCard.dart | 365 +++++++++++------- 4 files changed, 339 insertions(+), 174 deletions(-) diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 59706429..844ebf55 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -17,19 +17,23 @@ class LiveCarePatientViewModel extends BaseViewModel { LiveCarePatientServices _liveCarePatientServices = locator(); - StartCallRes get startCallRes => _liveCarePatientServices.startCallRes; - DashboardService _dashboardService = - locator(); + DashboardService _dashboardService = locator(); + + getPendingPatientERForDoctorApp({bool isFromTimer = false}) async { + if (isFromTimer) { + setState(ViewState.Idle); + } else { + setState(ViewState.BusyLocal); + } - getPendingPatientERForDoctorApp() async { - setState(ViewState.BusyLocal); PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel = - PendingPatientERForDoctorAppRequestModel(sErServiceID:_dashboardService.sServiceID, outSA: false); - await _liveCarePatientServices - .getPendingPatientERForDoctorApp(pendingPatientERForDoctorAppRequestModel); + PendingPatientERForDoctorAppRequestModel( + sErServiceID: _dashboardService.sServiceID, outSA: false); + await _liveCarePatientServices.getPendingPatientERForDoctorApp( + pendingPatientERForDoctorAppRequestModel); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; @@ -49,8 +53,7 @@ class LiveCarePatientViewModel extends BaseViewModel { endCallReq.isDestroy = isPatient; setState(ViewState.BusyLocal); - await _liveCarePatientServices - .endCall(endCallReq); + await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -59,7 +62,7 @@ class LiveCarePatientViewModel extends BaseViewModel { } } - getToken()async{ + getToken() async { String token = await sharedPref.getString(TOKEN); return token; } @@ -86,12 +89,11 @@ class LiveCarePatientViewModel extends BaseViewModel { } else { setState(ViewState.Idle); } - } + Future endCallWithCharge(int vcID) async { setState(ViewState.BusyLocal); - await _liveCarePatientServices - .endCallWithCharge(vcID); + await _liveCarePatientServices.endCallWithCharge(vcID); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -103,8 +105,7 @@ class LiveCarePatientViewModel extends BaseViewModel { Future transferToAdmin(int vcID, String notes) async { setState(ViewState.BusyLocal); - await _liveCarePatientServices - .transferToAdmin(vcID, notes); + await _liveCarePatientServices.transferToAdmin(vcID, notes); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -115,19 +116,20 @@ class LiveCarePatientViewModel extends BaseViewModel { } searchData(String str) { - var strExist= str.length > 0 ? true : false; + var strExist = str.length > 0 ? true : false; if (strExist) { filterData = []; for (var i = 0; i < _liveCarePatientServices.patientList.length; i++) { String fullName = - _liveCarePatientServices.patientList[i].fullName.toUpperCase(); + _liveCarePatientServices.patientList[i].fullName.toUpperCase(); String patientID = - _liveCarePatientServices.patientList[i].patientId.toString(); + _liveCarePatientServices.patientList[i].patientId.toString(); String mobile = - _liveCarePatientServices.patientList[i].mobileNumber.toUpperCase(); + _liveCarePatientServices.patientList[i].mobileNumber.toUpperCase(); if (fullName.contains(str.toUpperCase()) || - patientID.contains(str)|| mobile.contains(str)) { + patientID.contains(str) || + mobile.contains(str)) { filterData.add(_liveCarePatientServices.patientList[i]); } } diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 61fb4a2f..0cb067e0 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -7,6 +7,15 @@ class PatiantInformtion { String appointmentDate; dynamic appointmentNo; dynamic appointmentType; + String arrivalTime; + String arrivalTimeD; + int callStatus; + Null callStatusDisc; + int callTypeID; + String clientRequestID; + String clinicName; + String consoltationEnd; + String consultationNotes; int appointmentTypeId; String arrivedOn; int clinicGroupId; @@ -57,12 +66,14 @@ class PatiantInformtion { String startTime; String visitType; String nationalityFlagURL; + int patientStatus; int patientStatusType; int visitTypeId; String startTimes; String dischargeDate; int status; int vcId; + String voipToken; PatiantInformtion( {this.patientDetails, @@ -102,6 +113,15 @@ class PatiantInformtion { this.appointmentDate, this.startTime, this.appointmentNo, + this.arrivalTime, + this.arrivalTimeD, + this.callStatus, + this.callStatusDisc, + this.callTypeID, + this.clientRequestID, + this.clinicName, + this.consoltationEnd, + this.consultationNotes, this.appointmentType, this.appointmentTypeId, this.arrivedOn, @@ -122,20 +142,27 @@ class PatiantInformtion { this.fullNameN, this.nationalityFlagURL, this.patientStatusType, + this.patientStatus, this.visitTypeId, - this.startTimes,this.dischargeDate,this.status, this.vcId}); + this.startTimes, + this.dischargeDate, + this.status, + this.vcId, + this.voipToken}); factory PatiantInformtion.fromJson(Map json) => PatiantInformtion( - patientDetails: json['patientDetails'] != null ? new PatiantInformtion.fromJson(json['patientDetails']) + patientDetails: json['patientDetails'] != null + ? new PatiantInformtion.fromJson(json['patientDetails']) : null, projectId: json["ProjectID"] ?? json["projectID"], clinicId: json["ClinicID"] ?? json["clinicID"], doctorId: json["DoctorID"] ?? json["doctorID"], - patientId: json["PatientID"]!= null ?json["PatientID"] is String ? int.parse(json["PatientID"]):json["PatientID"]: - json["patientID"] ?? - json['patientMRN'] ?? - json['PatientMRN'], + patientId: json["PatientID"] != null + ? json["PatientID"] is String + ? int.parse(json["PatientID"]) + : json["PatientID"] + : json["patientID"] ?? json['patientMRN'] ?? json['PatientMRN'], doctorName: json["DoctorName"] ?? json["doctorName"], doctorNameN: json["DoctorNameN"] ?? json["doctorNameN"], firstName: json["FirstName"] ?? json["firstName"], @@ -144,17 +171,22 @@ class PatiantInformtion { firstNameN: json["FirstNameN"] ?? json["firstNameN"], middleNameN: json["MiddleNameN"] ?? json["middleNameN"], lastNameN: json["LastNameN"] ?? json["lastNameN"], - gender: json["Gender"]!= null? json["Gender"]is String ?int.parse(json["Gender"]):json["Gender"] :json["gender"], - fullName: json["fullName"] ?? json["fullName"]??json["PatientName"], - fullNameN: json["fullNameN"] ?? json["fullNameN"]??json["PatientName"], - dateofBirth: json["DateofBirth"] ?? json["dob"]??json['DateOfBirth'], + gender: json["Gender"] != null + ? json["Gender"] is String + ? int.parse(json["Gender"]) + : json["Gender"] + : json["gender"], + fullName: json["fullName"] ?? json["fullName"] ?? json["PatientName"], + fullNameN: + json["fullNameN"] ?? json["fullNameN"] ?? json["PatientName"], + dateofBirth: json["DateofBirth"] ?? json["dob"] ?? json['DateOfBirth'], nationalityId: json["NationalityID"] ?? json["nationalityID"], mobileNumber: json["MobileNumber"] ?? json["mobileNumber"], emailAddress: json["EmailAddress"] ?? json["emailAddress"], patientIdentificationNo: json["PatientIdentificationNo"] ?? json["patientIdentificationNo"], //TODO make 7 dynamic when the backend retrun it in patient arrival - patientType: json["PatientType"] ?? json["patientType"]??1, + patientType: json["PatientType"] ?? json["patientType"] ?? 1, admissionNo: json["AdmissionNo"] ?? json["admissionNo"], admissionDate: json["AdmissionDate"] ?? json["admissionDate"], createdOn: json["CreatedOn"] ?? json["CreatedOn"], @@ -176,10 +208,11 @@ class PatiantInformtion { genderDescription: json["GenderDescription"], nursingStationName: json["NursingStationName"], appointmentDate: json["AppointmentDate"] ?? '', - startTime: json["startTime"]??json['StartTime'], + startTime: json["startTime"] ?? json['StartTime'], appointmentNo: json['appointmentNo'] ?? json['AppointmentNo'], appointmentType: json['appointmentType'], - appointmentTypeId: json['appointmentTypeId']?? json['appointmentTypeid'], + appointmentTypeId: + json['appointmentTypeId'] ?? json['appointmentTypeid'], arrivedOn: json['ArrivedOn'] ?? json['arrivedOn'] ?? json['ArrivedOn'], clinicGroupId: json['clinicGroupId'], companyName: json['companyName'], @@ -192,15 +225,28 @@ class PatiantInformtion { medicationOrders: json['medicationOrders'], nationality: json['nationality'] ?? json['NationalityNameN'], patientMRN: json['patientMRN'] ?? json['PatientMRN'], - visitType: json['visitType'] ?? json['visitType']?? json['visitType'], + visitType: json['visitType'] ?? json['visitType'] ?? json['visitType'], nationalityFlagURL: json['NationalityFlagURL'] ?? json['NationalityFlagURL'], patientStatusType: json['patientStatusType'] ?? json['PatientStatusType'], - visitTypeId: json['visitTypeId'] ?? json['visitTypeId'] ?? json['visitTypeid'], + visitTypeId: + json['visitTypeId'] ?? json['visitTypeId'] ?? json['visitTypeid'], startTimes: json['StartTime'] ?? json['StartTime'], - dischargeDate: json['DischargeDate'] , - status: json['Status'] , - vcId: json['VC_ID'] , + dischargeDate: json['DischargeDate'], + status: json['Status'], + vcId: json['VC_ID'], + + arrivalTime: json['ArrivalTime'], + arrivalTimeD: json['ArrivalTimeD'], + callStatus: json['CallStatus'], + callStatusDisc: json['CallStatusDisc'], + callTypeID: json['CallTypeID'], + clientRequestID: json['ClientRequestID'], + clinicName: json['ClinicName'], + consoltationEnd: json['ConsoltationEnd'], + consultationNotes: json['ConsultationNotes'], + patientStatus: json['PatientStatus'], + voipToken: json['VoipToken'], ); } diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index abe8cf58..c5cdddbc 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; @@ -22,10 +24,30 @@ class LiveCarePatientScreen extends StatefulWidget { class _LiveCarePatientScreenState extends State { final _controller = TextEditingController(); + Timer timer; + LiveCarePatientViewModel _liveCareViewModel; + @override + void initState() { + super.initState(); + timer = Timer.periodic(Duration(seconds: 10), (Timer t) { + if(_liveCareViewModel != null){ + _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); + } + }); + } + + @override + void dispose() { + _liveCareViewModel = null; + timer?.cancel(); + super.dispose(); + } + @override Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { + _liveCareViewModel = model; await model.getPendingPatientERForDoctorApp(); }, diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/PatientCard.dart index 8515c115..45445bbf 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/PatientCard.dart @@ -43,15 +43,25 @@ class PatientCard extends StatelessWidget { ), child: CardWithBgWidget( padding: 0, - marginLeft: (!isMyPatient && isInpatient)?0:10, - marginSymmetric:isFromSearch ? 10 : 0.0, + marginLeft: (!isMyPatient && isInpatient) ? 0 : 10, + marginSymmetric: isFromSearch ? 10 : 0.0, hasBorder: false, - bgColor:isFromLiveCare?Colors.white:(isMyPatient && !isFromSearch)?Colors.green[500]: patientInfo.patientStatusType == 43 - ? Colors.green[500] - :isMyPatient? Colors.green[500]:isInpatient?Colors.white:!isFromSearch?Colors.red[800]:Colors.white, + bgColor: isFromLiveCare + ? Colors.white + : (isMyPatient && !isFromSearch) + ? Colors.green[500] + : patientInfo.patientStatusType == 43 + ? Colors.green[500] + : isMyPatient + ? Colors.green[500] + : isInpatient + ? Colors.white + : !isFromSearch + ? Colors.red[800] + : Colors.white, widget: Container( - color: Colors.white, - // padding: EdgeInsets.only(left: 10, right: 0, bottom: 0), + color: Colors.white, + // padding: EdgeInsets.only(left: 10, right: 0, bottom: 0), child: InkWell( child: Column( children: [ @@ -66,67 +76,120 @@ class PatientCard extends StatelessWidget { children: [ patientInfo.patientStatusType == 43 ? Row( - children: [ - AppText( - TranslationBase.of(context).arrivedP, + children: [ + AppText( + TranslationBase.of(context) + .arrivedP, color: Colors.green, fontWeight: FontWeight.bold, fontFamily: 'Poppins', fontSize: 10, ), - SizedBox(width: 8,), - SizedBox(height: 12,width: 1.5,child: Container(color: Colors.grey,),), - SizedBox(width: 8,), - AppText( - patientInfo.status==2? 'Confirmed':'Booked', - color: patientInfo.status==2? Colors.green:Colors.grey , - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 10, - ), - ], - ) - : patientInfo.patientStatusType == 42?Row( - children: [ - AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], + SizedBox( + width: 8, + ), + SizedBox( + height: 12, + width: 1.5, + child: Container( + color: Colors.grey, + ), + ), + SizedBox( + width: 8, + ), + AppText( + patientInfo.status == 2 + ? 'Confirmed' + : 'Booked', + color: patientInfo.status == 2 + ? Colors.green + : Colors.grey, fontWeight: FontWeight.bold, fontFamily: 'Poppins', fontSize: 10, ), - SizedBox(width: 8,), - SizedBox(height: 12,width: 1.5,child: Container(color: Colors.grey,),), - SizedBox(width: 8,), - AppText( - patientInfo.status==2? 'Confirmed':'Booked', - color: patientInfo.status==2? Colors.green:Colors.grey , - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 10, - ), - ], - ): !isFromSearch&&!isFromLiveCare && patientInfo.patientStatusType==null ? Row( - children: [ - AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - SizedBox(width: 8,), - SizedBox(height: 12,width: 1.5,child: Container(color: Colors.grey,),), - SizedBox(width: 8,), - AppText( - patientInfo.status==2? 'Booked':'Confirmed', - color: patientInfo.status==2? Colors.grey:Colors.green , - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - ], - ):SizedBox(), + ], + ) + : patientInfo.patientStatusType == 42 + ? Row( + children: [ + AppText( + TranslationBase.of(context) + .notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 10, + ), + SizedBox( + width: 8, + ), + SizedBox( + height: 12, + width: 1.5, + child: Container( + color: Colors.grey, + ), + ), + SizedBox( + width: 8, + ), + AppText( + patientInfo.status == 2 + ? 'Confirmed' + : 'Booked', + color: patientInfo.status == 2 + ? Colors.green + : Colors.grey, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 10, + ), + ], + ) + : !isFromSearch && + !isFromLiveCare && + patientInfo.patientStatusType == + null + ? Row( + children: [ + AppText( + TranslationBase.of(context) + .notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), + SizedBox( + width: 8, + ), + SizedBox( + height: 12, + width: 1.5, + child: Container( + color: Colors.grey, + ), + ), + SizedBox( + width: 8, + ), + AppText( + patientInfo.status == 2 + ? 'Booked' + : 'Confirmed', + color: + patientInfo.status == 2 + ? Colors.grey + : Colors.green, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ) + ], + ) + : SizedBox(), this.arrivalType == '1' ? AppText( patientInfo.startTime != null @@ -137,27 +200,39 @@ class PatientCard extends StatelessWidget { ) : patientInfo.arrivedOn != null ? AppText( - AppDateUtils.getDayMonthYearDate(AppDateUtils.convertStringToDate(patientInfo.arrivedOn,) - )+" "+ "${AppDateUtils.getStartTime(patientInfo.startTime)}", + AppDateUtils.getDayMonthYearDate( + AppDateUtils + .convertStringToDate( + patientInfo.arrivedOn, + )) + + " " + + "${AppDateUtils.getStartTime(patientInfo.startTime)}", fontFamily: 'Poppins', fontWeight: FontWeight.w400, - fontSize: 15, + fontSize: 15, ) - : (patientInfo.appointmentDate != null && patientInfo.appointmentDate.isNotEmpty)? - AppText( - - "${AppDateUtils.getDayMonthYearDate(AppDateUtils.convertStringToDate(patientInfo.appointmentDate,))} ${AppDateUtils.getStartTime(patientInfo.startTime)}", - fontFamily: 'Poppins', - fontWeight: FontWeight.w400, - fontSize: 15, - ):SizedBox() + : (patientInfo.appointmentDate != + null && + patientInfo + .appointmentDate.isNotEmpty) + ? AppText( + "${AppDateUtils.getDayMonthYearDate(AppDateUtils.convertStringToDate( + patientInfo.appointmentDate, + ))} ${AppDateUtils.getStartTime(patientInfo.startTime)}", + fontFamily: 'Poppins', + fontWeight: FontWeight.w400, + fontSize: 15, + ) + : SizedBox() ], )) : SizedBox(), - if(isInpatient && isMyPatient && !isFromSearch) + if (isInpatient && isMyPatient && !isFromSearch) Row( children: [ - SizedBox(width: 12,), + SizedBox( + width: 12, + ), AppText( 'My Patient', color: Colors.green, @@ -177,9 +252,14 @@ class PatientCard extends StatelessWidget { Expanded( // width: MediaQuery.of(context).size.width*0.51, child: AppText( - isFromLiveCare? Helpers.capitalize(patientInfo.fullName): (Helpers.capitalize(patientInfo.firstName) + - " " + - Helpers.capitalize(patientInfo.lastName)), + isFromLiveCare + ? Helpers.capitalize( + patientInfo.fullName) + : (Helpers.capitalize( + patientInfo.firstName) + + " " + + Helpers.capitalize( + patientInfo.lastName)), fontSize: 16, color: Color(0xff2e303a), fontWeight: FontWeight.w700, @@ -189,12 +269,14 @@ class PatientCard extends StatelessWidget { ), if (patientInfo.gender == 1) Icon( - DoctorApp.male_2, - color: Colors.blue, - ) else Icon( - DoctorApp.female_1, - color: Colors.pink, - ), + DoctorApp.male_2, + color: Colors.blue, + ) + else + Icon( + DoctorApp.female_1, + color: Colors.pink, + ), ]), ), Row( @@ -286,31 +368,30 @@ class PatientCard extends StatelessWidget { ), ), //if (isInpatient) - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 2.0 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: - TranslationBase.of(context).age + - " : ", - style: TextStyle(fontSize: 12)), - new TextSpan( - text: - "${AppDateUtils.getAgeByBirthday(patientInfo.dateofBirth, context, isServerFormat: !isFromLiveCare)}", - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 13)), - ], + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 2.0 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', ), + children: [ + new TextSpan( + text: TranslationBase.of(context).age + + " : ", + style: TextStyle(fontSize: 12)), + new TextSpan( + text: + "${AppDateUtils.getAgeByBirthday(patientInfo.dateofBirth, context, isServerFormat: !isFromLiveCare)}", + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 13)), + ], ), ), - if (isInpatient ) + ), + if (isInpatient) Container( child: RichText( text: new TextSpan( @@ -342,61 +423,75 @@ class PatientCard extends StatelessWidget { text: new TextSpan( style: new TextStyle( fontSize: - 2.0 * SizeConfig.textMultiplier, + 2.0 * SizeConfig.textMultiplier, color: Colors.black, fontFamily: 'Poppins', ), children: [ - new TextSpan( - text: TranslationBase.of(context).numOfDays + " : ", - style: TextStyle(fontSize: 12)), - new TextSpan( - text: "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patientInfo.admissionDate)).inDays + 1}", - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 13)), - ]))), - + new TextSpan( + text: TranslationBase.of(context) + .numOfDays + + " : ", + style: TextStyle(fontSize: 12)), + new TextSpan( + text: + "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patientInfo.admissionDate)).inDays + 1}", + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 13)), + ]))), ])) ]), - !isInpatient && !isFromSearch + isFromLiveCare ? Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Container( - padding: EdgeInsets.all(4), - child: Image.asset( - patientInfo.appointmentType == - 'Regular' && - patientInfo.visitTypeId == 100 - ? 'assets/images/livecare.png' - : patientInfo.appointmentType == - 'Walkin' - ? 'assets/images/walkin.png' - : 'assets/images/booked.png', - height: 25, - width: 35, - )), - ]) - : (isInpatient == true) + Container( + padding: EdgeInsets.all(4), + child: Image.asset( + 'assets/images/livecare.png', + height: 25, + width: 35, + color: Colors.grey.shade700, + )), + ], + ) + : !isInpatient && !isFromSearch ? Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( padding: EdgeInsets.all(4), child: Image.asset( - 'assets/images/inpatient.png', + patientInfo.appointmentType == + 'Regular' && + patientInfo.visitTypeId == 100 + ? 'assets/images/livecare.png' + : patientInfo.appointmentType == + 'Walkin' + ? 'assets/images/walkin.png' + : 'assets/images/booked.png', height: 25, width: 35, )), ]) - : SizedBox() + : (isInpatient == true) + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + padding: EdgeInsets.all(4), + child: Image.asset( + 'assets/images/inpatient.png', + height: 25, + width: 35, + )), + ]) + : SizedBox() ], ), onTap: onTap, )), )); } - - } From 3c325ef19979a78aa49b380a35abc9f415b99516 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 26 May 2021 17:05:08 +0300 Subject: [PATCH 101/241] fix load procedure --- lib/config/localized_values.dart | 2 +- .../procedure/procedure_service.dart | 4 ++-- lib/core/viewModel/procedure_View_model.dart | 12 +++++----- lib/models/patient/patiant_info_model.dart | 2 +- .../profile/lab_result/labs_home_page.dart | 3 ++- .../procedures/add-favourite-procedure.dart | 14 ++++-------- .../procedures/add-procedure-form.dart | 5 +++-- lib/screens/procedures/add_lab_orders.dart | 22 +------------------ .../procedures/add_radiology_order.dart | 21 +----------------- .../procedures/entity_list_fav_procedure.dart | 7 +++--- 10 files changed, 24 insertions(+), 68 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index c5460859..d27f698c 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -123,7 +123,7 @@ const Map> localizedValues = { 'en': 'please enter answer', 'ar': 'الرجاء ادخال اجابة ' }, - 'replay': {'en': 'Replay', 'ar': 'تاكيد'}, + 'replay': {'en': 'Reply', 'ar': 'تاكيد'}, 'progressNote': {'en': 'Progress Note', 'ar': 'ملاحظة التقدم'}, 'progress': {'en': 'Progress', 'ar': 'التقدم'}, 'note': {'en': 'Note', 'ar': 'ملاحظة'}, diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index 9e3d4297..0c284f3d 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -145,10 +145,10 @@ class ProcedureService extends BaseService { }, body: Map()); } - Future getProcedureCategory({String categoryName, String categoryID}) async { + Future getProcedureCategory({String categoryName, String categoryID,patientId}) async { _getProcedureCategoriseReqModel = GetProcedureReqModel( search: ["$categoryName"], - patientMRN: 0, + patientMRN: patientId, pageIndex: 0, clinicId: 0, pageSize: 0, diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 2c75f639..ad62158e 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -84,12 +84,11 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getProcedureCategory({String categoryName, String categoryID}) async { + Future getProcedureCategory({String categoryName, String categoryID, patientId}) async { hasError = false; - //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); await _procedureService.getProcedureCategory( - categoryName: categoryName, categoryID: categoryID); + categoryName: categoryName, categoryID: categoryID,patientId: patientId); if (_procedureService.hasError) { error = _procedureService.error; setState(ViewState.ErrorLocal); @@ -111,7 +110,6 @@ class ProcedureViewModel extends BaseViewModel { Future getProcedureTemplate({String categoryID}) async { hasError = false; - //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); await _procedureService.getProcedureTemplate(categoryID: categoryID); if (_procedureService.hasError) { @@ -135,10 +133,12 @@ class ProcedureViewModel extends BaseViewModel { .procedureTemplate .add(element); } else { - templateList.add(ProcedureTempleteDetailsModelList( + var template = ProcedureTempleteDetailsModelList( templateName: element.templateName, templateId: element.templateID, - template: element)); + template: element); + if(!templateList.contains(template)) + templateList.add(template); } }); print(templateList.length.toString()); diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 0cb067e0..75552184 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -10,7 +10,7 @@ class PatiantInformtion { String arrivalTime; String arrivalTimeD; int callStatus; - Null callStatusDisc; + dynamic callStatusDisc; int callTypeID; String clientRequestID; String clinicName; diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index 5c65ceb4..1ebc4fd3 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/screens/patients/profile/lab_result/laboratory_result_page.dart'; +import 'package:doctor_app_flutter/screens/procedures/add_lab_home_screen.dart'; import 'package:doctor_app_flutter/screens/procedures/add_lab_orders.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; @@ -111,7 +112,7 @@ class _LabsHomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddSelectedLabOrder( + builder: (context) => AddLabHomeScreen( patient: patient, model: model, )), diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index ac355a85..9b5a97ad 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -46,12 +46,8 @@ class _AddFavouriteProcedureState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) async { - // TODO mosa_change - // if (model.procedureTemplate.length == 0) { - model.getProcedureTemplate(); - // } - }, + onModelReady: (model) => + model.getProcedureTemplate(categoryID: widget.categoryID), builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -61,14 +57,12 @@ class _AddFavouriteProcedureState extends State { Container( height: MediaQuery.of(context).size.height * 0.070, ), - if (model.procedureTemplate.length != 0) + if (model.templateList.length != 0) Expanded( child: NetworkBaseView( baseViewModel: model, child: EntityListCheckboxSearchFavProceduresWidget( - model: widget.model, - // masterList: widget.model.procedureTemplate, - //TODO change it to the new model + model: model, removeFavProcedure: (item) { setState(() { entityList.remove(item); diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index 844ff246..354ada19 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -203,6 +203,7 @@ class _AddSelectedProcedureState extends State { if (procedureName.text.isNotEmpty && procedureName.text.length >= 3) model.getProcedureCategory( + patientId: patient.patientId, categoryName: procedureName.text); else @@ -223,8 +224,8 @@ class _AddSelectedProcedureState extends State { if (procedureName.text.isNotEmpty && procedureName.text.length >= 3) model.getProcedureCategory( - categoryName: - procedureName.text); + patientId: patient.patientId, + categoryName: procedureName.text); else DrAppToastMsg.showErrorToast( TranslationBase.of(context) diff --git a/lib/screens/procedures/add_lab_orders.dart b/lib/screens/procedures/add_lab_orders.dart index a4cb4e68..b8d4e7c7 100644 --- a/lib/screens/procedures/add_lab_orders.dart +++ b/lib/screens/procedures/add_lab_orders.dart @@ -138,7 +138,7 @@ class _AddSelectedLabOrderState extends State { final screenSize = MediaQuery.of(context).size; return BaseView( onModelReady: (model) => model.getProcedureCategory( - categoryName: "Laboratory", categoryID: "02"), + categoryName: "Laboratory", categoryID: "02",patientId: patient.patientId), builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -158,26 +158,6 @@ class _AddSelectedLabOrderState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context).applyForNewLabOrder, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - - InkWell( - child: Icon( - Icons.close, - size: 28.0, - ), - onTap: () { - Navigator.pop(context); - }, - ), - ], - ), SizedBox( height: 10.0, ), diff --git a/lib/screens/procedures/add_radiology_order.dart b/lib/screens/procedures/add_radiology_order.dart index 78e91ba8..dc68aacc 100644 --- a/lib/screens/procedures/add_radiology_order.dart +++ b/lib/screens/procedures/add_radiology_order.dart @@ -141,7 +141,7 @@ class _AddSelectedRadiologyOrderState extends State { final screenSize = MediaQuery.of(context).size; return BaseView( onModelReady: (model) => model.getProcedureCategory( - categoryName: "Radiology", categoryID: "03"), + categoryName: "Radiology", categoryID: "03",patientId: patient.patientId), builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -161,25 +161,6 @@ class _AddSelectedRadiologyOrderState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context).newRadiologyOrder, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 28.0, - ), - onTap: () { - Navigator.pop(context); - }, - ), - ], - ), SizedBox( height: 10.0, ), diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index c5189a48..822726ce 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -61,14 +61,13 @@ class _EntityListCheckboxSearchFavProceduresWidgetState } List items = List(); - List itemss = List(); List itemsProcedure = List(); List remarksList = List(); List typeList = List(); @override void initState() { - items.addAll(widget.masterList); + //items.addAll(widget.masterList); super.initState(); } @@ -103,9 +102,9 @@ class _EntityListCheckboxSearchFavProceduresWidgetState SizedBox( height: 15, ), - items.length != 0 + widget.model.templateList.length != 0 ? Column( - children: itemss.map((historyInfo) { + children: widget.model.templateList.map((historyInfo) { return ExpansionProcedure( procedureTempleteModel: historyInfo, model: widget.model, From e336821f65820259f288e48fa857cf4914f832af Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 27 May 2021 15:43:47 +0300 Subject: [PATCH 102/241] fix lab result --- lib/config/localized_values.dart | 2 +- .../profile/lab_result/laboratory_result_page.dart | 12 +++++++----- .../patients/profile/lab_result/labs_home_page.dart | 4 ++-- lib/screens/procedures/add_radiology_screen.dart | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d27f698c..231e7f9b 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -932,7 +932,7 @@ const Map> localizedValues = { "ar": "تقدم بطلب جديد للمختبر الأشعة" }, "addLabOrder": {"en": "Add Lab Order", "ar": "إضافة طلب معمل"}, - "addRadiologyOrder": {"en": "Add Radiology Order", "ar": "إضافة اشغة"}, + "addRadiologyOrder": {"en": "Add Radiology Order", "ar": "إضافة اشعة"}, "newRadiologyOrder": {"en": "New Radiology Order", "ar": "طلب الأشعة الجديد"}, "orderDate": {"en": "Order Date", "ar": "تاريخ الطلب"}, "examType": {"en": "Exam Type", "ar": "نوع الفحص"}, diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 3aae6e69..5f79038f 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -14,13 +14,15 @@ class LaboratoryResultPage extends StatefulWidget { final PatiantInformtion patient; final String patientType; final String arrivalType; + final bool isInpatient; LaboratoryResultPage( {Key key, this.patientLabOrders, this.patient, this.patientType, - this.arrivalType}); + this.arrivalType, + this.isInpatient}); @override _LaboratoryResultPageState createState() => _LaboratoryResultPageState(); @@ -40,7 +42,7 @@ class _LaboratoryResultPageState extends State { onModelReady: (model) => model.getPatientLabResult( patientLabOrder: widget.patientLabOrders, patient: widget.patient, - isInpatient: widget.patientType =="1"), + isInpatient: true), builder: (_, model, w) => AppScaffold( isShowAppBar: true, appBar: PatientProfileHeaderWhitAppointmentAppBar( @@ -64,9 +66,9 @@ class _LaboratoryResultPageState extends State { LaboratoryResultWidget( onTap: () async {}, billNo: widget.patientLabOrders.invoiceNo, - details: model - .patientLabSpecialResult.length > 0 ? model - .patientLabSpecialResult[0].resultDataHTML : null, + details: model.patientLabSpecialResult.length > 0 + ? model.patientLabSpecialResult[0].resultDataHTML + : null, orderNo: widget.patientLabOrders.orderNo, patientLabOrder: widget.patientLabOrders, patient: widget.patient, diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index 1ebc4fd3..578e9f17 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -181,9 +181,9 @@ class _LabsHomePageState extends State { context, FadePage( page: LaboratoryResultPage( - patientLabOrders: - model.patientLabOrdersList[index], + patientLabOrders: model.patientLabOrdersList[index], patient: patient, + isInpatient:isInpatient, arrivalType: arrivalType, patientType: patientType, ), diff --git a/lib/screens/procedures/add_radiology_screen.dart b/lib/screens/procedures/add_radiology_screen.dart index ac21e7d9..26308553 100644 --- a/lib/screens/procedures/add_radiology_screen.dart +++ b/lib/screens/procedures/add_radiology_screen.dart @@ -77,7 +77,7 @@ class _AddRadiologyScreenState extends State mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - TranslationBase.of(context).addLabOrder, + TranslationBase.of(context).addRadiologyOrder, fontWeight: FontWeight.w700, fontSize: 20, ), @@ -147,8 +147,8 @@ class _AddRadiologyScreenState extends State AddFavouriteProcedure( patient: patient, model: model, - addButtonTitle: TranslationBase.of(context).addLabOrder, - toolbarTitle: TranslationBase.of(context).applyForNewLabOrder, + addButtonTitle: TranslationBase.of(context).addRadiologyOrder, + toolbarTitle: TranslationBase.of(context).addRadiologyOrder, categoryID: "03", ), AddSelectedRadiologyOrder( From 54fbe76c7b90bada6d9ae440767725815d96f668 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 27 May 2021 15:56:43 +0300 Subject: [PATCH 103/241] medical report fixes and vital sign --- .../MedicalReport/MeidcalReportModel.dart | 38 +++- .../MedicalReportDetailPage.dart | 10 +- .../medical_report/MedicalReportPage.dart | 214 ++++++++++-------- .../vital_sign/vital_sign_details_screen.dart | 2 +- .../vital_sign_item_details_screen.dart | 2 +- 5 files changed, 168 insertions(+), 98 deletions(-) diff --git a/lib/models/patient/MedicalReport/MeidcalReportModel.dart b/lib/models/patient/MedicalReport/MeidcalReportModel.dart index 450b93f6..473140d1 100644 --- a/lib/models/patient/MedicalReport/MeidcalReportModel.dart +++ b/lib/models/patient/MedicalReport/MeidcalReportModel.dart @@ -6,10 +6,19 @@ class MedicalReportModel { String invoiceNo; int status; String verifiedOn; - int verifiedBy; + String verifiedBy; String editedOn; int editedBy; int lineItemNo; + String createdOn; + int templateID; + int doctorID; + int doctorGender; + String doctorGenderDescription; + String doctorGenderDescriptionN; + String doctorImageURL; + String doctorName; + String doctorNameN; String reportDataHtml; MedicalReportModel( @@ -24,6 +33,15 @@ class MedicalReportModel { this.editedOn, this.editedBy, this.lineItemNo, + this.createdOn, + this.templateID, + this.doctorID, + this.doctorGender, + this.doctorGenderDescription, + this.doctorGenderDescriptionN, + this.doctorImageURL, + this.doctorName, + this.doctorNameN, this.reportDataHtml}); MedicalReportModel.fromJson(Map json) { @@ -38,6 +56,15 @@ class MedicalReportModel { editedOn = json['EditedOn']; editedBy = json['EditedBy']; lineItemNo = json['LineItemNo']; + createdOn = json['CreatedOn']; + templateID = json['TemplateID']; + doctorID = json['DoctorID']; + doctorGender = json['DoctorGender']; + doctorGenderDescription = json['DoctorGenderDescription']; + doctorGenderDescriptionN = json['DoctorGenderDescriptionN']; + doctorImageURL = json['DoctorImageURL']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; reportDataHtml = json['ReportDataHtml']; } @@ -54,6 +81,15 @@ class MedicalReportModel { data['EditedOn'] = this.editedOn; data['EditedBy'] = this.editedBy; data['LineItemNo'] = this.lineItemNo; + data['CreatedOn'] = this.createdOn; + data['TemplateID'] = this.templateID; + data['DoctorID'] = this.doctorID; + data['DoctorGender'] = this.doctorGender; + data['DoctorGenderDescription'] = this.doctorGenderDescription; + data['DoctorGenderDescriptionN'] = this.doctorGenderDescriptionN; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; data['ReportDataHtml'] = this.reportDataHtml; return data; } diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index 1233fe98..e63f39eb 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; @@ -23,10 +24,11 @@ class MedicalReportDetailPage extends StatelessWidget { String arrivalType = routeArgs['arrivalType']; MedicalReportModel medicalReport = routeArgs['medicalReport']; - return BaseView( + return BaseView( builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileHeaderNewDesignAppBar( patient, patientType, @@ -57,7 +59,7 @@ class MedicalReportDetailPage extends StatelessWidget { ], ), ), - Container( + medicalReport.reportDataHtml != null ? Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), @@ -73,8 +75,10 @@ class MedicalReportDetailPage extends StatelessWidget { ), ), child: Html( - data: medicalReport.reportDataHtml + data: medicalReport.reportDataHtml ?? "" ), + ) : Container( + ), ], ), diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index b54d4837..eb078dd5 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -17,6 +17,7 @@ import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; import 'package:provider/provider.dart'; import '../../../../routes.dart'; @@ -84,113 +85,142 @@ class MedicalReportPage extends StatelessWidget { }, label: TranslationBase.of(context).createNewMedicalReport, ), - // if (model.state == ViewState.ErrorLocal) - // Container( - // child: ErrorMessage(error: model.error), - // ), if (model.state != ViewState.ErrorLocal) ...List.generate( model.medicalReportList.length, - (index) => CardWithBgWidget( - hasBorder: false, - bgColor: model.medicalReportList[index].status == 1 - ? Colors.red[700] - : Colors.green[700], - widget: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - model.medicalReportList[index].status == 1 - ? TranslationBase.of(context).onHold - : TranslationBase.of(context).verified, - color: model.medicalReportList[index].status == 1 - ? Colors.red[700] - : Colors.green[700], - ), - AppText( - "Jammal" ?? "", - fontSize: 15, - bold: true, - ), - ], - )), - Expanded( - child: Column( + (index) => Container( + margin: EdgeInsets.symmetric(horizontal: 8), + child: CardWithBgWidget( + hasBorder: false, + bgColor: model.medicalReportList[index].status == 1 + ? Colors.red[700] + : Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + model.medicalReportList[index].status == 1 + ? TranslationBase.of(context).onHold + : TranslationBase.of(context).verified, + color: + model.medicalReportList[index].status == + 1 + ? Colors.red[700] + : Colors.green[700], + fontSize: 1.4 * SizeConfig.textMultiplier, + bold: true, + ), + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index] + .doctorNameN + : model.medicalReportList[index] + .doctorName, + fontSize: 1.9 * SizeConfig.textMultiplier, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A), + ), + ], + )), + Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ AppText( - '${AppDateUtils.convertDateFromServerFormat( - model.medicalReportList[index].editedOn, - "dd/MM/yyyy")}', - color: Colors.black, + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "dd MMM yyyy")}', + color: Color(0xFF2E303A), fontWeight: FontWeight.w600, - fontSize: 14, + fontSize: 1.6 * SizeConfig.textMultiplier, ), AppText( - '${AppDateUtils.convertDateFromServerFormat( - model.medicalReportList[index].editedOn, - "hh:mm a")}', + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "hh:mm a")}', + color: Color(0xFF2E303A), fontWeight: FontWeight.w600, - color: Colors.grey[700], - fontSize: 14, + fontSize: 1.5 * SizeConfig.textMultiplier, ), ], ), - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - child: LargeAvatar( - name: "Jammal", - url: null, + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Container( + margin: EdgeInsets.only( + left: 0, top: 4, right: 8, bottom: 0), + child: LargeAvatar( + name: projectViewModel.isArabic + ? model + .medicalReportList[index].doctorNameN + : model + .medicalReportList[index].doctorName, + url: model + .medicalReportList[index].doctorImageURL, + ), + width: 50, + height: 50, ), - width: 55, - height: 55, - ), - Expanded(child: AppText("")), - InkWell( - onTap: () { - if (model.medicalReportList[index].status == - 1) { - Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_INSERT, - arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'medicalReport': - model.medicalReportList[index] - }); - } else { - Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_DETAIL, - arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'medicalReport': - model.medicalReportList[index] - }); - } - }, - child: Icon( - model.medicalReportList[index].status == 1 - ? EvaIcons.eye - : DoctorApp.edit_1, + Expanded( + child: Container( + height: 50, + child: AppText( + TranslationBase.of(context).showDetail, + fontSize: 1.4 * SizeConfig.textMultiplier, + ), + ), + // child: Html( + // data: model.medicalReportList[index] + // .reportDataHtml ?? + // ""), ), - ) - ], - ), - ], + Container( + child: InkWell( + onTap: () { + if (model.medicalReportList[index].status == + 1) { + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_DETAIL, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'medicalReport': + model.medicalReportList[index] + }); + } else { + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_INSERT, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'type': MedicalReportStatus.ADD, + 'medicalReport': + model.medicalReportList[index] + }); + } + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon( + model.medicalReportList[index].status == + 1 + ? EvaIcons.eye + : DoctorApp.edit_1, + ), + ], + ), + ), + ) + ], + ), + ], + ), ), ), ), diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index 33f9a1cb..e8314816 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -57,7 +57,7 @@ class VitalSignDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient.patientDetails?.firstName??''}'s", + "${patient.firstName ?? patient.patientDetails != null ? patient.patientDetails.firstName : patient.fullName}'s", fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 343d0590..9e6663de 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -202,7 +202,7 @@ class VitalSignItemDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient.patientDetails.firstName}'s", + "${patient.firstName ?? patient.patientDetails != null ? patient.patientDetails.firstName : patient.fullName}'s", fontFamily: 'Poppins', fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w600, From 6e660883f66bdfeca5a89435775e5a30fc9d2420 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 27 May 2021 16:12:17 +0300 Subject: [PATCH 104/241] Fix medical report --- .../MedicalReportDetailPage.dart | 4 +- .../medical_report/MedicalReportPage.dart | 235 +++++++++--------- 2 files changed, 121 insertions(+), 118 deletions(-) diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index e63f39eb..7bf6f1d9 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -10,6 +10,8 @@ import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.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/dr_app_embedded_error.dart'; +import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:provider/provider.dart'; @@ -78,7 +80,7 @@ class MedicalReportDetailPage extends StatelessWidget { data: medicalReport.reportDataHtml ?? "" ), ) : Container( - + child: ErrorMessage(error: "No Data",), ), ], ), diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index eb078dd5..746068ad 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -88,122 +88,122 @@ class MedicalReportPage extends StatelessWidget { if (model.state != ViewState.ErrorLocal) ...List.generate( model.medicalReportList.length, - (index) => Container( - margin: EdgeInsets.symmetric(horizontal: 8), - child: CardWithBgWidget( - hasBorder: false, - bgColor: model.medicalReportList[index].status == 1 - ? Colors.red[700] - : Colors.green[700], - widget: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - model.medicalReportList[index].status == 1 - ? TranslationBase.of(context).onHold - : TranslationBase.of(context).verified, - color: - model.medicalReportList[index].status == - 1 - ? Colors.red[700] - : Colors.green[700], - fontSize: 1.4 * SizeConfig.textMultiplier, - bold: true, - ), - AppText( - projectViewModel.isArabic - ? model.medicalReportList[index] - .doctorNameN - : model.medicalReportList[index] - .doctorName, - fontSize: 1.9 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700, - color: Color(0xFF2E303A), - ), - ], - )), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - AppText( - '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "dd MMM yyyy")}', - color: Color(0xFF2E303A), - fontWeight: FontWeight.w600, - fontSize: 1.6 * SizeConfig.textMultiplier, - ), - AppText( - '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "hh:mm a")}', - color: Color(0xFF2E303A), - fontWeight: FontWeight.w600, - fontSize: 1.5 * SizeConfig.textMultiplier, - ), - ], - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Container( - margin: EdgeInsets.only( - left: 0, top: 4, right: 8, bottom: 0), - child: LargeAvatar( - name: projectViewModel.isArabic - ? model - .medicalReportList[index].doctorNameN - : model - .medicalReportList[index].doctorName, - url: model - .medicalReportList[index].doctorImageURL, + (index) => InkWell( + onTap: (){ + if (model.medicalReportList[index].status == + 1) { + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_DETAIL, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'medicalReport': + model.medicalReportList[index] + }); + } else { + Navigator.of(context).pushNamed( + PATIENT_MEDICAL_REPORT_INSERT, + arguments: { + 'patient': patient, + 'patientType': patientType, + 'arrivalType': arrivalType, + 'type': MedicalReportStatus.ADD, + 'medicalReport': + model.medicalReportList[index] + }); + } + }, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 8), + child: CardWithBgWidget( + hasBorder: false, + bgColor: model.medicalReportList[index].status == 1 + ? Colors.red[700] + : Colors.green[700], + widget: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + model.medicalReportList[index].status == 1 + ? TranslationBase.of(context).onHold + : TranslationBase.of(context).verified, + color: + model.medicalReportList[index].status == + 1 + ? Colors.red[700] + : Colors.green[700], + fontSize: 1.4 * SizeConfig.textMultiplier, + bold: true, + ), + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index] + .doctorNameN + : model.medicalReportList[index] + .doctorName, + fontSize: 1.9 * SizeConfig.textMultiplier, + fontWeight: FontWeight.w700, + color: Color(0xFF2E303A), + ), + ], + )), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + AppText( + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "dd MMM yyyy")}', + color: Color(0xFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.6 * SizeConfig.textMultiplier, + ), + AppText( + '${AppDateUtils.convertDateFromServerFormat(model.medicalReportList[index].editedOn ?? model.medicalReportList[index].createdOn, "hh:mm a")}', + color: Color(0xFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.5 * SizeConfig.textMultiplier, + ), + ], ), - width: 50, - height: 50, - ), - Expanded( - child: Container( + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Container( + margin: EdgeInsets.only( + left: 0, top: 4, right: 8, bottom: 0), + child: LargeAvatar( + name: projectViewModel.isArabic + ? model + .medicalReportList[index].doctorNameN + : model + .medicalReportList[index].doctorName, + url: model + .medicalReportList[index].doctorImageURL, + ), + width: 50, height: 50, - child: AppText( - TranslationBase.of(context).showDetail, - fontSize: 1.4 * SizeConfig.textMultiplier, + ), + Expanded( + child: Container( + height: 50, + child: AppText( + TranslationBase.of(context).showDetail, + fontSize: 1.4 * SizeConfig.textMultiplier, + ), ), + // child: Html( + // data: model.medicalReportList[index] + // .reportDataHtml ?? + // ""), ), - // child: Html( - // data: model.medicalReportList[index] - // .reportDataHtml ?? - // ""), - ), - Container( - child: InkWell( - onTap: () { - if (model.medicalReportList[index].status == - 1) { - Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_DETAIL, - arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'medicalReport': - model.medicalReportList[index] - }); - } else { - Navigator.of(context).pushNamed( - PATIENT_MEDICAL_REPORT_INSERT, - arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'medicalReport': - model.medicalReportList[index] - }); - } - }, + Container( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -215,15 +215,16 @@ class MedicalReportPage extends StatelessWidget { ), ], ), - ), - ) - ], - ), - ], + ) + ], + ), + ], + ), ), ), ), ), + SizedBox(height: 15,) ], ), ), From 59e06f53af3e003b72506f00bc1e016e1afa2149 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 27 May 2021 16:33:57 +0300 Subject: [PATCH 105/241] hot fix --- .../patients/profile/vital_sign/vital_sign_details_screen.dart | 2 +- .../profile/vital_sign/vital_sign_item_details_screen.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index e8314816..37a7a60f 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -57,7 +57,7 @@ class VitalSignDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient.patientDetails != null ? patient.patientDetails.firstName : patient.fullName}'s", + "${patient.firstName ?? patient?.patientDetails?.firstName?? patient.fullName?? ''}'s", fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 9e6663de..49f82c2f 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -202,7 +202,7 @@ class VitalSignItemDetailsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - "${patient.firstName ?? patient.patientDetails != null ? patient.patientDetails.firstName : patient.fullName}'s", + "${patient.firstName ?? patient?.patientDetails?.firstName?? patient.fullName?? ''}'s", fontFamily: 'Poppins', fontSize: SizeConfig.textMultiplier * 1.6, fontWeight: FontWeight.w600, From 13fb50f9be283a1c3a2cb3abea3fe0744b476e0a Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 30 May 2021 14:59:13 +0300 Subject: [PATCH 106/241] prescription refactoring --- lib/screens/prescription/add_prescription_form.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index 894d7c33..3fd1fbb3 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -145,13 +145,10 @@ class _PrescriptionFormWidgetState extends State { dynamic box; dynamic x; - List indicationList; - @override void initState() { super.initState(); selectedType = 1; - indicationList = List(); } setSelectedType(int val) { @@ -348,9 +345,7 @@ class _PrescriptionFormWidgetState extends State { height: MediaQuery.of(context).size.height * 0.5, child: ListView.builder( padding: const EdgeInsets.only(top: 20), - scrollDirection: Axis.vertical, - // shrinkWrap: true, itemCount: model.allMedicationList == null ? 0 : model.allMedicationList.length, From c82a4a05d548df090eb91bee7a4edb941bb8e4e8 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 31 May 2021 10:36:44 +0300 Subject: [PATCH 107/241] medical report design changes --- .../MedicalReport/MeidcalReportModel.dart | 20 +++++ .../medical_report/MedicalReportPage.dart | 76 ++++++++++++------- lib/widgets/patients/PatientCard.dart | 29 +++++++ 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/lib/models/patient/MedicalReport/MeidcalReportModel.dart b/lib/models/patient/MedicalReport/MeidcalReportModel.dart index 473140d1..1acbc1b4 100644 --- a/lib/models/patient/MedicalReport/MeidcalReportModel.dart +++ b/lib/models/patient/MedicalReport/MeidcalReportModel.dart @@ -2,6 +2,8 @@ class MedicalReportModel { String reportData; String setupID; int projectID; + String projectName; + String projectNameN; int patientID; String invoiceNo; int status; @@ -19,12 +21,17 @@ class MedicalReportModel { String doctorImageURL; String doctorName; String doctorNameN; + int clinicID; + String clinicName; + String clinicNameN; String reportDataHtml; MedicalReportModel( {this.reportData, this.setupID, this.projectID, + this.projectName, + this.projectNameN, this.patientID, this.invoiceNo, this.status, @@ -42,12 +49,17 @@ class MedicalReportModel { this.doctorImageURL, this.doctorName, this.doctorNameN, + this.clinicID, + this.clinicName, + this.clinicNameN, this.reportDataHtml}); MedicalReportModel.fromJson(Map json) { reportData = json['ReportData']; setupID = json['SetupID']; projectID = json['ProjectID']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; patientID = json['PatientID']; invoiceNo = json['InvoiceNo']; status = json['Status']; @@ -65,6 +77,9 @@ class MedicalReportModel { doctorImageURL = json['DoctorImageURL']; doctorName = json['DoctorName']; doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + clinicNameN = json['ClinicNameN']; reportDataHtml = json['ReportDataHtml']; } @@ -73,6 +88,8 @@ class MedicalReportModel { data['ReportData'] = this.reportData; data['SetupID'] = this.setupID; data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['ProjectNameN'] = this.projectNameN; data['PatientID'] = this.patientID; data['InvoiceNo'] = this.invoiceNo; data['Status'] = this.status; @@ -90,6 +107,9 @@ class MedicalReportModel { data['DoctorImageURL'] = this.doctorImageURL; data['DoctorName'] = this.doctorName; data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['ClinicNameN'] = this.clinicNameN; data['ReportDataHtml'] = this.reportDataHtml; return data; } diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 746068ad..e2da651b 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -89,17 +89,15 @@ class MedicalReportPage extends StatelessWidget { ...List.generate( model.medicalReportList.length, (index) => InkWell( - onTap: (){ - if (model.medicalReportList[index].status == - 1) { + onTap: () { + if (model.medicalReportList[index].status == 1) { Navigator.of(context).pushNamed( PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, - 'medicalReport': - model.medicalReportList[index] + 'medicalReport': model.medicalReportList[index] }); } else { Navigator.of(context).pushNamed( @@ -109,8 +107,7 @@ class MedicalReportPage extends StatelessWidget { 'patientType': patientType, 'arrivalType': arrivalType, 'type': MedicalReportStatus.ADD, - 'medicalReport': - model.medicalReportList[index] + 'medicalReport': model.medicalReportList[index] }); } }, @@ -132,12 +129,13 @@ class MedicalReportPage extends StatelessWidget { AppText( model.medicalReportList[index].status == 1 ? TranslationBase.of(context).onHold - : TranslationBase.of(context).verified, - color: - model.medicalReportList[index].status == - 1 - ? Colors.red[700] - : Colors.green[700], + : TranslationBase.of(context) + .verified, + color: model.medicalReportList[index] + .status == + 1 + ? Colors.red[700] + : Colors.green[700], fontSize: 1.4 * SizeConfig.textMultiplier, bold: true, ), @@ -173,37 +171,55 @@ class MedicalReportPage extends StatelessWidget { ], ), Row( - crossAxisAlignment: CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( margin: EdgeInsets.only( left: 0, top: 4, right: 8, bottom: 0), child: LargeAvatar( name: projectViewModel.isArabic - ? model - .medicalReportList[index].doctorNameN - : model - .medicalReportList[index].doctorName, - url: model - .medicalReportList[index].doctorImageURL, + ? model.medicalReportList[index] + .doctorNameN + : model.medicalReportList[index] + .doctorName, + url: model.medicalReportList[index] + .doctorImageURL, ), width: 50, height: 50, ), Expanded( child: Container( - height: 50, - child: AppText( - TranslationBase.of(context).showDetail, - fontSize: 1.4 * SizeConfig.textMultiplier, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index] + .projectNameN + : model.medicalReportList[index] + .projectName, + fontSize: + 1.6 * SizeConfig.textMultiplier, + color: Color(0xFF2E303A), + ), + AppText( + projectViewModel.isArabic + ? model.medicalReportList[index] + .clinicNameN + : model.medicalReportList[index] + .clinicName, + fontSize: + 1.6 * SizeConfig.textMultiplier, + color: Color(0xFF2E303A), + ), + ], ), ), - // child: Html( - // data: model.medicalReportList[index] - // .reportDataHtml ?? - // ""), ), Container( + height: 50, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -224,7 +240,9 @@ class MedicalReportPage extends StatelessWidget { ), ), ), - SizedBox(height: 15,) + SizedBox( + height: 15, + ) ], ), ), diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/PatientCard.dart index 45445bbf..2174e6d5 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/PatientCard.dart @@ -440,6 +440,35 @@ class PatientCard extends StatelessWidget { fontWeight: FontWeight.w700, fontSize: 13)), ]))), + if (isFromLiveCare) + Column( + children: [ + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 2.0 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: + TranslationBase.of(context).clinic + + " : ", + style: TextStyle(fontSize: 12)), + new TextSpan( + text: + patientInfo.clinicName, + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 13)), + ], + ), + ), + ), + ], + ), ])) ]), isFromLiveCare From dc6cbdd1889b4114389c4aede5c6b017b2c8db68 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 31 May 2021 16:44:05 +0300 Subject: [PATCH 108/241] Add ChangeCallStatus services --- .../Service/SessionStatusAPI.java | 15 -- .../ui/VideoCallContract.java | 18 --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 6 +- .../Model/ChangeCallStatusRequestModel.java | 137 ++++++++++++++++++ .../hmgDr}/Model/GetSessionStatusModel.java | 2 +- .../hmg/hmgDr}/Model/SessionStatusModel.java | 2 +- .../com/hmg/hmgDr}/Service/AppRetrofit.java | 2 +- .../hmg/hmgDr/Service/SessionStatusAPI.java | 19 +++ .../com/hmg/hmgDr}/ui/VideoCallActivity.java | 14 +- .../com/hmg/hmgDr/ui/VideoCallContract.java | 24 +++ .../hmg/hmgDr}/ui/VideoCallPresenterImpl.java | 32 +++- 11 files changed, 224 insertions(+), 47 deletions(-) delete mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java delete mode 100644 android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java rename android/app/src/main/{java/com/example/doctor_app_flutter => kotlin/com/hmg/hmgDr}/Model/GetSessionStatusModel.java (98%) rename android/app/src/main/{java/com/example/doctor_app_flutter => kotlin/com/hmg/hmgDr}/Model/SessionStatusModel.java (98%) rename android/app/src/main/{java/com/example/doctor_app_flutter => kotlin/com/hmg/hmgDr}/Service/AppRetrofit.java (97%) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java rename android/app/src/main/{java/com/example/doctor_app_flutter => kotlin/com/hmg/hmgDr}/ui/VideoCallActivity.java (95%) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java rename android/app/src/main/{java/com/example/doctor_app_flutter => kotlin/com/hmg/hmgDr}/ui/VideoCallPresenterImpl.java (56%) diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java b/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java deleted file mode 100644 index fbc8d1d3..00000000 --- a/android/app/src/main/java/com/example/doctor_app_flutter/Service/SessionStatusAPI.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.doctor_app_flutter.Service; - -import com.example.doctor_app_flutter.Model.GetSessionStatusModel; -import com.example.doctor_app_flutter.Model.SessionStatusModel; - - -import retrofit2.Call; -import retrofit2.http.Body; -import retrofit2.http.POST; - -public interface SessionStatusAPI { - - @POST("LiveCareApi/DoctorApp/GetSessionStatus") - Call getSessionStatusModelData(@Body GetSessionStatusModel getSessionStatusModel); -} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java b/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java deleted file mode 100644 index 21122239..00000000 --- a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallContract.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.doctor_app_flutter.ui; - -import com.example.doctor_app_flutter.Model.GetSessionStatusModel; -import com.example.doctor_app_flutter.Model.SessionStatusModel; - -public interface VideoCallContract { - - interface VideoCallView{ - - void onCallSuccessful(SessionStatusModel sessionStatusModel); - void onFailure(); - } - - interface VideoCallPresenter { - - void callClintConnected(GetSessionStatusModel statusModel); - } -} diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index aed21dd3..612118c9 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -3,9 +3,9 @@ package com.hmg.hmgDr import android.app.Activity import android.content.Intent import androidx.annotation.NonNull -import com.example.doctor_app_flutter.Model.GetSessionStatusModel -import com.example.doctor_app_flutter.Model.SessionStatusModel -import com.example.doctor_app_flutter.ui.VideoCallActivity +import com.hmg.hmgDr.Model.GetSessionStatusModel +import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.ui.VideoCallActivity import com.google.gson.GsonBuilder import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java new file mode 100644 index 00000000..5fcdb611 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/ChangeCallStatusRequestModel.java @@ -0,0 +1,137 @@ +package com.hmg.hmgDr.Model; + + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + + +public class ChangeCallStatusRequestModel implements Parcelable { + + @SerializedName("CallStatus") + @Expose + private Integer callStatus; + @SerializedName("DoctorId") + @Expose + private Integer doctorId; + @SerializedName("generalid") + @Expose + private String generalid; + @SerializedName("TokenID") + @Expose + private String tokenID; + @SerializedName("VC_ID") + @Expose + private Integer vcId; + + public ChangeCallStatusRequestModel(Integer callStatus, Integer doctorId, String generalid, String tokenID, Integer vcId) { + this.callStatus = callStatus; + this.doctorId = doctorId; + this.generalid = generalid; + this.tokenID = tokenID; + this.vcId = vcId; + } + + protected ChangeCallStatusRequestModel(Parcel in) { + if (in.readByte() == 0) { + callStatus = null; + } else { + callStatus = in.readInt(); + } + if (in.readByte() == 0) { + doctorId = null; + } else { + doctorId = in.readInt(); + } + generalid = in.readString(); + tokenID = in.readString(); + if (in.readByte() == 0) { + vcId = null; + } else { + vcId = in.readInt(); + } + } + + public static final Creator CREATOR = new Creator() { + @Override + public ChangeCallStatusRequestModel createFromParcel(Parcel in) { + return new ChangeCallStatusRequestModel(in); + } + + @Override + public ChangeCallStatusRequestModel[] newArray(int size) { + return new ChangeCallStatusRequestModel[size]; + } + }; + + public Integer getCallStatus() { + return callStatus; + } + + public void setCallStatus(Integer callStatus) { + this.callStatus = callStatus; + } + + public Integer getDoctorId() { + return doctorId; + } + + public void setDoctorId(Integer doctorId) { + this.doctorId = doctorId; + } + + public String getGeneralid() { + return generalid; + } + + public void setGeneralid(String generalid) { + this.generalid = generalid; + } + + public String getTokenID() { + return tokenID; + } + + public void setTokenID(String tokenID) { + this.tokenID = tokenID; + } + + public Integer getVcId() { + return vcId; + } + + public void setVcId(Integer vcId) { + this.vcId = vcId; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + if (callStatus == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(callStatus); + } + if (doctorId == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(doctorId); + } + dest.writeString(generalid); + dest.writeString(tokenID); + if (vcId == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(vcId); + } + } +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Model/GetSessionStatusModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java similarity index 98% rename from android/app/src/main/java/com/example/doctor_app_flutter/Model/GetSessionStatusModel.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java index 8f83b7b9..d41aa146 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/Model/GetSessionStatusModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java @@ -1,4 +1,4 @@ -package com.example.doctor_app_flutter.Model; +package com.hmg.hmgDr.Model; import android.os.Parcel; import android.os.Parcelable; diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java similarity index 98% rename from android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java index da6bba1d..51b0b1ee 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/Model/SessionStatusModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/SessionStatusModel.java @@ -1,4 +1,4 @@ -package com.example.doctor_app_flutter.Model; +package com.hmg.hmgDr.Model; import android.os.Parcel; import android.os.Parcelable; diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/AppRetrofit.java similarity index 97% rename from android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/Service/AppRetrofit.java index 6646bd6f..9ca9abc1 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/Service/AppRetrofit.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/AppRetrofit.java @@ -1,4 +1,4 @@ -package com.example.doctor_app_flutter.Service; +package com.hmg.hmgDr.Service; import android.app.Activity; import android.app.Application; diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java new file mode 100644 index 00000000..e507650e --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/SessionStatusAPI.java @@ -0,0 +1,19 @@ +package com.hmg.hmgDr.Service; + +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.Model.GetSessionStatusModel; +import com.hmg.hmgDr.Model.SessionStatusModel; + + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.POST; + +public interface SessionStatusAPI { + + @POST("LiveCareApi/DoctorApp/GetSessionStatus") + Call getSessionStatusModelData(@Body GetSessionStatusModel getSessionStatusModel); + + @POST("LiveCareApi/DoctorApp/ChangeCallStatus") + Call changeCallStatus(@Body ChangeCallStatusRequestModel changeCallStatusRequestModel); +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java similarity index 95% rename from android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index 0b6adadb..e196e7f1 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -1,4 +1,4 @@ -package com.example.doctor_app_flutter.ui; +package com.hmg.hmgDr.ui; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -20,8 +20,9 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; -import com.example.doctor_app_flutter.Model.GetSessionStatusModel; -import com.example.doctor_app_flutter.Model.SessionStatusModel; +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.Model.GetSessionStatusModel; +import com.hmg.hmgDr.Model.SessionStatusModel; import com.hmg.hmgDr.R; import com.opentok.android.Session; import com.opentok.android.Stream; @@ -277,6 +278,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } isConnected = true; subscribeToStream(stream); + videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); } @Override @@ -369,6 +371,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi if (countDownTimer != null) { countDownTimer.cancel(); } + videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(16,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); finish(); } @@ -423,6 +426,11 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } + @Override + public void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel) { + + } + @Override public void onFailure() { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java new file mode 100644 index 00000000..2b099551 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallContract.java @@ -0,0 +1,24 @@ +package com.hmg.hmgDr.ui; + +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.Model.GetSessionStatusModel; +import com.hmg.hmgDr.Model.SessionStatusModel; + +public interface VideoCallContract { + + interface VideoCallView { + + void onCallSuccessful(SessionStatusModel sessionStatusModel); + + void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel); + + void onFailure(); + } + + interface VideoCallPresenter { + + void callClintConnected(GetSessionStatusModel statusModel); + + void callChangeCallStatus(ChangeCallStatusRequestModel statusModel); + } +} diff --git a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java similarity index 56% rename from android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java rename to android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java index 363d1ca8..ea2128ba 100644 --- a/android/app/src/main/java/com/example/doctor_app_flutter/ui/VideoCallPresenterImpl.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallPresenterImpl.java @@ -1,9 +1,10 @@ -package com.example.doctor_app_flutter.ui; +package com.hmg.hmgDr.ui; -import com.example.doctor_app_flutter.Model.GetSessionStatusModel; -import com.example.doctor_app_flutter.Model.SessionStatusModel; -import com.example.doctor_app_flutter.Service.AppRetrofit; -import com.example.doctor_app_flutter.Service.SessionStatusAPI; +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; +import com.hmg.hmgDr.Model.GetSessionStatusModel; +import com.hmg.hmgDr.Model.SessionStatusModel; +import com.hmg.hmgDr.Service.AppRetrofit; +import com.hmg.hmgDr.Service.SessionStatusAPI; import org.jetbrains.annotations.NotNull; @@ -46,4 +47,25 @@ public class VideoCallPresenterImpl implements VideoCallContract.VideoCallPresen }); } + + @Override + public void callChangeCallStatus(ChangeCallStatusRequestModel statusModel) { + sessionStatusAPI = AppRetrofit.getRetrofit(baseUrl).create(SessionStatusAPI.class); + + Call call = sessionStatusAPI.changeCallStatus(statusModel); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + if (!response.isSuccessful()) + view.onFailure(); + + } + + @Override + public void onFailure(@NotNull Call call, @NotNull Throwable t) { + view.onFailure(); + } + }); + } } From 9454e9d8affc47a8ed54c0b5dcd712337d8e5dbd Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 31 May 2021 16:59:28 +0300 Subject: [PATCH 109/241] working on procedure refactoring --- lib/config/localized_values.dart | 8 + .../procedure/procedure_service.dart | 2 +- .../radiology/radiology_service.dart | 3 + .../profile/lab_result/labs_home_page.dart | 14 +- .../radiology/radiology_home_page.dart | 38 +-- lib/screens/procedures/ProcedureType.dart | 5 + .../procedures/add-favourite-procedure.dart | 4 - .../procedures/add-procedure-form.dart | 142 ++++++------ .../procedures/add_lab_home_screen.dart | 218 ----------------- .../procedures/add_radiology_screen.dart | 219 ------------------ ....dart => base_add_procedure_tab_page.dart} | 110 +++++++-- lib/screens/procedures/procedure_screen.dart | 13 +- lib/util/translations_delegate_base.dart | 6 + 13 files changed, 215 insertions(+), 567 deletions(-) create mode 100644 lib/screens/procedures/ProcedureType.dart delete mode 100644 lib/screens/procedures/add_lab_home_screen.dart delete mode 100644 lib/screens/procedures/add_radiology_screen.dart rename lib/screens/procedures/{add_procedure_homeScreen.dart => base_add_procedure_tab_page.dart} (60%) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 231e7f9b..4d3c0e78 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -651,6 +651,10 @@ const Map> localizedValues = { 'en': "add Selected Procedures", 'ar': "اضافة العمليات المختارة " }, + 'addProcedures': { + 'en': "Add Procedure", + 'ar': "اضافة العمليات" + }, 'updateProcedure': {'en': "Update Procedure", 'ar': "تحديث العملية"}, 'orderProcedure': {'en': "order procedure", 'ar': "طلب العمليات"}, 'nameOrICD': {'en': "Name or ICD", 'ar': "الاسم او  ICD"}, @@ -998,4 +1002,8 @@ const Map> localizedValues = { "onHold": {"en": "On Hold", "ar": "قيد الانتظار"}, "verified": {"en": "Verified", "ar": "تم التحقق"}, "endCall": {"en": "End Call", "ar": "انهاء"}, + "favoriteTemplates": {"en": "Favorite Templates", "ar": "القوالب المفضلة"}, + "allProcedures": {"en": "All Procedures", "ar": "كل الإجراءات"}, + "allRadiology": {"en": "All Radiology", "ar": "كل الأشعة"}, + "allLab": {"en": "All Lab", "ar": "كل المختبرات"}, }; diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index 0c284f3d..526b2b3e 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -66,7 +66,7 @@ class ProcedureService extends BaseService { Future getProcedureTemplate( {int doctorId, int projectId, int clinicId, String categoryID}) async { _procedureTempleteRequestModel = ProcedureTempleteRequestModel( - tokenID: "@dm!n", + // tokenID: "@dm!n", patientID: 0, searchType: 1, ); diff --git a/lib/core/service/patient_medical_file/radiology/radiology_service.dart b/lib/core/service/patient_medical_file/radiology/radiology_service.dart index 7cf17753..df646ca9 100644 --- a/lib/core/service/patient_medical_file/radiology/radiology_service.dart +++ b/lib/core/service/patient_medical_file/radiology/radiology_service.dart @@ -46,6 +46,9 @@ class RadiologyService extends BaseService { if (isInPatient) { label = "List_GetRadOreders"; } + if(response[label] == null || response[label].length == 0){ + label = "FinalRadiologyList"; + } response[label].forEach((radiology) { finalRadiologyList.add(FinalRadiology.fromJson(radiology)); }); diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index 578e9f17..db3e6c21 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -3,8 +3,8 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/screens/patients/profile/lab_result/laboratory_result_page.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_lab_home_screen.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_lab_orders.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; +import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -112,10 +112,12 @@ class _LabsHomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddLabHomeScreen( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.LAB_RESULT, + ), + ), ); }, label: TranslationBase.of(context).applyForNewLabOrder, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 4e969793..9f93df35 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -3,8 +3,8 @@ import 'package:doctor_app_flutter/core/viewModel/project_view_model.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/screens/patients/profile/radiology/radiology_details_page.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_radiology_order.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_radiology_screen.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; +import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; @@ -100,9 +100,7 @@ class _RadiologyHomePageState extends State { fontSize: 13, ), AppText( - TranslationBase - .of(context) - .result, + TranslationBase.of(context).result, bold: true, fontSize: 22, ), @@ -110,18 +108,19 @@ class _RadiologyHomePageState extends State { ), ), if ((patient.patientStatusType != null && - patient.patientStatusType == 43) || + patient.patientStatusType == 43) || (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => - AddRadiologyScreen( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.RADIOLOGY, + ), + ), ); }, label: TranslationBase.of(context).applyForRadiologyOrder, @@ -153,11 +152,18 @@ class _RadiologyHomePageState extends State { ? Colors.black : Color(0xffa9a089), borderRadius: BorderRadius.only( - topLeft: projectViewModel.isArabic? Radius.circular(0):Radius.circular(8), - bottomLeft: projectViewModel.isArabic? Radius.circular(0):Radius.circular(8), - topRight: projectViewModel.isArabic? Radius.circular(8):Radius.circular(0), - bottomRight: projectViewModel.isArabic? Radius.circular(8):Radius.circular(0) - ), + topLeft: projectViewModel.isArabic + ? Radius.circular(0) + : Radius.circular(8), + bottomLeft: projectViewModel.isArabic + ? Radius.circular(0) + : Radius.circular(8), + topRight: projectViewModel.isArabic + ? Radius.circular(8) + : Radius.circular(0), + bottomRight: projectViewModel.isArabic + ? Radius.circular(8) + : Radius.circular(0)), ), child: RotatedBox( quarterTurns: 3, diff --git a/lib/screens/procedures/ProcedureType.dart b/lib/screens/procedures/ProcedureType.dart new file mode 100644 index 00000000..e05fb7e1 --- /dev/null +++ b/lib/screens/procedures/ProcedureType.dart @@ -0,0 +1,5 @@ +enum ProcedureType { + PROCEDURE, + LAB_RESULT, + RADIOLOGY, +} \ No newline at end of file diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index 9b5a97ad..a68336c7 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -1,12 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add_procedure_homeScreen.dart'; -import 'package:doctor_app_flutter/screens/procedures/entity_list_checkbox_search_widget.dart'; import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; import 'package:doctor_app_flutter/screens/procedures/procedure_checkout_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart index 354ada19..ba2ec3de 100644 --- a/lib/screens/procedures/add-procedure-form.dart +++ b/lib/screens/procedures/add-procedure-form.dart @@ -17,81 +17,9 @@ import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; +import 'ProcedureType.dart'; import 'entity_list_checkbox_search_widget.dart'; -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, - List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -postProcedure( - {ProcedureViewModel model, - String remarks, - String orderType, - PatiantInformtion patient, - List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = List(); - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId]; - List controls = List(); - controls.add( - Controls( - code: "remarks", - controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: element.type ?? "1"), - ); - controlsProcedure.add(Procedures( - category: element.categoryID, - procedure: element.procedureId, - controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast( - model.valadteProcedureList[0].entityList[0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - void addSelectedProcedure( context, ProcedureViewModel model, PatiantInformtion patient) { showModalBottomSheet( @@ -108,8 +36,9 @@ void addSelectedProcedure( class AddSelectedProcedure extends StatefulWidget { final ProcedureViewModel model; final PatiantInformtion patient; + final ProcedureType procedureType; - const AddSelectedProcedure({Key key, this.model, this.patient}) + const AddSelectedProcedure({Key key, this.model, this.patient, this.procedureType}) : super(key: key); @override @@ -352,4 +281,69 @@ class _AddSelectedProcedureState extends State { ), ); } + + postProcedure( + {ProcedureViewModel model, + String remarks, + String orderType, + PatiantInformtion patient, + List entityList, + ProcedureType procedureType}) async { + PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); + ProcedureValadteRequestModel procedureValadteRequestModel = + new ProcedureValadteRequestModel(); + procedureValadteRequestModel.patientMRN = patient.patientMRN; + procedureValadteRequestModel.episodeID = patient.episodeNo; + procedureValadteRequestModel.appointmentNo = patient.appointmentNo; + + List controlsProcedure = List(); + + postProcedureReqModel.appointmentNo = patient.appointmentNo; + postProcedureReqModel.episodeID = patient.episodeNo; + postProcedureReqModel.patientMRN = patient.patientMRN; + + entityList.forEach((element) { + procedureValadteRequestModel.procedure = [element.procedureId]; + List controls = List(); + controls.add( + Controls( + code: "remarks", + controlValue: element.remarks != null ? element.remarks : ""), + ); + controls.add( + Controls(code: "ordertype", controlValue: procedureType == + ProcedureType.PROCEDURE ? element.type ?? "1" : "0"), + ); + controlsProcedure.add(Procedures( + category: element.categoryID, + procedure: element.procedureId, + controls: controls)); + }); + + postProcedureReqModel.procedures = controlsProcedure; + await model.valadteProcedure(procedureValadteRequestModel); + if (model.state == ViewState.Idle) { + if (model.valadteProcedureList[0].entityList.length == 0) { + await model.postProcedure(postProcedureReqModel, patient.patientMRN); + + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + model.getProcedure(mrn: patient.patientMRN); + } else if (model.state == ViewState.Idle) { + DrAppToastMsg.showSuccesToast('procedure has been added'); + } + } else { + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + model.getProcedure(mrn: patient.patientMRN); + } else if (model.state == ViewState.Idle) { + Helpers.showErrorToast( + model.valadteProcedureList[0].entityList[0].warringMessages); + } + } + } else { + Helpers.showErrorToast(model.error); + } + } + } diff --git a/lib/screens/procedures/add_lab_home_screen.dart b/lib/screens/procedures/add_lab_home_screen.dart deleted file mode 100644 index d86c4ecd..00000000 --- a/lib/screens/procedures/add_lab_home_screen.dart +++ /dev/null @@ -1,218 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'add_lab_orders.dart'; - -class AddLabHomeScreen extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - const AddLabHomeScreen({Key key, this.model, this.patient}) : super(key: key); - @override - _AddLabHomeScreenState createState() => - _AddLabHomeScreenState(patient: patient, model: model); -} - -class _AddLabHomeScreenState extends State - with SingleTickerProviderStateMixin { - _AddLabHomeScreenState({this.patient, this.model}); - ProcedureViewModel model; - PatiantInformtion patient; - TabController _tabController; - int _activeTab = 0; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - _tabController.addListener(_handleTabSelection); - } - - @override - void dispose() { - super.dispose(); - _tabController.dispose(); - } - - _handleTabSelection() { - setState(() { - _activeTab = _tabController.index; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: - (BuildContext context, ScrollController scrollController) { - return Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - 'Add Procedure', - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Expanded( - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight( - MediaQuery.of(context).size.height * 0.070), - child: Container( - height: - MediaQuery.of(context).size.height * 0.070, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.5), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorColor: Colors.transparent, - indicatorWeight: 1.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only( - top: 0, left: 0, right: 0, bottom: 0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - tabWidget( - screenSize, - _activeTab == 0, - "Favorite Templates", - ), - tabWidget( - screenSize, - _activeTab == 1, - 'All Lab', - ), - ], - ), - ), - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AddFavouriteProcedure( - patient: patient, - model: model, - addButtonTitle: TranslationBase.of(context).addLabOrder, - toolbarTitle: TranslationBase.of(context).applyForNewLabOrder, - categoryID: "02", - ), - AddSelectedLabOrder( - model: model, - patient: patient, - ), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ), - ), - ); - } - - Widget tabWidget(Size screenSize, bool isActive, String title, - {int counter = -1}) { - return 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: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - title, - fontSize: SizeConfig.textMultiplier * 1.5, - color: isActive ? Colors.white : Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - if (counter != -1) - Container( - margin: EdgeInsets.all(4), - width: 15, - height: 15, - decoration: BoxDecoration( - color: isActive ? Colors.white : Color(0xFFD02127), - shape: BoxShape.circle, - ), - child: Center( - child: FittedBox( - child: AppText( - "$counter", - fontSize: SizeConfig.textMultiplier * 1.5, - color: !isActive ? Colors.white : Color(0xFFD02127), - fontWeight: FontWeight.w700, - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/procedures/add_radiology_screen.dart b/lib/screens/procedures/add_radiology_screen.dart deleted file mode 100644 index 26308553..00000000 --- a/lib/screens/procedures/add_radiology_screen.dart +++ /dev/null @@ -1,219 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'add_lab_orders.dart'; -import 'add_radiology_order.dart'; - -class AddRadiologyScreen extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - const AddRadiologyScreen({Key key, this.model, this.patient}) : super(key: key); - @override - _AddRadiologyScreenState createState() => - _AddRadiologyScreenState(patient: patient, model: model); -} - -class _AddRadiologyScreenState extends State - with SingleTickerProviderStateMixin { - _AddRadiologyScreenState({this.patient, this.model}); - ProcedureViewModel model; - PatiantInformtion patient; - TabController _tabController; - int _activeTab = 0; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - _tabController.addListener(_handleTabSelection); - } - - @override - void dispose() { - super.dispose(); - _tabController.dispose(); - } - - _handleTabSelection() { - setState(() { - _activeTab = _tabController.index; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: - (BuildContext context, ScrollController scrollController) { - return Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context).addRadiologyOrder, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Expanded( - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight( - MediaQuery.of(context).size.height * 0.070), - child: Container( - height: - MediaQuery.of(context).size.height * 0.070, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.5), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorColor: Colors.transparent, - indicatorWeight: 1.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only( - top: 0, left: 0, right: 0, bottom: 0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - tabWidget( - screenSize, - _activeTab == 0, - "Favorite Templates", - ), - tabWidget( - screenSize, - _activeTab == 1, - 'All Radiology', - ), - ], - ), - ), - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AddFavouriteProcedure( - patient: patient, - model: model, - addButtonTitle: TranslationBase.of(context).addRadiologyOrder, - toolbarTitle: TranslationBase.of(context).addRadiologyOrder, - categoryID: "03", - ), - AddSelectedRadiologyOrder( - model: model, - patient: patient, - ), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ), - ), - ); - } - - Widget tabWidget(Size screenSize, bool isActive, String title, - {int counter = -1}) { - return 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: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - title, - fontSize: SizeConfig.textMultiplier * 1.5, - color: isActive ? Colors.white : Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - if (counter != -1) - Container( - margin: EdgeInsets.all(4), - width: 15, - height: 15, - decoration: BoxDecoration( - color: isActive ? Colors.white : Color(0xFFD02127), - shape: BoxShape.circle, - ), - child: Center( - child: FittedBox( - child: AppText( - "$counter", - fontSize: SizeConfig.textMultiplier * 1.5, - color: !isActive ? Colors.white : Color(0xFFD02127), - fontWeight: FontWeight.w700, - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/base_add_procedure_tab_page.dart similarity index 60% rename from lib/screens/procedures/add_procedure_homeScreen.dart rename to lib/screens/procedures/base_add_procedure_tab_page.dart index 39ed4b25..4d25de2b 100644 --- a/lib/screens/procedures/add_procedure_homeScreen.dart +++ b/lib/screens/procedures/base_add_procedure_tab_page.dart @@ -2,30 +2,41 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.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/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -class AddProcedureHome extends StatefulWidget { +import 'ProcedureType.dart'; +import 'add-favourite-procedure.dart'; +import 'add-procedure-form.dart'; +import 'add_lab_orders.dart'; +import 'add_radiology_order.dart'; + +class BaseAddProcedureTabPage extends StatefulWidget { final ProcedureViewModel model; final PatiantInformtion patient; - const AddProcedureHome({Key key, this.model, this.patient}) : super(key: key); + final ProcedureType procedureType; + + const BaseAddProcedureTabPage( + {Key key, this.model, this.patient, this.procedureType}) + : super(key: key); + @override - _AddProcedureHomeState createState() => - _AddProcedureHomeState(patient: patient, model: model); + _BaseAddProcedureTabPageState createState() => + _BaseAddProcedureTabPageState(patient: patient, model: model, procedureType: procedureType); } -class _AddProcedureHomeState extends State +class _BaseAddProcedureTabPageState extends State with SingleTickerProviderStateMixin { - _AddProcedureHomeState({this.patient, this.model}); - ProcedureViewModel model; - PatiantInformtion patient; + final ProcedureViewModel model; + final PatiantInformtion patient; + final ProcedureType procedureType; + + _BaseAddProcedureTabPageState({this.patient, this.model, this.procedureType}); + TabController _tabController; int _activeTab = 0; @@ -50,11 +61,9 @@ class _AddProcedureHomeState extends State @override Widget build(BuildContext context) { - //final routeArgs = ModalRoute.of(context).settings.arguments as Map; - //PatiantInformtion patient = routeArgs['patient']; final screenSize = MediaQuery.of(context).size; + return BaseView( - //onModelReady: (model) => model.getCategory(), builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( isShowAppBar: false, @@ -77,7 +86,13 @@ class _AddProcedureHomeState extends State mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - 'Add Procedure', + procedureType == ProcedureType.PROCEDURE + ? TranslationBase.of(context).addProcedures + : procedureType == ProcedureType.RADIOLOGY + ? TranslationBase.of(context) + .addRadiologyOrder + : TranslationBase.of(context) + .addLabOrder, fontWeight: FontWeight.w700, fontSize: 20, ), @@ -125,12 +140,21 @@ class _AddProcedureHomeState extends State tabWidget( screenSize, _activeTab == 0, - "Favorite Templates", + TranslationBase.of(context) + .favoriteTemplates, ), tabWidget( screenSize, _activeTab == 1, - 'All Procedures', + procedureType == ProcedureType.PROCEDURE + ? TranslationBase.of(context) + .allProcedures + : procedureType == + ProcedureType.RADIOLOGY + ? TranslationBase.of(context) + .allRadiology + : TranslationBase.of(context) + .allLab, ), ], ), @@ -147,13 +171,49 @@ class _AddProcedureHomeState extends State AddFavouriteProcedure( patient: patient, model: model, - addButtonTitle: TranslationBase.of(context).addSelectedProcedures, - toolbarTitle: 'Add Procedure', - ), - AddSelectedProcedure( - model: model, - patient: patient, + addButtonTitle: procedureType == + ProcedureType.PROCEDURE + ? TranslationBase.of(context) + .addProcedures + : procedureType == + ProcedureType.RADIOLOGY + ? TranslationBase.of(context) + .addRadiologyOrder + : TranslationBase.of(context) + .addLabOrder, + toolbarTitle: procedureType == + ProcedureType.PROCEDURE + ? TranslationBase.of(context) + .addProcedures + : procedureType == + ProcedureType.RADIOLOGY + ? TranslationBase.of(context) + .addRadiologyOrder + : TranslationBase.of(context) + .addLabOrder, + categoryID: procedureType == + ProcedureType.PROCEDURE + ? null + : procedureType == + ProcedureType.RADIOLOGY + ? "03" + : "02", ), + procedureType == ProcedureType.PROCEDURE + ? AddSelectedProcedure( + model: model, + patient: patient, + ) + : procedureType == + ProcedureType.RADIOLOGY + ? AddSelectedRadiologyOrder( + model: model, + patient: patient, + ) + : AddSelectedLabOrder( + model: model, + patient: patient, + ), ], ), ), @@ -177,7 +237,7 @@ class _AddProcedureHomeState extends State child: Container( height: screenSize.height * 0.070, decoration: TextFieldsUtils.containerBorderDecoration( - isActive ? Color(0xFFD02127 /*B8382B*/) : Color(0xFFEAEAEA), + isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), borderRadius: 4, borderWidth: 0), @@ -216,3 +276,5 @@ class _AddProcedureHomeState extends State ); } } + + diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index f6752c4a..756a19a0 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -5,7 +5,6 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.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/screens/procedures/add_procedure_homeScreen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -15,6 +14,8 @@ import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'ProcedureCard.dart'; +import 'ProcedureType.dart'; +import 'base_add_procedure_tab_page.dart'; class ProcedureScreen extends StatelessWidget { int doctorNameP; @@ -107,10 +108,12 @@ class ProcedureScreen extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddProcedureHome( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.PROCEDURE, + ), + ), ); }, child: Container( diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 9ed00146..78041705 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1035,6 +1035,8 @@ class TranslationBase { String get addSelectedProcedures => localizedValues['addSelectedProcedures'][locale.languageCode]; + String get addProcedures => + localizedValues['addProcedures'][locale.languageCode]; String get updateProcedure => localizedValues['updateProcedure'][locale.languageCode]; @@ -1355,6 +1357,10 @@ class TranslationBase { String get impressionRecommendation => localizedValues['impressionRecommendation'][locale.languageCode]; String get onHold => localizedValues['onHold'][locale.languageCode]; String get verified => localizedValues['verified'][locale.languageCode]; + String get favoriteTemplates => localizedValues['favoriteTemplates'][locale.languageCode]; + String get allProcedures => localizedValues['allProcedures'][locale.languageCode]; + String get allRadiology => localizedValues['allRadiology'][locale.languageCode]; + String get allLab => localizedValues['allLab'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 519e6f2fec046bb2cfe07d81dc5a1c2cdf894daa Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 1 Jun 2021 12:51:50 +0300 Subject: [PATCH 110/241] Prescription favourite templates --- lib/core/viewModel/medicine_view_model.dart | 75 +- lib/core/viewModel/procedure_View_model.dart | 136 +--- .../add_favourite_prescription.dart | 119 +++ .../prescription/add_prescription_form.dart | 4 +- .../prescription_checkout_screen.dart | 760 ++++++++++++++++++ .../prescription_home_screen.dart | 203 +++++ .../prescription/prescriptions_page.dart | 77 +- .../procedures/ExpansionProcedure.dart | 118 +-- .../procedures/entity_list_fav_procedure.dart | 38 +- 9 files changed, 1292 insertions(+), 238 deletions(-) create mode 100644 lib/screens/prescription/add_favourite_prescription.dart create mode 100644 lib/screens/prescription/prescription_checkout_screen.dart create mode 100644 lib/screens/prescription/prescription_home_screen.dart diff --git a/lib/core/viewModel/medicine_view_model.dart b/lib/core/viewModel/medicine_view_model.dart index d49b8cc3..8ccf1a70 100644 --- a/lib/core/viewModel/medicine_view_model.dart +++ b/lib/core/viewModel/medicine_view_model.dart @@ -1,8 +1,10 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/service/patient_medical_file/prescription/medicine_service.dart'; import 'package:doctor_app_flutter/core/service/patient_medical_file/prescription/prescription_service.dart'; +import 'package:doctor_app_flutter/core/service/patient_medical_file/procedure/procedure_service.dart'; import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/GetAssessmentResModel.dart'; @@ -11,9 +13,12 @@ import '../../locator.dart'; import 'base_view_model.dart'; class MedicineViewModel extends BaseViewModel { + bool hasError = false; MedicineService _medicineService = locator(); + ProcedureService _procedureService = locator(); PrescriptionService _prescriptionService = locator(); - + List get procedureTemplate => _procedureService.templateList; + List templateList = List(); get pharmacyItemsList => _medicineService.pharmacyItemsList; get searchText => _medicineService.searchText; get pharmaciesList => _medicineService.pharmaciesList; @@ -27,20 +32,15 @@ class MedicineViewModel extends BaseViewModel { get medicationFrequencyList => _prescriptionService.medicationFrequencyList; get boxQuintity => _prescriptionService.boxQuantity; - get medicationIndicationsList => - _prescriptionService.medicationIndicationsList; + get medicationIndicationsList => _prescriptionService.medicationIndicationsList; get medicationDoseTimeList => _prescriptionService.medicationDoseTimeList; - List get patientAssessmentList => - _prescriptionService.patientAssessmentList; + List get patientAssessmentList => _prescriptionService.patientAssessmentList; - List get allMedicationList => - _prescriptionService.allMedicationList; + List get allMedicationList => _prescriptionService.allMedicationList; List get itemMedicineList => _prescriptionService.itemMedicineList; - List get itemMedicineListRoute => - _prescriptionService.itemMedicineListRoute; - List get itemMedicineListUnit => - _prescriptionService.itemMedicineListUnit; + List get itemMedicineListRoute => _prescriptionService.itemMedicineListRoute; + List get itemMedicineListUnit => _prescriptionService.itemMedicineListUnit; Future getItem({int itemID}) async { //hasError = false; @@ -54,6 +54,35 @@ class MedicineViewModel extends BaseViewModel { setState(ViewState.Idle); } + setTemplateListDependOnId() { + procedureTemplate.forEach((element) { + List templateListData = + templateList.where((elementTemplate) => elementTemplate.templateId == element.templateID).toList(); + + if (templateListData.length != 0) { + templateList[templateList.indexOf(templateListData[0])].procedureTemplate.add(element); + } else { + var template = ProcedureTempleteDetailsModelList( + templateName: element.templateName, templateId: element.templateID, template: element); + if (!templateList.contains(template)) templateList.add(template); + } + }); + print(templateList.length.toString()); + } + + Future getProcedureTemplate({String categoryID}) async { + hasError = false; + setState(ViewState.Busy); + await _procedureService.getProcedureTemplate(categoryID: categoryID); + if (_procedureService.hasError) { + error = _procedureService.error; + setState(ViewState.ErrorLocal); + } else { + setTemplateListDependOnId(); + setState(ViewState.Idle); + } + } + Future getPrescription({int mrn}) async { //hasError = false; //_insuranceCardService.clearInsuranceCard(); @@ -86,8 +115,7 @@ class MedicineViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getPatientAssessment( - GetAssessmentReqModel getAssessmentReqModel) async { + Future getPatientAssessment(GetAssessmentReqModel getAssessmentReqModel) async { setState(ViewState.Busy); await _prescriptionService.getPatientAssessment(getAssessmentReqModel); if (_prescriptionService.hasError) { @@ -99,8 +127,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationStrength() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationStrength); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationStrength); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -110,8 +137,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationRoute() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationRoute); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationRoute); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -121,8 +147,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationIndications() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationIndications); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationIndications); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -132,8 +157,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationDoseTime() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationDoseTime); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationDoseTime); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -143,8 +167,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationFrequency() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationFrequency); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationFrequency); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -154,8 +177,7 @@ class MedicineViewModel extends BaseViewModel { Future getMedicationDuration() async { setState(ViewState.Busy); - await _prescriptionService - .getMasterLookup(MasterKeysService.MedicationDuration); + await _prescriptionService.getMasterLookup(MasterKeysService.MedicationDuration); if (_prescriptionService.hasError) { error = _prescriptionService.error; setState(ViewState.Error); @@ -163,8 +185,7 @@ class MedicineViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getBoxQuantity( - {int itemCode, int duration, double strength, int freq}) async { + Future getBoxQuantity({int itemCode, int duration, double strength, int freq}) async { setState(ViewState.Busy); await _prescriptionService.calculateBoxQuantity( strength: strength, itemCode: itemCode, duration: duration, freq: freq); diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index ad62158e..cb3a2a7e 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -28,14 +28,11 @@ class ProcedureViewModel extends BaseViewModel { bool hasError = false; ProcedureService _procedureService = locator(); - List get procedureList => - _procedureService.procedureList; + List get procedureList => _procedureService.procedureList; - List get valadteProcedureList => - _procedureService.valadteProcedureList; + List get valadteProcedureList => _procedureService.valadteProcedureList; - List get categoriesList => - _procedureService.categoriesList; + List get categoriesList => _procedureService.categoriesList; List get categoryList => _procedureService.categoryList; RadiologyService _radiologyService = locator(); @@ -44,25 +41,18 @@ class ProcedureViewModel extends BaseViewModel { List _finalRadiologyListHospital = List(); List get finalRadiologyList => - filterType == FilterType.Clinic - ? _finalRadiologyListClinic - : _finalRadiologyListHospital; + filterType == FilterType.Clinic ? _finalRadiologyListClinic : _finalRadiologyListHospital; - List get radiologyList => - _radiologyService.finalRadiologyList; + List get radiologyList => _radiologyService.finalRadiologyList; - List get patientLabOrdersList => - _labsService.patientLabOrdersList; + List get patientLabOrdersList => _labsService.patientLabOrdersList; - List get labOrdersResultsList => - _labsService.labOrdersResultsList; + List get labOrdersResultsList => _labsService.labOrdersResultsList; - List get procedureTemplate => - _procedureService.templateList; + List get procedureTemplate => _procedureService.templateList; List templateList = List(); - List get procedureTemplateDetails => - _procedureService.templateDetailsList; + List get procedureTemplateDetails => _procedureService.templateDetailsList; List _patientLabOrdersListClinic = List(); List _patientLabOrdersListHospital = List(); @@ -88,7 +78,7 @@ class ProcedureViewModel extends BaseViewModel { hasError = false; setState(ViewState.Busy); await _procedureService.getProcedureCategory( - categoryName: categoryName, categoryID: categoryID,patientId: patientId); + categoryName: categoryName, categoryID: categoryID, patientId: patientId); if (_procedureService.hasError) { error = _procedureService.error; setState(ViewState.ErrorLocal); @@ -123,22 +113,15 @@ class ProcedureViewModel extends BaseViewModel { setTemplateListDependOnId() { procedureTemplate.forEach((element) { - List templateListData = templateList - .where((elementTemplate) => - elementTemplate.templateId == element.templateID) - .toList(); + List templateListData = + templateList.where((elementTemplate) => elementTemplate.templateId == element.templateID).toList(); if (templateListData.length != 0) { - templateList[templateList.indexOf(templateListData[0])] - .procedureTemplate - .add(element); + templateList[templateList.indexOf(templateListData[0])].procedureTemplate.add(element); } else { var template = ProcedureTempleteDetailsModelList( - templateName: element.templateName, - templateId: element.templateID, - template: element); - if(!templateList.contains(template)) - templateList.add(template); + templateName: element.templateName, templateId: element.templateID, template: element); + if (!templateList.contains(template)) templateList.add(template); } }); print(templateList.length.toString()); @@ -159,8 +142,7 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future postProcedure( - PostProcedureReqModel postProcedureReqModel, int mrn) async { + Future postProcedure(PostProcedureReqModel postProcedureReqModel, int mrn) async { hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); @@ -174,8 +156,7 @@ class ProcedureViewModel extends BaseViewModel { } } - Future valadteProcedure( - ProcedureValadteRequestModel procedureValadteRequestModel) async { + Future valadteProcedure(ProcedureValadteRequestModel procedureValadteRequestModel) async { hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); @@ -188,9 +169,7 @@ class ProcedureViewModel extends BaseViewModel { } } - Future updateProcedure( - {UpdateProcedureRequestModel updateProcedureRequestModel, - int mrn}) async { + Future updateProcedure({UpdateProcedureRequestModel updateProcedureRequestModel, int mrn}) async { hasError = false; //_insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); @@ -203,11 +182,9 @@ class ProcedureViewModel extends BaseViewModel { //await getProcedure(mrn: mrn); } - void getPatientRadOrders(PatiantInformtion patient, - {String patientType, bool isInPatient = false}) async { + void getPatientRadOrders(PatiantInformtion patient, {String patientType, bool isInPatient = false}) async { setState(ViewState.Busy); - await _radiologyService.getPatientRadOrders(patient, - isInPatient: isInPatient); + await _radiologyService.getPatientRadOrders(patient, isInPatient: isInPatient); if (_radiologyService.hasError) { error = _radiologyService.error; if (patientType == "7") @@ -216,39 +193,32 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); } else { _radiologyService.finalRadiologyList.forEach((element) { - List finalRadiologyListClinic = - _finalRadiologyListClinic - .where((elementClinic) => - elementClinic.filterName == element.clinicDescription) - .toList(); + List finalRadiologyListClinic = _finalRadiologyListClinic + .where((elementClinic) => elementClinic.filterName == element.clinicDescription) + .toList(); if (finalRadiologyListClinic.length != 0) { - _finalRadiologyListClinic[ - finalRadiologyListClinic.indexOf(finalRadiologyListClinic[0])] + _finalRadiologyListClinic[finalRadiologyListClinic.indexOf(finalRadiologyListClinic[0])] .finalRadiologyList .add(element); } else { - _finalRadiologyListClinic.add(FinalRadiologyList( - filterName: element.clinicDescription, finalRadiology: element)); + _finalRadiologyListClinic + .add(FinalRadiologyList(filterName: element.clinicDescription, finalRadiology: element)); } // FinalRadiologyList list sort via project - List finalRadiologyListHospital = - _finalRadiologyListHospital - .where( - (elementClinic) => - elementClinic.filterName == element.projectName, - ) - .toList(); + List finalRadiologyListHospital = _finalRadiologyListHospital + .where( + (elementClinic) => elementClinic.filterName == element.projectName, + ) + .toList(); if (finalRadiologyListHospital.length != 0) { - _finalRadiologyListHospital[finalRadiologyListHospital - .indexOf(finalRadiologyListHospital[0])] + _finalRadiologyListHospital[finalRadiologyListHospital.indexOf(finalRadiologyListHospital[0])] .finalRadiologyList .add(element); } else { - _finalRadiologyListHospital.add(FinalRadiologyList( - filterName: element.projectName, finalRadiology: element)); + _finalRadiologyListHospital.add(FinalRadiologyList(filterName: element.projectName, finalRadiology: element)); } }); @@ -258,17 +228,10 @@ class ProcedureViewModel extends BaseViewModel { String get radImageURL => _radiologyService.url; - getRadImageURL( - {int invoiceNo, - int lineItem, - int projectId, - @required PatiantInformtion patient}) async { + getRadImageURL({int invoiceNo, int lineItem, int projectId, @required PatiantInformtion patient}) async { setState(ViewState.Busy); await _radiologyService.getRadImageURL( - invoiceNo: invoiceNo, - lineItem: lineItem, - projectId: projectId, - patient: patient); + invoiceNo: invoiceNo, lineItem: lineItem, projectId: projectId, patient: patient); if (_radiologyService.hasError) { error = _radiologyService.error; setState(ViewState.Error); @@ -281,8 +244,7 @@ class ProcedureViewModel extends BaseViewModel { notifyListeners(); } - List get patientLabSpecialResult => - _labsService.patientLabSpecialResult; + List get patientLabSpecialResult => _labsService.patientLabSpecialResult; List get labResultList => _labsService.labResultList; @@ -304,18 +266,10 @@ class ProcedureViewModel extends BaseViewModel { } getLaboratoryResult( - {String projectID, - int clinicID, - String invoiceNo, - String orderNo, - PatiantInformtion patient}) async { + {String projectID, int clinicID, String invoiceNo, String orderNo, PatiantInformtion patient}) async { setState(ViewState.Busy); await _labsService.getLaboratoryResult( - invoiceNo: invoiceNo, - orderNo: orderNo, - projectID: projectID, - clinicID: clinicID, - patient: patient); + invoiceNo: invoiceNo, orderNo: orderNo, projectID: projectID, clinicID: clinicID, patient: patient); if (_labsService.hasError) { error = _labsService.error; setState(ViewState.Error); @@ -324,15 +278,10 @@ class ProcedureViewModel extends BaseViewModel { } } - getPatientLabOrdersResults( - {PatientLabOrders patientLabOrder, - String procedure, - PatiantInformtion patient}) async { + getPatientLabOrdersResults({PatientLabOrders patientLabOrder, String procedure, PatiantInformtion patient}) async { setState(ViewState.Busy); await _labsService.getPatientLabOrdersResults( - patientLabOrder: patientLabOrder, - procedure: procedure, - patient: patient); + patientLabOrder: patientLabOrder, procedure: procedure, patient: patient); if (_labsService.hasError) { error = _labsService.error; setState(ViewState.Error); @@ -340,9 +289,8 @@ class ProcedureViewModel extends BaseViewModel { bool isShouldClear = false; if (_labsService.labOrdersResultsList.length == 1) { labOrdersResultsList.forEach((element) { - if (element.resultValue.contains('/') || - element.resultValue.contains('*') || - element.resultValue.isEmpty) isShouldClear = true; + if (element.resultValue.contains('/') || element.resultValue.contains('*') || element.resultValue.isEmpty) + isShouldClear = true; }); } if (isShouldClear) _labsService.labOrdersResultsList.clear(); diff --git a/lib/screens/prescription/add_favourite_prescription.dart b/lib/screens/prescription/add_favourite_prescription.dart new file mode 100644 index 00000000..7dad10dd --- /dev/null +++ b/lib/screens/prescription/add_favourite_prescription.dart @@ -0,0 +1,119 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/prescription/prescription_checkout_screen.dart'; +import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:flutter/material.dart'; + +class AddFavPrescription extends StatefulWidget { + final PrescriptionViewModel model; + final PatiantInformtion patient; + final String categoryID; + + const AddFavPrescription({Key key, this.model, this.patient, this.categoryID}) : super(key: key); + + @override + _AddFavPrescriptionState createState() => _AddFavPrescriptionState(); +} + +class _AddFavPrescriptionState extends State { + MedicineViewModel model; + PatiantInformtion patient; + + List entityList = List(); + ProcedureTempleteDetailsModel groupProcedures; + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getProcedureTemplate(categoryID: widget.categoryID), + builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( + isShowAppBar: false, + baseViewModel: model, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + ), + if (model.templateList.length != 0) + Expanded( + child: NetworkBaseView( + baseViewModel: model, + child: EntityListCheckboxSearchFavProceduresWidget( + isProcedure: false, + model: model, + removeFavProcedure: (item) { + setState(() { + entityList.remove(item); + }); + }, + addFavProcedure: (history) { + setState(() { + entityList.add(history); + }); + }, + isEntityFavListSelected: (master) => isEntityListSelected(master), + groupProcedures: groupProcedures, + selectProcedures: (valasd) { + setState(() { + groupProcedures = valasd; + }); + }, + ), + ), + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: 'Add Prescription', + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () { + if (groupProcedures == null) { + DrAppToastMsg.showErrorToast( + 'Please Select item ', + ); + return; + } + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PrescriptionCheckOutScreen( + patient: widget.patient, + model: widget.model, + groupProcedures: groupProcedures, + ), + ), + ); + }, + ), + ], + ), + ), + ], + ), + ), + ); + } + + bool isEntityListSelected(ProcedureTempleteDetailsModel masterKey) { + Iterable history = entityList.where( + (element) => masterKey.templateID == element.templateID && masterKey.procedureName == element.procedureName); + if (history.length > 0) { + return true; + } + return false; + } +} diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index 3fd1fbb3..797d0255 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -261,7 +261,7 @@ class _PrescriptionFormWidgetState extends State { Column( children: [ SizedBox( - height: 15, + height: 60, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -468,7 +468,7 @@ class _PrescriptionFormWidgetState extends State { PrescriptionTextFiled( hintText: TranslationBase.of(context).frequency, elementError: frequencyError, - element: frequencyError, + element: frequency, elementList: model.itemMedicineList, keyId: 'parameterCode', keyName: 'description', diff --git a/lib/screens/prescription/prescription_checkout_screen.dart b/lib/screens/prescription/prescription_checkout_screen.dart new file mode 100644 index 00000000..78c78590 --- /dev/null +++ b/lib/screens/prescription/prescription_checkout_screen.dart @@ -0,0 +1,760 @@ +import 'package:autocomplete_textfield/autocomplete_textfield.dart'; +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/Prescriptions/post_prescrition_req_model.dart'; +import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_model.dart'; +import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; +import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; +import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/SOAP/GetAssessmentReqModel.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/screens/prescription/prescription_text_filed.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/TextFields.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/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; + +class PrescriptionCheckOutScreen extends StatefulWidget { + final PrescriptionViewModel model; + final PatiantInformtion patient; + final List prescriptionList; + final ProcedureTempleteDetailsModel groupProcedures; + + const PrescriptionCheckOutScreen({Key key, this.model, this.patient, this.prescriptionList, this.groupProcedures}) + : super(key: key); + + @override + _PrescriptionCheckOutScreenState createState() => _PrescriptionCheckOutScreenState(); +} + +class _PrescriptionCheckOutScreenState extends State { + postPrescription( + {String duration, + String doseTimeIn, + String dose, + String drugId, + String strength, + String route, + String frequency, + String indication, + String instruction, + PrescriptionViewModel model, + DateTime doseTime, + String doseUnit, + String icdCode, + PatiantInformtion patient, + String patientType}) async { + PostPrescriptionReqModel postProcedureReqModel = new PostPrescriptionReqModel(); + List prescriptionList = List(); + + postProcedureReqModel.appointmentNo = patient.appointmentNo; + postProcedureReqModel.clinicID = patient.clinicId; + postProcedureReqModel.episodeID = patient.episodeNo; + postProcedureReqModel.patientMRN = patient.patientMRN; + + prescriptionList.add(PrescriptionRequestModel( + covered: true, + dose: double.parse(dose), + itemId: drugId.isEmpty ? 1 : int.parse(drugId), + doseUnitId: int.parse(doseUnit), + route: route.isEmpty ? 1 : int.parse(route), + frequency: frequency.isEmpty ? 1 : int.parse(frequency), + remarks: instruction, + approvalRequired: true, + icdcode10Id: icdCode.toString(), + doseTime: doseTimeIn.isEmpty ? 1 : int.parse(doseTimeIn), + duration: duration.isEmpty ? 1 : int.parse(duration), + doseStartDate: doseTime.toIso8601String())); + postProcedureReqModel.prescriptionRequestModel = prescriptionList; + await model.postPrescription(postProcedureReqModel, patient.patientMRN); + + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + } else if (model.state == ViewState.Idle) { + model.getPrescriptions(patient); + DrAppToastMsg.showSuccesToast('Medication has been added'); + } + } + + String routeError; + String frequencyError; + String doseTimeError; + String durationError; + String unitError; + String strengthError; + + int selectedType; + + TextEditingController strengthController = TextEditingController(); + TextEditingController indicationController = TextEditingController(); + TextEditingController instructionController = TextEditingController(); + + bool visbiltyPrescriptionForm = true; + bool visbiltySearch = true; + + final myController = TextEditingController(); + DateTime selectedDate; + int strengthChar; + GetMedicationResponseModel _selectedMedication; + GlobalKey key = new GlobalKey>(); + + TextEditingController drugIdController = TextEditingController(); + TextEditingController doseController = TextEditingController(); + final searchController = TextEditingController(); + stt.SpeechToText speech = stt.SpeechToText(); + var event = RobotProvider(); + var reconizedWord; + + final GlobalKey formKey = GlobalKey(); + final double spaceBetweenTextFileds = 12; + dynamic route; + dynamic frequency; + dynamic duration; + dynamic doseTime; + dynamic indication; + dynamic units; + dynamic uom; + dynamic box; + dynamic x; + + @override + void initState() { + super.initState(); + selectedType = 1; + } + + onVoiceText() async { + new SpeechToText(context: context).showAlertDialog(context); + var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; + bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); + if (available) { + speech.listen( + onResult: resultListener, + listenMode: stt.ListenMode.confirmation, + localeId: lang == 'en' ? 'en-US' : 'ar-SA', + ); + } else { + print("The user has denied the use of speech recognition."); + } + } + + void errorListener(SpeechRecognitionError error) { + event.setValue({"searchText": 'null'}); + print(error); + } + + void statusListener(String status) { + reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....'; + } + + void requestPermissions() async { + Map statuses = await [ + Permission.microphone, + ].request(); + } + + void resultListener(result) { + reconizedWord = result.recognizedWords; + event.setValue({"searchText": reconizedWord}); + + if (result.finalResult == true) { + setState(() { + SpeechToText.closeAlertDialog(context); + speech.stop(); + indicationController.text += reconizedWord + '\n'; + }); + } else { + print(result.finalResult); + } + } + + Future initSpeechState() async { + bool hasSpeech = await speech.initialize(onError: errorListener, onStatus: statusListener); + print(hasSpeech); + if (!mounted) return; + } + + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return BaseView( + onModelReady: (model) async { + model.getItem(itemID: int.parse(widget.groupProcedures.aliasN.replaceAll("item code ;", ""))); + + x = model.patientAssessmentList.map((element) { + return element.icdCode10ID; + }); + GetAssessmentReqModel getAssessmentReqModel = GetAssessmentReqModel( + patientMRN: widget.patient.patientMRN, + episodeID: widget.patient.episodeNo.toString(), + editedBy: '', + doctorID: '', + appointmentNo: widget.patient.appointmentNo); + if (model.medicationStrengthList.length == 0) { + await model.getMedicationStrength(); + } + if (model.medicationDurationList.length == 0) { + await model.getMedicationDuration(); + } + if (model.medicationDoseTimeList.length == 0) { + await model.getMedicationDoseTime(); + } + await model.getPatientAssessment(getAssessmentReqModel); + }, + builder: ( + BuildContext context, + MedicineViewModel model, + Widget child, + ) => + AppScaffold( + backgroundColor: Color(0xffF8F8F8).withOpacity(0.9), + isShowAppBar: false, + body: NetworkBaseView( + baseViewModel: model, + child: GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(new FocusNode()); + }, + child: SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).size.height * 1.35, + color: Color(0xffF8F8F8), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0), + child: Column( + children: [ + Column( + children: [ + SizedBox( + height: 60, + ), + Row( + //mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + child: Icon( + Icons.arrow_back_ios, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ), + SizedBox( + width: 7.0, + ), + AppText( + TranslationBase.of(context).newPrescriptionOrder, + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ], + ), + ], + ), + SizedBox( + height: spaceBetweenTextFileds, + ), + Container( + child: Form( + key: formKey, + child: Column( + children: [ + Container( + child: Column( + children: [ + SizedBox( + height: 14.5, + ), + ], + ), + ), + SizedBox( + height: spaceBetweenTextFileds, + ), + Visibility( + visible: visbiltyPrescriptionForm, + child: Container( + child: Column( + children: [ + AppText( + widget.groupProcedures.procedureName ?? "", + bold: true, + ), + Container( + child: Row( + children: [ + AppText( + TranslationBase.of(context).orderType, + fontWeight: FontWeight.w600, + ), + Radio( + activeColor: Color(0xFFB9382C), + value: 1, + groupValue: selectedType, + onChanged: (value) { + setSelectedType(value); + }, + ), + Text(TranslationBase.of(context).regular), + ], + ), + ), + SizedBox(height: spaceBetweenTextFileds), + Container( + width: double.infinity, + child: Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.35, + child: AppTextFieldCustom( + height: 40, + validationError: strengthError, + hintText: 'Strength', + isTextFieldHasSuffix: false, + enabled: true, + controller: strengthController, + onChanged: (String value) { + setState(() { + strengthChar = value.length; + }); + if (strengthChar >= 5) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context).only5DigitsAllowedForStrength, + ); + } + }, + inputType: TextInputType.numberWithOptions( + decimal: true, + ), + ), + ), + SizedBox( + width: 5.0, + ), + PrescriptionTextFiled( + width: MediaQuery.of(context).size.width * 0.560, + element: units, + elementError: unitError, + keyName: 'description', + keyId: 'parameterCode', + hintText: 'Select', + elementList: model.itemMedicineListUnit, + okFunction: (selectedValue) { + setState(() { + units = selectedValue; + units['isDefault'] = true; + }); + }, + ), + ], + ), + ), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + elementList: model.itemMedicineListRoute, + element: route, + elementError: routeError, + keyId: 'parameterCode', + keyName: 'description', + okFunction: (selectedValue) { + setState(() { + route = selectedValue; + route['isDefault'] = true; + }); + }, + hintText: TranslationBase.of(context).route, + ), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + hintText: TranslationBase.of(context).frequency, + elementError: frequencyError, + element: frequency, + elementList: model.itemMedicineList, + keyId: 'parameterCode', + keyName: 'description', + okFunction: (selectedValue) { + setState(() { + frequency = selectedValue; + frequency['isDefault'] = true; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text)); + + return; + } + }); + }), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + hintText: TranslationBase.of(context).doseTime, + elementError: doseTimeError, + element: doseTime, + elementList: model.medicationDoseTimeList, + keyId: 'id', + keyName: 'nameEn', + okFunction: (selectedValue) { + setState(() { + doseTime = selectedValue; + }); + }), + SizedBox(height: spaceBetweenTextFileds), + if (model.patientAssessmentList.isNotEmpty) + Container( + height: screenSize.height * 0.070, + width: double.infinity, + color: Colors.white, + child: Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.29, + child: TextField( + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].icdCode10ID.toString(), + indication != null ? indication['name'] : null, + false), + enabled: true, + readOnly: true, + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.65, + color: Colors.white, + child: TextField( + maxLines: 5, + decoration: textFieldSelectorDecoration( + model.patientAssessmentList[0].asciiDesc.toString(), + indication != null ? indication['name'] : null, + false), + enabled: true, + readOnly: true, + ), + ), + ], + ), + ), + SizedBox(height: spaceBetweenTextFileds), + Container( + height: screenSize.height * 0.070, + color: Colors.white, + child: InkWell( + onTap: () => selectDate(context, widget.model), + child: TextField( + decoration: textFieldSelectorDecoration( + TranslationBase.of(context).date, + selectedDate != null + ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" + : null, + true, + suffixIcon: Icon( + Icons.calendar_today, + color: Colors.black, + )), + enabled: false, + ), + ), + ), + SizedBox(height: spaceBetweenTextFileds), + PrescriptionTextFiled( + element: duration, + elementError: durationError, + hintText: TranslationBase.of(context).duration, + elementList: model.medicationDurationList, + keyName: 'nameEn', + keyId: 'id', + okFunction: (selectedValue) { + setState(() { + duration = selectedValue; + if (_selectedMedication != null && + duration != null && + frequency != null && + strengthController.text != null) { + model.getBoxQuantity( + freq: frequency['parameterCode'], + duration: duration['id'], + itemCode: _selectedMedication.itemId, + strength: double.parse(strengthController.text), + ); + box = model.boxQuintity; + + return; + } + }); + }, + ), + SizedBox(height: spaceBetweenTextFileds), + // Container( + // color: Colors.white, + // child: AppTextFieldCustom( + // hintText: "UOM", + // isTextFieldHasSuffix: false, + // dropDownText: uom != null ? uom : null, + // enabled: false, + // ), + // ), + SizedBox(height: spaceBetweenTextFileds), + // Container( + // color: Colors.white, + // child: AppTextFieldCustom( + // hintText: TranslationBase.of(context).boxQuantity, + // isTextFieldHasSuffix: false, + // dropDownText: box != null + // ? TranslationBase.of(context).boxQuantity + + // ": " + + // model.boxQuintity.toString() + // : null, + // enabled: false, + // ), + // ), + SizedBox(height: spaceBetweenTextFileds), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(6.0)), + border: Border.all(width: 1.0, color: HexColor("#CCCCCC"))), + child: Stack( + children: [ + TextFields( + maxLines: 6, + minLines: 4, + hintText: TranslationBase.of(context).instruction, + controller: instructionController, + //keyboardType: TextInputType.number, + ), + Positioned( + top: 0, + right: 15, + child: IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35, + ), + onPressed: () { + initSpeechState().then((value) => {onVoiceText()}); + }, + ), + ), + ], + ), + ), + SizedBox(height: spaceBetweenTextFileds), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + color: Color(0xff359846), + title: TranslationBase.of(context).addMedication, + fontWeight: FontWeight.w600, + onPressed: () async { + if (route != null && + duration != null && + doseTime != null && + frequency != null && + units != null && + selectedDate != null && + strengthController.text != "") { + // if (_selectedMedication.isNarcotic == true) { + // DrAppToastMsg.showErrorToast(TranslationBase.of(context) + // .narcoticMedicineCanOnlyBePrescribedFromVida); + // Navigator.pop(context); + // return; + // } + + if (double.parse(strengthController.text) > 1000.0) { + DrAppToastMsg.showErrorToast("1000 is the MAX for the strength"); + return; + } + if (double.parse(strengthController.text) < 0.0) { + DrAppToastMsg.showErrorToast("strength can't be zero"); + return; + } + + if (formKey.currentState.validate()) { + Navigator.pop(context); + // openDrugToDrug(model); + { + postPrescription( + icdCode: model.patientAssessmentList.isNotEmpty + ? model.patientAssessmentList[0].icdCode10ID.isEmpty + ? "test" + : model.patientAssessmentList[0].icdCode10ID.toString() + : "test", + // icdCode: model + // .patientAssessmentList + // .map((value) => value + // .icdCode10ID + // .trim()) + // .toList() + // .join(' '), + dose: strengthController.text, + doseUnit: model.itemMedicineListUnit.length == 1 + ? model.itemMedicineListUnit[0]['parameterCode'].toString() + : units['parameterCode'].toString(), + patient: widget.patient, + doseTimeIn: doseTime['id'].toString(), + model: widget.model, + duration: duration['id'].toString(), + frequency: model.itemMedicineList.length == 1 + ? model.itemMedicineList[0]['parameterCode'].toString() + : frequency['parameterCode'].toString(), + route: model.itemMedicineListRoute.length == 1 + ? model.itemMedicineListRoute[0]['parameterCode'].toString() + : route['parameterCode'].toString(), + drugId: (widget.groupProcedures.aliasN + .replaceAll("item code ;", "")), + strength: strengthController.text, + indication: indicationController.text, + instruction: instructionController.text, + doseTime: selectedDate, + ); + } + } + } else { + setState(() { + if (duration == null) { + durationError = TranslationBase.of(context).fieldRequired; + } else { + durationError = null; + } + if (doseTime == null) { + doseTimeError = TranslationBase.of(context).fieldRequired; + } else { + doseTimeError = null; + } + if (route == null) { + routeError = TranslationBase.of(context).fieldRequired; + } else { + routeError = null; + } + if (frequency == null) { + frequencyError = TranslationBase.of(context).fieldRequired; + } else { + frequencyError = null; + } + if (units == null) { + unitError = TranslationBase.of(context).fieldRequired; + } else { + unitError = null; + } + if (strengthController.text == "") { + strengthError = TranslationBase.of(context).fieldRequired; + } else { + strengthError = null; + } + }); + } + + formKey.currentState.save(); + }, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + ), + ); + } + + selectDate(BuildContext context, PrescriptionViewModel model) async { + Helpers.hideKeyboard(context); + DateTime selectedDate; + selectedDate = DateTime.now(); + final DateTime picked = await showDatePicker( + context: context, + initialDate: selectedDate, + firstDate: DateTime.now(), + lastDate: DateTime(2040), + initialEntryMode: DatePickerEntryMode.calendar, + ); + if (picked != null && picked != selectedDate) { + setState(() { + this.selectedDate = picked; + }); + } + } + + InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, + {Icon suffixIcon}) { + return InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + hintText: selectedText != null ? selectedText : hintText, + suffixIcon: isDropDown + ? suffixIcon != null + ? suffixIcon + : Icon( + Icons.keyboard_arrow_down_sharp, + color: Color(0xff2E303A), + ) + : null, + hintStyle: TextStyle( + fontSize: 13, + color: Color(0xff2E303A), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ), + labelText: selectedText != null ? '$hintText\n$selectedText' : null, + labelStyle: TextStyle( + fontSize: 13, + color: Color(0xff2E303A), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ), + ); + } +} diff --git a/lib/screens/prescription/prescription_home_screen.dart b/lib/screens/prescription/prescription_home_screen.dart new file mode 100644 index 00000000..641b684a --- /dev/null +++ b/lib/screens/prescription/prescription_home_screen.dart @@ -0,0 +1,203 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/prescription/add_favourite_prescription.dart'; +import 'package:doctor_app_flutter/screens/prescription/add_prescription_form.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/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionHomeScreen extends StatefulWidget { + final PrescriptionViewModel model; + final PatiantInformtion patient; + + const PrescriptionHomeScreen({Key key, this.model, this.patient}) : super(key: key); + @override + _PrescriptionHomeScreenState createState() => _PrescriptionHomeScreenState(); +} + +class _PrescriptionHomeScreenState extends State with SingleTickerProviderStateMixin { + PrescriptionViewModel model; + PatiantInformtion patient; + TabController _tabController; + int _activeTab = 0; + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + _tabController.addListener(_handleTabSelection); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + _handleTabSelection() { + setState(() { + _activeTab = _tabController.index; + }); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + return BaseView( + //onModelReady: (model) => model.getCategory(), + builder: (BuildContext context, ProcedureViewModel model, Widget child) => AppScaffold( + isShowAppBar: false, + body: NetworkBaseView( + baseViewModel: model, + child: DraggableScrollableSheet( + minChildSize: 0.90, + initialChildSize: 0.95, + maxChildSize: 1.0, + builder: (BuildContext context, ScrollController scrollController) { + return Container( + height: MediaQuery.of(context).size.height * 1.20, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + InkWell( + child: Icon( + Icons.arrow_back_ios, + size: 24.0, + ), + onTap: () { + Navigator.pop(context); + }, + ), + SizedBox( + width: 7.0, + ), + AppText( + 'Add prescription', + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ]), + SizedBox( + height: MediaQuery.of(context).size.height * 0.04, + ), + Expanded( + child: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.070), + child: Container( + height: MediaQuery.of(context).size.height * 0.070, + decoration: BoxDecoration( + border: Border( + bottom: + BorderSide(color: Theme.of(context).dividerColor, width: 0.5), //width: 0.7 + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorColor: Colors.transparent, + indicatorWeight: 1.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + tabWidget( + screenSize, + _activeTab == 0, + 'All Prescription', + ), + tabWidget( + screenSize, + _activeTab == 1, + "Favorite Templates", + ), + ], + ), + ), + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + PrescriptionFormWidget( + widget.model, widget.patient, widget.model.prescriptionList), + AddFavPrescription( + model: widget.model, + patient: widget.patient, + categoryID: '55', + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }), + ), + ), + ); + } + + Widget tabWidget(Size screenSize, bool isActive, String title, {int counter = -1}) { + return 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: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + title, + fontSize: SizeConfig.textMultiplier * 1.5, + color: isActive ? Colors.white : Color(0xFF2B353E), + fontWeight: FontWeight.w700, + ), + if (counter != -1) + Container( + margin: EdgeInsets.all(4), + width: 15, + height: 15, + decoration: BoxDecoration( + color: isActive ? Colors.white : Color(0xFFD02127), + shape: BoxShape.circle, + ), + child: Center( + child: FittedBox( + child: AppText( + "$counter", + fontSize: SizeConfig.textMultiplier * 1.5, + color: !isActive ? Colors.white : Color(0xFFD02127), + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 81c8760f..b56befdb 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.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/screens/prescription/add_prescription_form.dart'; +import 'package:doctor_app_flutter/screens/prescription/prescription_home_screen.dart'; import 'package:doctor_app_flutter/screens/prescription/prescription_item_in_patient_page.dart'; import 'package:doctor_app_flutter/screens/prescription/prescription_items_page.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -49,8 +50,7 @@ class PrescriptionsPage extends StatelessWidget { SizedBox( height: 12, ), - if (model.prescriptionsList.isNotEmpty && - patient.patientStatusType != 43) + if (model.prescriptionsList.isNotEmpty && patient.patientStatusType != 43) Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -70,8 +70,7 @@ class PrescriptionsPage extends StatelessWidget { ], ), ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) + if (patient.patientStatusType != null && patient.patientStatusType == 43) Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -91,16 +90,20 @@ class PrescriptionsPage extends StatelessWidget { ], ), ), - if ((patient.patientStatusType != null && - patient.patientStatusType == 43) || + if ((patient.patientStatusType != null && patient.patientStatusType == 43) || (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { - addPrescriptionForm(context, model, patient, - model.prescriptionList); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PrescriptionHomeScreen( + patient: patient, + model: model, + )), + ); }, - label: TranslationBase.of(context) - .applyForNewPrescriptionsOrder, + label: TranslationBase.of(context).applyForNewPrescriptionsOrder, ), ...List.generate( model.prescriptionsList.length, @@ -109,8 +112,7 @@ class PrescriptionsPage extends StatelessWidget { context, FadePage( page: PrescriptionItemsPage( - prescriptions: - model.prescriptionsList[index], + prescriptions: model.prescriptionsList[index], patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -118,22 +120,16 @@ class PrescriptionsPage extends StatelessWidget { ), ), child: DoctorCard( - doctorName: - model.prescriptionsList[index].doctorName, - profileUrl: model - .prescriptionsList[index].doctorImageURL, + doctorName: model.prescriptionsList[index].doctorName, + profileUrl: model.prescriptionsList[index].doctorImageURL, branch: model.prescriptionsList[index].name, - clinic: model.prescriptionsList[index] - .clinicDescription, + clinic: model.prescriptionsList[index].clinicDescription, isPrescriptions: true, - appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( - model.prescriptionsList[index] - .appointmentDate, + appointmentDate: AppDateUtils.getDateTimeFromServerFormat( + model.prescriptionsList[index].appointmentDate, ), ))), - if (model.prescriptionsList.isEmpty && - patient.patientStatusType != 43) + if (model.prescriptionsList.isEmpty && patient.patientStatusType != 43) Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -144,8 +140,7 @@ class PrescriptionsPage extends StatelessWidget { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context) - .noPrescriptionsFound), + child: AppText(TranslationBase.of(context).noPrescriptionsFound), ) ], ), @@ -170,38 +165,29 @@ class PrescriptionsPage extends StatelessWidget { FadePage( page: PrescriptionItemsInPatientPage( prescriptionIndex: index, - prescriptions: model - .inPatientPrescription[index], + prescriptions: model.inPatientPrescription[index], patient: patient, patientType: patientType, arrivalType: arrivalType, - startOn: AppDateUtils - .getDateTimeFromServerFormat( - model.inPatientPrescription[index] - .startDatetime, + startOn: AppDateUtils.getDateTimeFromServerFormat( + model.inPatientPrescription[index].startDatetime, ), - stopOn: AppDateUtils - .getDateTimeFromServerFormat( - model.inPatientPrescription[index] - .stopDatetime, + stopOn: AppDateUtils.getDateTimeFromServerFormat( + model.inPatientPrescription[index].stopDatetime, ), ), ), ), child: InPatientDoctorCard( - doctorName: model.inPatientPrescription[index] - .itemDescription, + doctorName: model.inPatientPrescription[index].itemDescription, profileUrl: 'sss', branch: 'hamza', clinic: 'basheer', isPrescriptions: true, - appointmentDate: - AppDateUtils.getDateTimeFromServerFormat( - model.inPatientPrescription[index] - .prescriptionDatetime, + appointmentDate: AppDateUtils.getDateTimeFromServerFormat( + model.inPatientPrescription[index].prescriptionDatetime, ), - createdBy: model.inPatientPrescription[index] - .createdByName, + createdBy: model.inPatientPrescription[index].createdByName, ))), if (model.inPatientPrescription.length == 0) Center( @@ -214,8 +200,7 @@ class PrescriptionsPage extends StatelessWidget { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context) - .noPrescriptionsFound), + child: AppText(TranslationBase.of(context).noPrescriptionsFound), ) ], ), diff --git a/lib/screens/procedures/ExpansionProcedure.dart b/lib/screens/procedures/ExpansionProcedure.dart index cdad16da..06e56f03 100644 --- a/lib/screens/procedures/ExpansionProcedure.dart +++ b/lib/screens/procedures/ExpansionProcedure.dart @@ -15,10 +15,12 @@ class ExpansionProcedure extends StatefulWidget { final ProcedureViewModel model; final Function(ProcedureTempleteDetailsModel) removeFavProcedure; final Function(ProcedureTempleteDetailsModel) addFavProcedure; - final Function(ProcedureTempleteDetailsModel) addProceduresRemarks; + final Function(ProcedureTempleteDetailsModel) selectProcedures; final bool Function(ProcedureTempleteModel) isEntityListSelected; final bool Function(ProcedureTempleteDetailsModel) isEntityFavListSelected; + final bool isProcedure; + final ProcedureTempleteDetailsModel groupProcedures; const ExpansionProcedure( {Key key, @@ -26,9 +28,11 @@ class ExpansionProcedure extends StatefulWidget { this.model, this.removeFavProcedure, this.addFavProcedure, - this.addProceduresRemarks, + this.selectProcedures, this.isEntityListSelected, - this.isEntityFavListSelected}) + this.isEntityFavListSelected, + this.isProcedure = true, + this.groupProcedures}) : super(key: key); @override @@ -70,11 +74,11 @@ class _ExpansionProcedureState extends State { ), Expanded( child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 0), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), child: AppText( - "Procedures for " + - widget.procedureTempleteModel.templateName, + widget.isProcedure == true + ? "Procedures for " + widget.procedureTempleteModel.templateName + : "Prescription for " + widget.procedureTempleteModel.templateName, fontSize: 16.0, variant: "bodyText", bold: true, @@ -87,9 +91,7 @@ class _ExpansionProcedureState extends State { width: 25, height: 25, child: Icon( - _isShowMore - ? Icons.keyboard_arrow_up - : Icons.keyboard_arrow_down, + _isShowMore ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, color: Colors.grey[800], size: 22, ), @@ -111,48 +113,62 @@ class _ExpansionProcedureState extends State { )), duration: Duration(milliseconds: 7000), child: Column( - children: widget.procedureTempleteModel.procedureTemplate - .map((itemProcedure) { - return Container( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 11), - child: Checkbox( - value: widget - .isEntityFavListSelected(itemProcedure), - activeColor: Color(0xffD02127), - onChanged: (bool newValue) { - setState(() { - if (widget.isEntityFavListSelected( - itemProcedure)) { - widget - .removeFavProcedure(itemProcedure); - } else { - widget.addFavProcedure(itemProcedure); - } - }); - }), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), - child: AppText(itemProcedure.procedureName, - fontSize: 14.0, - variant: "bodyText", - bold: true, - color: Color(0xff575757)), + children: widget.procedureTempleteModel.procedureTemplate.map((itemProcedure) { + return InkWell( + onTap: () { + if (widget.isProcedure) { + setState(() { + if (widget.isEntityFavListSelected(itemProcedure)) { + widget.removeFavProcedure(itemProcedure); + } else { + widget.addFavProcedure(itemProcedure); + } + }); + } else { + widget.selectProcedures(itemProcedure); + } + }, + child: Container( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 11), + child: widget.isProcedure + ? Checkbox( + value: widget.isEntityFavListSelected(itemProcedure), + activeColor: Color(0xffD02127), + onChanged: (bool newValue) { + setState(() { + if (widget.isEntityFavListSelected(itemProcedure)) { + widget.removeFavProcedure(itemProcedure); + } else { + widget.addFavProcedure(itemProcedure); + } + }); + }) + : Radio( + value: itemProcedure, + groupValue: widget.groupProcedures, + activeColor: Color(0xffD02127), + onChanged: (newValue) { + widget.selectProcedures(newValue); + })), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), + child: AppText(itemProcedure.procedureName, + fontSize: 14.0, variant: "bodyText", bold: true, color: Color(0xff575757)), + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), ); diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index 822726ce..c386afc8 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -22,12 +22,15 @@ class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { final Function(ProcedureTempleteDetailsModel) removeFavProcedure; final Function(ProcedureTempleteDetailsModel) addFavProcedure; - final Function(ProcedureTempleteDetailsModel) addProceduresRemarks; + final Function(ProcedureTempleteDetailsModel) selectProcedures; + final ProcedureTempleteDetailsModel groupProcedures; final bool Function(ProcedureTempleteModel) isEntityListSelected; final bool Function(ProcedureTempleteDetailsModel) isEntityFavListSelected; final List masterList; + final bool isProcedure; + EntityListCheckboxSearchFavProceduresWidget( {Key key, this.model, @@ -36,11 +39,13 @@ class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { this.masterList, this.addHistory, this.addFavProcedure, - this.addProceduresRemarks, + this.selectProcedures, this.removeFavProcedure, this.isEntityListSelected, this.isEntityFavListSelected, - this.addRemarks}) + this.addRemarks, + this.isProcedure = true, + this.groupProcedures}) : super(key: key); @override @@ -48,8 +53,7 @@ class EntityListCheckboxSearchFavProceduresWidget extends StatefulWidget { _EntityListCheckboxSearchFavProceduresWidgetState(); } -class _EntityListCheckboxSearchFavProceduresWidgetState - extends State { +class _EntityListCheckboxSearchFavProceduresWidgetState extends State { int selectedType = 0; int typeUrgent; int typeRegular; @@ -85,9 +89,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState child: Center( child: Container( margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: Colors.white), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: Colors.white), child: ListView( children: [ TextFields( @@ -106,20 +108,20 @@ class _EntityListCheckboxSearchFavProceduresWidgetState ? Column( children: widget.model.templateList.map((historyInfo) { return ExpansionProcedure( - procedureTempleteModel: historyInfo, - model: widget.model, - removeFavProcedure: widget.removeFavProcedure, - addFavProcedure: widget.addFavProcedure, - addProceduresRemarks: widget.addProceduresRemarks, - isEntityListSelected: widget.isEntityListSelected, - isEntityFavListSelected: widget.isEntityFavListSelected, - ); + procedureTempleteModel: historyInfo, + model: widget.model, + removeFavProcedure: widget.removeFavProcedure, + addFavProcedure: widget.addFavProcedure, + selectProcedures: widget.selectProcedures, + isEntityListSelected: widget.isEntityListSelected, + isEntityFavListSelected: widget.isEntityFavListSelected, + isProcedure: widget.isProcedure, + groupProcedures: widget.groupProcedures); }).toList(), ) : Center( child: Container( - child: AppText("Sorry , No Match", - color: Color(0xFFB9382C)), + child: AppText("Sorry , No Match", color: Color(0xFFB9382C)), ), ) ], From bc48d915c67e428ed7bbf06cd60cd6bbd2e69a42 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 1 Jun 2021 15:19:06 +0300 Subject: [PATCH 111/241] procedure refactoring --- lib/config/config.dart | 4 +- lib/core/viewModel/procedure_View_model.dart | 83 ++++- lib/screens/procedures/ProcedureType.dart | 78 +++- .../procedures/add-procedure-form.dart | 349 ------------------ .../procedures/add-procedure-page.dart | 265 +++++++++++++ lib/screens/procedures/add_lab_orders.dart | 269 -------------- .../procedures/add_radiology_order.dart | 270 -------------- .../base_add_procedure_tab_page.dart | 85 +---- .../procedures/procedure_checkout_screen.dart | 5 +- 9 files changed, 442 insertions(+), 966 deletions(-) delete mode 100644 lib/screens/procedures/add-procedure-form.dart create mode 100644 lib/screens/procedures/add-procedure-page.dart delete mode 100644 lib/screens/procedures/add_lab_orders.dart delete mode 100644 lib/screens/procedures/add_radiology_order.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index c8af8ad9..0283577e 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index ad62158e..68937c1c 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -4,10 +4,10 @@ import 'package:doctor_app_flutter/core/model/labs/LabOrderResult.dart'; import 'package:doctor_app_flutter/core/model/labs/lab_result.dart'; import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/model/labs/patient_lab_special_result.dart'; +import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; @@ -19,8 +19,12 @@ import 'package:doctor_app_flutter/core/service/patient_medical_file/radiology/r import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:flutter/cupertino.dart'; +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart' + as cpe; class ProcedureViewModel extends BaseViewModel { //TODO Hussam clean it @@ -84,11 +88,15 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getProcedureCategory({String categoryName, String categoryID, patientId}) async { + Future getProcedureCategory( + {String categoryName, String categoryID, patientId}) async { + if (categoryName == null) return; hasError = false; setState(ViewState.Busy); await _procedureService.getProcedureCategory( - categoryName: categoryName, categoryID: categoryID,patientId: patientId); + categoryName: categoryName, + categoryID: categoryID, + patientId: patientId); if (_procedureService.hasError) { error = _procedureService.error; setState(ViewState.ErrorLocal); @@ -137,8 +145,7 @@ class ProcedureViewModel extends BaseViewModel { templateName: element.templateName, templateId: element.templateID, template: element); - if(!templateList.contains(template)) - templateList.add(template); + if (!templateList.contains(template)) templateList.add(template); } }); print(templateList.length.toString()); @@ -357,4 +364,70 @@ class ProcedureViewModel extends BaseViewModel { } else DrAppToastMsg.showSuccesToast(mes); } + + Future preparePostProcedure( + {String remarks, + String orderType, + PatiantInformtion patient, + List entityList, + ProcedureType procedureType}) async { + PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); + ProcedureValadteRequestModel procedureValadteRequestModel = + new ProcedureValadteRequestModel(); + procedureValadteRequestModel.patientMRN = patient.patientMRN; + procedureValadteRequestModel.episodeID = patient.episodeNo; + procedureValadteRequestModel.appointmentNo = patient.appointmentNo; + + List controlsProcedure = List(); + + postProcedureReqModel.appointmentNo = patient.appointmentNo; + postProcedureReqModel.episodeID = patient.episodeNo; + postProcedureReqModel.patientMRN = patient.patientMRN; + + entityList.forEach((element) { + procedureValadteRequestModel.procedure = [element.procedureId]; + List controls = List(); + controls.add( + Controls( + code: "remarks", + controlValue: element.remarks != null ? element.remarks : ""), + ); + controls.add( + Controls( + code: "ordertype", + controlValue: procedureType == ProcedureType.PROCEDURE + ? element.type ?? "1" + : "0"), + ); + controlsProcedure.add(Procedures( + category: element.categoryID, + procedure: element.procedureId, + controls: controls)); + }); + + postProcedureReqModel.procedures = controlsProcedure; + await valadteProcedure(procedureValadteRequestModel); + if (state == ViewState.Idle) { + if (valadteProcedureList[0].entityList.length == 0) { + await postProcedure(postProcedureReqModel, patient.patientMRN); + + if (state == ViewState.ErrorLocal) { + Helpers.showErrorToast(error); + getProcedure(mrn: patient.patientMRN); + } else if (state == ViewState.Idle) { + DrAppToastMsg.showSuccesToast('procedure has been added'); + } + } else { + if (state == ViewState.ErrorLocal) { + Helpers.showErrorToast(error); + getProcedure(mrn: patient.patientMRN); + } else if (state == ViewState.Idle) { + Helpers.showErrorToast( + valadteProcedureList[0].entityList[0].warringMessages); + } + } + } else { + Helpers.showErrorToast(error); + } + } } diff --git a/lib/screens/procedures/ProcedureType.dart b/lib/screens/procedures/ProcedureType.dart index e05fb7e1..4fc7781a 100644 --- a/lib/screens/procedures/ProcedureType.dart +++ b/lib/screens/procedures/ProcedureType.dart @@ -1,5 +1,81 @@ +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; + enum ProcedureType { PROCEDURE, LAB_RESULT, RADIOLOGY, -} \ No newline at end of file +} + +extension procedureType on ProcedureType { + + String getFavouriteTabName(BuildContext context) { + return TranslationBase.of(context).favoriteTemplates; + } + + String getAllLabelName(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).allProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).allLab; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).allRadiology; + default: + return ""; + } + } + + String getToolbarLabel(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).addProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).addRadiologyOrder; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).addLabOrder; + default: + return ""; + } + } + + String getAddButtonTitle(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).addProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).addRadiologyOrder; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).addLabOrder; + default: + return ""; + } + } + + String getCategoryId() { + switch (this) { + case ProcedureType.PROCEDURE: + return null; + case ProcedureType.LAB_RESULT: + return "02"; + case ProcedureType.RADIOLOGY: + return "03"; + default: + return null; + } + } + + String getCategoryName() { + switch (this) { + case ProcedureType.PROCEDURE: + return null; + case ProcedureType.LAB_RESULT: + return "Laboratory"; + case ProcedureType.RADIOLOGY: + return "Radiology"; + default: + return null; + } + } + +} diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart deleted file mode 100644 index ba2ec3de..00000000 --- a/lib/screens/procedures/add-procedure-form.dart +++ /dev/null @@ -1,349 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; -import 'package:flutter/material.dart'; - -import 'ProcedureType.dart'; -import 'entity_list_checkbox_search_widget.dart'; - -void addSelectedProcedure( - context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedProcedure( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedProcedure extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - final ProcedureType procedureType; - - const AddSelectedProcedure({Key key, this.model, this.patient, this.procedureType}) - : super(key: key); - - @override - _AddSelectedProcedureState createState() => - _AddSelectedProcedureState(patient: patient, model: model); -} - -class _AddSelectedProcedureState extends State { - int selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - - _AddSelectedProcedureState({this.patient, this.model}); - - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = List(); - List entityListProcedure = List(); - TextEditingController procedureName = TextEditingController(); - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( - isShowAppBar: false, - body: Column( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.070, - ), - Expanded( - child: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, - ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context) - .pleaseEnterProcedure, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - ]), - SizedBox( - height: - MediaQuery.of(context).size.height * 0.04, - ), - Row( - children: [ - Container( - width: MediaQuery.of(context).size.width * - 0.79, - child: AppTextFieldCustom( - hintText: TranslationBase.of(context) - .searchProcedureHere, - isTextFieldHasSuffix: false, - - maxLines: 1, - minLines: 1, - hasBorder: true, - controller: procedureName, - // onSubmitted: (_) { - // model.getProcedureCategory( - // categoryName: procedureName.text); - // }, - onClick: () { - if (procedureName.text.isNotEmpty && - procedureName.text.length >= 3) - model.getProcedureCategory( - patientId: patient.patientId, - categoryName: - procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .atLeastThreeCharacters, - ); - }, - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * - 0.02, - ), - Expanded( - child: InkWell( - onTap: () { - if (procedureName.text.isNotEmpty && - procedureName.text.length >= 3) - model.getProcedureCategory( - patientId: patient.patientId, - categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .atLeastThreeCharacters, - ); - }, - child: Icon( - Icons.search, - size: 25.0, - ), - ), - ), - ], - ), - if (procedureName.text.isNotEmpty && - model.procedureList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: widget - .model.categoriesList[0].entityList, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => - isEntityListSelected(master), - )), - SizedBox( - height: 115.0, - ), - ], - ), - ), - ), - ); - }), - ), - ), - Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addSelectedProcedures, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .fillTheMandatoryProcedureDetails, - ); - return; - } - - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, - ), - ], - ), - ), - ], - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList - .where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, - {Icon suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } - - postProcedure( - {ProcedureViewModel model, - String remarks, - String orderType, - PatiantInformtion patient, - List entityList, - ProcedureType procedureType}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = List(); - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId]; - List controls = List(); - controls.add( - Controls( - code: "remarks", - controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: procedureType == - ProcedureType.PROCEDURE ? element.type ?? "1" : "0"), - ); - controlsProcedure.add(Procedures( - category: element.categoryID, - procedure: element.procedureId, - controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast( - model.valadteProcedureList[0].entityList[0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } - } - -} diff --git a/lib/screens/procedures/add-procedure-page.dart b/lib/screens/procedures/add-procedure-page.dart new file mode 100644 index 00000000..65f0b2e1 --- /dev/null +++ b/lib/screens/procedures/add-procedure-page.dart @@ -0,0 +1,265 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:flutter/material.dart'; + +import 'ProcedureType.dart'; +import 'entity_list_checkbox_search_widget.dart'; + +class AddProcedurePage extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + final ProcedureType procedureType; + + const AddProcedurePage( + {Key key, this.model, this.patient, this.procedureType}) + : super(key: key); + + @override + _AddProcedurePageState createState() => _AddProcedurePageState( + patient: patient, model: model, procedureType: this.procedureType); +} + +class _AddProcedurePageState extends State { + int selectedType; + ProcedureViewModel model; + PatiantInformtion patient; + ProcedureType procedureType; + + _AddProcedurePageState({this.patient, this.model, this.procedureType}); + + TextEditingController procedureController = TextEditingController(); + TextEditingController remarksController = TextEditingController(); + List entityList = List(); + List entityListProcedure = List(); + TextEditingController procedureName = TextEditingController(); + + dynamic selectedCategory; + + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) { + model.getProcedureCategory( + categoryName: procedureType.getCategoryName(), + categoryID: procedureType.getCategoryId(), + patientId: patient.patientId); + }, + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + ), + Expanded( + child: NetworkBaseView( + baseViewModel: model, + child: SingleChildScrollView( + child: Container( + // height: MediaQuery.of(context).size.height * 1.2, + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (procedureType == ProcedureType.PROCEDURE) + Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + AppText( + TranslationBase.of(context) + .pleaseEnterProcedure, + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ], + ), + SizedBox( + height: + MediaQuery.of(context).size.height * 0.02, + ), + Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * + 0.79, + child: AppTextFieldCustom( + hintText: TranslationBase.of(context) + .searchProcedureHere, + isTextFieldHasSuffix: false, + maxLines: 1, + minLines: 1, + hasBorder: true, + controller: procedureName, + // onClick: () { + // if (procedureName.text.isNotEmpty && + // procedureName.text.length >= 3) + // model.getProcedureCategory( + // patientId: patient.patientId, + // categoryName: + // procedureName.text); + // else + // DrAppToastMsg.showErrorToast( + // TranslationBase.of(context) + // .atLeastThreeCharacters, + // ); + // }, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * + 0.02, + ), + Expanded( + child: InkWell( + onTap: () { + if (procedureName.text.isNotEmpty && + procedureName.text.length >= 3) + model.getProcedureCategory( + patientId: patient.patientId, + categoryName: + procedureName.text); + else + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .atLeastThreeCharacters, + ); + }, + child: Icon( + Icons.search, + size: 25.0, + ), + ), + ), + ], + ), + ], + ), + if (procedureName.text.isNotEmpty && + model.categoriesList.length != 0) + NetworkBaseView( + baseViewModel: model, + child: EntityListCheckboxSearchWidget( + model: widget.model, + masterList: + model.categoriesList[0].entityList, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), + )), + ], + ), + ), + ), + ), + ), + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: procedureType.getAddButtonTitle(context), + fontWeight: FontWeight.w700, + color: Color(0xff359846), + onPressed: () async { + if (entityList.isEmpty == true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .fillTheMandatoryProcedureDetails, + ); + return; + } + + Navigator.pop(context); + await model.preparePostProcedure( + orderType: selectedType.toString(), + entityList: entityList, + patient: patient, + remarks: remarksController.text); + }, + ), + ], + ), + ), + ], + ), + ), + ); + } + + bool isEntityListSelected(EntityList masterKey) { + Iterable history = entityList + .where((element) => masterKey.procedureId == element.procedureId); + if (history.length > 0) { + return true; + } + return false; + } + + InputDecoration textFieldSelectorDecoration( + String hintText, String selectedText, bool isDropDown, + {Icon suffixIcon}) { + return InputDecoration( + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), + borderRadius: BorderRadius.circular(8), + ), + hintText: selectedText != null ? selectedText : hintText, + suffixIcon: isDropDown + ? suffixIcon != null + ? suffixIcon + : Icon( + Icons.arrow_drop_down, + color: Colors.black, + ) + : null, + hintStyle: TextStyle( + fontSize: 14, + color: Colors.grey.shade600, + ), + ); + } +} diff --git a/lib/screens/procedures/add_lab_orders.dart b/lib/screens/procedures/add_lab_orders.dart deleted file mode 100644 index b8d4e7c7..00000000 --- a/lib/screens/procedures/add_lab_orders.dart +++ /dev/null @@ -1,269 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -import 'entity_list_checkbox_search_widget.dart'; - -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, - List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -postProcedure( - {ProcedureViewModel model, - String remarks, - String orderType, - PatiantInformtion patient, - List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = List(); - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId]; - List controls = List(); - controls.add( - Controls( - code: "remarks", - controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: "0"), - ); - controlsProcedure.add(Procedures( - category: element.categoryID, - procedure: element.procedureId, - controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getLabs(patient); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getLabs(patient); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast( - model.valadteProcedureList[0].entityList[0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - -void addSelectedLabOrder( - context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedLabOrder( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedLabOrder extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - - const AddSelectedLabOrder({Key key, this.model, this.patient}) - : super(key: key); - @override - _AddSelectedLabOrderState createState() => - _AddSelectedLabOrderState(patient: patient, model: model); -} - -class _AddSelectedLabOrderState extends State { - int selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - _AddSelectedLabOrderState({this.patient, this.model}); - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = List(); - List entityListProcedure = List(); - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - onModelReady: (model) => model.getProcedureCategory( - categoryName: "Laboratory", categoryID: "02",patientId: patient.patientId), - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: - (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * .90, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 10.0, - ), - if (widget.model.categoriesList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: - widget.model.categoriesList[0].entityList, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => - isEntityListSelected(master), - )), - ], - ), - ), - ), - ); - }), - ), - bottomSheet: Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addLabOrder, - fontWeight: FontWeight.w700, - color: Color(0xff359846), - onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context) - .fillTheMandatoryProcedureDetails, - ); - return; - } - - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, - ), - ], - ), - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList - .where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, - {Icon suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } -} diff --git a/lib/screens/procedures/add_radiology_order.dart b/lib/screens/procedures/add_radiology_order.dart deleted file mode 100644 index dc68aacc..00000000 --- a/lib/screens/procedures/add_radiology_order.dart +++ /dev/null @@ -1,270 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -import 'entity_list_checkbox_search_widget.dart'; - -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, - List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -postProcedure( - {ProcedureViewModel model, - String remarks, - String orderType, - PatiantInformtion patient, - List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = - new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = List(); - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId]; - List controls = List(); - controls.add( - Controls( - code: "remarks", - controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: "0"), - ); - controlsProcedure.add(Procedures( - category: element.categoryID, - procedure: element.procedureId, - controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getPatientRadOrders(patient); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getPatientRadOrders(patient); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast( - model.valadteProcedureList[0].entityList[0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - -void addSelectedRadiologyOrder( - context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedRadiologyOrder( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedRadiologyOrder extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - - const AddSelectedRadiologyOrder({Key key, this.model, this.patient}) - : super(key: key); - - @override - _AddSelectedRadiologyOrderState createState() => - _AddSelectedRadiologyOrderState(patient: patient, model: model); -} - -class _AddSelectedRadiologyOrderState extends State { - int selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - - _AddSelectedRadiologyOrderState({this.patient, this.model}); - - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = List(); - List entityListProcedure = List(); - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - onModelReady: (model) => model.getProcedureCategory( - categoryName: "Radiology", categoryID: "03",patientId: patient.patientId), - builder: (BuildContext context, ProcedureViewModel model, Widget child) => - AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: - (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.0, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 10.0, - ), - if (widget.model.categoriesList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: - widget.model.categoriesList[0].entityList, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => - isEntityListSelected(master), - )), - ], - ), - ), - ), - ); - }), - ), - bottomSheet: Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addRadiologyOrder, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast(TranslationBase.of(context) - .fillTheMandatoryProcedureDetails); - return; - } - - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, - ), - ], - ), - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList - .where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration( - String hintText, String selectedText, bool isDropDown, - {Icon suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } -} diff --git a/lib/screens/procedures/base_add_procedure_tab_page.dart b/lib/screens/procedures/base_add_procedure_tab_page.dart index 4d25de2b..f4a6c85e 100644 --- a/lib/screens/procedures/base_add_procedure_tab_page.dart +++ b/lib/screens/procedures/base_add_procedure_tab_page.dart @@ -11,9 +11,7 @@ import 'package:flutter/material.dart'; import 'ProcedureType.dart'; import 'add-favourite-procedure.dart'; -import 'add-procedure-form.dart'; -import 'add_lab_orders.dart'; -import 'add_radiology_order.dart'; +import 'add-procedure-page.dart'; class BaseAddProcedureTabPage extends StatefulWidget { final ProcedureViewModel model; @@ -25,8 +23,8 @@ class BaseAddProcedureTabPage extends StatefulWidget { : super(key: key); @override - _BaseAddProcedureTabPageState createState() => - _BaseAddProcedureTabPageState(patient: patient, model: model, procedureType: procedureType); + _BaseAddProcedureTabPageState createState() => _BaseAddProcedureTabPageState( + patient: patient, model: model, procedureType: procedureType); } class _BaseAddProcedureTabPageState extends State @@ -86,13 +84,7 @@ class _BaseAddProcedureTabPageState extends State mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - procedureType == ProcedureType.PROCEDURE - ? TranslationBase.of(context).addProcedures - : procedureType == ProcedureType.RADIOLOGY - ? TranslationBase.of(context) - .addRadiologyOrder - : TranslationBase.of(context) - .addLabOrder, + procedureType.getToolbarLabel(context), fontWeight: FontWeight.w700, fontSize: 20, ), @@ -140,21 +132,13 @@ class _BaseAddProcedureTabPageState extends State tabWidget( screenSize, _activeTab == 0, - TranslationBase.of(context) - .favoriteTemplates, + procedureType + .getFavouriteTabName(context), ), tabWidget( screenSize, _activeTab == 1, - procedureType == ProcedureType.PROCEDURE - ? TranslationBase.of(context) - .allProcedures - : procedureType == - ProcedureType.RADIOLOGY - ? TranslationBase.of(context) - .allRadiology - : TranslationBase.of(context) - .allLab, + procedureType.getAllLabelName(context), ), ], ), @@ -171,49 +155,18 @@ class _BaseAddProcedureTabPageState extends State AddFavouriteProcedure( patient: patient, model: model, - addButtonTitle: procedureType == - ProcedureType.PROCEDURE - ? TranslationBase.of(context) - .addProcedures - : procedureType == - ProcedureType.RADIOLOGY - ? TranslationBase.of(context) - .addRadiologyOrder - : TranslationBase.of(context) - .addLabOrder, - toolbarTitle: procedureType == - ProcedureType.PROCEDURE - ? TranslationBase.of(context) - .addProcedures - : procedureType == - ProcedureType.RADIOLOGY - ? TranslationBase.of(context) - .addRadiologyOrder - : TranslationBase.of(context) - .addLabOrder, - categoryID: procedureType == - ProcedureType.PROCEDURE - ? null - : procedureType == - ProcedureType.RADIOLOGY - ? "03" - : "02", + addButtonTitle: procedureType + .getAddButtonTitle(context), + toolbarTitle: procedureType + .getToolbarLabel(context), + categoryID: + procedureType.getCategoryId(), + ), + AddProcedurePage( + model: model, + patient: patient, + procedureType: procedureType, ), - procedureType == ProcedureType.PROCEDURE - ? AddSelectedProcedure( - model: model, - patient: patient, - ) - : procedureType == - ProcedureType.RADIOLOGY - ? AddSelectedRadiologyOrder( - model: model, - patient: patient, - ) - : AddSelectedLabOrder( - model: model, - patient: patient, - ), ], ), ), @@ -276,5 +229,3 @@ class _BaseAddProcedureTabPageState extends State ); } } - - diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index 76d6cf6f..4c054fc5 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/core/model/procedure/procedure_template_detai import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.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/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/screens/procedures/add-procedure-page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -223,10 +223,9 @@ class _ProcedureCheckOutScreenState extends State { ); }); Navigator.pop(context); - await postProcedure( + await model.preparePostProcedure( entityList: entityList, patient: widget.patient, - model: widget.model, remarks: remarksController.text); Navigator.pop(context); Navigator.pop(context); From ad74ff00dc6e1f775810c5596ad8bb9b36fd37d2 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 1 Jun 2021 15:49:51 +0300 Subject: [PATCH 112/241] fix issues in android and add ChangeCallStatus services in IOS --- android/app/build.gradle | 2 +- android/app/src/main/AndroidManifest.xml | 4 + .../com/hmg/hmgDr/ui/VideoCallActivity.java | 12 +- ios/Podfile | 2 +- ios/Podfile.lock | 331 ------------------ ios/Runner/VideoViewController.swift | 35 +- lib/client/base_app_client.dart | 12 +- lib/config/config.dart | 4 +- lib/screens/qr_reader/QR_reader_screen.dart | 6 +- pubspec.lock | 12 +- pubspec.yaml | 2 +- 11 files changed, 63 insertions(+), 359 deletions(-) delete mode 100644 ios/Podfile.lock diff --git a/android/app/build.gradle b/android/app/build.gradle index fd6c7720..b7605ad0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -70,7 +70,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' //openTok - implementation 'com.opentok.android:opentok-android-sdk:2.16.5' + implementation 'com.opentok.android:opentok-android-sdk:2.20.1' //permissions implementation 'pub.devrel:easypermissions:0.4.0' //retrofit diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 57a59745..c656ebbf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ V155AOUHR@9FAHStrVKyp#vxj6c$Z76t+ItSj}J)9&KR#cbIeoO8$614_p9oayTAXl>|iRuskEGLy%e@=+&nC) zCNcAR31;j?l13Z%F{85wV80gFS-e6%(QzsqU{z12rW~JYeWp5YT`#j)cjnZwfAIPD zx?W9gx;*=8bg|qYpv2OJQdTn2N*&!%Fl~v(So-;sH>+19w5CYZe3AesR(LZjIjCkK z^hz0~p8t9!QM=4_o!KhFe&ZotZHL% z-D--%G_uS)eHF`q|F!&yl7D@BD zWq!B1HDCSee5&u5SWMjVAA|OUNFTz|T^(UGjP|pltHvYfOAN@yVwM8CQZ=KeZbKn$ z1!a0kC6UT!_&ni$c|>-@r9+;@VS%?RXN~3|yPw5#3bMUZdZ9z9&XwQjX1-l$#u#)U zZ9#k|xp9^A>wFKqF}YHtoN7O}f?tgz0mfBfz*;P=Xw^R5f>+YWl8}>uEnN{XULepK z<)brWE`x29G3k9qkj}5D5qWsC7JGpSM9K~WyR3gd^cO?k6q7W2^c61|9IZe$T*pg= zCRWhF?wL|)w3Q!VP`ku&{OOYWVctVVJQ5EPk95ZK0+_wjQR+K-sECzCsAamCSaZRG zNY`db#6JpBnyk8|efQFc)_F()hcu)RW)jA!)UzbH033^x>?+9&p?g@4;bW}Cx*Itc zfz3gsl0j9s$omPX-fDBIq7nFk%A{~qo=sift6XT4t1FyfA!qKuo?4O)gE z+643$aXzX$$z~$cR(~60+g(lk1C~{L;Mmv?zYR2RU}??wdwt=*v~zOQS@snR@YT7POn#@(81KDH zNaA0)#~uooQ6UTAxPrz(oy@CWcpOifl}0ufh9Zk7nAGq0OGYZWB=vVz zg1*!qbLy57_g4hIgq4%~IAVStnKFvnc;&TCrs~d1kvC|fvxxixE6a)VqM9TY^ZJX{R-5Rw{4ZJSl!cA zNNjXghMA=YDqxS=0HJK}OQ({xYTDzW*gDzTrORR62?bjomL?bQy@Vu~iTc*dS$Djs zmHS{#&wX6xIQdt^0AO;A8xJuLx;o#gYFeMW^si;64PcM%WjE$j7$+5SxbIIZZ=d!I z5Xh%#R9&7MMUU0jic}~T)GYFY|dQe?l+GQ3>BQoFa{$%3mwmwtcDy9iHCf{AeuR;^=oF)Q)R84g$T?0 zFajJwpm7UZI?Q;AqBqTH%B``ru&bN*EcoPavFC-{?_ic?ROXf3Lb+)wA&=qLgkK+x zy{fq%pd8n-BzImF!3XBvxWj(Q|II&X`!Q6)O)$!UU5NLO;8}?(0jAgUi z`tjFG@4SDjYqr|4myu%^ZK-u2TzakNWUfgTYi9Y6`D6_tW5cDTl~Z{RA@uADImS>W zPWC)epskI3aWUnaDT6TE&-2Lj!6$?fAuM5{f#&MCZ6br#a%II){$t`o^(URW%9@_8 z!oyZy`cfex$lAo(vAN+>g!}~CpTLNTON*X~f=YT82i+6q4rlihY5J~SkBi2^m&MK@ zu9pd<&wHxbU*@)whr5VfXjTmKr&sh|C*Y)|497fn? z$JQCC60yJ~?c2cp=kG49Ke=pBFXZ7u3gpID)t}*;@vzk|E2cX9H0bzuACdmC5>3EP z_V}k`u>Gf|&~eXXTI0)+28L}CuHB4Z5v6;y3v#NJyatsY8=YH{u!MFOq-RRxG@mCO zw%G9=1dolqUv@0}90=EM8W#jxD%b7{4BqqI+2jW?`@j0R;mM;Y90PfTanJ+glUa|T z4wk%~T|G3yNy)}*VL0N!$gq@sKU}p{2tpwMST3?I?@J7MLzn3|VG}z>+i#xxiO9w= z-S9$TNuH4(hpjlEb$Ne1(D-5w?8q&xH+FwHU*Fy-+i^=lb0fzhOZxS=chnLQh$Q5R zat_RRBw+ymer){IJkX08kFQ1oGck9OwoFbMEc2MXFUBp~BoiSPM`F$NfPoDWEZ4X? zA>5lYzttrnniMpVlak-VJ3TnWZ`@QM*o$0@>Sx>~ICTJSP#)ofIBRNQOCKhM1rIs? z955DtpKuwm9#X;wXnnLh8JTIV@)6Ba_`U{Vbq;Jr(EDfQdX$9mr@uw#4i~)y(Il0L zFJ>+uJu$0g`&&RiRZRCFI0v@uJ^f0()|mZxg+l}x!e-7+Q5`mbzN+(_JcPw>KMVcq zxJpjd)oEy#)>^Qfm&7NHm_OYP!bx^iPbT(vyIkxMq5kkrHUkT6xqIaGGi&*!X$ThM z&jBJJN;!WyiXKqi^9LVj8Hsqg&cX%t-*zQylF+Aq7gs4FDE~P+v#{Y8(iH5Zldg zG*ksFn2B2{l}@9IYxO!B&Oc1V>T+r}fGT65(m9LuNmrW+8rxM2jRn{N5P%%l7U^tWvO(IC~1|H;^S*A762tpIMx zu`GqRzkwML;mA&;SF5ubD_@EpE8f~;PeOkvk$StVj}kb_wToG zKstN!yK!Jftm5tNMl;+0iGc{Q^UCoJBIT*%rC^FM=}S)Y@{a#Xd){yk$eZooldFC$ zQm?b%%xfDHRPo{--h3)QuIp~>5EktO}D{%5lXSO?yiqV9JRCYWtn71xvI(n3OFu0@m<$uM~Z_u`x676p7 z&3Uu6@38Vhk(z2!!hE)(yP7soMFd%vy4fd1!#iu~R+oB0d2;V+!Ui}5)~-YFr2@!U z&I>RfJlOhov1p4PiTf>CusETxYT__R| zVx^$O9Z%R`7kg_>tJfIi-6EV-nN4?(CrE|!1CJj}s{L+BT~p0?AGjR_cJ*#@hU@|q zWiH_fj$2u&C!P)Obj|%&dG3NNOe(+b_ITDs$Bf`tf}i^Sxc}|0c@Tw>P;QsZfNrjp)eDJ->cO(~#AY+JAjajd0AZ6Wr<`{?^$ z1NXd8bo^%*?pgtyW8t%7aU;Advv7?$hh(YsvDxLvt%-Gh|} zD=DrSeO+U4IBI~p0cAm0hu*g# zjdep=Lh;vk@|woJb?Ae%ZX`iS(N#r__-!sjg2g*?I~OIpV5He}c!MmIfB6N?DoW0^ zHWF3g$sKunKu;s9=)v?%Msnzb{qvNRdjo$j3}`U#nu5K(kI>^thkz!mF}E}su`Cc$61wxY2(T^Bq`$2*lJQR=a8FN9boCNunrS^N$k z7pky56s%^9ylWPi5d~YBrqF{Y<5rxNRGyqA;tT5I-Vw(NPIDmawkv2#zh6z>SLqz@ zxVZ9RFP*yV4zB-DL7Wvm-#$zErk7&GmJbh8iR3L~Hn!X~IW!$Xg8vT2nH0mG%T&(> zCBp1G2rgtegR|b;=`9zXAhU5chD&o=3)e*RSZU}?*rj!-%rW(jHf#cLi@j`cW|7Sw zQq}vX|1vi7C+)pU@47^qsmYlAPv^dbhU##xJ8Tl}d-rSaI4{a7_vcn{d(J$a{!c+T z;VbGXe9SPAOzrB&d{{aAgjheD_y&d*x8UE~H9!@rq`z!@&cefn&!;l_y^g55W|azk z{pho@J2ARTA|?9E4Ch@Tmh=&gV1?2T?XjEucjgR$ED(=RlOJefvlJES|If^iW8koK zQ>9_IEpi>)1+*4&J@yW>AvM#9Iu$lV zrL6Kn{M*j9?~_*C690*q7rOC{C|aDqwKPfzxz1T-JtXGQ%xe7t$WX2=aRvosFzBTb zVvEeF3wm+-Dt|Vn=(eqKQ(vO{pZRr<#r48K8KlymJl`|*0q7V}nO5Oy5W!x+tgp?( zTTlGrK0-kzpJ>Y*XzK)h)R;RsYNuQ+Lk&H-b0t6p>rK9yRC%)YzN>gn$pUQOTV^cd zQh1nforLSIshv#jJ=nvreF0Cj$Zl|rm!j{wC$&TPq&U=!7XQxOG2w(8_v)%ol{Nfo zrn99Rd#OD!Y{sKkAdsR(r9FA@+C@qDG^){?qQYc<7jGG$Bit z!qrBO-{b$BydRv>lxgn^m!=&bRo^huSEQ9)b?pO6tVA*#~~xTZpX!UiIS1 zcs;c@t@!b`?|ejczgIZOAR9}d_s(pQa^PJie*q4sipIP?+lh|tcIc^pS%fDcOUuLx z1@Gu>4`4QQKl&(}$u5tDvty?m>M-`I2)i#3=j5xM!(nDqiI-KHA@4Mq4p%AZr=_}l+X{0OE z<^B-*Umh|HjJRk511GOw{1K10tsDH2jA9r{#21f#)ciVA`*u6P!Yc|d|CQ4w>IpOM z?BN79wA`>-ALwvz+WOBC0C`14`s;5T5tgpZ8GF%iO}zm=n;_n>h9Qi9H*Lzm6doM@ ziXxqapT(ghpaIv!yiVRDw)1?&7>(yA|E*`8xpr*o-CRp`ShB|o$VA+LWT|ZC2np`Z zdo6L$8zg6v>9Gst2eBo{2cBXS{D}oydRT2~9C^EY)WfgZAKk3^LG|w-tLU)xd@aQ~ zOFaal*3#apVZKfpZO%-z%6%(DvLwhx5Q|7sFLs3VX|%UBg$c%l5A*t_fNqME!1f4g z({0Q1hXikzA5SH8XN+wsMcf(th7pU2JeP%&fd*+F1(uu>*a3qgFCE z@RF6wmb=yAYJD;rHc&yIldQSYcWGUId9T&|#?0XoP=YeYpGEsTJ`0veh^xHua#4=L zawpJ5@^Mh&7<|KhI&MkhiN^X~%ykm%N_VA=9tGDt#|${EC>EuP z-H2<)#&+A+7kLr5CK$EVwVU|6_(N6o51)YRcxXucobfB}uBE{UY>uiWIhhL)+3<&&(Z%Rde zI_-hV>h4xm>s?UL1*qcvqOi0`&UPRE2aU>EFfE z={gZp)FV^eV-7txqW3<6`g2W>CYgAJ9WmJTru6}(4`_DWlv8_M^%e1dF0xJrj{2Ez zG|I%QxT?^8s-_R!-jdv=q*S+29+jxT?imf$O<({TGDMPi@(x$vZ?lO)R97HlJ|)6? zooA7br$fX2O&@?UPr#*1NjF`JwSHMGi?y;GSJaS}QgnN9e=JQ0aIO?FgT=9vavbia zR-9(nnPNCQqCUd@)PbJEv7nb*ya~rw1!>7sG&*`H@;hTHC-^l%iDNU#waPrHOH^sP ziHT}?QufPmKaV{#Lsb5|{&7mo#Wndk(O#_$K47 z-IMEEmE?@~TE8?{$pl}w!p;}~lR#Yh8+7md%Phqpr~kSwM7j05nsFqvJ>0zvZjx>< zobYKK^|<+D%*oBhz3h8En!p)XABeV%qEns+2*K>p+g!H_UCm~AEj6)b?6P$;?_7x= z%vVs6fU{l{{o+)>_rF;>EpokP^_YL>0n*K9m1+>zPg#+8<_%^e?j*A~**BO44!t#x$9ZR>tV&949Xi{j{r`Ed%`>fsx4>d9}3=U zDdG^98j6xp3`kwUYwF&`;IZOdXGsKN@Zai{PVMExiGJF%A0S}=Zm66XPerLwJC72j zZ8|(CB*ypla17MayM*Lc_o@8%zFCOze1wOI8Aa_C0^hdqg|nbdi%*+X3P<(^j!oF$ zELHl8!{5uL>>1+sOuyHC{y(qhoacMK%Xz-%^Uhnqn1R_hvx5vJ3r68^ZkB*EU;Cc9V zrLlgI03ZU=P zH`SG-)7)#HPp$UeI5oWIOO_3N&}(OEJj%neuCNoe**Ebwrau5)H6*;ioH2nk(Y+ge!=^}fW;2qr@KdinDp>_nG8{x! zt=B!@f3*MXgz(@qHpILEupv&MUC97mKuMmjqRGi~tMZMBm@4blfxxZtFu1w!{aYO| zTgYxNm)!VE2#x#H}yT zgs!VKoeNk*RJ(CbaQdjg3vKl3z6;$`wtO)qUykLBc~Y2>0G`-D70K~c|JFMueVJ_F ze0gd3Fr}aw7gi}2&|q8rrpx1k0LxORA$>Q7rbmv-s=S!VHgHRAG$P`W3UB&f;r6(7 z%jEN9QZ`ke^yXGQ@oG=`3($@x=`1vK-}g&cy2m&7U67$?A{MC-Rd6EMo}r*-lL^hZ z?7ig$PbfEHSyvpUG}v2{4_6JO+`~kX@?>}bmV*9lcjYVp?P64!OhB4OmX_yp!k^4$ zsRSxn{Qymct7_2>q9c2Y*{%ZIh@?3}mD188RjQ$kUlrDbm1UCoGv$AH zS%g^8Qr>hb^ z(9|d+TkBpS<0)z1S^1S7L$p$t5Noaz9SXRm^3K>M1ORU=O^8UHV03==W7_Rru3>%* zR&$pC3SO8q`0b=s8FQMZkrJdph3y0Io)wx(uY*^~QaW-b^VsvXiWAvfAofP!UtgI2 z)kLO}Rc&vPlgzn@01hwZ1n+#!dwMLfTRlQJH7;ij(nYiog8e)Ky72{{eNdqFaw9Eq zP@6W$EqUW}HGuTELH@PcS9z4=oSyWy3f_T|840Asw!`k^wJjUT1minmw!#Cc*yD0C zfK8q@PCfh1L6#MIMmcQc9NMqjpTGXe**qO6Yl2dVR(sfr*+I$X37TJmHKLo`{{sTU z(Hdrz_WlENXgy2jI?^Eui8Rwe9+Ca_?Xa9x(?Q1iU+%`}K}utU6?vFMx7M< z+W$xg+7b=jZD@McDvBQolqe1xEgJp~6b)J;B0dS>5@n+qvQ6X2-L~sy1R@a9*z{?9 z?HhPn{h95U9JWF7KNI`x1f$%7#bHtJpvmo%Ab?_0QGfjYQ9 zuJkovn-$DP7W5zYe^Isn@Zqmkv-|SgO|)Oo2wvD%8$&1i+kb_DTopi}!nW}`dqpWG z__;qasf?^p@M8scS(|C8=G!|Y^hiZg{>h$C_yggDA>{nFuhAwCVEbcJRALJJG}YBa z?#O{4Ob5w4>Et$`QRtzc)uKufv!`<*Z7_GSvBX;(Mo%Vrloy)$?uma;oEm@CT^r+; ztq4S;Rxg#qGc7D~%94@(g7vo(UCZ$Y)q7#}VZ>Zina+-vm9EWPQ# zl0<1B>fAw2@J88AcjdICUTB2=Xt_AU8Bf0RQM7ncv3MWT`PHS%dhfOiaKhIVEcjfS z1q^e(ou53O$@A@N)W$;rYJf!0VHAE5+ti*Ia)k64()3!$&w{Z%uDH|lqfWV@YkTFFy!cC@e@t~1fG^>6 z%xrBH_BEkfHgM^qY+^!z^x$8E>1SU@xEoHnt~6V_E2I-#UZn1Q0#U5F&6MA1vvjAS zi_l}S1wa^LqD9WI739?hl~u)=z#G+Uj*;`Fd4?x3K{4<#7)*D%C^5wH+yjl|E7=FX z-wpbEy^|Eii_E$MP^2t0bYfldUq`fyk1bQKR7~vSGGW)Or&$RRl0tMsZn&1d=cd!Y z0UWm#&la47if$2ri6V$@(!ZSm^Ew%zJx{AXHTu$3bLghbv_)0keN7FLT|NQTyZxjN zMbpp@GYK&~mv&)y%}8G}%-ViJV0Xk#=drgfDI6bnP(F!ff1?Z#k-y!R z1hnlkMVvHzJqAvv5ko=I`=G7H{l7JDzh_p*&sRug5(t~8hmS2s65&8m>Wn+;^%DY8 zFZFDQFQ|Oa>{{nU7kh`w4Ax9}3-I^Xqog+)IXCZJKX3@~sW!2CFjv+@R8A+r&`kaDpK*77s*5IQtx&{cDp;kGN?M^GLmD33eTr{y=%YoH9wTtK|4Z*`! zL~TwT)mG1+gH#pwYDQA@S{#KfFdpWU?8B%%w^%TTfW(|+@8+i8d7&0V?1g;4xSBsy z8DzcWSW$^25lx>v$WASE_u3YziA`Uer@Bl(lK-Ktg6`a2Oh@M0hUi35*m67Tz8tKw z+OgLSP1a!SLI8`0V4l?BEcWu|>YJlWxG}kt$`=!nwb+;AeS|9r)7}RCC$-pF$9nye z8ft|C{I1-|$8}T7u{&Eup=#PMIV+W+?k>&;B8o)I%4b=r5PH;u_qcO6F9E>Dnd zCT)^8{)vm_y1XU`?S}uYcZtz34=~kkE3Umc%^nrsb_mUnnKAAilE$(DkFkM;ew7|3 F@_+AV*hT;V literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json b/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json new file mode 100644 index 00000000..1ecfeae9 --- /dev/null +++ b/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "expand.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/expand_video.imageset/expand.png b/ios/Runner/Assets.xcassets/expand_video.imageset/expand.png new file mode 100644 index 0000000000000000000000000000000000000000..7020dc2ef8e2f6f35465c65c06836422cda0fd91 GIT binary patch literal 5366 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 PzPNO?j5Ob>+lTxQOg$37 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json b/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json new file mode 100644 index 00000000..2a0f4d2e --- /dev/null +++ b/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "mic_mute.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/mic_mute.imageset/mic_mute.png b/ios/Runner/Assets.xcassets/mic_mute.imageset/mic_mute.png new file mode 100644 index 0000000000000000000000000000000000000000..266cb6c72418b5aba18b32c421c2b4e75f05e47e GIT binary patch literal 6537 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 Becu28 literal 0 HcmV?d00001 diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index 73e18f76..17833007 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,16 +1,16 @@ - + - + - + - + @@ -23,12 +23,12 @@ - + - + - + @@ -37,252 +37,451 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - + - + + + + - + + @@ -292,5 +491,7 @@ + + diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift new file mode 100644 index 00000000..c6466343 --- /dev/null +++ b/ios/Runner/MainAppViewController.swift @@ -0,0 +1,142 @@ +// +// MainAppViewController.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 08/06/2021. +// Copyright © 2021 The Chromium Authors. All rights reserved. +// + +import Foundation + +class MainAppViewController: FlutterViewController{ + var videoCallContainer:UIView! + var videoCallViewController:VideoCallViewController! + var videoCallFlutterResult:FlutterResult? + var vdoCallViewMinConstraint:[NSLayoutConstraint]! + var vdoCallViewMaxConstraint:[NSLayoutConstraint]! + + + override func viewDidLoad() { + super.viewDidLoad() + initFlutterBridge() + prepareVideoCallView() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + private func initFlutterBridge(){ + let videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: binaryMessenger) + videoCallChannel.setMethodCallHandler({ + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + switch call.method { + case "openVideoCall": + self.startVideoCall(result: result, call: call) + default: + result(FlutterMethodNotImplemented) + } + }) + } + +} + + +// Video Call Functions +extension MainAppViewController : ICallProtocol{ + + func prepareVideoCallView(){ + videoCallContainer = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)) + videoCallContainer.alpha = 0.0 + videoCallContainer.backgroundColor = UIColor.black + view.addSubview(videoCallContainer) + setVideoViewConstrints() + NSLayoutConstraint.activate(vdoCallViewMaxConstraint) + NSLayoutConstraint.deactivate(vdoCallViewMinConstraint) + + ViewEmbedder.embed( + withIdentifier: "videoCall", // Storyboard ID + parent: self, + container: self.videoCallContainer){ vc in + self.videoCallViewController = vc as? VideoCallViewController + + } + } + + private func startVideoCall(result: @escaping FlutterResult, call:FlutterMethodCall) { + videoCallFlutterResult = result + + if let arguments = call.arguments as? NSDictionary{ + showVideoCallView(true) + + videoCallViewController.onMinimize = { min in + self.minimizeVideoCall(min) + } + videoCallViewController.onClose = videoCallClosed + videoCallViewController.callBack = self + videoCallViewController.start(params: VideoCallRequestParameters(dictionary: arguments)) + } + + + } + + private func minimizeVideoCall(_ value:Bool){ + UIView.animate(withDuration: 0.5) { + if(value){ + NSLayoutConstraint.deactivate(self.vdoCallViewMaxConstraint) + NSLayoutConstraint.activate(self.vdoCallViewMinConstraint) + }else{ + NSLayoutConstraint.deactivate(self.vdoCallViewMinConstraint) + NSLayoutConstraint.activate(self.vdoCallViewMaxConstraint) + } + self.videoCallContainer.layer.cornerRadius = value ? 10 : 0 + self.videoCallContainer.layer.borderColor = value ? UIColor.white.cgColor : nil + self.videoCallContainer.layer.borderWidth = value ? 2 : 0 + self.view.layoutIfNeeded() + } + } + + private func showVideoCallView(_ value:Bool){ + UIView.animate(withDuration: 0.5) { + self.videoCallContainer.alpha = value ? 1.0 : 0.0 + } completion: { complete in + if(value == false){ + self.videoCallContainer.removeFromSuperview() + } + } + } + + private func videoCallClosed(){ + showVideoCallView(false) + } + + func sessionDone(res: Any) { + videoCallFlutterResult?(res) + } + + func sessionNotResponded(res: Any) { + videoCallFlutterResult?(res) + } + + + func setVideoViewConstrints(){ + let screen = UIScreen.main.bounds + + + videoCallContainer.translatesAutoresizingMaskIntoConstraints = false + + vdoCallViewMinConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), + videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width/3), + videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height/3.5) + ] + vdoCallViewMaxConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width), + videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height) + ] + } + +} diff --git a/ios/Runner/VCEmbeder.swift b/ios/Runner/VCEmbeder.swift new file mode 100644 index 00000000..e86dde75 --- /dev/null +++ b/ios/Runner/VCEmbeder.swift @@ -0,0 +1,71 @@ +// +// VCEmbeder.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 08/06/2021. +// Copyright © 2021 The Chromium Authors. All rights reserved. +// + +import Foundation + +extension UIView { + func fill(to parent: UIView) { + topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + } + + func fillToParent() { + if let parent = self.superview{ + topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + } + } + + func fillTo(view:UIView) { + view.addSubview(self) + fill(to: view) + } +} + +class ViewEmbedder { + class func embed( + parent:UIViewController, + container:UIView, + child:UIViewController, + previous:UIViewController?){ + + if let previous = previous { + removeFromParent(vc: previous) + } + child.willMove(toParent: parent) + parent.addChild(child) + container.addSubview(child.view) + child.didMove(toParent: parent) + let w = container.frame.size.width; + let h = container.frame.size.height; + child.view.frame = CGRect(x: 0, y: 0, width: w, height: h) + + child.view.fill(to: container) + } + + class func removeFromParent(vc:UIViewController){ + vc.willMove(toParent: nil) + vc.view.removeFromSuperview() + vc.removeFromParent() + } + + class func embed(withIdentifier id:String, parent:UIViewController, container:UIView, completion:((UIViewController)->Void)? = nil){ + let vc = parent.storyboard!.instantiateViewController(withIdentifier: id) + embed( + parent: parent, + container: container, + child: vc, + previous: parent.children.first + ) + completion?(vc) + } +} diff --git a/ios/Runner/VideoCallRequestParameters.swift b/ios/Runner/VideoCallRequestParameters.swift new file mode 100644 index 00000000..2366c562 --- /dev/null +++ b/ios/Runner/VideoCallRequestParameters.swift @@ -0,0 +1,27 @@ + + +import Foundation + +class VideoCallRequestParameters{ + var apiKey:String? + var sessionId:String? + var token:String? + var lang:String? + var vcId:Int? + var tokenId:String? + var generalId:String? + var doctorId:Int? + var baseUrl:String? + + init(dictionary:NSDictionary){ + self.apiKey = dictionary["kApiKey"] as? String + self.sessionId = dictionary["kSessionId"] as? String + self.token = dictionary["kToken"] as? String + self.lang = dictionary["appLang"] as? String + self.vcId = dictionary["VC_ID"] as? Int + self.tokenId = dictionary["TokenID"] as? String + self.generalId = dictionary["generalId"] as? String + self.doctorId = dictionary["DoctorId"] as? Int + self.baseUrl = dictionary["baseUrl"] as? String + } +} diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoCallViewController.swift similarity index 84% rename from ios/Runner/VideoViewController.swift rename to ios/Runner/VideoCallViewController.swift index 44e45f3a..a05957c9 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -11,7 +11,7 @@ import OpenTok import Alamofire -class ViewController: UIViewController { +class VideoCallViewController: UIViewController { var session: OTSession? var publisher: OTPublisher? @@ -34,18 +34,104 @@ class ViewController: UIViewController { var seconds = 30 var isUserConnect : Bool = false + var onMinimize:((Bool)->Void)? = nil + var onClose:(()->Void)? = nil + + // Bottom Actions + @IBOutlet weak var actionsHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var videoMuteBtn: UIButton! + @IBOutlet weak var micMuteBtn: UIButton! + + @IBOutlet weak var localvideoTopMargin: NSLayoutConstraint! + @IBOutlet weak var localVideo: UIView! + @IBOutlet weak var remoteVideo: UIView! + @IBOutlet weak var controlButtons: UIView! + @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! + @IBOutlet weak var localVideoMutedBg: UIView! override func viewDidLoad() { - super.viewDidLoad() + super.viewDidLoad() + localVideo.layer.borderColor = UIColor.white.cgColor + } + + @IBAction func didClickMuteButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + publisher!.publishAudio = !sender.isSelected - setupButtons() - askForMicrophonePermission() - requestCameraPermissionsIfNeeded() - hideVideoMuted() - setupSession() - - } + } + @IBAction func didClickSpeakerButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + subscriber?.subscribeToAudio = !sender.isSelected + // resetHideButtonsTimer() + } + + @IBAction func didClickVideoMuteButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + if publisher!.publishVideo { + publisher!.publishVideo = false + } else { + publisher!.publishVideo = true + } + localVideo.isHidden = sender.isSelected + localVideoMutedBg.isHidden = !sender.isSelected + // resetHideButtonsTimer() + + } + + + @IBAction func didClickSwitchCameraButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + if sender.isSelected { + publisher!.cameraPosition = AVCaptureDevice.Position.front + } else { + publisher!.cameraPosition = AVCaptureDevice.Position.back + } + /// resetHideButtonsTimer() + } + + @IBAction func hangUp(_ sender: UIButton) { + callBack?.sessionDone(res:["callResponse":"CallEnd"]) + sessionDisconnect() + } + + var minimized = false + @IBAction func onMinimize(_ sender: UIButton) { + minimized = !minimized + sender.isSelected = minimized + onMinimize?(minimized) + + self.videoMuteBtn.isHidden = minimized + self.micMuteBtn.isHidden = minimized + + let min_ = minimized + UIView.animate(withDuration: 1) { + self.actionsHeightConstraint.constant = min_ ? 30 : 60 + self.localvideoTopMargin.constant = min_ ? 20 : 40 + + let vdoBound = self.localVideo.bounds + self.publisher?.view?.frame = CGRect(x: 0, y: 0, width: vdoBound.size.width, height: vdoBound.size.height) + self.publisher?.view?.layoutIfNeeded() + } + } + + func start(params:VideoCallRequestParameters){ + + self.kApiKey = params.apiKey ?? "" + self.kSessionId = params.sessionId ?? "" + self.kToken = params.token ?? "" + self.VC_ID = params.vcId ?? 0 + self.generalid = params.generalId ?? "" + self.TokenID = params.tokenId ?? "" + self.DoctorId = params.doctorId ?? 0 + self.baseUrl = params.baseUrl ?? "" + + setupButtons() + askForMicrophonePermission() + requestCameraPermissionsIfNeeded() + hideVideoMuted() + setupSession() + } private func changeCallStatus(callStatus:Int){ let URL_USER_REGISTER = baseUrl+"LiveCareApi/DoctorApp/ChangeCallStatus" @@ -137,59 +223,15 @@ class ViewController: UIViewController { // display a useful message asking the user to grant permissions from within Settings > Privacy > Camera } - - @IBAction func didClickMuteButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - publisher!.publishAudio = !sender.isSelected - - } - - @IBAction func didClickSpeakerButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - subscriber?.subscribeToAudio = !sender.isSelected - // resetHideButtonsTimer() - } - - @IBAction func didClickVideoMuteButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - if publisher!.publishVideo { - publisher!.publishVideo = false - } else { - publisher!.publishVideo = true - } - localVideo.isHidden = sender.isSelected - localVideoMutedBg.isHidden = !sender.isSelected - localVideoMutedIndicator.isHidden = !sender.isSelected - // resetHideButtonsTimer() - - } - - - @IBAction func didClickSwitchCameraButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - if sender.isSelected { - publisher!.cameraPosition = AVCaptureDevice.Position.front - } else { - publisher!.cameraPosition = AVCaptureDevice.Position.back - } - /// resetHideButtonsTimer() - } - - @IBAction func hangUp(_ sender: UIButton) { - callBack?.sessionDone(res:["callResponse":"CallEnd"]) - sessionDisconnect() - } - - func sessionDisconnect() { changeCallStatus(callStatus: 16) if (session != nil) { print("disconnecting....") session!.disconnect(nil) dismiss(animated: true) - return } dismiss(animated: true) + onClose?() } func requestCameraPermissionsIfNeeded() { @@ -226,7 +268,6 @@ class ViewController: UIViewController { func hideVideoMuted() { remoteVideoMutedIndicator.isHidden = true localVideoMutedBg.isHidden = true - localVideoMutedIndicator.isHidden = true } func setupSession() { @@ -267,19 +308,6 @@ class ViewController: UIViewController { - @IBOutlet weak var localVideo: UIView! - - @IBOutlet weak var remoteVideo: UIView! - - @IBOutlet weak var controlButtons: UIView! - - @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! - - @IBOutlet weak var localVideoMutedBg: UIImageView! - - - @IBOutlet weak var localVideoMutedIndicator: UIImageView! - @objc func updateTimer(){ seconds -= 1 //This will decrement(count down)the seconds. print(seconds) @@ -293,7 +321,7 @@ class ViewController: UIViewController { } -extension ViewController: OTSessionDelegate { +extension VideoCallViewController: OTSessionDelegate { func sessionDidConnect(_ session: OTSession) { print("The client connected to the OpenTok session.") @@ -301,7 +329,7 @@ extension ViewController: OTSessionDelegate { - timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true) + timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(VideoCallViewController.updateTimer)), userInfo: nil, repeats: true) setupPublisher() @@ -318,9 +346,8 @@ extension ViewController: OTSessionDelegate { if error != nil { showAlert(error?.localizedDescription) } - - publisher?.view!.frame = CGRect(x: localVideo.bounds.origin.x, y: localVideo.bounds.origin.y, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) - + + publisher?.view!.frame = CGRect(x: 0, y: 0, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) localVideo.addSubview((publisher?.view)!) } @@ -408,7 +435,7 @@ extension ViewController: OTSessionDelegate { } -extension ViewController: OTPublisherDelegate { +extension VideoCallViewController: OTPublisherDelegate { func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { print("The publisher failed: \(error)") } @@ -420,7 +447,7 @@ extension ViewController: OTPublisherDelegate { } } -extension ViewController: OTSubscriberDelegate { +extension VideoCallViewController: OTSubscriberDelegate { public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) { print("The subscriber did connect to the stream.") } diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 10181bf4..c011a4e1 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -109,7 +109,7 @@ class BaseAppClient { parsed['AndroidLink'], parsed['IOSLink']); } - if (!parsed['IsAuthenticated']) { + if (parsed['IsAuthenticated'] != null && !parsed['IsAuthenticated']) { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 55b2d6f9..30f53a0b 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -289,60 +289,64 @@ class _PatientProfileScreenState extends State EndCallScreen(patient:patient))); } else { GifLoaderDialogUtils.showMyDialog(context); - await model.startCall( isReCall : false, vCID: patient.vcId); + // await model.startCall( isReCall : false, vCID: patient.vcId); - if(model.state == ViewState.ErrorLocal) { - GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(model.error); - } else { - await model.getDoctorProfile(); - patient.appointmentNo = model.startCallRes.appointmentNo; - patient.episodeNo = 0; + if(model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); + Helpers.showErrorToast(model.error); + } else { + await model.getDoctorProfile(); + // patient.appointmentNo = model.startCallRes.appointmentNo; + patient.episodeNo = 0; - GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: model.startCallRes.openTokenID, - kSessionId: model.startCallRes.openSessionID, - kApiKey: '46209962', - vcId: patient.vcId, - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - }, - onCallEnd: () { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, false,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); + GifLoaderDialogUtils.hideDialog(context); + await VideoChannel.openVideoCallScreen( + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, + kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, + kApiKey: '47247954',//46209962 + vcId: patient.vcId, + tokenID: await model.getToken(), + generalId: GENERAL_ID, + doctorId: model.doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + }, + onCallEnd: () { + var asd=""; + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, false,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + var asd=""; + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // + // }); + }); - }); - }); - } + } } + }, ), ), diff --git a/pubspec.lock b/pubspec.lock index 25596d43..77df9848 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 176c0ab97cc26fe4141b2deb0c5dda0594465971 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 14:18:16 +0300 Subject: [PATCH 141/241] first step from live care fixes --- .../live_care/AlternativeServicesList.dart | 1 + .../patient/LiveCarePatientServices.dart | 10 +- .../viewModel/LiveCarePatientViewModel.dart | 10 +- lib/models/livecare/start_call_req.dart | 72 +++--- lib/screens/home/home_patient_card.dart | 9 +- lib/screens/home/home_screen.dart | 2 +- lib/screens/live_care/end_call_screen.dart | 9 +- .../live-care_transfer_to_admin.dart | 2 +- .../live_care/live_care_patient_screen.dart | 2 +- .../patient_profile_screen.dart | 231 ++++++++++-------- 10 files changed, 182 insertions(+), 166 deletions(-) diff --git a/lib/core/model/live_care/AlternativeServicesList.dart b/lib/core/model/live_care/AlternativeServicesList.dart index fab11b71..11f27b95 100644 --- a/lib/core/model/live_care/AlternativeServicesList.dart +++ b/lib/core/model/live_care/AlternativeServicesList.dart @@ -11,6 +11,7 @@ class AlternativeService { AlternativeService.fromJson(Map json) { serviceID = json['ServicID']; serviceName = json['ServiceName']; + isSelected = false; } Map toJson() { diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index e813e017..de381962 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -18,7 +18,7 @@ class LiveCarePatientServices extends BaseService { bool _isFinished = false; - bool _isLive = true; + bool _isLive = false; bool get isFinished => _isFinished; @@ -74,7 +74,7 @@ class LiveCarePatientServices extends BaseService { }, body: startCallReq.toJson(), isLiveCare: _isLive); } - Future endCallWithCharge(int vcID, String altServiceList) async { + Future endCallWithCharge(int vcID, List altServiceList) async { hasError = false; await baseAppClient.post(END_CALL_WITH_CHARGE, onSuccess: (dynamic response, int statusCode) { endCallResponse = response; @@ -84,6 +84,7 @@ class LiveCarePatientServices extends BaseService { }, body: { "VC_ID": vcID, "AltServiceList": altServiceList, + "generalid":GENERAL_ID }, isLiveCare: _isLive); } @@ -110,7 +111,7 @@ class LiveCarePatientServices extends BaseService { hasError = true; super.error = error; }, body: { - "VC_ID": vcID, + "VC_ID": vcID, "generalid": GENERAL_ID }, isLiveCare: _isLive); } @@ -140,6 +141,7 @@ class LiveCarePatientServices extends BaseService { super.error = error; }, body: { "VC_ID": vcID, - }, isLiveCare: _isLive); + "generalid": GENERAL_ID + }, isLiveCare: _isLive); } } diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index 8dc83c06..378013bd 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -101,13 +101,13 @@ class LiveCarePatientViewModel extends BaseViewModel { Future endCallWithCharge(int vcID, bool isConfirmed) async { setState(ViewState.BusyLocal); - String selectedServicesString = ""; + List selectedServices = []; if (isConfirmed) { - selectedServicesString = getSelectedAlternativeServices(); + selectedServices = getSelectedAlternativeServices(); } await _liveCarePatientServices.endCallWithCharge( - vcID, selectedServicesString); + vcID, selectedServices); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; setState(ViewState.ErrorLocal); @@ -117,14 +117,14 @@ class LiveCarePatientViewModel extends BaseViewModel { } } - String getSelectedAlternativeServices() { + List getSelectedAlternativeServices() { List selectedServices = List(); for (AlternativeService service in alternativeServicesList) { if (service.isSelected) { selectedServices.add(service.serviceID); } } - return selectedServices.toString(); + return selectedServices; } Future getAlternativeServices(int vcID) async { diff --git a/lib/models/livecare/start_call_req.dart b/lib/models/livecare/start_call_req.dart index 1ad04480..b3ceabb5 100644 --- a/lib/models/livecare/start_call_req.dart +++ b/lib/models/livecare/start_call_req.dart @@ -1,56 +1,56 @@ class StartCallReq { - int vCID; - bool isrecall; - String tokenID; - String generalid; + String clincName; + int clinicId; + String docSpec; + String docotrName; int doctorId; + String generalid; bool isOutKsa; + bool isrecall; String projectName; - String docotrName; - String clincName; - String docSpec; - int clinicId; + String tokenID; + int vCID; StartCallReq( - {this.vCID, - this.isrecall, - this.tokenID, - this.generalid, - this.doctorId, - this.isOutKsa, - this.projectName, - this.docotrName, - this.clincName, - this.docSpec, - this.clinicId}); + {this.clincName, + this.clinicId, + this.docSpec, + this.docotrName, + this.doctorId, + this.generalid, + this.isOutKsa, + this.isrecall, + this.projectName, + this.tokenID, + this.vCID}); StartCallReq.fromJson(Map json) { - vCID = json['VC_ID']; - isrecall = json['isrecall']; - tokenID = json['TokenID']; - generalid = json['generalid']; + clincName = json['clincName']; + clinicId = json['ClinicId']; + docSpec = json['Doc_Spec']; + docotrName = json['DocotrName']; doctorId = json['DoctorId']; + generalid = json['generalid']; isOutKsa = json['IsOutKsa']; + isrecall = json['isrecall']; projectName = json['projectName']; - docotrName = json['DocotrName']; - clincName = json['clincName']; - docSpec = json['Doc_Spec']; - clinicId = json['ClinicId']; + tokenID = json['TokenID']; + vCID = json['VC_ID']; } Map toJson() { final Map data = new Map(); - data['VC_ID'] = this.vCID; - data['isrecall'] = this.isrecall; - data['TokenID'] = this.tokenID; - data['generalid'] = this.generalid; + data['clincName'] = this.clincName; + data['ClinicId'] = this.clinicId; + data['Doc_Spec'] = this.docSpec; + data['DocotrName'] = this.docotrName; data['DoctorId'] = this.doctorId; + data['generalid'] = this.generalid; data['IsOutKsa'] = this.isOutKsa; + data['isrecall'] = this.isrecall; data['projectName'] = this.projectName; - data['DocotrName'] = this.docotrName; - data['clincName'] = this.clincName; - data['Doc_Spec'] = this.docSpec; - data['ClinicId'] = this.clinicId; + data['TokenID'] = this.tokenID; + data['VC_ID'] = this.vCID; return data; } -} +} \ No newline at end of file diff --git a/lib/screens/home/home_patient_card.dart b/lib/screens/home/home_patient_card.dart index 6f6712ec..b388a7e2 100644 --- a/lib/screens/home/home_patient_card.dart +++ b/lib/screens/home/home_patient_card.dart @@ -36,11 +36,10 @@ class HomePatientCard extends StatelessWidget { Expanded( child: Stack( children: [ - Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, + Container( + margin: EdgeInsets.only(top: 18, left: 10), + color:Colors.transparent, + child: Icon( cardIcon, size: iconSize * 2, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index ab0fe73f..82add64c 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -329,7 +329,7 @@ class _HomeScreenState extends State { backgroundIconColor: backgroundIconColors[colorIndex], cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], - iconSize: 24, + iconSize: 21, text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", onTap: () { diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 1b652e36..617eef34 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -142,25 +142,22 @@ class _EndCallScreenState extends State { 'patient/health_summary.png', onTap: () { Helpers.showConfirmationDialog(context, - "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC}${TranslationBase.of(context).instruction} ?", + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC} ${TranslationBase.of(context).instruction} ?", () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - liveCareModel.sendSMSInstruction(widget.patient.vcId); + await liveCareModel.sendSMSInstruction(widget.patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } else { DrAppToastMsg.showSuccesToast("You successfully sent SMS instructions"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); } }); }, isInPatient: isInpatient, isDartIcon: true, - isDisable: true, + // isDisable: true, dartIcon: DoctorApp.send_instruction), PatientProfileCardModel( TranslationBase.of(context).transferTo, diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart index 2d0fb7d7..233f59d8 100644 --- a/lib/screens/live_care/live-care_transfer_to_admin.dart +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -120,7 +120,7 @@ class _LivaCareTransferToAdminState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - model.transferToAdmin(widget.patient.vcId, noteController.text); + await model.transferToAdmin(widget.patient.vcId, noteController.text); GifLoaderDialogUtils.hideDialog(context); if (model.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(model.error); diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 0b741989..e6cdad17 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -31,7 +31,7 @@ class _LiveCarePatientScreenState extends State { super.initState(); timer = Timer.periodic(Duration(seconds: 10), (Timer t) { if (_liveCareViewModel != null) { - _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); + // _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); } }); } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 55b2d6f9..e64b582f 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,18 +1,13 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; -import 'package:doctor_app_flutter/models/livecare/session_status_model.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/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; -import 'package:doctor_app_flutter/util/VideoChannel.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -156,51 +151,57 @@ class _PatientProfileScreenState extends State SizedBox( height: MediaQuery.of(context).size.height * 0.05, ) - ], - ), - ), - ], ), - if (patient.patientStatusType != null && - patient.patientStatusType == 43) - BaseView( - onModelReady: (model) async {}, - builder: (_, model, w) => Positioned( - top: 180, - left: 20, - right: 20, - child: Row( - children: [ - Expanded(child: Container()), - if (patient.episodeNo == 0) - AppButton( - title: - "${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}", - color: patient.patientStatusType == 43 - ? Colors.red.shade700 - : Colors.grey.shade700, - fontColor: Colors.white, - vPadding: 8, - radius: 30, - hPadding: 20, - fontWeight: FontWeight.normal, - fontSize: 1.6, - icon: Image.asset( - "assets/images/create-episod.png", - color: Colors.white, + ), + ], + ), + if (isFromLiveCare + ? patient.episodeNo != null + : patient.patientStatusType != null && + patient.patientStatusType == 43) + BaseView( + onModelReady: (model) async {}, + builder: (_, model, w) => Positioned( + top: 180, + left: 20, + right: 20, + child: Row( + children: [ + Expanded(child: Container()), + if (patient.episodeNo == 0) + AppButton( + title: + "${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}", + color: isFromLiveCare + ? Colors.red.shade700 + : patient.patientStatusType == 43 + ? Colors.red.shade700 + : Colors.grey.shade700, + fontColor: Colors.white, + vPadding: 8, + radius: 30, + hPadding: 20, + fontWeight: FontWeight.normal, + fontSize: 1.6, + icon: Image.asset( + "assets/images/create-episod.png", + color: Colors.white, height: 30, ), onPressed: () async { - if (patient.patientStatusType == - 43) { + if ((isFromLiveCare && + patient.appointmentNo != null && + patient.appointmentNo != 0) || + patient.patientStatusType == + 43) { PostEpisodeReqModel - postEpisodeReqModel = - PostEpisodeReqModel( - appointmentNo: - patient.appointmentNo, - patientMRN: - patient.patientMRN); + postEpisodeReqModel = + PostEpisodeReqModel( + appointmentNo: + patient.appointmentNo, + patientMRN: + patient.patientMRN); GifLoaderDialogUtils.showMyDialog( context); await model.postEpisode( @@ -220,11 +221,18 @@ class _PatientProfileScreenState extends State if (patient.episodeNo != 0) AppButton( title: - "${TranslationBase.of(context).update}\n${TranslationBase.of(context).episode}", + "${TranslationBase + .of(context) + .update}\n${TranslationBase + .of(context) + .episode}", color: - patient.patientStatusType == 43 - ? Colors.red.shade700 - : Colors.grey.shade700, + isFromLiveCare + ? Colors.red.shade700 + : patient.patientStatusType == + 43 + ? Colors.red.shade700 + : Colors.grey.shade700, fontColor: Colors.white, vPadding: 8, radius: 30, @@ -237,8 +245,12 @@ class _PatientProfileScreenState extends State height: 30, ), onPressed: () { - if (patient.patientStatusType == - 43) { + if ((isFromLiveCare && + patient.appointmentNo != + null && + patient.appointmentNo != 0) || + patient.patientStatusType == + 43) { Navigator.of(context).pushNamed( UPDATE_EPISODE, arguments: { @@ -283,65 +295,70 @@ class _PatientProfileScreenState extends State TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - if(isCallFinished) { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); - } else { - GifLoaderDialogUtils.showMyDialog(context); - await model.startCall( isReCall : false, vCID: patient.vcId); - - if(model.state == ViewState.ErrorLocal) { - GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(model.error); - } else { - await model.getDoctorProfile(); - patient.appointmentNo = model.startCallRes.appointmentNo; - patient.episodeNo = 0; + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); - GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: model.startCallRes.openTokenID, - kSessionId: model.startCallRes.openSessionID, - kApiKey: '46209962', - vcId: patient.vcId, - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - }, - onCallEnd: () { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, false,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - WidgetsBinding.instance.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }); - } - } + // if(isCallFinished) { + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); + // } else { + // GifLoaderDialogUtils.showMyDialog(context); + // await model.startCall( isReCall : false, vCID: patient.vcId); + // + // if(model.state == ViewState.ErrorLocal) { + // GifLoaderDialogUtils.hideDialog(context); + // Helpers.showErrorToast(model.error); + // } else { + // await model.getDoctorProfile(); + // patient.appointmentNo = model.startCallRes.appointmentNo; + // patient.episodeNo = 0; + // + // GifLoaderDialogUtils.hideDialog(context); + // await VideoChannel.openVideoCallScreen( + // kToken: model.startCallRes.openTokenID, + // kSessionId: model.startCallRes.openSessionID, + // kApiKey: '46209962', + // vcId: patient.vcId, + // tokenID: await model.getToken(), + // generalId: GENERAL_ID, + // doctorId: model.doctorProfile.doctorID, + // onFailure: (String error) { + // DrAppToastMsg.showErrorToast(error); + // }, + // onCallEnd: () { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, false,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // }); + // }, + // onCallNotRespond: (SessionStatusModel sessionStatusModel) { + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // + // }); + // }); + // } + // } }, ), From e76ecf172fe331c10acb068779fcefa65f5ae492 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 9 Jun 2021 14:46:03 +0300 Subject: [PATCH 142/241] video-straming-android-changes --- android/app/build.gradle | 1 + .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 32 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 385 ++++++++++++++++++ android/app/src/main/res/values/strings.xml | 2 + pubspec.lock | 2 +- 5 files changed, 410 insertions(+), 12 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt diff --git a/android/app/build.gradle b/android/app/build.gradle index 16960d54..deb42f99 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -70,6 +70,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index 612118c9..b95e7cb9 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -2,17 +2,19 @@ package com.hmg.hmgDr import android.app.Activity import android.content.Intent +import android.os.Bundle import androidx.annotation.NonNull +import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel -import com.hmg.hmgDr.ui.VideoCallActivity -import com.google.gson.GsonBuilder +import io.flutter.embedding.android.FlutterFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant + class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { private val CHANNEL = "Dr.cloudSolution/videoCall" @@ -20,6 +22,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 + private val flutterFragment: FlutterFragment? = null override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -27,6 +30,11 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(this) } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + } + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { @@ -59,15 +67,17 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { // val videoCallActivity = VideoCallActivity() - val intent = Intent(this, VideoCallActivity::class.java) - intent.putExtra("apiKey", apiKey) - intent.putExtra("sessionId", sessionId) - intent.putExtra("token", token) - intent.putExtra("appLang", appLang) - intent.putExtra("baseUrl", baseUrl) - intent.putExtra("sessionStatusModel", sessionStatusModel) - startActivityForResult(intent, LAUNCH_VIDEO) - +// val intent = Intent(this, VideoCallActivity::class.java) +// intent.putExtra("apiKey", apiKey) +// intent.putExtra("sessionId", sessionId) +// intent.putExtra("token", token) +// intent.putExtra("appLang", appLang) +// intent.putExtra("baseUrl", baseUrl) +// intent.putExtra("sessionStatusModel", sessionStatusModel) +// startActivityForResult(intent, LAUNCH_VIDEO) + + val transaction = supportFragmentManager.beginTransaction() +// transaction.add() } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt new file mode 100644 index 00000000..be343b89 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -0,0 +1,385 @@ +package com.hmg.hmgDr.ui.fragment + +import android.Manifest +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import android.opengl.GLSurfaceView +import android.os.Bundle +import android.os.CountDownTimer +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.* +import androidx.fragment.app.Fragment +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel +import com.hmg.hmgDr.Model.GetSessionStatusModel +import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.R +import com.hmg.hmgDr.ui.VideoCallActivity +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView +import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.opentok.android.* +import com.opentok.android.PublisherKit.PublisherListener +import pub.devrel.easypermissions.AfterPermissionGranted +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions +import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks +import java.util.* + +class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, + SubscriberKit.VideoListener, VideoCallView { + + lateinit var videoCallPresenter: VideoCallPresenter + + private var mSession: Session? = null + private var mPublisher: Publisher? = null + private var mSubscriber: Subscriber? = null + + private var mVolHandler: Handler? = null + private var mConnectedHandler: Handler? = null + private var mVolRunnable: Runnable? = null + private var mConnectedRunnable: Runnable? = null + + private var mPublisherViewContainer: FrameLayout? = null + private var mSubscriberViewContainer: RelativeLayout? = null + private var controlPanel: RelativeLayout? = null + + private var apiKey: String? = null + private var sessionId: String? = null + private var token: String? = null + private var appLang: String? = null + private var baseUrl: String? = null + + private var isSwitchCameraClicked = false + private var isCameraClicked = false + private var isSpeckerClicked = false + private var isMicClicked = false + + private var mCallBtn: ImageView? = null + private var mCameraBtn: ImageView? = null + private var mSwitchCameraBtn: ImageView? = null + private var mspeckerBtn: ImageView? = null + private var mMicBtn: ImageView? = null + + private val progressBar: ProgressBar? = null + private val countDownTimer: CountDownTimer? = null + private val progressBarTextView: TextView? = null + private val progressBarLayout: RelativeLayout? = null + + private var isConnected = false + + private var sessionStatusModel: GetSessionStatusModel? = null + + + override fun onCreate(savedInstanceState: Bundle?) { + requireActivity().setTheme(R.style.AppTheme) + super.onCreate(savedInstanceState) + + requestPermissions() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + val view = inflater.inflate(R.layout.activity_video_call, container, false) + + Objects.requireNonNull(requireActivity().actionBar)!!.hide() + initUI(view) + + return view + } + + override fun onPause() { + super.onPause() + if (mSession == null) { + return + } + mSession!!.onPause() + if (requireActivity().isFinishing) { + disconnectSession() + } + } + + override fun onResume() { + super.onResume() + if (mSession == null) { + return + } + mSession!!.onResume() + } + + override fun onDestroy() { + disconnectSession() + super.onDestroy() + } + + @SuppressLint("ClickableViewAccessibility") + private fun initUI(view: View) { + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + } + + controlPanel = view.findViewById(R.id.control_panel) + videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) + mCallBtn = view.findViewById(R.id.btn_call) + mCameraBtn = view.findViewById(R.id.btn_camera) + mSwitchCameraBtn = view.findViewById(R.id.btn_switch_camera) + mspeckerBtn = view.findViewById(R.id.btn_specker) + mMicBtn = view.findViewById(R.id.btn_mic) + + // progressBarLayout=findViewById(R.id.progressBar); + // progressBar=findViewById(R.id.progress_bar); +// progressBarTextView=findViewById(R.id.progress_bar_text); +// progressBar.setVisibility(View.GONE); + hiddenButtons() + checkClientConnected() + mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> + controlPanel!!.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + true + } + if (appLang == "ar") { + progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL + } + } + + private fun checkClientConnected() { + mConnectedHandler = Handler((Looper.getMainLooper())) + mConnectedRunnable = Runnable { + if (!isConnected) { + videoCallPresenter.callClintConnected(sessionStatusModel) + } + } + mConnectedHandler!!.postDelayed(mConnectedRunnable!!, (55 * 1000).toLong()) + } + + private fun hiddenButtons() { + mVolHandler = Handler() + mVolRunnable = Runnable { controlPanel!!.visibility = View.GONE } + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size) + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size) + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + AppSettingsDialog.Builder(this) + .setTitle(getString(R.string.title_settings_dialog)) + .setRationale(getString(R.string.rationale_ask_again)) + .setPositiveButton(getString(R.string.setting)) + .setNegativeButton(getString(R.string.cancel)) + .setRequestCode(RC_SETTINGS_SCREEN_PERM) + .build() + .show() + } + } + + @AfterPermissionGranted(RC_VIDEO_APP_PERM) + private fun requestPermissions() { + val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA) + if (EasyPermissions.hasPermissions(requireContext(), *perms)) { + try { + mSession = Session.Builder(context, apiKey, sessionId).build() + mSession!!.setSessionListener(this) + mSession!!.connect(token) + } catch (e: Exception) { + e.printStackTrace() + } + } else { + EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, *perms) + } + } + + override fun onConnected(session: Session?) { + Log.i(TAG, "Session Connected") + mPublisher = Publisher.Builder(requireContext()).build() + mPublisher!!.setPublisherListener(this) + mPublisherViewContainer!!.addView(mPublisher!!.view) + if (mPublisher!!.getView() is GLSurfaceView) { + (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) + } + mSession!!.publish(mPublisher) + } + + override fun onDisconnected(session: Session) { + Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) + mSession = null + } + + override fun onError(session: Session, opentokError: OpentokError) { + Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) + Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() + requireActivity().finish() + } + + override fun onStreamReceived(session: Session, stream: Stream) { + Log.d(TAG, "onStreamReceived: New stream " + stream.streamId + " in session " + session.sessionId) + if (mSubscriber != null) { + isConnected = true + return + } + isConnected = true + subscribeToStream(stream) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + } + + override fun onStreamDropped(session: Session, stream: Stream) { + Log.d(TAG, "onStreamDropped: Stream " + stream.streamId + " dropped from session " + session.sessionId) + if (mSubscriber == null) { + return + } + if (mSubscriber!!.stream == stream) { + mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriber!!.destroy() + mSubscriber = null + } + disconnectSession() + } + + override fun onStreamCreated(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamCreated: Own stream " + stream.streamId + " created") + } + + override fun onStreamDestroyed(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamDestroyed: Own stream " + stream.streamId + " destroyed") + } + + override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { + Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") + Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() + requireActivity().finish() + } + + override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { + mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) + mSubscriberViewContainer!!.addView(mSubscriber!!.view) + } + + override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoDisableWarning(subscriberKit: SubscriberKit?) {} + + override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {} + + private fun subscribeToStream(stream: Stream) { + mSubscriber = Subscriber.Builder(requireContext(), stream).build() + mSubscriber!!.setVideoListener(this) + mSession!!.subscribe(mSubscriber) + } + + private fun disconnectSession() { + if (mSession == null) { + requireActivity().setResult(Activity.RESULT_CANCELED) + requireActivity().finish() + return + } + if (mSubscriber != null) { + mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSession!!.unsubscribe(mSubscriber) + mSubscriber!!.destroy() + mSubscriber = null + } + if (mPublisher != null) { + mPublisherViewContainer!!.removeView(mPublisher!!.view) + mSession!!.unpublish(mPublisher) + mPublisher!!.destroy() + mPublisher = null + } + mSession!!.disconnect() + countDownTimer?.cancel() + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + requireActivity().finish() + } + + fun onSwitchCameraClicked(view: View?) { + if (mPublisher != null) { + isSwitchCameraClicked = !isSwitchCameraClicked + mPublisher!!.cycleCamera() + val res = if (isSwitchCameraClicked) R.drawable.flip_disapled else R.drawable.flip_enabled + mSwitchCameraBtn!!.setImageResource(res) + } + } + + fun onCameraClicked(view: View?) { + if (mPublisher != null) { + isCameraClicked = !isCameraClicked + mPublisher!!.publishVideo = !isCameraClicked + val res = if (isCameraClicked) R.drawable.video_disanabled else R.drawable.video_enabled + mCameraBtn!!.setImageResource(res) + } + } + + fun onSpeckerClicked(view: View?) { + if (mSubscriber != null) { + isSpeckerClicked = !isSpeckerClicked + mSubscriber!!.subscribeToAudio = !isSpeckerClicked + val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled + mspeckerBtn!!.setImageResource(res) + } + } + + fun onMicClicked(view: View?) { + if (mPublisher != null) { + isMicClicked = !isMicClicked + mPublisher!!.publishAudio = !isMicClicked + val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled + mMicBtn!!.setImageResource(res) + } + } + + fun onCallClicked(view: View?) { + disconnectSession() + } + + override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { + if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { + val returnIntent = Intent() + returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) + requireActivity().setResult(Activity.RESULT_OK, returnIntent) + requireActivity().finish() + } + } + + override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + + override fun onFailure() {} + + companion object { + @JvmStatic + fun newInstance(args: Bundle) = + VideoCallFragment().apply { + arguments = args + } + + private val TAG = VideoCallActivity::class.java.simpleName + + private const val RC_SETTINGS_SCREEN_PERM = 123 + private const val RC_VIDEO_APP_PERM = 124 + + } +} \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 74349756..bc694f7c 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -4,5 +4,7 @@ الوقت المتبقي بالثانيه: Settings Cancel + + Hello blank fragment \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 77df9848..49ff6372 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -587,7 +587,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.1" + version: "0.6.2" json_annotation: dependency: transitive description: From 0b52b4009dadc429fda86c2adcc64db68176adaa Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 9 Jun 2021 14:46:45 +0300 Subject: [PATCH 143/241] fix label on replay referral --- android/app/src/main/AndroidManifest.xml | 13 +++++++++--- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 20 ++++++++++--------- .../referral/AddReplayOnReferralPatient.dart | 10 +++++----- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c656ebbf..0e71249f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,12 +9,19 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - - - + + + + + + + + + + controlPanel.setVisibility(View.GONE); mVolHandler.postDelayed(mVolRunnable, 5 * 1000); } @@ -269,8 +265,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi public void onError(Session session, OpentokError opentokError) { Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId()); - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); + // Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); + //finish(); } @Override @@ -282,6 +278,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } isConnected = true; subscribeToStream(stream); + if(mConnectedHandler!=null && mConnectedRunnable!=null) + mConnectedHandler.removeCallbacks(mConnectedRunnable); videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); } @@ -315,8 +313,8 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi public void onError(PublisherKit publisherKit, OpentokError opentokError) { Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher"); - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); + // Toast.makeText(this, "onError: Error (" + opentokError.getMessage() + ") in publisher", Toast.LENGTH_LONG).show(); + // finish(); } @Override @@ -427,6 +425,10 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel); setResult(Activity.RESULT_OK, returnIntent); finish(); + } else if( sessionStatusModel.getSessionStatus() == 4 ){ + isConnected = true; + if(mConnectedHandler!=null && mConnectedRunnable!=null) + mConnectedHandler.removeCallbacks(mConnectedRunnable); } } diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index f54a18ac..8055517d 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -58,7 +58,7 @@ class _AddReplayOnReferralPatientState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - BottomSheetTitle(title: 'Replay'), + BottomSheetTitle(title: 'Reply'), SizedBox( height: 10.0, ), @@ -70,7 +70,7 @@ class _AddReplayOnReferralPatientState Stack( children: [ AppTextFieldCustom( - hintText: 'Replay your responses here', + hintText: 'Reply your responses here', controller: replayOnReferralController, maxLines: 35, minLines: 25, @@ -128,7 +128,7 @@ class _AddReplayOnReferralPatientState Container( margin: EdgeInsets.all(5), child: AppButton( - title: 'Submit Replay', + title: 'Submit Reply', color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () async { @@ -147,12 +147,12 @@ class _AddReplayOnReferralPatientState } else { GifLoaderDialogUtils.hideDialog(context); DrAppToastMsg.showSuccesToast( - "Your Replay Added Successfully"); + "Your Reply Added Successfully"); Navigator.of(context).pop(); Navigator.of(context).pop(); } } else { - Helpers.showErrorToast("You can't add empty replay"); + Helpers.showErrorToast("You can't add empty reply"); setState(() { isSubmitted = false; }); From 36caca0e4659d7d518f59f7e90e7940519fe681a Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:07:58 +0300 Subject: [PATCH 144/241] test live care and general result header in lab result --- lib/config/config.dart | 4 +- .../patient/LiveCarePatientServices.dart | 2 +- .../live_care/live_care_patient_screen.dart | 2 +- .../lab_result/laboratory_result_page.dart | 46 ++- .../patient_profile_screen.dart | 129 +++---- .../profile/GeneralLabResultHeader.dart | 347 ++++++++++++++++++ 6 files changed, 445 insertions(+), 85 deletions(-) create mode 100644 lib/widgets/patients/profile/GeneralLabResultHeader.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index e2f9eb6a..97e1d4dd 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index de381962..29b120ec 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -18,7 +18,7 @@ class LiveCarePatientServices extends BaseService { bool _isFinished = false; - bool _isLive = false; + bool _isLive = true; bool get isFinished => _isFinished; diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index e6cdad17..0b741989 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -31,7 +31,7 @@ class _LiveCarePatientScreenState extends State { super.initState(); timer = Timer.periodic(Duration(seconds: 10), (Timer t) { if (_liveCareViewModel != null) { - // _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); + _liveCareViewModel.getPendingPatientERForDoctorApp(isFromTimer: true); } }); } diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 5f79038f..91e5145f 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -2,7 +2,7 @@ import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/viewModel/labs_view_model.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/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/GeneralLabResultHeader.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -32,37 +32,45 @@ class _LaboratoryResultPageState extends State { @override Widget build(BuildContext context) { return BaseView( - // onModelReady: (model) => model.getLaboratoryResult( - // invoiceNo: widget.patientLabOrders.invoiceNo, - // clinicID: widget.patientLabOrders.clinicID, - // projectID: widget.patientLabOrders.projectID, - // orderNo: widget.patientLabOrders.orderNo, - // patient: widget.patient, - // isInpatient: widget.patientType == "1"), onModelReady: (model) => model.getPatientLabResult( patientLabOrder: widget.patientLabOrders, patient: widget.patient, isInpatient: true), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: widget.patient, - patientType: widget.patientType ?? "0", - arrivalType: widget.arrivalType ?? "0", - orderNo: widget.patientLabOrders.orderNo, - appointmentDate: widget.patientLabOrders.orderDate, - doctorName: widget.patientLabOrders.doctorName, - branch: widget.patientLabOrders.projectName, - clinic: widget.patientLabOrders.clinicDescription, - profileUrl: widget.patientLabOrders.doctorImageURL, - invoiceNO: widget.patientLabOrders.invoiceNo, + appBar: GeneralLabResultHeader( + patient: widget.patient, + patientType: widget.patientType ?? "0", + arrivalType: widget.arrivalType ?? "0", + orderNo: widget.patientLabOrders.orderNo, + appointmentDate: widget.patientLabOrders.orderDate, + doctorName: widget.patientLabOrders.doctorName, + branch: widget.patientLabOrders.projectName, + clinic: widget.patientLabOrders.clinicDescription, + profileUrl: widget.patientLabOrders.doctorImageURL, + invoiceNO: widget.patientLabOrders.invoiceNo, ), + + + // PatientProfileHeaderWhitAppointmentAppBar( + // patient: widget.patient, + // patientType: widget.patientType ?? "0", + // arrivalType: widget.arrivalType ?? "0", + // orderNo: widget.patientLabOrders.orderNo, + // appointmentDate: widget.patientLabOrders.orderDate, + // doctorName: widget.patientLabOrders.doctorName, + // branch: widget.patientLabOrders.projectName, + // clinic: widget.patientLabOrders.clinicDescription, + // profileUrl: widget.patientLabOrders.doctorImageURL, + // invoiceNO: widget.patientLabOrders.invoiceNo, + // ), baseViewModel: model, body: AppScaffold( isShowAppBar: false, body: SingleChildScrollView( child: Column( children: [ + LaboratoryResultWidget( onTap: () async {}, billNo: widget.patientLabOrders.invoiceNo, diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e64b582f..d9aa7d8d 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,13 +1,18 @@ +import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.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/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -295,70 +300,70 @@ class _PatientProfileScreenState extends State TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); - // if(isCallFinished) { - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => - // EndCallScreen(patient:patient))); - // } else { - // GifLoaderDialogUtils.showMyDialog(context); - // await model.startCall( isReCall : false, vCID: patient.vcId); - // - // if(model.state == ViewState.ErrorLocal) { - // GifLoaderDialogUtils.hideDialog(context); - // Helpers.showErrorToast(model.error); - // } else { - // await model.getDoctorProfile(); - // patient.appointmentNo = model.startCallRes.appointmentNo; - // patient.episodeNo = 0; - // - // GifLoaderDialogUtils.hideDialog(context); - // await VideoChannel.openVideoCallScreen( - // kToken: model.startCallRes.openTokenID, - // kSessionId: model.startCallRes.openSessionID, - // kApiKey: '46209962', - // vcId: patient.vcId, - // tokenID: await model.getToken(), - // generalId: GENERAL_ID, - // doctorId: model.doctorProfile.doctorID, - // onFailure: (String error) { - // DrAppToastMsg.showErrorToast(error); - // }, - // onCallEnd: () { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - // }, - // onCallNotRespond: (SessionStatusModel sessionStatusModel) { - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // - // }); - // }); - // } - // } + if(isCallFinished) { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => + EndCallScreen(patient:patient))); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await model.startCall( isReCall : false, vCID: patient.vcId); + + if(model.state == ViewState.ErrorLocal) { + GifLoaderDialogUtils.hideDialog(context); + Helpers.showErrorToast(model.error); + } else { + await model.getDoctorProfile(); + patient.appointmentNo = model.startCallRes.appointmentNo; + patient.episodeNo = 0; + + GifLoaderDialogUtils.hideDialog(context); + await VideoChannel.openVideoCallScreen( + kToken: model.startCallRes.openTokenID, + kSessionId: model.startCallRes.openSessionID, + kApiKey: '46209962', + vcId: patient.vcId, + tokenID: await model.getToken(), + generalId: GENERAL_ID, + doctorId: model.doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + }, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(context); + model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } + setState(() { + isCallFinished = true; + }); + }); + + }); + }); + } + } }, ), diff --git a/lib/widgets/patients/profile/GeneralLabResultHeader.dart b/lib/widgets/patients/profile/GeneralLabResultHeader.dart new file mode 100644 index 00000000..5f22459a --- /dev/null +++ b/lib/widgets/patients/profile/GeneralLabResultHeader.dart @@ -0,0 +1,347 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class GeneralLabResultHeader extends StatelessWidget + with PreferredSizeWidget { + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final String doctorName; + final String branch; + final DateTime appointmentDate; + final String profileUrl; + final String invoiceNO; + final String orderNo; + final bool isPrescriptions; + final bool isMedicalFile; + final String episode; + final String vistDate; + + final String clinic; + GeneralLabResultHeader( + {this.patient, + this.patientType, + this.arrivalType, + this.doctorName, + this.branch, + this.appointmentDate, + this.profileUrl, + this.invoiceNO, + this.orderNo, + this.isPrescriptions = false, + this.clinic, + this.isMedicalFile = false, + this.episode, + this.vistDate}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + int gender = 1; + if (patient.patientDetails != null) { + gender = patient.patientDetails.gender; + } else { + gender = patient.gender; + } + + return Container( + padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), + decoration: BoxDecoration( + color: Colors.white, + ), + height: MediaQuery.of(context).size.height * 0.23, + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only(left: 12.0), + child: Row(children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Colors.black, //Colors.black, + onPressed: () => Navigator.pop(context), + ), + Expanded( + child: AppText( + patient.firstName != null + ? (Helpers.capitalize(patient.firstName) + + " " + + Helpers.capitalize(patient.lastName)) + : Helpers.capitalize(patient.fullName??patient?.patientDetails?.fullName??""), + fontSize: SizeConfig.textMultiplier * 2.2, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 4), + child: InkWell( + onTap: () { + launch("tel://" + patient?.mobileNumber??""); + }, + child: Icon( + Icons.phone, + color: Colors.black87, + ), + ), + ) + ]), + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 12.0), + child: Container( + width: 60, + height: 60, + child: Image.asset( + gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SERVICES_PATIANT2[int.parse(patientType)] == + "patientArrivalList" + ? Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + patient.patientStatusType == 43 + ? AppText( + TranslationBase.of(context).arrivedP, + color: Colors.green, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ) + : AppText( + TranslationBase.of(context).notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), + arrivalType == '1' || patient.arrivedOn == null + ? AppText( + patient.startTime != null + ? patient.startTime + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + : AppText( + AppDateUtils.convertStringToDateFormat( + patient.arrivedOn, + 'MM-dd-yyyy HH:mm'), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + ) + ], + )) + : SizedBox(), + if (SERVICES_PATIANT2[int.parse(patientType)] == + "List_MyOutPatient") + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).appointmentDate + + " : ", + fontSize: 14, + ), + patient.startTime != null + ? Container( + height: 15, + width: 60, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + color: HexColor("#20A169"), + ), + child: AppText( + patient.startTime ?? "", + color: Colors.white, + fontSize: 1.5 * SizeConfig.textMultiplier, + textAlign: TextAlign.center, + fontWeight: FontWeight.bold, + ), + ) + : SizedBox(), + SizedBox( + width: 3.5, + ), + Container( + child: AppText( + convertDateFormat2( + patient.appointmentDate.toString() ?? ''), + fontSize: 1.5 * SizeConfig.textMultiplier, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 0.5, + ) + ], + ), + margin: EdgeInsets.only( + top: 8, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black), + children: [ + new TextSpan( + text: TranslationBase.of(context).fileNumber, + style: TextStyle( + fontSize: 12, fontFamily: 'Poppins')), + new TextSpan( + text: patient?.patientId?.toString() ?? "", + style: TextStyle( + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 14)), + ], + ), + ), + Row( + children: [ + AppText( + patient.nationalityName ?? + patient.nationality ?? + "", + fontWeight: FontWeight.bold, + fontSize: 12, + ), + patient.nationality != null + ? ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Image.network( + patient?.nationalityFlagURL??"", + height: 25, + width: 30, + errorBuilder: (BuildContext context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: TranslationBase.of(context).age + " : ", + style: TextStyle(fontSize: 14)), + new TextSpan( + text: + "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth : patient.dateofBirth, context)}", + style: TextStyle( + fontWeight: FontWeight.w700, fontSize: 14)), + ], + ), + ), + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: "Result Date: ", + style: TextStyle(fontSize: 14)), + new TextSpan( + text: + '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', + style: TextStyle( + fontWeight: FontWeight.w700, fontSize: 14)), + ], + ), + ), + ), + ], + ), + ), + ]), + ], + ), + ), + ); + } + + convertDateFormat2(String str) { + String newDate = ""; + const start = "/Date("; + const end = "+0300)"; + + if (str.isNotEmpty) { + final startIndex = str.indexOf(start); + final endIndex = str.indexOf(end, startIndex + start.length); + + var date = new DateTime.fromMillisecondsSinceEpoch( + int.parse(str.substring(startIndex + start.length, endIndex))); + newDate = date.year.toString() + + "/" + + date.month.toString().padLeft(2, '0') + + "/" + + date.day.toString().padLeft(2, '0'); + } + + return newDate.toString(); + } + + + + @override + Size get preferredSize => Size(double.maxFinite, 310); +} From cb5abfb2ec4a68f079bfefdaebb1395f040d80c7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:10:24 +0300 Subject: [PATCH 145/241] remove comment code --- .../profile/lab_result/laboratory_result_page.dart | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 91e5145f..c7a98924 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -51,19 +51,6 @@ class _LaboratoryResultPageState extends State { invoiceNO: widget.patientLabOrders.invoiceNo, ), - - // PatientProfileHeaderWhitAppointmentAppBar( - // patient: widget.patient, - // patientType: widget.patientType ?? "0", - // arrivalType: widget.arrivalType ?? "0", - // orderNo: widget.patientLabOrders.orderNo, - // appointmentDate: widget.patientLabOrders.orderDate, - // doctorName: widget.patientLabOrders.doctorName, - // branch: widget.patientLabOrders.projectName, - // clinic: widget.patientLabOrders.clinicDescription, - // profileUrl: widget.patientLabOrders.doctorImageURL, - // invoiceNO: widget.patientLabOrders.invoiceNo, - // ), baseViewModel: model, body: AppScaffold( isShowAppBar: false, From 1a158f49bb7de67116f40b932619c35a5576b9d2 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 9 Jun 2021 16:23:18 +0300 Subject: [PATCH 146/241] no message --- ios/Runner/Base.lproj/Main.storyboard | 21 ++++++--- ios/Runner/MainAppViewController.swift | 11 +++-- ios/Runner/VCEmbeder.swift | 30 +++++++----- ios/Runner/VideoCallViewController.swift | 58 ++++++++++-------------- 4 files changed, 64 insertions(+), 56 deletions(-) diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index 17833007..9f1b5e1a 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -39,6 +39,7 @@ + @@ -50,7 +51,7 @@ - + @@ -78,6 +79,11 @@ + + + + + @@ -134,6 +140,7 @@ + @@ -150,6 +157,7 @@ + @@ -160,20 +168,19 @@ + - - + + - - + + - - diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index c6466343..9a59b862 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -47,8 +47,10 @@ extension MainAppViewController : ICallProtocol{ func prepareVideoCallView(){ videoCallContainer = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)) - videoCallContainer.alpha = 0.0 videoCallContainer.backgroundColor = UIColor.black + videoCallContainer.isHidden = true + videoCallContainer.clipsToBounds = true + view.addSubview(videoCallContainer) setVideoViewConstrints() NSLayoutConstraint.activate(vdoCallViewMaxConstraint) @@ -97,12 +99,13 @@ extension MainAppViewController : ICallProtocol{ } private func showVideoCallView(_ value:Bool){ + videoCallContainer.alpha = value ? 0.0 : 1 + self.videoCallContainer.isHidden = !value + UIView.animate(withDuration: 0.5) { self.videoCallContainer.alpha = value ? 1.0 : 0.0 } completion: { complete in - if(value == false){ - self.videoCallContainer.removeFromSuperview() - } + self.videoCallContainer.isHidden = !value } } diff --git a/ios/Runner/VCEmbeder.swift b/ios/Runner/VCEmbeder.swift index e86dde75..7e2ea0fd 100644 --- a/ios/Runner/VCEmbeder.swift +++ b/ios/Runner/VCEmbeder.swift @@ -9,25 +9,31 @@ import Foundation extension UIView { - func fill(to parent: UIView) { - topAnchor.constraint(equalTo: parent.topAnchor).isActive = true - leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true - bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true - trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + func fill(to parent: UIView, animateDuration:Double = 0.5) { + self.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + self.leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + self.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + self.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + UIView.animate(withDuration: animateDuration) { + parent.layoutIfNeeded() + } } - func fillToParent() { + func fillToParent(animateDuration:Double = 0.5) { if let parent = self.superview{ - topAnchor.constraint(equalTo: parent.topAnchor).isActive = true - leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true - bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true - trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + self.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + self.leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + self.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + self.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + UIView.animate(withDuration: animateDuration) { + parent.layoutIfNeeded() + } } } - func fillTo(view:UIView) { + func fillInTo(view:UIView) { view.addSubview(self) - fill(to: view) + fillToParent() } } diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index a05957c9..689c9f63 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -101,17 +101,19 @@ class VideoCallViewController: UIViewController { sender.isSelected = minimized onMinimize?(minimized) - self.videoMuteBtn.isHidden = minimized - self.micMuteBtn.isHidden = minimized - let min_ = minimized - UIView.animate(withDuration: 1) { + UIView.animate(withDuration: 0.5) { self.actionsHeightConstraint.constant = min_ ? 30 : 60 self.localvideoTopMargin.constant = min_ ? 20 : 40 + self.videoMuteBtn.isHidden = min_ + self.micMuteBtn.isHidden = min_ - let vdoBound = self.localVideo.bounds - self.publisher?.view?.frame = CGRect(x: 0, y: 0, width: vdoBound.size.width, height: vdoBound.size.height) + let localVdoSize = self.localVideo.bounds.size + let remoteVdoSize = self.remoteVideo.bounds.size + self.publisher?.view?.frame = CGRect(x: 0, y: 0, width: localVdoSize.width, height: localVdoSize.height) + self.subscriber?.view?.frame = CGRect(x: 0, y: 0, width: remoteVdoSize.width, height: remoteVdoSize.height) self.publisher?.view?.layoutIfNeeded() + self.subscriber?.view?.layoutIfNeeded() } } @@ -324,14 +326,8 @@ class VideoCallViewController: UIViewController { extension VideoCallViewController: OTSessionDelegate { func sessionDidConnect(_ session: OTSession) { - print("The client connected to the OpenTok session.") - - - - - timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(VideoCallViewController.updateTimer)), userInfo: nil, repeats: true) - - + print("The client connected to the OpenTok session.") + timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(VideoCallViewController.updateTimer)), userInfo: nil, repeats: true) setupPublisher() } @@ -373,27 +369,23 @@ extension VideoCallViewController: OTSessionDelegate { func session(_ session: OTSession, streamCreated stream: OTStream) { - subscriber = OTSubscriber(stream: stream, delegate: self) - guard let subscriber = subscriber else { - return - } + subscriber = OTSubscriber(stream: stream, delegate: self) + guard let subscriber = subscriber else { + return + } - var error: OTError? - session.subscribe(subscriber, error: &error) - guard error == nil else { - print(error!) - return - } + var error: OTError? + session.subscribe(subscriber, error: &error) + guard error == nil else { + print(error!) + return + } - guard let subscriberView = subscriber.view else { - return - } - subscriberView.frame = UIScreen.main.bounds - view.insertSubview(subscriberView, at: 0) - -// if nil == subscriber { -// setupSubscribe(stream) -// } + guard let subscriberView = subscriber.view else { + return + } + subscriberView.frame = CGRect(x: 0, y: 0, width: remoteVideo.bounds.width, height: remoteVideo.bounds.height) + remoteVideo.addSubview(subscriberView) } func setupSubscribe(_ stream: OTStream?) { From 4cdc654348df8b084ba8877e658dbf3b5b67cdbe Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 16:50:35 +0300 Subject: [PATCH 147/241] fix font size in header --- lib/widgets/patients/profile/GeneralLabResultHeader.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/widgets/patients/profile/GeneralLabResultHeader.dart b/lib/widgets/patients/profile/GeneralLabResultHeader.dart index 5f22459a..153a4ccf 100644 --- a/lib/widgets/patients/profile/GeneralLabResultHeader.dart +++ b/lib/widgets/patients/profile/GeneralLabResultHeader.dart @@ -224,13 +224,15 @@ class GeneralLabResultHeader extends StatelessWidget RichText( text: TextSpan( style: TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black), + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), children: [ new TextSpan( text: TranslationBase.of(context).fileNumber, style: TextStyle( - fontSize: 12, fontFamily: 'Poppins')), + fontSize: 14, fontFamily: 'Poppins')), new TextSpan( text: patient?.patientId?.toString() ?? "", style: TextStyle( From 10441e4af08fc3797376e1879d2f18fceacf3d0a Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 9 Jun 2021 17:10:39 +0300 Subject: [PATCH 148/241] referral changes --- lib/config/config.dart | 2 +- lib/config/localized_values.dart | 2 + .../referral/MyReferralPatientModel.dart | 7 +- .../patient/MyReferralPatientService.dart | 2 +- .../referral/AddReplayOnReferralPatient.dart | 131 ++++---- .../ReplySummeryOnReferralPatient.dart | 119 ++++++++ .../my-referral-inpatient-screen.dart | 1 - .../referral_patient_detail_in-paint.dart | 279 +++++++++++------- lib/util/translations_delegate_base.dart | 2 + .../patient-referral-item-widget.dart | 16 +- 10 files changed, 385 insertions(+), 176 deletions(-) create mode 100644 lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index e2f9eb6a..eb946dea 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -181,7 +181,7 @@ const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; -const GET_MY_REFERRAL_OUTPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; +const GET_MY_REFERRAL_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 11f31ba6..4d0436aa 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1008,4 +1008,6 @@ const Map> localizedValues = { "allLab": {"en": "All Lab", "ar": "جميع المختبرات"}, "allPrescription": {"en": "All Prescription", "ar": "جميع الوصفات"}, "addPrescription": {"en": "Add prescription", "ar": "إضافة الوصفات"}, + "edit": {"en": "Edit", "ar": "تعديل"}, + "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, }; diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 7aa375b8..ebf12857 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -159,7 +159,12 @@ class MyReferralPatientModel { referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; referralStatus = json["ReferralStatus"] is String ?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0: json["ReferralStatus"]; - referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); + try { + referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); + } catch (e){ + referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + } + referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 9f29c4dc..39a75e8f 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -63,7 +63,7 @@ class MyReferralInPatientService extends BaseService { patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( - GET_MY_REFERRAL_OUTPATIENT, + GET_MY_REFERRAL_OUT_PATIENT, onSuccess: (dynamic response, int statusCode) { if (response['List_MyOutPatientReferral'] != null) { response['List_MyOutPatientReferral'].forEach((v) { diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index f54a18ac..df941a5d 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -14,17 +14,24 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; +import 'ReplySummeryOnReferralPatient.dart'; + class AddReplayOnReferralPatient extends StatefulWidget { final PatientReferralViewModel patientReferralViewModel; final MyReferralPatientModel myReferralInPatientModel; + final bool isEdited; const AddReplayOnReferralPatient( - {Key key, this.patientReferralViewModel, this.myReferralInPatientModel}) + {Key key, + this.patientReferralViewModel, + this.myReferralInPatientModel, + this.isEdited}) : super(key: key); @override @@ -39,10 +46,13 @@ class _AddReplayOnReferralPatientState var reconizedWord; var event = RobotProvider(); TextEditingController replayOnReferralController = TextEditingController(); + @override void initState() { requestPermissions(); super.initState(); + replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks?? ""; + } @override @@ -51,11 +61,9 @@ class _AddReplayOnReferralPatientState isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.0, - child: Padding( - padding: EdgeInsets.all(0.0), - child: Column( + child: Column( + children: [ + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ BottomSheetTitle(title: 'Replay'), @@ -103,61 +111,70 @@ class _AddReplayOnReferralPatientState ), ], ), - ), - ), - ), - bottomSheet: Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Column( - children: [ - replayOnReferralController.text.isEmpty - ? SizedBox() - : Container( + Container( + height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Column( + children: [ + replayOnReferralController.text.isEmpty + ? SizedBox() + : Container( margin: EdgeInsets.all(5), child: Expanded( child: AppButton( - title: TranslationBase.of(context).clearText, - onPressed: () { - setState(() { - replayOnReferralController.text = ''; - }); - }, - )), + title: TranslationBase.of(context).clearText, + onPressed: () { + setState(() { + replayOnReferralController.text = ''; + }); + }, + )), ), - Container( - margin: EdgeInsets.all(5), - child: AppButton( - title: 'Submit Replay', - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - setState(() { - isSubmitted = true; - }); - if (replayOnReferralController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - await widget.patientReferralViewModel.replay( - replayOnReferralController.text.trim(), - widget.myReferralInPatientModel); - if (widget.patientReferralViewModel.state == - ViewState.ErrorLocal) { - Helpers.showErrorToast( - widget.patientReferralViewModel.error); - } else { - GifLoaderDialogUtils.hideDialog(context); - DrAppToastMsg.showSuccesToast( - "Your Replay Added Successfully"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } - } else { - Helpers.showErrorToast("You can't add empty replay"); - setState(() { - isSubmitted = false; - }); - } - })), + Container( + margin: EdgeInsets.all(5), + child: AppButton( + title: 'Submit Replay', + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () async { + setState(() { + isSubmitted = true; + }); + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replay( + replayOnReferralController.text.trim(), + widget.myReferralInPatientModel); + if (widget.patientReferralViewModel.state == + ViewState.ErrorLocal) { + Helpers.showErrorToast( + widget.patientReferralViewModel.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + DrAppToastMsg.showSuccesToast( + "Your Replay Added Successfully"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + Navigator.push( + context, + FadePage( + page: ReplySummeryOnReferralPatient( + widget.myReferralInPatientModel, + replayOnReferralController.text.trim()), + ), + ); + } + } else { + Helpers.showErrorToast("You can't add empty replay"); + setState(() { + isSubmitted = false; + }); + } + })), + ], + ), + ), ], ), ), diff --git a/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart new file mode 100644 index 00000000..2a48e079 --- /dev/null +++ b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart @@ -0,0 +1,119 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.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/date-utils.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.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/buttons/app_buttons_widget.dart'; +import 'package:flutter/material.dart'; + +import '../../../../routes.dart'; + +class ReplySummeryOnReferralPatient extends StatefulWidget { + final MyReferralPatientModel referredPatient; + final String doctorReply; + + ReplySummeryOnReferralPatient(this.referredPatient, this.doctorReply); + + @override + _ReplySummeryOnReferralPatientState createState() => + _ReplySummeryOnReferralPatientState(this.referredPatient); +} + +class _ReplySummeryOnReferralPatientState + extends State { + final MyReferralPatientModel referredPatient; + + _ReplySummeryOnReferralPatientState(this.referredPatient); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).summeryReply, + body: Container( + child: Column( + children: [ + + Expanded( + child: SingleChildScrollView( + child: Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + widget.doctorReply ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), + ), + ), + ), + Container( + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + onPressed: () { + Navigator.of(context).pop(); + }, + title: TranslationBase.of(context).cancel, + fontColor: Colors.white, + color: Colors.red[600], + ), + ), + SizedBox(width: 4,), + Expanded( + child: AppButton( + onPressed: () {}, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + ), + ], + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 9813286e..636a596f 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -64,7 +64,6 @@ class MyReferralInPatientScreen extends StatelessWidget { ) : SingleChildScrollView( child: Container( - margin: EdgeInsets.only(top: 70), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 0e7b214b..e2175bae 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -19,6 +19,7 @@ import 'AddReplayOnReferralPatient.dart'; class ReferralPatientDetailScreen extends StatelessWidget { final MyReferralPatientModel referredPatient; final PatientReferralViewModel patientReferralViewModel; + ReferralPatientDetailScreen( this.referredPatient, this.patientReferralViewModel); @@ -214,30 +215,6 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( child: Column( children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - "${TranslationBase.of(context).refClinic}: ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - referredPatient - .referringClinicDescription, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], - ), - if(referredPatient.frequency != null) Row( mainAxisAlignment: MainAxisAlignment.start, @@ -245,9 +222,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .frequency + - ": ", + "${TranslationBase.of(context).refClinic}: ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.7 * @@ -257,7 +232,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( child: AppText( referredPatient - .frequencyDescription??'', + .referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * @@ -267,6 +242,38 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ], ), + if (referredPatient.frequency != null) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .frequency + + ": ", + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + Expanded( + child: AppText( + referredPatient + .frequencyDescription ?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig + .textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), ], ), ), @@ -304,59 +311,69 @@ class ReferralPatientDetailScreen extends StatelessWidget { ) ], ), - if(referredPatient.priorityDescription != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).priority + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient.priorityDescription??'', + if (referredPatient.priorityDescription != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).priority + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, fontSize: - 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - ), - ], - ), - if(referredPatient.mAXResponseTime != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .maxResponseTime + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient.mAXResponseTime != null? AppDateUtils.convertDateFromServerFormat( - referredPatient.mAXResponseTime, - "dd MMM,yyyy"):'', + Expanded( + child: AppText( + referredPatient.priorityDescription ?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), + if (referredPatient.mAXResponseTime != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .maxResponseTime + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, fontSize: - 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - ), - ], - ), + Expanded( + child: AppText( + referredPatient.mAXResponseTime != + null + ? AppDateUtils + .convertDateFromServerFormat( + referredPatient + .mAXResponseTime, + "dd MMM,yyyy") + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -448,48 +465,93 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: SingleChildScrollView( - child: Container( - width: double.infinity, - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - border: Border.fromBorderSide(BorderSide( - color: Colors.white, - width: 1.0, - )), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).remarks, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 2.4 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + children: [ + Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), ), - AppText( - referredPatient.referringDoctorRemarks??'', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).remarks, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referringDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], ), - SizedBox( - height: 8, + ), + if (referredPatient.referredDoctorRemarks.isNotEmpty) + Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 0), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referredDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), ), - ], - ), + ], ), ), ), Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: AppButton( - title: TranslationBase.of(context).replay, + title: referredPatient.referredDoctorRemarks.isEmpty ? TranslationBase.of(context).replay : TranslationBase.of(context).edit, color: Colors.red[700], fontColor: Colors.white, fontWeight: FontWeight.w700, @@ -503,6 +565,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, + isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 16ae07bd..165a9bb5 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1363,6 +1363,8 @@ class TranslationBase { String get allLab => localizedValues['allLab'][locale.languageCode]; String get allPrescription => localizedValues['allPrescription'][locale.languageCode]; String get addPrescription => localizedValues['addPrescription'][locale.languageCode]; + String get edit => localizedValues['edit'][locale.languageCode]; + String get summeryReply => localizedValues['summeryReply'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index 6e581954..02b2d241 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -155,6 +155,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( isSameBranch ? TranslationBase.of(context).referredFrom :TranslationBase.of(context).refClinic, @@ -163,13 +164,14 @@ class PatientReferralItemWidget extends StatelessWidget { fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), - - AppText( - !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + Expanded( + child: AppText( + !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), From 23feb2c354d304fbaa659c6e05a4fcd63baa8b98 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 17:11:52 +0300 Subject: [PATCH 149/241] remove unused code --- .../vital_sign/vital-signs-screen.dart | 1074 ----------------- .../prescription/prescription_screen.dart | 591 --------- .../prescription_screen_history.dart | 516 -------- .../profile/patient-page-header-widget.dart | 114 -- 4 files changed, 2295 deletions(-) delete mode 100644 lib/screens/patients/profile/vital_sign/vital-signs-screen.dart delete mode 100644 lib/screens/prescription/prescription_screen.dart delete mode 100644 lib/screens/prescription/prescription_screen_history.dart delete mode 100644 lib/widgets/patients/profile/patient-page-header-widget.dart diff --git a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart b/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart deleted file mode 100644 index 0bf2197b..00000000 --- a/lib/screens/patients/profile/vital_sign/vital-signs-screen.dart +++ /dev/null @@ -1,1074 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.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/profile/patient-page-header-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/shared/expandable-widget-header-body.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -class PatientVitalSignScreen extends StatelessWidget { - @override - Widget build(BuildContext context) { - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatiantInformtion patient = routeArgs['patient']; - String from = routeArgs['from']; - String to = routeArgs['to']; - - return BaseView( - onModelReady: (model) => model.getPatientVitalSign(patient), - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - appBarTitle: TranslationBase.of(context).vitalSign, - body: model.patientVitalSigns != null - ? SingleChildScrollView( - child: Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - PatientPageHeaderWidget(patient), - SizedBox( - height: 16, - ), - Container( - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).weight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.weightKg} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - Row( - children: [ - AppText( - "${TranslationBase.of(context).idealBodyWeight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.idealBodyWeightLbs} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).height} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.heightCm} ${TranslationBase.of(context).cm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - /*Row( - children: [ - AppText( - "${TranslationBase.of(context).waistSize} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.waistSizeInch} ${TranslationBase.of(context).inch}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ),*/ - Row( - children: [ - AppText( - "${TranslationBase.of(context).headCircum} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.headCircumCm} ${TranslationBase.of(context).cm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 16, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).leanBodyWeight} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.leanBodyWeightLbs} ${TranslationBase.of(context).kg}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).bodyMassIndex} :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "${model.patientVitalSigns.bodyMassIndex}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - SizedBox( - width: 8, - ), - Container( - color: Colors.green, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: 2, horizontal: 8), - child: AppText( - "${model.getBMI(model.patientVitalSigns.bodyMassIndex)}", - fontSize: - SizeConfig.textMultiplier * 2, - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ) - ], - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "G.C.S :", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 8, - ), - AppText( - "N/A", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - TemperatureWidget(model, model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - PulseWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - RespirationWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - BloodPressureWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - OxygenationWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - PainScaleWidget(model.patientVitalSigns), - SizedBox( - height: 16, - ), - const Divider( - color: Color(0xffCCCCCC), - height: 1, - thickness: 2, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 16, - ), - ], - ), - ) - ], - ), - ), - ) - : Center( - child: AppText( - "${TranslationBase.of(context).vitalSignEmptyMsg}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: HexColor("#B8382B"), - fontWeight: FontWeight.normal, - ), - ), - ), - ); - } -} - -class TemperatureWidget extends StatefulWidget { - final VitalSignsViewModel model; - final VitalSignData vitalSign; - - TemperatureWidget(this.model, this.vitalSign); - - @override - _TemperatureWidgetState createState() => _TemperatureWidgetState(); -} - -class _TemperatureWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).temperature}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).temperature} (C):", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.temperatureCelcius}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).temperature} (F):", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.temperatureCelcius * (9 / 5) + 32}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).method} :", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.model.getTempratureMethod(widget.vitalSign.temperatureCelciusMethod)}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class PulseWidget extends StatefulWidget { - final VitalSignData vitalSign; - - PulseWidget(this.vitalSign); - - @override - _PulseWidgetState createState() => _PulseWidgetState(); -} - -class _PulseWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).pulse}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).pulseBeats}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.pulseBeatPerMinute}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).rhythm}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.pulseRhythm}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class RespirationWidget extends StatefulWidget { - final VitalSignData vitalSign; - - RespirationWidget(this.vitalSign); - - @override - _RespirationWidgetState createState() => _RespirationWidgetState(); -} - -class _RespirationWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).respiration}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).respBeats}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.respirationBeatPerMinute}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).patternOfRespiration}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.respirationPattern}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class BloodPressureWidget extends StatefulWidget { - final VitalSignData vitalSign; - - BloodPressureWidget(this.vitalSign); - - @override - _BloodPressureWidgetState createState() => _BloodPressureWidgetState(); -} - -class _BloodPressureWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).bloodPressure}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).bloodPressureDiastoleAndSystole}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressureHigher}, ${widget.vitalSign.bloodPressureLower}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).cuffLocation}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressureCuffLocation}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - ], - ), - SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: AppText( - "${TranslationBase.of(context).patientPosition}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppText( - "${widget.vitalSign.bloodPressurePatientPosition}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ), - ], - ), - ), - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).cuffSize}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.bloodPressureCuffSize}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class OxygenationWidget extends StatefulWidget { - final VitalSignData vitalSign; - - OxygenationWidget(this.vitalSign); - - @override - _OxygenationWidgetState createState() => _OxygenationWidgetState(); -} - -class _OxygenationWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).oxygenation}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - "${TranslationBase.of(context).sao2}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.sao2}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - Row( - children: [ - AppText( - "${TranslationBase.of(context).fio2}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.fio2}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} - -class PainScaleWidget extends StatefulWidget { - final VitalSignData vitalSign; - - PainScaleWidget(this.vitalSign); - - @override - _PainScaleWidgetState createState() => _PainScaleWidgetState(); -} - -class _PainScaleWidgetState extends State { - bool isExpand = false; - - @override - Widget build(BuildContext context) { - return Container( - child: HeaderBodyExpandableNotifier( - headerWidget: Container( - margin: EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - "${TranslationBase.of(context).painScale}", - fontSize: SizeConfig.textMultiplier * 2.5, - color: Colors.black, - fontWeight: isExpand ? FontWeight.bold : FontWeight.normal, - ), - InkWell( - onTap: () { - setState(() { - isExpand = !isExpand; - }); - }, - child: Icon(isExpand ? Icons.remove : Icons.add), - ), - ], - ), - ), - bodyWidget: Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).painScale}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.painScore}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - Expanded( - child: Row( - children: [ - AppText( - "${TranslationBase.of(context).painManagement}", - fontSize: SizeConfig.textMultiplier * 1.8, - color: Colors.black, - fontWeight: FontWeight.w700, - ), - SizedBox( - width: 8, - ), - AppText( - "${widget.vitalSign.isPainManagementDone}", - fontSize: SizeConfig.textMultiplier * 2, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), - ], - ), - ), - ], - ), - ], - ), - ), - isExpand: isExpand, - ), - ); - } -} diff --git a/lib/screens/prescription/prescription_screen.dart b/lib/screens/prescription/prescription_screen.dart deleted file mode 100644 index d5a94c61..00000000 --- a/lib/screens/prescription/prescription_screen.dart +++ /dev/null @@ -1,591 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.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/screens/prescription/add_prescription_form.dart'; -import 'package:doctor_app_flutter/screens/prescription/update_prescription_form.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-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/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionScreen extends StatefulWidget { - @override - _NewPrescriptionScreenState createState() => _NewPrescriptionScreenState(); -} - -class _NewPrescriptionScreenState extends State { - PersistentBottomSheetController _controller; - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - int strengthChar; - PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: (BuildContext context, PrescriptionViewModel model, Widget child) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription, - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox(height: model.prescriptionList[0].rowcount == 0 ? 200.0 : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - InkWell( - child: Container( - height: 50.0, - width: 450.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(10.0), - ), - child: Padding( - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - ' Add more medication', - fontWeight: FontWeight.w100, - fontSize: 12.5, - ), - Icon( - Icons.add, - color: Color(0XFFB8382C), - ) - ], - ), - ), - ), - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - ), - SizedBox( - height: 10.0, - ), - ...List.generate( - model.prescriptionList[0].rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.022, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.21, - width: MediaQuery.of(context).size.width * 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList[index] - .createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList[index].createdOn) - .year) - .toString() - : DateTime.now().year) - .toString(), - color: Colors.green, - fontSize: 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0] - .entityList[index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList[index].createdOn) - .month) - : DateTime.now().month) - .toUpperCase(), - color: Colors.green, - ), - AppText( - DateTime.parse( - model.prescriptionList[0].entityList[index].createdOn) - .day - .toString(), - color: Colors.green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[0].entityList[index].createdOn)) - .toString(), - color: Colors.green, - ), - ], - ), - ), - Container( - color: Colors.white, - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of(context).size.width * 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0].entityList[index].startDate)), - fontSize: 13.5, - ), - ), - SizedBox( - width: 6.0, - ), - AppText( - 'Order Type:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .orderTypeDescription, - fontSize: 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - color: Colors.white, - child: Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .medicationName, - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index].doseDetail, - fontSize: 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model - .prescriptionList[0].entityList[index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .quantity - .toString() == - null - ? "" - : model.prescriptionList[0].entityList[index] - .quantity - .toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .pharmacyInervention == - null - ? "" - : model.prescriptionList[0].entityList[index] - .pharmacyInervention - .toString()), - ), - ), - ], - ), - SizedBox(height: 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index] - .pharmacistRemarks == - null - ? "" - : model.prescriptionList[0].entityList[index] - .pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context).doctorName + ": ", - fontWeight: FontWeight.w600, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList[index].doctorName, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 13.0, - ), - Expanded( - child: Container( - color: Colors.white, - // height: MediaQuery.of(context).size.height * - // 0.038, - child: RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 10.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index] - .remarks != - null - ? model.prescriptionList[0].entityList[index] - .remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.16, - width: MediaQuery.of(context).size.width * 0.06, - child: Column( - children: [ - InkWell( - child: Icon(Icons.edit), - onTap: () { - updatePrescriptionForm( - box: model - .prescriptionList[0].entityList[index].quantity, - uom: model.prescriptionList[0].entityList[index].uom, - drugNameGeneric: model.prescriptionList[0] - .entityList[index].medicationName, - doseUnit: model.prescriptionList[0].entityList[index] - .doseDailyUnitID - .toString(), - doseStreangth: model.prescriptionList[0] - .entityList[index].doseDailyQuantity - .toString(), - duration: model.prescriptionList[0].entityList[index] - .doseDurationDays - .toString(), - startDate: model - .prescriptionList[0].entityList[index].startDate - .toString(), - dose: model.prescriptionList[0].entityList[index].doseTimingID - .toString(), - frequency: model - .prescriptionList[0].entityList[index].frequencyID - .toString(), - rouat: model.prescriptionList[0].entityList[index].routeID - .toString(), - patient: patient, - drugId: model.prescriptionList[0].entityList[index].medicineCode, - drugName: model.prescriptionList[0].entityList[index].medicationName, - remarks: model.prescriptionList[0].entityList[index].remarks, - model: model, - enteredRemarks: model.prescriptionList[0].entityList[index].remarks, - context: context); - //model.postPrescription(); - }, - ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/screens/prescription/prescription_screen_history.dart b/lib/screens/prescription/prescription_screen_history.dart deleted file mode 100644 index 5ce98c54..00000000 --- a/lib/screens/prescription/prescription_screen_history.dart +++ /dev/null @@ -1,516 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.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/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-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/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionHistoryScreen extends StatefulWidget { - @override - _NewPrescriptionHistoryScreenState createState() => - _NewPrescriptionHistoryScreenState(); -} - -class _NewPrescriptionHistoryScreenState - extends State { - PersistentBottomSheetController _controller; - final _scaffoldKey = GlobalKey(); - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - int strengthChar; - PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: - (BuildContext context, PrescriptionViewModel model, Widget child) => - AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription, - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox( - height: - model.prescriptionList[0].rowcount == 0 - ? 200.0 - : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Container( - child: AppText( - 'Sorry , Theres no prescriptions for this patient', - color: Color(0xFFB9382C), - ), - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - ...List.generate( - model.prescriptionList[0] - .rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of( - context) - .size - .height * - 0.022, - ), - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - height: MediaQuery.of( - context) - .size - .height * - 0.21, - width: MediaQuery.of( - context) - .size - .width * - 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn).year) - .toString() - : DateTime.now() - .year) - .toString(), - color: Colors - .green, - fontSize: - 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0].entityList[index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0].entityList[index].createdOn) - .month) - : DateTime.now() - .month) - .toUpperCase(), - color: Colors - .green, - ), - AppText( - DateTime.parse(model - .prescriptionList[ - 0] - .entityList[ - index] - .createdOn) - .day - .toString(), - color: Colors - .green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[ - 0] - .entityList[ - index] - .createdOn)) - .toString(), - color: Colors - .green, - ), - ], - ), - ), - Container( - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of( - context) - .size - .width * - 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: - FontWeight - .w700, - fontSize: - 14.0, - ), - Expanded( - child: - AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0] - .entityList[index] - .startDate)), - fontSize: - 13.5, - ), - ), - SizedBox( - width: - 6.0, - ), - AppText( - 'Order Type:', - fontWeight: - FontWeight - .w700, - fontSize: - 14.0, - ), - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .orderTypeDescription, - fontSize: - 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - child: - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .medicationName, - fontWeight: - FontWeight.w700, - fontSize: - 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .doseDetail, - fontSize: - 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].quantity.toString() == null ? "" : model.prescriptionList[0].entityList[index].quantity.toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: - FontWeight - .w700, - fontSize: - 17.0, - ), - Expanded( - child: - RichText( - maxLines: - 3, - overflow: - TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 12.0), - text: TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].pharmacyInervention == null ? "" : model.prescriptionList[0].entityList[index].pharmacyInervention.toString()), - ), - ), - ], - ), - SizedBox( - height: - 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: - FontWeight - .w700, - fontSize: - 15.0, - ), - Expanded( - child: AppText( - // commening below code because there is an error coming in the model please fix it before pushing it - model.prescriptionList[0].entityList[index].pharmacistRemarks == null ? "" : model.prescriptionList[0].entityList[index].pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context) - .doctorName + - ": ", - fontWeight: - FontWeight - .w600, - ), - Expanded( - child: - AppText( - model - .prescriptionList[0] - .entityList[index] - .doctorName, - fontWeight: - FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: - FontWeight - .w700, - fontSize: - 13.0, - ), - Expanded( - child: - Container( - // height: MediaQuery.of(context).size.height * - // 0.038, - child: - RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: - StrutStyle(fontSize: 10.0), - text: - TextSpan( - style: - TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList[index].remarks != null - ? model.prescriptionList[0].entityList[index].remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Container( - child: AppText( - 'Sorry , theres no prescriptions listed for this patient', - color: Color(0xFFB9382C), - ), - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/widgets/patients/profile/patient-page-header-widget.dart b/lib/widgets/patients/profile/patient-page-header-widget.dart deleted file mode 100644 index 49ad8f4e..00000000 --- a/lib/widgets/patients/profile/patient-page-header-widget.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; -import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/SOAP/GeneralGetReqForSOAP.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/screens/patients/profile/profile_screen/patient_profile_screen.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class PatientPageHeaderWidget extends StatelessWidget { - - final PatiantInformtion patient; - PatientPageHeaderWidget(this.patient); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return BaseView( - onModelReady: (model) async { - GeneralGetReqForSOAP generalGetReqForSOAP = GeneralGetReqForSOAP( - patientMRN: patient.patientMRN??patient.patientId, - doctorID: '', - editedBy: ''); - await model.getPatientAllergy(generalGetReqForSOAP); - if (model.allergiesList.length == 0) { - await model.getMasterLookup(MasterKeysService.Allergies); - } - if (model.allergySeverityList.length == 0) { - await model.getMasterLookup(MasterKeysService.AllergySeverity); - } - - }, - builder: (_, model, w) => Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - AvatarWidget( - Icon( - patient.genderDescription == "Male" - ? DoctorApp.male - : DoctorApp.female_icon, - size: 70, - color: Colors.white, - ), - ), - SizedBox( - width: 20, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SizedBox( - height: 5, - ), - AppText( - patient.patientDetails.fullName != null ? patient.patientDetails.fullName : patient.firstName, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).age , - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 20, - ), - AppText( - patient.age.toString(), - color: Colors.black, - fontWeight: FontWeight.normal, - ), - ], - ), - model.patientAllergiesList.isNotEmpty && model.getAllergicNames(projectViewModel.isArabic)!='' ?AppText( - TranslationBase.of(context).allergicTO +" : "+model.getAllergicNames(projectViewModel.isArabic), - color: Color(0xFFB9382C), - fontWeight: FontWeight.bold, - ) : AppText(''), - ], - ), - ) - ], - ), - ), - Container( - width: double.infinity, - height: 1, - color: Color(0xffCCCCCC), - ), - SizedBox( - width: 20, - ), - ], - ), - )); - } -} From ca0cc745d5a3647d03db6a912c9e2890a1608baf Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 9 Jun 2021 17:15:23 +0300 Subject: [PATCH 150/241] remove headers --- ...-profile-header-new-design_in_patient.dart | 242 --------- ..._profile_header_with_appointment_card.dart | 507 ------------------ 2 files changed, 749 deletions(-) delete mode 100644 lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart delete mode 100644 lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart b/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart deleted file mode 100644 index c3a8638f..00000000 --- a/lib/widgets/patients/profile/patient-profile-header-new-design_in_patient.dart +++ /dev/null @@ -1,242 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class PatientProfileHeaderNewDesignInPatient extends StatelessWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final double height; - - PatientProfileHeaderNewDesignInPatient( - this.patient, this.patientType, this.arrivalType, - {this.height = 0.0}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - return Container( - padding: EdgeInsets.only( - left: 0, - right: 5, - bottom: 5, - ), - decoration: BoxDecoration( - color: Colors.white, - ), - height: height == 0 ? 200 : height, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - // margin: EdgeInsets.only(top: 50), - child: Column( - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ), - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - AppText( - TranslationBase.of(context).fileNumber, - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText(patient.patientId.toString(), - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - AppDateUtils.convertDateFromServerFormat( - patient.admissionDate, "hh:mm a"), - fontWeight: FontWeight.bold, - fontSize: 1.4 * SizeConfig.textMultiplier, - ), - ], - ) - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - "${TranslationBase.of(context).admissionDate}: ", - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText( - AppDateUtils.convertDateFromServerFormat( - patient.admissionDate, "dd MMM,yyyy"), - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality ?? - patient.nationalityId ?? - '', - fontWeight: FontWeight.bold, - fontSize: 1.4 * SizeConfig.textMultiplier, - ), - patient.nationalityFlagURL != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: (BuildContext context, - Object exception, - StackTrace stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - if(patient.admissionDate!=null) - Row( - children: [ - AppText( - "${TranslationBase.of(context).numOfDays}: ", - fontSize: 1.2 * SizeConfig.textMultiplier, - ), - AppText( - "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patient.admissionDate)).inDays + 1}", - fontSize: 1.4 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700), - ], - ), - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate; - const start = "/Date("; - if (str.isNotEmpty) { - const end = "+0300)"; - - final startIndex = str.indexOf(start); - final endIndex = str.indexOf(end, startIndex + start.length); - - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(str.substring(startIndex + start.length, endIndex))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - isToday(date) { - DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == - DateFormat("yyyy-MM-dd").format(DateTime.now()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart deleted file mode 100644 index f3e01316..00000000 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card.dart +++ /dev/null @@ -1,507 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'large_avatar.dart'; - -class PatientProfileHeaderWhitAppointment extends StatelessWidget { - - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final String doctorName; - final String branch; - final DateTime appointmentDate; - final String profileUrl; - final String invoiceNO; - final String orderNo; - final bool isPrescriptions; - final String clinic; - PatientProfileHeaderWhitAppointment( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, this.isPrescriptions = false, this.clinic}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails.gender; - } else { - gender = patient.gender; - } - - ProjectViewModel projectViewModel = Provider.of(context); - return Container( - padding: EdgeInsets.only( - left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - //height: 300, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - patient.firstName != null ? - (Helpers.capitalize(patient.firstName) + - " " + - Helpers.capitalize( - patient.lastName)) : Helpers.capitalize(patient.patientDetails.fullName), - fontSize: SizeConfig.textMultiplier *2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[ - int.parse(patientType)] == - "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - patient.patientStatusType == - 43 - ? AppText( - TranslationBase.of( - context) - .arrivedP, - color: Colors.green, - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of( - context) - .notArrived, - color: - Colors.red[800], - fontWeight: - FontWeight.bold, - fontFamily: - 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != - null - ? patient - .startTime - : '', - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient - .arrivedOn, - 'MM-dd-yyyy HH:mm'), - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[ - int.parse(patientType)] == - "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .appointmentDate + - " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: - BoxDecoration( - borderRadius: - BorderRadius - .circular( - 25), - color: HexColor( - "#20A169"), - ), - child: AppText( - patient.startTime, - color: Colors.white, - fontSize: 1.5 * - SizeConfig - .textMultiplier, - textAlign: TextAlign - .center, - fontWeight: - FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2(patient.appointmentDate.toString()?? ''), - fontSize: 1.5 * - SizeConfig - .textMultiplier, - fontWeight: - FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 1.6 * - SizeConfig - .textMultiplier, - color: Colors.black), - children: [ - new TextSpan( - text: - TranslationBase.of( - context) - .fileNumber, - style: TextStyle( - fontSize: 12, - fontFamily: - 'Poppins')), - new TextSpan( - text: patient.patientId - .toString(), - style: TextStyle( - fontWeight: - FontWeight.w700, - fontFamily: - 'Poppins', - fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? - patient.nationality??"", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationality != null - ? ClipRRect( - borderRadius: - BorderRadius - .circular( - 20.0), - child: Image.network( - patient.nationalityFlagURL, - height: 25, - width: 30, - errorBuilder: - (BuildContext - context, - Object - exception, - StackTrace - stackTrace) { - return Text( - 'No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * - SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: TranslationBase.of( - context) - .age + - " : ", - style: TextStyle( - fontSize: 14)), - new TextSpan( - text: - "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails.dateofBirth ??"": patient.dateofBirth??"", context)}", - style: TextStyle( - fontWeight: - FontWeight.w700, - fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 30, - height: 30, - margin: EdgeInsets.only(left: projectViewModel.isArabic?10:85, right: projectViewModel.isArabic?85:10,top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom:BorderSide(color: Colors.grey[400],width: 2.5), - left: BorderSide(color: Colors.grey[400],width: 2.5), - ) - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName, - url: profileUrl, - ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.all(10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - '${TranslationBase.of(context).dr}.$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 14, - ), - if (orderNo != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Order No:', - color: Colors.grey[800], - ), - AppText( - orderNo ?? '', - ) - ], - ), - if (invoiceNO != null && !isPrescriptions) - Row( - children: [ - AppText( - 'Invoice:', - color: Colors.grey[800], - ), - AppText( - invoiceNO, - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Branch:', - color: Colors.grey[800], - ), - AppText( - branch?? '', - ) - ], - ), - if(isPrescriptions) - Row( - children: [ - AppText( - 'Clinic:', - color: Colors.grey[800], - ), - AppText( - clinic?? '', - ) - ], - ), - Row( - children: [ - AppText( - !isPrescriptions? 'Result Date:': 'Prescriptions Date', - color: Colors.grey[800], - ), - Expanded( - child: AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', - ), - ) - ], - ) - ]), - ), - ), - - ], - ), - ), - ), - ], - ) - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate =""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - final startIndex = str.indexOf(start); - final endIndex = str.indexOf(end, startIndex + start.length); - - var date = new DateTime.fromMillisecondsSinceEpoch( - int.parse(str.substring(startIndex + start.length, endIndex))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - isToday(date) { - DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == - DateFormat("yyyy-MM-dd").format(DateTime.now()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} From 017669c406e4868b7fe64084806240beecea37cc Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 10 Jun 2021 09:51:34 +0300 Subject: [PATCH 151/241] Merge branch 'development' into procedure_refactoring # Conflicts: # lib/core/service/patient/LiveCarePatientServices.dart --- .../referral/MyReferralPatientModel.dart | 2 + .../my_referred_patient_model.dart | 4 +- .../referral/AddReplayOnReferralPatient.dart | 212 +++++++++--------- 3 files changed, 111 insertions(+), 107 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index ebf12857..ac069e8d 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -163,6 +163,8 @@ class MyReferralPatientModel { referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); } catch (e){ referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + } finally { + referralDate = DateTime.now(); } referringDoctorRemarks = json['ReferringDoctorRemarks']; diff --git a/lib/models/patient/my_referral/my_referred_patient_model.dart b/lib/models/patient/my_referral/my_referred_patient_model.dart index cb61975a..b353e587 100644 --- a/lib/models/patient/my_referral/my_referred_patient_model.dart +++ b/lib/models/patient/my_referral/my_referred_patient_model.dart @@ -166,8 +166,9 @@ class MyReferredPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; + createdOn = json['CreatedOn']; referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus']; - referralDate = json['ReferralDate']; + referralDate = json['ReferralDate'] ?? createdOn; referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; @@ -179,7 +180,6 @@ class MyReferredPatientModel { appointmentDate = json['AppointmentDate']; appointmentType = json['AppointmentType']; patientMRN = json['PatientMRN']; - createdOn = json['CreatedOn']; clinicID = json['ClinicID']; nationalityID = json['NationalityID']; age = json['Age']; diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index 97db3d40..aadcd5f0 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -51,8 +51,8 @@ class _AddReplayOnReferralPatientState void initState() { requestPermissions(); super.initState(); - replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks?? ""; - + replayOnReferralController.text = + widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; } @override @@ -60,67 +60,70 @@ class _AddReplayOnReferralPatientState return AppScaffold( isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: SingleChildScrollView( - child: Column( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BottomSheetTitle(title: 'Reply'), - SizedBox( - height: 10.0, - ), - Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - children: [ - Stack( - children: [ - AppTextFieldCustom( - hintText: 'Reply your responses here', - controller: replayOnReferralController, - maxLines: 35, - minLines: 25, - hasBorder: true, - validationError: - replayOnReferralController.text.isEmpty && - isSubmitted - ? TranslationBase.of(context).emptyMessage - : null, - ), - Positioned( - top: 0, //MediaQuery.of(context).size.height * 0, - right: 15, - child: IconButton( - icon: Icon( - DoctorApp.speechtotext, - color: Colors.black, - size: 35, - ), - onPressed: () { - onVoiceText(); - }, + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BottomSheetTitle(title: 'Reply'), + SizedBox( + height: 10.0, + ), + Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + children: [ + Stack( + children: [ + AppTextFieldCustom( + hintText: 'Reply your responses here', + controller: replayOnReferralController, + maxLines: 35, + minLines: 25, + hasBorder: true, + validationError: replayOnReferralController + .text.isEmpty && + isSubmitted + ? TranslationBase.of(context).emptyMessage + : null, ), - ) - ], - ), - ], + Positioned( + top: 0, + //MediaQuery.of(context).size.height * 0, + right: 15, + child: IconButton( + icon: Icon( + DoctorApp.speechtotext, + color: Colors.black, + size: 35, + ), + onPressed: () { + onVoiceText(); + }, + ), + ) + ], + ), + ], + ), ), ), - ), - ], + ], + ), ), - Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Column( - children: [ - replayOnReferralController.text.isEmpty - ? SizedBox() - : Container( - margin: EdgeInsets.all(5), - child: Expanded( + ), + Container( + height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Column( + children: [ + replayOnReferralController.text.isEmpty + ? SizedBox() + : Container( + margin: EdgeInsets.all(5), child: AppButton( title: TranslationBase.of(context).clearText, onPressed: () { @@ -128,55 +131,54 @@ class _AddReplayOnReferralPatientState replayOnReferralController.text = ''; }); }, - )), - ), - Container( - margin: EdgeInsets.all(5), - child: AppButton( - title: 'Submit Reply', - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - setState(() { - isSubmitted = true; - }); - if (replayOnReferralController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - await widget.patientReferralViewModel.replay( - replayOnReferralController.text.trim(), - widget.myReferralInPatientModel); - if (widget.patientReferralViewModel.state == - ViewState.ErrorLocal) { - Helpers.showErrorToast( - widget.patientReferralViewModel.error); - } else { - GifLoaderDialogUtils.hideDialog(context); - DrAppToastMsg.showSuccesToast( - "Your Reply Added Successfully"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - - Navigator.push( - context, - FadePage( - page: ReplySummeryOnReferralPatient( - widget.myReferralInPatientModel, - replayOnReferralController.text.trim()), - ), - ); - } + ), + ), + Container( + margin: EdgeInsets.all(5), + child: AppButton( + title: 'Submit Reply', + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () async { + setState(() { + isSubmitted = true; + }); + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replay( + replayOnReferralController.text.trim(), + widget.myReferralInPatientModel); + if (widget.patientReferralViewModel.state == + ViewState.ErrorLocal) { + Helpers.showErrorToast( + widget.patientReferralViewModel.error); } else { - Helpers.showErrorToast("You can't add empty reply"); - setState(() { - isSubmitted = false; - }); + GifLoaderDialogUtils.hideDialog(context); + DrAppToastMsg.showSuccesToast( + "Your Reply Added Successfully"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + Navigator.push( + context, + FadePage( + page: ReplySummeryOnReferralPatient( + widget.myReferralInPatientModel, + replayOnReferralController.text.trim()), + ), + ); } - })), - ], - ), + } else { + Helpers.showErrorToast("You can't add empty reply"); + setState(() { + isSubmitted = false; + }); + } + })), + ], ), - ], - ), + ), + ], ), ); } From 42a4f9330ac5819f6f763b2c84ea9570af2dd16f Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Thu, 10 Jun 2021 10:12:58 +0300 Subject: [PATCH 152/241] no message --- ios/Podfile | 1 + ios/Runner.xcodeproj/project.pbxproj | 4 ++++ ios/Runner/Base.lproj/Main.storyboard | 16 +++++++++++++--- ios/Runner/Extensions.swift | 20 ++++++++++++++++++++ ios/Runner/MainAppViewController.swift | 10 ++++++++-- ios/Runner/VideoCallViewController.swift | 18 +++++++++++++----- 6 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 ios/Runner/Extensions.swift diff --git a/ios/Podfile b/ios/Podfile index 62207805..c2335042 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -65,6 +65,7 @@ target 'Runner' do pod 'Flutter', :path => 'Flutter' pod 'OpenTok' pod 'Alamofire', '~> 5.2' + pod 'AADraggableView' # Plugin Pods # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0e446318..66be39bf 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 29211E4225C172B700DD740D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 29211E4125C172B700DD740D /* GoogleService-Info.plist */; }; 300790FA266FB14B0052174C /* VCEmbeder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300790F9266FB14B0052174C /* VCEmbeder.swift */; }; + 300790FC26710CAB0052174C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300790FB26710CAB0052174C /* Extensions.swift */; }; 30F70E6C266F56FD005D8F8E /* MainAppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */; }; 30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; @@ -41,6 +42,7 @@ 29211CD725C165D600DD740D /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = ""; }; 29211E4125C172B700DD740D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 300790F9266FB14B0052174C /* VCEmbeder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VCEmbeder.swift; sourceTree = ""; }; + 300790FB26710CAB0052174C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainAppViewController.swift; sourceTree = ""; }; 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallRequestParameters.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; @@ -78,6 +80,7 @@ isa = PBXGroup; children = ( 300790F9266FB14B0052174C /* VCEmbeder.swift */, + 300790FB26710CAB0052174C /* Extensions.swift */, ); name = helpers; sourceTree = ""; @@ -326,6 +329,7 @@ 300790FA266FB14B0052174C /* VCEmbeder.swift in Sources */, 30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 300790FC26710CAB0052174C /* Extensions.swift in Sources */, 9CE61EBD24AB366E008D68DD /* VideoCallViewController.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 9CE61ECD24ADBB4C008D68DD /* ICallProtocoll.swift in Sources */, diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index 9f1b5e1a..12e173a7 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -48,7 +48,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -98,6 +98,11 @@ + + + + + @@ -237,7 +242,7 @@ - + @@ -282,6 +287,11 @@ + + + + + + + + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - + + - + - + + + + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - - - - - - diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index 35ef4e1b..a6e4bcea 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -32,8 +32,10 @@ class MainAppViewController: FlutterViewController{ videoCallChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in switch call.method { - case "openVideoCall": - self.startVideoCall(result: result, call: call) + case "openVideoCall": + self.startVideoCall(result: result, call: call) + case "showVideo": + self.showVideo() default: result(FlutterMethodNotImplemented) } @@ -69,6 +71,10 @@ extension MainAppViewController : ICallProtocol{ } } + private func showVideo(){ + videoCallContainer.isHidden = false + } + private func startVideoCall(result: @escaping FlutterResult, call:FlutterMethodCall) { videoCallFlutterResult = result @@ -78,6 +84,9 @@ extension MainAppViewController : ICallProtocol{ videoCallViewController.onMinimize = { min in self.minimizeVideoCall(min) } + videoCallViewController.onHide = { + self.videoCallContainer.isHidden = true + } videoCallViewController.onClose = videoCallClosed videoCallViewController.callBack = self videoCallViewController.start(params: VideoCallRequestParameters(dictionary: arguments)) diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index 69d65fb3..3e8b612c 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -35,23 +35,30 @@ class VideoCallViewController: UIViewController { var isUserConnect : Bool = false var onMinimize:((Bool)->Void)? = nil + var onHide:(()->Void)? = nil var onClose:(()->Void)? = nil + + @IBOutlet weak var lblRemoteUsername: UILabel! + // Bottom Actions - @IBOutlet weak var actionsHeightConstraint: NSLayoutConstraint! @IBOutlet weak var videoMuteBtn: UIButton! @IBOutlet weak var micMuteBtn: UIButton! - @IBOutlet weak var localvideoTopMargin: NSLayoutConstraint! + @IBOutlet var minimizeConstraint: [NSLayoutConstraint]! + @IBOutlet var maximisedConstraint: [NSLayoutConstraint]! + + @IBOutlet weak var hideVideoBtn: UIButton! + @IBOutlet weak var draggableBoundryDefiner: UIView! var localVideoDraggable:AADraggableView? @IBOutlet weak var controlButtons: UIView! @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! @IBOutlet weak var localVideoMutedBg: UIView! + @IBOutlet weak var lblCallDuration: UILabel! @IBOutlet weak var remoteVideo: UIView! @IBOutlet weak var localVideo: UIView!{ didSet{ - localVideo.layer.borderColor = UIColor.white.cgColor localVideoDraggable = localVideo?.superview as? AADraggableView localVideoDraggable?.reposition = .edgesOnly } @@ -59,6 +66,7 @@ class VideoCallViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + localVideoDraggable?.respectedView = draggableBoundryDefiner } @IBAction func didClickMuteButton(_ sender: UIButton) { @@ -107,12 +115,16 @@ class VideoCallViewController: UIViewController { minimized = !minimized onMinimize?(minimized) sender.isSelected = minimized + + NSLayoutConstraint.activate(minimized ? minimizeConstraint : maximisedConstraint) + NSLayoutConstraint.deactivate(minimized ? maximisedConstraint : minimizeConstraint) localVideoDraggable?.enable(!minimized) + lblRemoteUsername.isHidden = minimized + hideVideoBtn.isHidden = !minimized + let min_ = minimized UIView.animate(withDuration: 0.5) { - self.actionsHeightConstraint.constant = min_ ? 30 : 60 - self.localvideoTopMargin.constant = min_ ? 20 : 40 self.videoMuteBtn.isHidden = min_ self.micMuteBtn.isHidden = min_ @@ -125,6 +137,10 @@ class VideoCallViewController: UIViewController { } } + @IBAction func hideVideoBtnTapped(_ sender: Any) { + onHide?() + } + func start(params:VideoCallRequestParameters){ self.kApiKey = params.apiKey ?? "" @@ -352,6 +368,8 @@ extension VideoCallViewController: OTSessionDelegate { } publisher?.view!.frame = CGRect(x: 0, y: 0, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) + publisher?.view?.layer.cornerRadius = 5 + publisher?.view?.clipsToBounds = true localVideo.addSubview((publisher?.view)!) } From 3fefcf60d7d304274af6fbfdbe93b3bf9d4d593f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 10:06:42 +0300 Subject: [PATCH 163/241] match the app header design --- lib/config/config.dart | 4 +- .../profile/patient-profile-app-bar.dart | 130 ++++++++---------- 2 files changed, 59 insertions(+), 75 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index eb946dea..4bbbd40e 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 750ee9d5..770137a2 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -9,7 +9,6 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; -import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -98,7 +97,7 @@ class PatientProfileAppBar extends StatelessWidget child: Row(children: [ IconButton( icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, + color: Color(0xFF2B353E), //Colors.black, onPressed: () => Navigator.pop(context), ), Expanded( @@ -111,6 +110,7 @@ class PatientProfileAppBar extends StatelessWidget fontSize: SizeConfig.textMultiplier * 1.8, fontWeight: FontWeight.bold, fontFamily: 'Poppins', + color: Color(0xFF2B353E), ), ), gender == 1 @@ -215,10 +215,10 @@ class PatientProfileAppBar extends StatelessWidget AppText( TranslationBase.of(context).appointmentDate + " : ", - fontSize: 14, - fontWeight: FontWeight.normal, + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, fontFamily: 'Poppins', - color: Colors.black, ), patient.startTime != null ? Container( @@ -231,7 +231,7 @@ class PatientProfileAppBar extends StatelessWidget child: AppText( patient.startTime ?? "", color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, + fontSize: 12, textAlign: TextAlign.center, fontWeight: FontWeight.bold, ), @@ -244,7 +244,7 @@ class PatientProfileAppBar extends StatelessWidget child: AppText( AppDateUtils.convertDateFormatImproved( patient.appointmentDate ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, + fontSize: 12, fontWeight: FontWeight.bold, ), ), @@ -267,17 +267,23 @@ class PatientProfileAppBar extends StatelessWidget color: Colors.black), children: [ new TextSpan( - text: TranslationBase - .of(context) - .fileNumber, - style: TextStyle( - fontSize: 14, fontFamily: 'Poppins')), + text: TranslationBase + .of(context) + .fileNumber, + + style: TextStyle( + fontSize: 10, + fontFamily: 'Poppins', + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + + ),), new TextSpan( text: patient.patientId.toString(), style: TextStyle( - fontWeight: FontWeight.w700, - fontFamily: 'Poppins', - fontSize: 14)), + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 12, color: Color(0xFF2E303A),)), ], ), ), @@ -316,8 +322,10 @@ class PatientProfileAppBar extends StatelessWidget ), children: [ new TextSpan( - text: TranslationBase.of(context).age+ " : ", - style: TextStyle(fontSize: 14)), + text: TranslationBase + .of(context) + .age + " : ", + style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),)), new TextSpan( text: "${AppDateUtils.getAgeByBirthday( @@ -327,7 +335,9 @@ class PatientProfileAppBar extends StatelessWidget : patient.dateofBirth ?? "", context, isServerFormat: !isFromLiveCare)}", style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),)), ], ), ), @@ -361,9 +371,7 @@ class PatientProfileAppBar extends StatelessWidget child: RichText( text: new TextSpan( style: new TextStyle( - fontSize: - 2.0 * SizeConfig.textMultiplier, - color: Colors.black, + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), fontFamily: 'Poppins', ), children: [ @@ -373,21 +381,22 @@ class PatientProfileAppBar extends StatelessWidget : TranslationBase.of(context) .admissionDate + " : ", - style: TextStyle(fontSize: 14)), + style: TextStyle(fontSize: 10)), new TextSpan( text: patient.admissionDate == null ? "" : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 15)), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),)), ]))), if (patient.admissionDate != null) Row( children: [ AppText( "${TranslationBase.of(context).numOfDays}: ", - fontSize: 15, + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757) ), if(isDischargedPatient && patient.dischargeDate != null) @@ -399,8 +408,10 @@ class PatientProfileAppBar extends StatelessWidget .getDateTimeFromServerFormat( patient.admissionDate)) .inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700) + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ) else AppText( "${DateTime @@ -409,8 +420,9 @@ class PatientProfileAppBar extends StatelessWidget .getDateTimeFromServerFormat( patient.admissionDate)) .inDays + 1}", - fontSize: 15, - fontWeight: FontWeight.w700), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A),), ], ), ], @@ -468,17 +480,17 @@ class PatientProfileAppBar extends StatelessWidget '${TranslationBase .of(context) .dr}$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 9, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700, + fontSize: 12, ), if (orderNo != null && !isPrescriptions) Row( children: [ AppText('Order No: ', - color: Colors.grey[800], - fontSize: 12), + + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(orderNo ?? '', fontSize: 12) ], @@ -488,8 +500,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Invoice: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(invoiceNO ?? "", fontSize: 12) ], @@ -498,8 +509,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Branch: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(branch ?? '', fontSize: 12) ], @@ -509,8 +519,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Clinic: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(clinic ?? '', fontSize: 12) ], @@ -520,8 +529,7 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Episode: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(episode ?? '', fontSize: 12) ], @@ -531,23 +539,20 @@ class PatientProfileAppBar extends StatelessWidget Row( children: [ AppText('Visit Date: ', - color: Colors.grey[800], - fontSize: 12), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757),), AppText(visitDate ?? '', fontSize: 12) ], ), if (!isMedicalFile) Row( + children: [ - Expanded( - child: AppText( - !isPrescriptions - ? 'Result Date: ' - : 'Prescriptions Date ', - color: Colors.grey[800], - fontSize: 12, - ), + AppText( + !isPrescriptions + ? 'Result Date:' + : 'Prescriptions Date ', + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), ), AppText( '${AppDateUtils @@ -573,27 +578,6 @@ class PatientProfileAppBar extends StatelessWidget ), ); } - - - - - isToday(date) { - DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == - DateFormat("yyyy-MM-dd").format(DateTime.now()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } - @override Size get preferredSize => Size(double.maxFinite, height == 0 From bc53ca7b8aab8aa5d992b98ef2e79cfd781bc3cf Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 13:07:39 +0300 Subject: [PATCH 164/241] fix appointment date in header --- .../patient_profile_screen.dart | 2 +- lib/util/date-utils.dart | 6 +- .../profile/patient-profile-app-bar.dart | 113 +++++++----------- 3 files changed, 48 insertions(+), 73 deletions(-) diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index cc71dd6d..e0bea0b7 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -108,7 +108,7 @@ class _PatientProfileScreenState extends State isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && patient.patientStatusType == 43) - ? 210 + ? 220 : isDischargedPatient ? 240 : 0, diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 511b99e9..9b00ba2b 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -16,7 +16,11 @@ class AppDateUtils { } static String convertStringToDateFormat(String date, String dateFormat) { - DateTime dateTime = DateTime.parse(date); + DateTime dateTime ; + if(date.contains("/Date")) + dateTime= getDateTimeFromServerFormat(date); + else + dateTime = DateTime.parse(date); return convertDateToFormat(dateTime, dateFormat); } diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 770137a2..5d676061 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -60,6 +60,7 @@ class PatientProfileAppBar extends StatelessWidget this.isFromSOAP = false, this.isFromLabResult = false}); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -84,8 +85,8 @@ class PatientProfileAppBar extends StatelessWidget ? isInpatient ? 215 : isAppointmentHeader - ? 310 - : 200 + ? 325 + : 215 : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), @@ -157,8 +158,7 @@ class PatientProfileAppBar extends StatelessWidget child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SERVICES_PATIANT2[int.parse(patientType)] == - "patientArrivalList" + patient.patientStatusType != null ? Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -182,81 +182,18 @@ class PatientProfileAppBar extends StatelessWidget fontFamily: 'Poppins', fontSize: 12, ), - arrivalType == '1' || patient.arrivedOn == null + patient.startTime != null ? AppText( patient.startTime != null ? patient.startTime : '', fontFamily: 'Poppins', fontWeight: FontWeight.w600, - ) - : AppText( - patient.arrivedOn != null - ? (isFromSOAP ? AppDateUtils - .getDayMonthYearDateFormatted( - AppDateUtils.convertStringToDate( - patient.arrivedOn)) : AppDateUtils - .convertStringToDateFormat( - patient.arrivedOn, - 'MM-dd-yyyy HH:mm')) - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) + ):SizedBox() ], )) : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == - "List_MyOutPatient" && !isFromLiveCare) - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate + - " : ", - fontSize: 10, - color: Color(0xFF575757), - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 12, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - AppDateUtils.convertDateFormatImproved( - patient.appointmentDate ?? ''), - fontSize: 12, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), + Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -342,6 +279,40 @@ class PatientProfileAppBar extends StatelessWidget ), ), ), + + if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).appointmentDate + + " : ", + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + ), + SizedBox( + width: 3.5, + ), + AppText( + (isFromSOAP ? AppDateUtils + .getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate( + patient.appointmentDate)) : AppDateUtils + .convertStringToDateFormat( + patient.appointmentDate, + 'MM-dd-yyyy')) + , + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ), + SizedBox( + height: 0.5, + ) + ], + ), if(isFromLabResult)Container( child: RichText( text: new TextSpan( @@ -581,6 +552,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 310 : 200 + ? isInpatient ? 215 : isAppointmentHeader ? 325 : 215 : height); } From 1b4988e5f05a9da553ecce811844f7a351999b45 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Sun, 13 Jun 2021 14:45:46 +0300 Subject: [PATCH 165/241] no message --- .../xcshareddata/xcschemes/Runner.xcscheme | 8 ++- ios/Runner/Base.lproj/Main.storyboard | 70 ++++++++++++------- ios/Runner/MainAppViewController.swift | 9 ++- ios/Runner/VideoCallViewController.swift | 29 +++++++- .../patient_profile_screen.dart | 34 ++++++--- lib/util/VideoChannel.dart | 24 ++++++- ...ent-profile-header-new-design-app-bar.dart | 24 ++++++- 7 files changed, 153 insertions(+), 45 deletions(-) diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb2dffc4..a28140cf 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -27,6 +27,8 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + - - + + + + - + + + + + + - + + + @@ -200,6 +207,21 @@ + @@ -209,22 +231,11 @@ - - @@ -281,6 +294,7 @@ + @@ -288,18 +302,24 @@ - + - - - - - - - - + + + + + + + + + + + + + + diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index a6e4bcea..3849635e 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -27,9 +27,10 @@ class MainAppViewController: FlutterViewController{ super.viewDidAppear(animated) } + var videoCallChannel:FlutterMethodChannel? private func initFlutterBridge(){ - let videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: binaryMessenger) - videoCallChannel.setMethodCallHandler({ + videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: binaryMessenger) + videoCallChannel?.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in switch call.method { case "openVideoCall": @@ -86,6 +87,10 @@ extension MainAppViewController : ICallProtocol{ } videoCallViewController.onHide = { self.videoCallContainer.isHidden = true + self.videoCallChannel?.invokeMethod("onHide", arguments: nil) + } + videoCallViewController.onVideoDuration = { duration in + self.videoCallChannel?.invokeMethod("onVideoDuration", arguments: duration) } videoCallViewController.onClose = videoCallClosed videoCallViewController.callBack = self diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index 3e8b612c..fd25541b 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -36,6 +36,7 @@ class VideoCallViewController: UIViewController { var onMinimize:((Bool)->Void)? = nil var onHide:(()->Void)? = nil + var onVideoDuration:((String)->Void)? = nil var onClose:(()->Void)? = nil @@ -44,6 +45,7 @@ class VideoCallViewController: UIViewController { // Bottom Actions @IBOutlet weak var videoMuteBtn: UIButton! @IBOutlet weak var micMuteBtn: UIButton! + @IBOutlet weak var camSwitchBtn: UIButton! @IBOutlet var minimizeConstraint: [NSLayoutConstraint]! @IBOutlet var maximisedConstraint: [NSLayoutConstraint]! @@ -109,6 +111,10 @@ class VideoCallViewController: UIViewController { callBack?.sessionDone(res:["callResponse":"CallEnd"]) sessionDisconnect() } + + @IBAction func hideVideoBtnTapped(_ sender: Any) { + onHide?() + } var minimized = false @IBAction func onMinimize(_ sender: UIButton) { @@ -122,11 +128,13 @@ class VideoCallViewController: UIViewController { lblRemoteUsername.isHidden = minimized hideVideoBtn.isHidden = !minimized + lblCallDuration.superview?.isHidden = !hideVideoBtn.isHidden let min_ = minimized UIView.animate(withDuration: 0.5) { self.videoMuteBtn.isHidden = min_ self.micMuteBtn.isHidden = min_ + self.camSwitchBtn.isHidden = min_ let localVdoSize = self.localVideo.bounds.size let remoteVdoSize = self.remoteVideo.bounds.size @@ -137,8 +145,20 @@ class VideoCallViewController: UIViewController { } } - @IBAction func hideVideoBtnTapped(_ sender: Any) { - onHide?() + var durationTimer:Timer?; + func startUpdateCallDuration(){ + var seconds = 0 + durationTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in + seconds = seconds+1 + let durationSegments = (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60) + let hours = String(format: "%02d", durationSegments.0) + let mins = String(format: "%02d", durationSegments.1) + let secs = String(format: "%02d", durationSegments.2) + let durationString = "\(mins):\(secs)" + + self.lblCallDuration.text = durationString + self.onVideoDuration?(durationString) + } } func start(params:VideoCallRequestParameters){ @@ -410,8 +430,11 @@ extension VideoCallViewController: OTSessionDelegate { guard let subscriberView = subscriber.view else { return } + subscriberView.frame = CGRect(x: 0, y: 0, width: remoteVideo.bounds.width, height: remoteVideo.bounds.height) remoteVideo.addSubview(subscriberView) + + startUpdateCallDuration() } func setupSubscribe(_ stream: OTStream?) { @@ -474,7 +497,7 @@ extension VideoCallViewController: OTSubscriberDelegate { print("The subscriber failed to connect to the stream.") } @objc func hideControlButtons() { - controlButtons.isHidden = true +// controlButtons.isHidden = true } } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 30f53a0b..f2a52411 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; @@ -46,10 +48,15 @@ class _PatientProfileScreenState extends State TabController _tabController; int index = 0; int _activeTab = 0; + + StreamController videoCallDurationStreamController; + Stream videoCallDurationStream = (() async*{})(); @override void initState() { _tabController = TabController(length: 2, vsync: this); super.initState(); + videoCallDurationStreamController = StreamController(); + videoCallDurationStream = videoCallDurationStreamController.stream; } @override @@ -103,16 +110,20 @@ class _PatientProfileScreenState extends State Column( children: [ PatientProfileHeaderNewDesignAppBar( - patient, arrivalType ?? '0', patientType, - isInpatient: isInpatient, - isFromLiveCare: isFromLiveCare, - height: (patient.patientStatusType != null && - patient.patientStatusType == 43) - ? 210 - : isDischargedPatient - ? 240 - : 0, - isDischargedPatient: isDischargedPatient), + patient, arrivalType ?? '0', patientType, + videoCallDurationStream: videoCallDurationStream, + onVideoDurationTap: (){ + VideoChannel.show(); + }, + isInpatient: isInpatient, + isFromLiveCare: isFromLiveCare, + height: (patient.patientStatusType != null && + patient.patientStatusType == 43) + ? 210 + : isDischargedPatient + ? 240 + : 0, + isDischargedPatient: isDischargedPatient), Container( height: !isSearchAndOut ? isDischargedPatient @@ -311,6 +322,9 @@ class _PatientProfileScreenState extends State onFailure: (String error) { DrAppToastMsg.showErrorToast(error); }, + onVideoDuration: (duration){ + videoCallDurationStreamController.sink.add(duration); + }, onCallEnd: () { var asd=""; // WidgetsBinding.instance.addPostFrameCallback((_) { diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index a0962010..a9c2b5e2 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -4,15 +4,30 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class VideoChannel{ /// channel name static const _channel = const MethodChannel("Dr.cloudSolution/videoCall"); - static openVideoCallScreen( - {kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID,String generalId,int doctorId, Function() onCallEnd , Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure}) async { + static openVideoCallScreen({kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID, + String generalId,int doctorId, Function() onCallEnd , + Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure, VoidCallback onHide, Function(String) onVideoDuration}) async { + + onHide = onHide ?? (){}; + onVideoDuration = onVideoDuration ?? (v){}; + var result; try { + _channel.setMethodCallHandler((call) { + if(call.method == 'onHide'){ + onHide(); + }else if(call.method == 'onVideoDuration'){ + onVideoDuration(call.arguments); + } + return true as dynamic; + }); + result = await _channel.invokeMethod( 'openVideoCall', { @@ -29,6 +44,7 @@ class VideoChannel{ ); if(result['callResponse'] == 'CallEnd') { onCallEnd(); + onVideoDuration(null); } else { SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(Platform.isIOS ?result['sessionStatus'] :json.decode(result['sessionStatus'])); @@ -40,6 +56,10 @@ class VideoChannel{ } } + + static show(){ + _channel.invokeMethod("showVideo"); + } } \ No newline at end of file diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 995ac57a..69bb9758 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -21,8 +21,11 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final bool isDischargedPatient; final bool isFromLiveCare; + final Stream videoCallDurationStream; + final VoidCallback onVideoDurationTap; + PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); + this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream, this.onVideoDurationTap}); @override Widget build(BuildContext context) { @@ -88,6 +91,25 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ), ), ), + StreamBuilder( + stream: videoCallDurationStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if(snapshot.hasData) + return InkWell( + onTap: (){ + if(onVideoDurationTap != null) + onVideoDurationTap(); + }, + child: Container( + decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.symmetric(vertical: 2, horizontal: 10), + child: Text(snapshot.data, style: TextStyle(color: Colors.white),), + ), + ); + else + return Container(); + }, + ), ]), ), Row(children: [ From 411746da984b7d83592a578421260170b5dff3b0 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 15:00:54 +0300 Subject: [PATCH 166/241] remove patient type and arrival type form patient profile header --- lib/screens/live_care/end_call_screen.dart | 2 +- .../medical-file/health_summary_page.dart | 2 - .../medical-file/medical_file_details.dart | 2 - lib/screens/patients/ECGPage.dart | 2 +- .../insurance_approval_screen_patient.dart | 2 - .../patients/insurance_approvals_details.dart | 2 +- .../profile/UCAF/UCAF-detail-screen.dart | 2 +- .../profile/UCAF/UCAF-input-screen.dart | 2 +- .../admission-request-first-screen.dart | 2 +- .../admission-request-third-screen.dart | 2 +- .../admission-request_second-screen.dart | 2 +- .../lab_result/laboratory_result_page.dart | 3 +- .../profile/lab_result/labs_home_page.dart | 3 +- .../MedicalReportDetailPage.dart | 2 - .../medical_report/MedicalReportPage.dart | 2 - .../profile/note/progress_note_screen.dart | 2 - .../patient_profile_screen.dart | 3 +- .../radiology/radiology_details_page.dart | 2 - .../radiology/radiology_home_page.dart | 2 - .../refer-patient-screen-in-patient.dart | 2 - .../referral/refer-patient-screen.dart | 2 +- .../soap_update/update_soap_index.dart | 2 +- .../vital_sign/vital_sign_details_screen.dart | 2 +- .../vital_sign_item_details_screen.dart | 2 +- .../prescription_item_in_patient_page.dart | 2 +- .../prescription/prescription_items_page.dart | 2 - .../prescription/prescriptions_page.dart | 2 - lib/screens/procedures/procedure_screen.dart | 2 - lib/screens/sick-leave/add-sickleave.dart | 2 - lib/screens/sick-leave/show-sickleave.dart | 2 - .../profile/patient-profile-app-bar.dart | 61 +++++++++---------- 31 files changed, 44 insertions(+), 80 deletions(-) diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 411079fc..754ccb47 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -185,7 +185,7 @@ class _EndCallScreenState extends State { backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, appBar: PatientProfileAppBar( - widget.patient, arrivalType ?? '7', '1', + widget.patient, isInpatient: isInpatient, height: (widget.patient.patientStatusType != null && widget.patient.patientStatusType == 43) diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index ee4726e2..6b4b066c 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -32,8 +32,6 @@ class _HealthSummaryPageState extends State { AppScaffold( appBar: PatientProfileAppBar( patient, - patientType.toString() ?? "0", - arrivalType, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/medical-file/medical_file_details.dart b/lib/screens/medical-file/medical_file_details.dart index 64d76f06..b53284a9 100644 --- a/lib/screens/medical-file/medical_file_details.dart +++ b/lib/screens/medical-file/medical_file_details.dart @@ -104,8 +104,6 @@ class _MedicalFileDetailsState extends State { AppScaffold( appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? "0", - patient.arrivedOn.toString() ?? 0, doctorName: doctorName, profileUrl: doctorImage, clinic: clinicName, diff --git a/lib/screens/patients/ECGPage.dart b/lib/screens/patients/ECGPage.dart index 97923959..ba4c108c 100644 --- a/lib/screens/patients/ECGPage.dart +++ b/lib/screens/patients/ECGPage.dart @@ -31,7 +31,7 @@ class ECGPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Color(0xffF8F8F8), - appBar: PatientProfileAppBar(patient,arrivalType??'0',patientType), + appBar: PatientProfileAppBar(patient), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 3d03589b..1ab0734b 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -46,8 +46,6 @@ class _InsuranceApprovalScreenNewState AppScaffold( appBar: PatientProfileAppBar( patient, - patientType.toString() ?? "0", - patientType, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/patients/insurance_approvals_details.dart b/lib/screens/patients/insurance_approvals_details.dart index 57af55d8..0945df37 100644 --- a/lib/screens/patients/insurance_approvals_details.dart +++ b/lib/screens/patients/insurance_approvals_details.dart @@ -55,7 +55,7 @@ class _InsuranceApprovalsDetailsState extends State { isShowAppBar: true, baseViewModel: model, appBar: PatientProfileAppBar( - patient, patient.patientType.toString(), patient.arrivedOn), + patient), body: patient.admissionNo != null ? SingleChildScrollView( child: Container( diff --git a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart index af61de0d..081f1a6e 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart @@ -48,7 +48,7 @@ class _UcafDetailScreenState extends State { baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).ucaf, body: Column( children: [ diff --git a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart index 7c163a79..3bbc6637 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart @@ -66,7 +66,7 @@ class _UCAFInputScreenState extends State { baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).ucaf, body: model.patientVitalSignsHistory.length > 0 && model.patientChiefComplaintList != null && diff --git a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart index dd6d9d76..f0ccaece 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart @@ -62,7 +62,7 @@ class _AdmissionRequestThirdScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart index 175f5669..563b4827 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart @@ -53,7 +53,7 @@ class _AdmissionRequestThirdScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart index f7e03533..dc79b2be 100644 --- a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart @@ -75,7 +75,7 @@ class _AdmissionRequestSecondScreenState baseViewModel: model, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).admissionRequest, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 23b17830..d6b4d2bc 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -40,8 +40,7 @@ class _LaboratoryResultPageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( widget.patient, - widget.patientType ?? "0", - widget.arrivalType ?? "0", + isFromLabResult: true, appointmentDate: widget.patientLabOrders.orderDate, ), diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index 96b64675..b2bfa2fd 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -54,8 +54,7 @@ class _LabsHomePageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - patientType, + isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index 7b787f44..ab24f8e0 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -33,8 +33,6 @@ class MedicalReportDetailPage extends StatelessWidget { backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( patient, - patientType, - arrivalType, ), body: Container( child: SingleChildScrollView( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 5f6b3eea..aa9d0b58 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -45,8 +45,6 @@ class MedicalReportPage extends StatelessWidget { backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( patient, - patientType, - arrivalType, ), body: SingleChildScrollView( physics: BouncingScrollPhysics(), diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 087cab80..723ee75f 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -90,8 +90,6 @@ class _ProgressNoteState extends State { // appBarTitle: TranslationBase.of(context).progressNote, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - arrivalType, isInpatient: true, ), body: model.patientProgressNoteList == null || diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e0bea0b7..8a831c4d 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -103,8 +103,7 @@ class _PatientProfileScreenState extends State Column( children: [ PatientProfileAppBar( - patient, arrivalType ?? '0', patientType, - isInpatient: isInpatient, + patient, isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && patient.patientStatusType == 43) diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index cb0cd99a..48bef68a 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -37,8 +37,6 @@ class RadiologyDetailsPage extends StatelessWidget { builder: (_, model, widget) => AppScaffold( appBar: PatientProfileAppBar( patient, - patientType ?? "0", - arrivalType ?? "0", appointmentDate: finalRadiology.orderDate, doctorName: finalRadiology.doctorName, clinic: finalRadiology.clinicDescription, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index 8d0946c5..3d8d527c 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -52,8 +52,6 @@ class _RadiologyHomePageState extends State { // appBarTitle: TranslationBase.of(context).radiology, appBar: PatientProfileAppBar( patient, - patient.patientType.toString() ?? '0', - arrivalType, isInpatient: isInpatient, ), baseViewModel: model, diff --git a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart index 11ace2f6..66fd22fd 100644 --- a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart +++ b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart @@ -138,8 +138,6 @@ class _PatientMakeInPatientReferralScreenState extends State { appBarTitle: TranslationBase.of(context).referPatient, isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), body: SingleChildScrollView( child: Container( child: Column( diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index ab5e02d0..60597b11 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -82,7 +82,7 @@ class _UpdateSoapIndexState extends State mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - PatientProfileAppBar(patient, '7', '7',isFromSOAP: true,), + PatientProfileAppBar(patient), Container( width: double.infinity, height: 1, diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index a67e213f..23266095 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -41,7 +41,7 @@ class VitalSignDetailsScreen extends StatelessWidget { isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient), appBarTitle: TranslationBase.of(context).vitalSign, body: mode.patientVitalSignsHistory.length > 0 ? Column( diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index 0c41386c..0ed9da56 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -191,7 +191,7 @@ class VitalSignItemDetailsScreen extends StatelessWidget { backgroundColor: Color.fromRGBO(248, 248, 248, 1), isShowAppBar: true, appBar: PatientProfileAppBar( - patient, patientType, arrivalType), + patient,), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/screens/prescription/prescription_item_in_patient_page.dart b/lib/screens/prescription/prescription_item_in_patient_page.dart index 472f6dd8..7cf33935 100644 --- a/lib/screens/prescription/prescription_item_in_patient_page.dart +++ b/lib/screens/prescription/prescription_item_in_patient_page.dart @@ -45,7 +45,7 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { backgroundColor: Colors.grey[100], baseViewModel: model, appBar: PatientProfileAppBar( - patient, patient.patientType.toString(), patient.arrivedOn), + patient), body: SingleChildScrollView( child: Container( child: Column( diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index e888dddd..b97343c4 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -30,8 +30,6 @@ class PrescriptionItemsPage extends StatelessWidget { baseViewModel: model, appBar: PatientProfileAppBar( patient, - patientType??"0", - arrivalType??"0", clinic: prescriptions.clinicDescription, branch: prescriptions.name, isPrescriptions: true, diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 17b36233..1a99299b 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -37,8 +37,6 @@ class PrescriptionsPage extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - patientType ?? '0', - arrivalType, isInpatient: isInpatient, ), body: patient.admissionNo == null diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index aa51fc18..79371459 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -46,8 +46,6 @@ class ProcedureScreen extends StatelessWidget { baseViewModel: model, appBar: PatientProfileAppBar( patient, - arrivalType ?? '0', - patientType, isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/sick-leave/add-sickleave.dart b/lib/screens/sick-leave/add-sickleave.dart index d7759f9e..7b065321 100644 --- a/lib/screens/sick-leave/add-sickleave.dart +++ b/lib/screens/sick-leave/add-sickleave.dart @@ -36,8 +36,6 @@ class AddSickLeavScreen extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/screens/sick-leave/show-sickleave.dart b/lib/screens/sick-leave/show-sickleave.dart index 4ead8cd3..726524d8 100644 --- a/lib/screens/sick-leave/show-sickleave.dart +++ b/lib/screens/sick-leave/show-sickleave.dart @@ -27,8 +27,6 @@ class ShowSickLeaveScreen extends StatelessWidget { backgroundColor: Colors.grey[100], appBar: PatientProfileAppBar( patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", ), body: SingleChildScrollView( child: Column( diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5d676061..467d681b 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -1,4 +1,3 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -8,7 +7,6 @@ import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -17,8 +15,6 @@ import 'large_avatar.dart'; class PatientProfileAppBar extends StatelessWidget with PreferredSizeWidget { final PatiantInformtion patient; - final String patientType; - final String arrivalType; final double height; final bool isInpatient; final bool isDischargedPatient; @@ -36,11 +32,10 @@ class PatientProfileAppBar extends StatelessWidget final String visitDate; final String clinic; final bool isAppointmentHeader; - final bool isFromSOAP; final bool isFromLabResult; PatientProfileAppBar( - this.patient, this.patientType, this.arrivalType, + this.patient, {this.height = 0.0, this.isInpatient = false, this.isDischargedPatient = false, @@ -57,7 +52,6 @@ class PatientProfileAppBar extends StatelessWidget this.episode, this.visitDate, this.isAppointmentHeader = false, - this.isFromSOAP = false, this.isFromLabResult = false}); @@ -86,7 +80,7 @@ class PatientProfileAppBar extends StatelessWidget ? 215 : isAppointmentHeader ? 325 - : 215 + : 200 : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), @@ -173,25 +167,24 @@ class PatientProfileAppBar extends StatelessWidget fontFamily: 'Poppins', fontSize: 12, ) - : AppText( - TranslationBase - .of(context) - .notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - patient.startTime != null - ? AppText( + : AppText( + TranslationBase.of(context).notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), patient.startTime != null - ? patient.startTime - : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ):SizedBox() - ], - )) + ? AppText( + patient.startTime != null + ? patient.startTime + : '', + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A)) + : SizedBox() + ], + )) : SizedBox(), Row( @@ -296,13 +289,10 @@ class PatientProfileAppBar extends StatelessWidget width: 3.5, ), AppText( - (isFromSOAP ? AppDateUtils + AppDateUtils .getDayMonthYearDateFormatted( AppDateUtils.convertStringToDate( - patient.appointmentDate)) : AppDateUtils - .convertStringToDateFormat( - patient.appointmentDate, - 'MM-dd-yyyy')) + patient.appointmentDate)) , fontWeight: FontWeight.w700, fontSize: 12, @@ -356,7 +346,12 @@ class PatientProfileAppBar extends StatelessWidget new TextSpan( text: patient.admissionDate == null ? "" - : "${AppDateUtils.convertDateFromServerFormat(patient.admissionDate.toString(), 'yyyy-MM-dd')}", + : "${AppDateUtils + .getDayMonthYearDateFormatted( + (AppDateUtils + .getDateTimeFromServerFormat( + patient.admissionDate + .toString())))}", style: TextStyle( fontWeight: FontWeight.w700, fontSize: 12, @@ -552,6 +547,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 325 : 215 + ? isInpatient ? 215 : isAppointmentHeader ? 325 : 200 : height); } From 142fbb93fd533379857803f1e560cb6280c4f386 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Sun, 13 Jun 2021 15:09:27 +0300 Subject: [PATCH 167/241] Referrel Doctor reply --- dart | 0 lib/config/config.dart | 1 + .../referral/MyReferralPatientModel.dart | 6 +- .../add_referred_remarks_request.dart | 72 +++++++ .../patient/MyReferralPatientService.dart | 71 ++++--- .../viewModel/patient-referral-viewmodel.dart | 103 +++++---- .../referral/AddReplayOnReferralPatient.dart | 86 +++++--- .../my-referral-inpatient-screen.dart | 20 +- .../referral_patient_detail_in-paint.dart | 201 ++++++------------ lib/screens/qr_reader/QR_reader_screen.dart | 28 +-- pubspec.lock | 6 +- 11 files changed, 311 insertions(+), 283 deletions(-) create mode 100644 dart create mode 100644 lib/core/model/referral/add_referred_remarks_request.dart diff --git a/dart b/dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/config/config.dart b/lib/config/config.dart index eb946dea..492d7ada 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -224,6 +224,7 @@ const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RE const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; +const ADD_REFERRED_REMARKS_NEW = "Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks_New"; var selectedPatientType = 1; diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 1072e098..ce8a6447 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -61,6 +61,7 @@ class MyReferralPatientModel { String priorityDescription; String referringClinicDescription; String referringDoctorName; + int referalStatus; MyReferralPatientModel( {this.rowID, @@ -122,10 +123,12 @@ class MyReferralPatientModel { this.nursingStationName, this.priorityDescription, this.referringClinicDescription, - this.referringDoctorName}); + this.referringDoctorName, + this.referalStatus}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; + referalStatus = json['ReferalStatus']; projectID = json['ProjectID']; lineItemNo = json['LineItemNo']; doctorID = json['DoctorID']; @@ -203,6 +206,7 @@ class MyReferralPatientModel { Map toJson() { final Map data = new Map(); data['RowID'] = this.rowID; + data['ReferalStatus'] = this.referalStatus; data['ProjectID'] = this.projectID; data['LineItemNo'] = this.lineItemNo; data['DoctorID'] = this.doctorID; diff --git a/lib/core/model/referral/add_referred_remarks_request.dart b/lib/core/model/referral/add_referred_remarks_request.dart new file mode 100644 index 00000000..14089513 --- /dev/null +++ b/lib/core/model/referral/add_referred_remarks_request.dart @@ -0,0 +1,72 @@ +class AddReferredRemarksRequestModel { + int projectID; + int admissionNo; + int lineItemNo; + String referredDoctorRemarks; + int editedBy; + int referalStatus; + bool isLoginForDoctorApp; + String iPAdress; + bool patientOutSA; + String tokenID; + int languageID; + double versionID; + int channel; + String sessionID; + int deviceTypeID; + + AddReferredRemarksRequestModel( + {this.projectID, + this.admissionNo, + this.lineItemNo, + this.referredDoctorRemarks, + this.editedBy, + this.referalStatus, + this.isLoginForDoctorApp, + this.iPAdress, + this.patientOutSA, + this.tokenID, + this.languageID, + this.versionID, + this.channel, + this.sessionID, + this.deviceTypeID}); + + AddReferredRemarksRequestModel.fromJson(Map json) { + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + lineItemNo = json['LineItemNo']; + referredDoctorRemarks = json['ReferredDoctorRemarks']; + editedBy = json['EditedBy']; + referalStatus = json['ReferalStatus']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + iPAdress = json['IPAdress']; + patientOutSA = json['PatientOutSA']; + tokenID = json['TokenID']; + languageID = json['LanguageID']; + versionID = json['VersionID']; + channel = json['Channel']; + sessionID = json['SessionID']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['LineItemNo'] = this.lineItemNo; + data['ReferredDoctorRemarks'] = this.referredDoctorRemarks; + data['EditedBy'] = this.editedBy; + data['ReferalStatus'] = this.referalStatus; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['IPAdress'] = this.iPAdress; + data['PatientOutSA'] = this.patientOutSA; + data['TokenID'] = this.tokenID; + data['LanguageID'] = this.languageID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['SessionID'] = this.sessionID; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 39a75e8f..87fcdd23 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/request_add_referred_doctor_remarks.dart'; @@ -11,20 +12,19 @@ class MyReferralInPatientService extends BaseService { hasError = false; await getDoctorProfile(); - MyReferralPatientRequestModel myReferralPatientRequestModel = - MyReferralPatientRequestModel( - doctorID: doctorProfile.doctorID, - firstName: "0", - middleName: "0", - lastName: "0", - patientMobileNumber: "0", - patientIdentificationID: "0", - patientID: 0, - from: "0", - to: "0", - stamp: DateTime.now().toIso8601String(), - isLoginForDoctorApp: true, - patientTypeID: 1); + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( + doctorID: doctorProfile.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( GET_MY_REFERRAL_INPATIENT, @@ -47,8 +47,7 @@ class MyReferralInPatientService extends BaseService { hasError = false; await getDoctorProfile(); - MyReferralPatientRequestModel myReferralPatientRequestModel = - MyReferralPatientRequestModel( + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( doctorID: doctorProfile.doctorID, firstName: "0", middleName: "0", @@ -79,18 +78,14 @@ class MyReferralInPatientService extends BaseService { ); } - Future replay( - String referredDoctorRemarks, MyReferralPatientModel referral) async { + Future replay(String referredDoctorRemarks, MyReferralPatientModel referral) async { hasError = false; await getDoctorProfile(); - RequestAddReferredDoctorRemarks _requestAddReferredDoctorRemarks = - RequestAddReferredDoctorRemarks(); + RequestAddReferredDoctorRemarks _requestAddReferredDoctorRemarks = RequestAddReferredDoctorRemarks(); _requestAddReferredDoctorRemarks.projectID = referral.projectID; - _requestAddReferredDoctorRemarks.admissionNo = - referral.admissionNo.toString(); + _requestAddReferredDoctorRemarks.admissionNo = referral.admissionNo.toString(); _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; - _requestAddReferredDoctorRemarks.referredDoctorRemarks = - referredDoctorRemarks; + _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; _requestAddReferredDoctorRemarks.patientID = referral.patientID; _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; @@ -104,4 +99,32 @@ class MyReferralInPatientService extends BaseService { }, ); } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + hasError = false; + await getDoctorProfile(); + AddReferredRemarksRequestModel _requestAddReferredDoctorRemarks = AddReferredRemarksRequestModel( + editedBy: doctorProfile.doctorID, + projectID: doctorProfile.projectID, + referredDoctorRemarks: referredDoctorRemarks, + referalStatus: referalStatus); + _requestAddReferredDoctorRemarks.projectID = referral.projectID; + _requestAddReferredDoctorRemarks.admissionNo = int.parse(referral.admissionNo); + _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; + _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; + _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; + _requestAddReferredDoctorRemarks.referalStatus = referalStatus; + + // _requestAddReferredDoctorRemarks.patientID = referral.patientID; + // _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; + await baseAppClient.post( + ADD_REFERRED_REMARKS_NEW, + body: _requestAddReferredDoctorRemarks.toJson(), + onSuccess: (dynamic body, int statusCode) {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } } diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 01d40e62..9e852978 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/referral/DischargeReferralPatient.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/service/patient/DischargedPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/MyReferralPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/ReferralService.dart'; @@ -18,16 +19,13 @@ import 'package:flutter/cupertino.dart'; import '../../locator.dart'; class PatientReferralViewModel extends BaseViewModel { - PatientReferralService _referralPatientService = - locator(); + PatientReferralService _referralPatientService = locator(); ReferralService _referralService = locator(); - MyReferralInPatientService _myReferralService = - locator(); + MyReferralInPatientService _myReferralService = locator(); - DischargedPatientService _dischargedPatientService = - locator(); + DischargedPatientService _dischargedPatientService = locator(); List get myDischargeReferralPatient => _dischargedPatientService.myDischargeReferralPatients; @@ -36,28 +34,21 @@ class PatientReferralViewModel extends BaseViewModel { List get clinicsList => _referralPatientService.clinicsList; - List get referralFrequencyList => - _referralPatientService.frequencyList; + List get referralFrequencyList => _referralPatientService.frequencyList; List doctorsList = []; - List get clinicDoctorsList => - _referralPatientService.doctorsList; + List get clinicDoctorsList => _referralPatientService.doctorsList; - List get myReferralPatients => - _myReferralService.myReferralPatients; + List get myReferralPatients => _myReferralService.myReferralPatients; - List get listMyReferredPatientModel => - _referralPatientService.listMyReferredPatientModel; + List get listMyReferredPatientModel => _referralPatientService.listMyReferredPatientModel; - List get pendingReferral => - _referralPatientService.pendingReferralList; + List get pendingReferral => _referralPatientService.pendingReferralList; - List get patientReferral => - _referralPatientService.patientReferralList; + List get patientReferral => _referralPatientService.patientReferralList; - List get patientArrivalList => - _referralPatientService.patientArrivalList; + List get patientArrivalList => _referralPatientService.patientArrivalList; Future getPatientReferral(PatiantInformtion patient) async { setState(ViewState.Busy); @@ -106,8 +97,7 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getClinicDoctors( - PatiantInformtion patient, int clinicId, int branchId) async { + Future getClinicDoctors(PatiantInformtion patient, int clinicId, int branchId) async { setState(ViewState.BusyLocal); await _referralPatientService.getDoctorsList(patient, clinicId, branchId); if (_referralPatientService.hasError) { @@ -125,10 +115,7 @@ class PatientReferralViewModel extends BaseViewModel { Future getDoctorBranch() async { DoctorProfileModel doctorProfile = await getDoctorProfile(); if (doctorProfile != null) { - dynamic _selectedBranch = { - "facilityId": doctorProfile.projectID, - "facilityName": doctorProfile.projectName - }; + dynamic _selectedBranch = {"facilityId": doctorProfile.projectID, "facilityName": doctorProfile.projectName}; return _selectedBranch; } return null; @@ -175,27 +162,38 @@ class PatientReferralViewModel extends BaseViewModel { } Future getMyReferralPatientService({bool localBusy = false}) async { - if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); await _myReferralService.getMyReferralPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); } else setState(ViewState.Idle); } Future getMyReferralOutPatientService({bool localBusy = false}) async { - if(localBusy) setState(ViewState.BusyLocal); else setState(ViewState.Busy); + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); await _myReferralService.getMyReferralOutPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error; - if(localBusy) setState(ViewState.ErrorLocal); else setState(ViewState.Error); + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); } else setState(ViewState.Idle); } - Future replay( - String referredDoctorRemarks, MyReferralPatientModel referral) async { + Future replay(String referredDoctorRemarks, MyReferralPatientModel referral) async { setState(ViewState.Busy); await _myReferralService.replay(referredDoctorRemarks, referral); if (_myReferralService.hasError) { @@ -205,8 +203,7 @@ class PatientReferralViewModel extends BaseViewModel { getMyReferralPatientService(); } - Future responseReferral( - PendingReferral pendingReferral, bool isAccepted) async { + Future responseReferral(PendingReferral pendingReferral, bool isAccepted) async { setState(ViewState.Busy); await _referralPatientService.responseReferral(pendingReferral, isAccepted); if (_referralPatientService.hasError) { @@ -216,11 +213,10 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future makeReferral(PatiantInformtion patient, String isoStringDate, - int projectID, int clinicID, int doctorID, String remarks) async { + Future makeReferral(PatiantInformtion patient, String isoStringDate, int projectID, int clinicID, int doctorID, + String remarks) async { setState(ViewState.Busy); - await _referralPatientService.makeReferral( - patient, isoStringDate, projectID, clinicID, doctorID, remarks); + await _referralPatientService.makeReferral(patient, isoStringDate, projectID, clinicID, doctorID, remarks); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.Error); @@ -260,12 +256,10 @@ class PatientReferralViewModel extends BaseViewModel { } } - Future getPatientDetails( - String fromDate, String toDate, int patientMrn, int appointmentNo) async { + Future getPatientDetails(String fromDate, String toDate, int patientMrn, int appointmentNo) async { setState(ViewState.Busy); - await _referralPatientService.getPatientArrivalList(toDate, - fromDate: fromDate, patientMrn: patientMrn); + await _referralPatientService.getPatientArrivalList(toDate, fromDate: fromDate, patientMrn: patientMrn); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.Error); @@ -284,8 +278,7 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future verifyReferralDoctorRemarks( - MyReferredPatientModel referredPatient) async { + Future verifyReferralDoctorRemarks(MyReferredPatientModel referredPatient) async { setState(ViewState.Busy); await _referralPatientService.verifyReferralDoctorRemarks(referredPatient); if (_referralPatientService.hasError) { @@ -324,8 +317,7 @@ class PatientReferralViewModel extends BaseViewModel { } } - PatiantInformtion getPatientFromReferral( - MyReferredPatientModel referredPatient) { + PatiantInformtion getPatientFromReferral(MyReferredPatientModel referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -350,8 +342,7 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - PatiantInformtion getPatientFromReferralO( - MyReferralPatientModel referredPatient) { + PatiantInformtion getPatientFromReferralO(MyReferralPatientModel referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -376,8 +367,7 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - PatiantInformtion getPatientFromDischargeReferralPatient( - DischargeReferralPatient referredPatient) { + PatiantInformtion getPatientFromDischargeReferralPatient(DischargeReferralPatient referredPatient) { PatiantInformtion patient = PatiantInformtion(); patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; @@ -396,10 +386,19 @@ class PatientReferralViewModel extends BaseViewModel { patient.roomId = referredPatient.roomID; patient.bedId = referredPatient.bedID; patient.nationalityName = referredPatient.nationalityName; - patient.nationalityFlagURL = - ''; // TODO from backend referredPatient.nationalityFlagURL; + patient.nationalityFlagURL = ''; // TODO from backend referredPatient.nationalityFlagURL; patient.age = referredPatient.age; patient.clinicDescription = referredPatient.clinicDescription; return patient; } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + setState(ViewState.Busy); + await _myReferralService.replayReferred(referredDoctorRemarks, referral, referalStatus); + if (_myReferralService.hasError) { + error = _myReferralService.error; + setState(ViewState.ErrorLocal); + } else + getMyReferralPatientService(); + } } diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index c246a3ad..56ff85c4 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -1,7 +1,7 @@ import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -14,7 +14,6 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; -import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; @@ -25,23 +24,25 @@ import 'ReplySummeryOnReferralPatient.dart'; class AddReplayOnReferralPatient extends StatefulWidget { final PatientReferralViewModel patientReferralViewModel; final MyReferralPatientModel myReferralInPatientModel; + final AddReferredRemarksRequestModel myReferralInPatientRequestModel; final bool isEdited; const AddReplayOnReferralPatient( {Key key, this.patientReferralViewModel, this.myReferralInPatientModel, - this.isEdited}) + this.isEdited, + this.myReferralInPatientRequestModel}) : super(key: key); @override - _AddReplayOnReferralPatientState createState() => - _AddReplayOnReferralPatientState(); + _AddReplayOnReferralPatientState createState() => _AddReplayOnReferralPatientState(); } -class _AddReplayOnReferralPatientState - extends State { +class _AddReplayOnReferralPatientState extends State { bool isSubmitted = false; + int replay = 1; + int reject = 2; stt.SpeechToText speech = stt.SpeechToText(); var reconizedWord; var event = RobotProvider(); @@ -51,8 +52,7 @@ class _AddReplayOnReferralPatientState void initState() { requestPermissions(); super.initState(); - replayOnReferralController.text = - widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; + replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; } @override @@ -84,9 +84,7 @@ class _AddReplayOnReferralPatientState maxLines: 35, minLines: 25, hasBorder: true, - validationError: replayOnReferralController - .text.isEmpty && - isSubmitted + validationError: replayOnReferralController.text.isEmpty && isSubmitted ? TranslationBase.of(context).emptyMessage : null, ), @@ -139,8 +137,33 @@ class _AddReplayOnReferralPatientState children: [ Expanded( child: AppButton( - onPressed: () { - Navigator.of(context).pop(); + onPressed: () async { + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, reject); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + DrAppToastMsg.showSuccesToast("Has been rejected"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), + // ), + // ); + } + } else { + Helpers.showErrorToast("You can't add empty reply"); + setState(() { + isSubmitted = false; + }); + } }, title: TranslationBase.of(context).reject, fontColor: Colors.white, @@ -158,32 +181,26 @@ class _AddReplayOnReferralPatientState }); if (replayOnReferralController.text.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); - await widget.patientReferralViewModel.replay( - replayOnReferralController.text.trim(), - widget.myReferralInPatientModel); - if (widget.patientReferralViewModel.state == - ViewState.ErrorLocal) { - Helpers.showErrorToast( - widget.patientReferralViewModel.error); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, replay); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); } else { GifLoaderDialogUtils.hideDialog(context); - DrAppToastMsg.showSuccesToast( - "Your Reply Added Successfully"); + DrAppToastMsg.showSuccesToast("Your Reply Added Successfully"); Navigator.of(context).pop(); Navigator.of(context).pop(); - Navigator.push( - context, - FadePage( - page: ReplySummeryOnReferralPatient( - widget.myReferralInPatientModel, - replayOnReferralController.text.trim()), - ), - ); + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), + // ), + // ); } } else { - Helpers.showErrorToast( - "You can't add empty reply"); + Helpers.showErrorToast("You can't add empty reply"); setState(() { isSubmitted = false; }); @@ -250,8 +267,7 @@ class _AddReplayOnReferralPatientState onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; - bool available = await speech.initialize( - onStatus: statusListener, onError: errorListener); + bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index f4a002d6..3ebd7896 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -16,7 +16,6 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class MyReferralInPatientScreen extends StatelessWidget { PatientType patientType = PatientType.IN_PATIENT; - @override Widget build(BuildContext context) { return BaseView( @@ -30,7 +29,7 @@ class MyReferralInPatientScreen extends StatelessWidget { Container( margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( - (patientType) async { + (patientType) async { this.patientType = patientType; GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { @@ -62,7 +61,7 @@ class MyReferralInPatientScreen extends StatelessWidget { ), ) : Expanded( - child: SingleChildScrollView( + child: SingleChildScrollView( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -74,30 +73,31 @@ class MyReferralInPatientScreen extends StatelessWidget { Navigator.push( context, FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index],model), + page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), ), ); }, child: PatientReferralItemWidget( - referralStatus: model.getReferralStatusNameByCode(model.myReferralPatients[index].referralStatus,context), + referralStatus: model.getReferralStatusNameByCode( + model.myReferralPatients[index].referralStatus, context), referralStatusCode: model.myReferralPatients[index].referralStatus, patientName: model.myReferralPatients[index].patientName, patientGender: model.myReferralPatients[index].gender, - referredDate: AppDateUtils.getDayMonthYearDateFormatted(model.myReferralPatients[index].referralDate), + referredDate: AppDateUtils.getDayMonthYearDateFormatted( + model.myReferralPatients[index].referralDate), referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate), patientID: "${model.myReferralPatients[index].patientID}", isSameBranch: false, isReferral: true, isReferralClinic: true, - referralClinic:"${model.myReferralPatients[index].referringClinicDescription}", + referralClinic: "${model.myReferralPatients[index].referringClinicDescription}", remark: model.myReferralPatients[index].referringDoctorRemarks, nationality: model.myReferralPatients[index].nationalityName, nationalityFlag: model.myReferralPatients[index].nationalityFlagURL, doctorAvatar: model.myReferralPatients[index].doctorImageURL, referralDoctorName: model.myReferralPatients[index].referringDoctorName, clinicDescription: model.myReferralPatients[index].referringClinicDescription, - infoIcon: Icon(FontAwesomeIcons.arrowRight, - size: 25, color: Colors.black), + infoIcon: Icon(FontAwesomeIcons.arrowRight, size: 25, color: Colors.black), ), ), ), @@ -105,7 +105,7 @@ class MyReferralInPatientScreen extends StatelessWidget { ), ), ), - ), + ), ], ), ), diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 7f0cd146..66e01364 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -20,8 +20,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { final MyReferralPatientModel referredPatient; final PatientReferralViewModel patientReferralViewModel; - ReferralPatientDetailScreen( - this.referredPatient, this.patientReferralViewModel); + ReferralPatientDetailScreen(this.referredPatient, this.patientReferralViewModel); @override Widget build(BuildContext context) { @@ -52,8 +51,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - (Helpers.capitalize( - "${referredPatient.firstName} ${referredPatient.lastName}")), + (Helpers.capitalize("${referredPatient.firstName} ${referredPatient.lastName}")), fontSize: SizeConfig.textMultiplier * 2.5, fontWeight: FontWeight.bold, fontFamily: 'Poppins', @@ -70,18 +68,14 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), InkWell( onTap: () { - PatiantInformtion patient = model - .getPatientFromReferralO(referredPatient); - Navigator.of(context) - .pushNamed(PATIENTS_PROFILE, arguments: { + PatiantInformtion patient = model.getPatientFromReferralO(referredPatient); + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", "isInpatient": true, "arrivalType": "1", - "from": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), - "to": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), + "from": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), + "to": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), }); }, child: Icon( @@ -98,18 +92,14 @@ class ReferralPatientDetailScreen extends StatelessWidget { children: [ InkWell( onTap: () { - PatiantInformtion patient = model - .getPatientFromReferralO(referredPatient); - Navigator.of(context) - .pushNamed(PATIENTS_PROFILE, arguments: { + PatiantInformtion patient = model.getPatientFromReferralO(referredPatient); + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", "isInpatient": true, "arrivalType": "1", - "from": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), - "to": AppDateUtils.convertDateToFormat( - DateTime.now(), 'yyyy-MM-dd'), + "from": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), + "to": AppDateUtils.convertDateToFormat(DateTime.now(), 'yyyy-MM-dd'), }); }, child: Padding( @@ -144,8 +134,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { child: Column( children: [ Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( "${model.getReferralStatusNameByCode(referredPatient.referralStatus, context)}", @@ -170,28 +159,23 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( - mainAxisAlignment: - MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .fileNumber, + TranslationBase.of(context).fileNumber, fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), AppText( "${referredPatient.patientID}", fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -208,35 +192,29 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Column( children: [ Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( "${TranslationBase.of(context).refClinic}: ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient - .referringClinicDescription, + referredPatient.referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -244,31 +222,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), if (referredPatient.frequency != null) Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .frequency + - ": ", + TranslationBase.of(context).frequency + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient - .frequencyDescription ?? - '', + referredPatient.frequencyDescription ?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -280,29 +249,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { Row( children: [ AppText( - referredPatient.nationalityName != - null + referredPatient.nationalityName != null ? referredPatient.nationalityName : "", fontWeight: FontWeight.bold, color: Color(0xFF2E303A), - fontSize: - 1.4 * SizeConfig.textMultiplier, + fontSize: 1.4 * SizeConfig.textMultiplier, ), - referredPatient.nationalityFlagURL != - null + referredPatient.nationalityFlagURL != null ? ClipRRect( - borderRadius: - BorderRadius.circular(20.0), + borderRadius: BorderRadius.circular(20.0), child: Image.network( - referredPatient - .nationalityFlagURL, + referredPatient.nationalityFlagURL, height: 25, width: 30, - errorBuilder: (BuildContext - context, - Object exception, - StackTrace stackTrace) { + errorBuilder: + (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -314,26 +276,21 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.priorityDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context).priority + - ": ", + TranslationBase.of(context).priority + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient.priorityDescription ?? - '', + referredPatient.priorityDescription ?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -342,33 +299,24 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - TranslationBase.of(context) - .maxResponseTime + - ": ", + TranslationBase.of(context).maxResponseTime + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, - fontSize: - 1.7 * SizeConfig.textMultiplier, + fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), Expanded( child: AppText( - referredPatient.mAXResponseTime != - null - ? AppDateUtils - .convertDateFromServerFormat( - referredPatient - .mAXResponseTime, - "dd MMM,yyyy") + referredPatient.mAXResponseTime != null + ? AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime, "dd MMM,yyyy") : '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: - 1.8 * SizeConfig.textMultiplier, + fontSize: 1.8 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ), @@ -378,8 +326,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: - EdgeInsets.only(left: 10, right: 0), + margin: EdgeInsets.only(left: 10, right: 0), child: Image.asset( 'assets/images/patient/ic_ref_arrow_up.png', height: 50, @@ -387,26 +334,17 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ), Container( - margin: EdgeInsets.only( - left: 0, - top: 25, - right: 0, - bottom: 0), - padding: EdgeInsets.only( - left: 4.0, right: 4.0), - child: referredPatient.doctorImageURL != - null + margin: EdgeInsets.only(left: 0, top: 25, right: 0, bottom: 0), + padding: EdgeInsets.only(left: 4.0, right: 4.0), + child: referredPatient.doctorImageURL != null ? ClipRRect( - borderRadius: - BorderRadius.circular(20.0), + borderRadius: BorderRadius.circular(20.0), child: Image.network( referredPatient.doctorImageURL, height: 25, width: 30, errorBuilder: - (BuildContext context, - Object exception, - StackTrace stackTrace) { + (BuildContext context, Object exception, StackTrace stackTrace) { return Text('No Image'); }, )) @@ -422,30 +360,22 @@ class ReferralPatientDetailScreen extends StatelessWidget { Expanded( flex: 4, child: Container( - margin: EdgeInsets.only( - left: 10, - top: 30, - right: 10, - bottom: 0), + margin: EdgeInsets.only(left: 10, top: 30, right: 10, bottom: 0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( "${TranslationBase.of(context).dr} ${referredPatient.referringDoctorName}", fontFamily: 'Poppins', fontWeight: FontWeight.w800, - fontSize: 1.5 * - SizeConfig.textMultiplier, + fontSize: 1.5 * SizeConfig.textMultiplier, color: Colors.black, ), AppText( - referredPatient - .referringClinicDescription, + referredPatient.referringClinicDescription, fontFamily: 'Poppins', fontWeight: FontWeight.w700, - fontSize: 1.3 * - SizeConfig.textMultiplier, + fontSize: 1.3 * SizeConfig.textMultiplier, color: Color(0XFF2E303A), ), ], @@ -469,10 +399,8 @@ class ReferralPatientDetailScreen extends StatelessWidget { children: [ Container( width: double.infinity, - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), - padding: - EdgeInsets.symmetric(horizontal: 16, vertical: 16), + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.rectangle, @@ -508,10 +436,8 @@ class ReferralPatientDetailScreen extends StatelessWidget { if (referredPatient.referredDoctorRemarks.isNotEmpty) Container( width: double.infinity, - margin: - EdgeInsets.symmetric(horizontal: 16, vertical: 0), - padding: EdgeInsets.symmetric( - horizontal: 16, vertical: 16), + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.rectangle, @@ -566,8 +492,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, - isEdited: referredPatient - .referredDoctorRemarks.isNotEmpty, + isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index 30c05fef..a411aaa7 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -61,8 +61,7 @@ class _QrReaderScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, - appBarTitle: - TranslationBase.of(context).qr + TranslationBase.of(context).reader, + appBarTitle: TranslationBase.of(context).qr + TranslationBase.of(context).reader, body: Center( child: Container( margin: EdgeInsets.only(top: SizeConfig.realScreenHeight / 7), @@ -80,9 +79,7 @@ class _QrReaderScreenState extends State { height: 7, ), AppText(TranslationBase.of(context).scanQrCode, - fontSize: 14, - fontWeight: FontWeight.w400, - textAlign: TextAlign.center), + fontSize: 14, fontWeight: FontWeight.w400, textAlign: TextAlign.center), SizedBox( height: 15, ), @@ -106,18 +103,13 @@ class _QrReaderScreenState extends State { margin: EdgeInsets.only(top: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.0), - color: - Theme.of(context).errorColor.withOpacity(0.06), + color: Theme.of(context).errorColor.withOpacity(0.06), ), - padding: EdgeInsets.symmetric( - vertical: 8.0, horizontal: 12.0), + padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), child: Row( children: [ Expanded( - child: AppText( - error ?? - TranslationBase.of(context) - .errorMessage, + child: AppText(error ?? TranslationBase.of(context).errorMessage, color: Theme.of(context).errorColor)), ], ), @@ -162,9 +154,7 @@ class _QrReaderScreenState extends State { case "0": if (response['List_MyOutPatient'] != null) { setState(() { - patientList = - ModelResponse.fromJson(response['List_MyOutPatient']) - .list; + patientList = ModelResponse.fromJson(response['List_MyOutPatient']).list; isLoading = false; }); Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { @@ -181,8 +171,7 @@ class _QrReaderScreenState extends State { case "1": if (response['List_MyInPatient'] != null) { setState(() { - patientList = - ModelResponse.fromJson(response['List_MyInPatient']).list; + patientList = ModelResponse.fromJson(response['List_MyInPatient']).list; isLoading = false; error = ""; }); @@ -203,8 +192,7 @@ class _QrReaderScreenState extends State { isLoading = false; isError = true; }); - DrAppToastMsg.showErrorToast( - response['ErrorEndUserMessage'] ?? response['ErrorMessage']); + DrAppToastMsg.showErrorToast(response['ErrorEndUserMessage'] ?? response['ErrorMessage']); } }).catchError((error) { setState(() { diff --git a/pubspec.lock b/pubspec.lock index 77df9848..25596d43 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.4" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <2.11.0" + dart: ">=2.10.0 <=2.11.0-213.1.beta" flutter: ">=1.22.0 <2.0.0" From 161cb1e872b2416d7cf94a915f13940d0930b200 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 15:51:44 +0300 Subject: [PATCH 168/241] fix profile height size --- lib/config/config.dart | 4 ++-- .../patient_profile_screen.dart | 1 + .../profile/patient-profile-app-bar.dart | 19 ++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 4bbbd40e..eb946dea 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 8a831c4d..21515268 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -105,6 +105,7 @@ class _PatientProfileScreenState extends State PatientProfileAppBar( patient, isFromLiveCare: isFromLiveCare, + isInpatient: isInpatient, height: (patient.patientStatusType != null && patient.patientStatusType == 43) ? 220 diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 467d681b..09c987fd 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -75,13 +75,13 @@ class PatientProfileAppBar extends StatelessWidget decoration: BoxDecoration( color: Colors.white, ), - height: height == 0 - ? isInpatient - ? 215 - : isAppointmentHeader - ? 325 - : 200 - : height, + // height: height == 0 + // ? isInpatient + // ? 215 + // : isAppointmentHeader + // ? 325 + // : 200 + // : height, child: Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), margin: EdgeInsets.only(top: 50), @@ -324,10 +324,11 @@ class PatientProfileAppBar extends StatelessWidget ), ), ), - if(isInpatient) + // if(isInpatient) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + if(patient.admissionDate != null && patient.admissionDate.isNotEmpty) Container( child: RichText( text: new TextSpan( @@ -547,6 +548,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 215 : isAppointmentHeader ? 325 : 200 + ? isInpatient ? 160 : isAppointmentHeader ? 290 : 160 : height); } From 712a742aa230355c881da306055719ba2143499f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Sun, 13 Jun 2021 17:26:14 +0300 Subject: [PATCH 169/241] fix small issue --- .../patients/profile/patient-profile-app-bar.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 09c987fd..1a47dd00 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -314,12 +314,15 @@ class PatientProfileAppBar extends StatelessWidget children: [ new TextSpan( text: "Result Date: ", - style: TextStyle(fontSize: 14)), + style: TextStyle( fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins',)), new TextSpan( text: '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate, isArabic: projectViewModel.isArabic)}', style: TextStyle( - fontWeight: FontWeight.w700, fontSize: 14)), + fontWeight: FontWeight.w700, fontSize: 12)), ], ), ), @@ -519,7 +522,7 @@ class PatientProfileAppBar extends StatelessWidget !isPrescriptions ? 'Result Date:' : 'Prescriptions Date ', - fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), + fontSize: 10, fontWeight: FontWeight.w600,color: Color(0xFF575757), ), AppText( '${AppDateUtils @@ -527,7 +530,7 @@ class PatientProfileAppBar extends StatelessWidget appointmentDate, isArabic: projectViewModel .isArabic)}', - fontSize: 14, + fontSize: 12, ) ], ) @@ -548,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 160 : isAppointmentHeader ? 290 : 160 + ? isInpatient ? 160 : isAppointmentHeader ? 290 : 170 : height); } From f60ff85e319e8d325b0dc9383d8523cd1a994a03 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 14 Jun 2021 10:54:51 +0300 Subject: [PATCH 170/241] no message --- ios/Runner/AppDelegate.swift | 1 - .../hide_video_icon.png | Bin 175 -> 906 bytes ios/Runner/Base.lproj/Main.storyboard | 16 +++---- ios/Runner/MainAppViewController.swift | 35 ++++++---------- ios/Runner/VCEmbeder.swift | 1 + ios/Runner/VideoCallViewController.swift | 39 +++++++++--------- .../patient_profile_screen.dart | 25 ++++++++--- lib/util/VideoChannel.dart | 20 ++++----- lib/util/helpers.dart | 7 ++++ ...ent-profile-header-new-design-app-bar.dart | 7 +--- pubspec.lock | 2 +- pubspec.yaml | 2 +- 12 files changed, 79 insertions(+), 76 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index dc938e36..8ebd4235 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -49,7 +49,6 @@ import OpenTok navVC.modalPresentationStyle = .fullScreen window.rootViewController?.present(navVC, animated: true, completion: nil) - } } diff --git a/ios/Runner/Assets.xcassets/hide_video_icon.imageset/hide_video_icon.png b/ios/Runner/Assets.xcassets/hide_video_icon.imageset/hide_video_icon.png index 8dea84b1de80408985f9dc89728ab042c7750a7c..40889f7710b0615cba211a52f145ae817ecad67b 100644 GIT binary patch literal 906 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lxRtf@J#ddWzYh$IT%O>_%)r1c48n{Iv*t)JFfcJ@hD4M^`1)8S=jZArrsOB3 z>Q&?xfOIj~R9FF-xv3?I3Kh9IdBs*0wn|_XRzNmLSYJs2tfVB{Rw=?aK*2e`C{@8s z&p^*W$&O1wLBXadCCw_x#SN+*$g@?-C@Cqh($_C9FV`zK*2^zS*Eh7ZwA42+(l;{F z1**_3uFNY*tkBIXR)!b?Gsh*hIJqdZpd>RtPXT0ZVp4u-iLH_n$Rap^xU(cP4PjGW zG1OZ?59)(t^bPe4^s#A6t;oco4I~562KE=kIvbE-R{lkqsXzyVoMmTd1GWG~4Bd9J*EaW`dB5fYK%l^v_RH}Bo5VQqYnxsq(Fnj2v`&tC3ajk z`tazr<7$5V$ORbV$(}BbAsMW1FB)<&DDbcteEnY^W`4X(Q{<#C7yH!`9z}-+21X_p z4gm!iqk}aqrn0y8bKckGm6PXg+H~}tt^CVv3-iq`@m{M&QU}%G#mXmkiG{0r - - - - - - - @@ -114,6 +107,13 @@ + + + + + + + @@ -333,7 +333,7 @@ - + diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index 3849635e..87610042 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -35,8 +35,6 @@ class MainAppViewController: FlutterViewController{ switch call.method { case "openVideoCall": self.startVideoCall(result: result, call: call) - case "showVideo": - self.showVideo() default: result(FlutterMethodNotImplemented) } @@ -72,8 +70,10 @@ extension MainAppViewController : ICallProtocol{ } } - private func showVideo(){ - videoCallContainer.isHidden = false + private func showVideo(show:Bool){ + UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: { + self.videoCallContainer.isHidden = !show + }) } private func startVideoCall(result: @escaping FlutterResult, call:FlutterMethodCall) { @@ -82,17 +82,16 @@ extension MainAppViewController : ICallProtocol{ if let arguments = call.arguments as? NSDictionary{ showVideoCallView(true) - videoCallViewController.onMinimize = { min in - self.minimizeVideoCall(min) + videoCallViewController.onFloat = { min in + self.floatVideoCallView(min) } - videoCallViewController.onHide = { - self.videoCallContainer.isHidden = true - self.videoCallChannel?.invokeMethod("onHide", arguments: nil) + videoCallViewController.onCallConnect = { + self.videoCallChannel?.invokeMethod("onCallConnected",arguments: nil) } - videoCallViewController.onVideoDuration = { duration in - self.videoCallChannel?.invokeMethod("onVideoDuration", arguments: duration) + videoCallViewController.onCallDisconnect = { + self.showVideoCallView(false) + self.videoCallChannel?.invokeMethod("onCallDisconnected",arguments: nil) } - videoCallViewController.onClose = videoCallClosed videoCallViewController.callBack = self videoCallViewController.start(params: VideoCallRequestParameters(dictionary: arguments)) } @@ -100,7 +99,7 @@ extension MainAppViewController : ICallProtocol{ } - private func minimizeVideoCall(_ value:Bool){ + private func floatVideoCallView(_ value:Bool){ videoCallContainer.enable(value) UIView.animate(withDuration: 0.5) { @@ -119,20 +118,11 @@ extension MainAppViewController : ICallProtocol{ } private func showVideoCallView(_ value:Bool){ - videoCallContainer.alpha = value ? 0.0 : 1 - self.videoCallContainer.isHidden = !value - UIView.animate(withDuration: 0.5) { - self.videoCallContainer.alpha = value ? 1.0 : 0.0 - } completion: { complete in self.videoCallContainer.isHidden = !value } } - private func videoCallClosed(){ - showVideoCallView(false) - } - func sessionDone(res: Any) { videoCallFlutterResult?(res) } @@ -144,7 +134,6 @@ extension MainAppViewController : ICallProtocol{ func setVideoViewConstrints(){ let screen = UIScreen.main.bounds - videoCallContainer.translatesAutoresizingMaskIntoConstraints = false diff --git a/ios/Runner/VCEmbeder.swift b/ios/Runner/VCEmbeder.swift index 7e2ea0fd..9617a247 100644 --- a/ios/Runner/VCEmbeder.swift +++ b/ios/Runner/VCEmbeder.swift @@ -54,6 +54,7 @@ class ViewEmbedder { let w = container.frame.size.width; let h = container.frame.size.height; child.view.frame = CGRect(x: 0, y: 0, width: w, height: h) + child.view.backgroundColor = UIColor.black child.view.fill(to: container) } diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index fd25541b..27268128 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -34,11 +34,11 @@ class VideoCallViewController: UIViewController { var seconds = 30 var isUserConnect : Bool = false - var onMinimize:((Bool)->Void)? = nil - var onHide:(()->Void)? = nil - var onVideoDuration:((String)->Void)? = nil - var onClose:(()->Void)? = nil - + var onFloat:((Bool)->Void)? = nil + var onMinimize:(()->Void)? = nil + var onCallConnect:(()->Void)? = nil + var onCallDisconnect:(()->Void)? = nil + @IBOutlet weak var lblRemoteUsername: UILabel! @@ -61,6 +61,7 @@ class VideoCallViewController: UIViewController { @IBOutlet weak var remoteVideo: UIView! @IBOutlet weak var localVideo: UIView!{ didSet{ + localVideo.layer.borderColor = UIColor.white.cgColor localVideoDraggable = localVideo?.superview as? AADraggableView localVideoDraggable?.reposition = .edgesOnly } @@ -74,7 +75,6 @@ class VideoCallViewController: UIViewController { @IBAction func didClickMuteButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected publisher!.publishAudio = !sender.isSelected - } @IBAction func didClickSpeakerButton(_ sender: UIButton) { @@ -113,24 +113,24 @@ class VideoCallViewController: UIViewController { } @IBAction func hideVideoBtnTapped(_ sender: Any) { - onHide?() + onMinimize?() } - var minimized = false + var floated = false @IBAction func onMinimize(_ sender: UIButton) { - minimized = !minimized - onMinimize?(minimized) - sender.isSelected = minimized + floated = !floated + onFloat?(floated) + sender.isSelected = floated - NSLayoutConstraint.activate(minimized ? minimizeConstraint : maximisedConstraint) - NSLayoutConstraint.deactivate(minimized ? maximisedConstraint : minimizeConstraint) - localVideoDraggable?.enable(!minimized) + NSLayoutConstraint.activate(floated ? minimizeConstraint : maximisedConstraint) + NSLayoutConstraint.deactivate(floated ? maximisedConstraint : minimizeConstraint) + localVideoDraggable?.enable(!floated) - lblRemoteUsername.isHidden = minimized - hideVideoBtn.isHidden = !minimized + lblRemoteUsername.isHidden = floated + hideVideoBtn.isHidden = !floated lblCallDuration.superview?.isHidden = !hideVideoBtn.isHidden - let min_ = minimized + let min_ = floated UIView.animate(withDuration: 0.5) { self.videoMuteBtn.isHidden = min_ self.micMuteBtn.isHidden = min_ @@ -157,7 +157,6 @@ class VideoCallViewController: UIViewController { let durationString = "\(mins):\(secs)" self.lblCallDuration.text = durationString - self.onVideoDuration?(durationString) } } @@ -277,7 +276,8 @@ class VideoCallViewController: UIViewController { dismiss(animated: true) } dismiss(animated: true) - onClose?() + onCallDisconnect?() + durationTimer?.invalidate() } func requestCameraPermissionsIfNeeded() { @@ -435,6 +435,7 @@ extension VideoCallViewController: OTSessionDelegate { remoteVideo.addSubview(subscriberView) startUpdateCallDuration() + onCallConnect?() } func setupSubscribe(_ stream: OTStream?) { diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index f2a52411..5212df0c 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -22,6 +22,7 @@ import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dar import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; +import 'package:quiver/async.dart'; import '../../../../routes.dart'; @@ -95,6 +96,23 @@ class _PatientProfileScreenState extends State _activeTab = 1; } + StreamSubscription callTimer; + callConnected(){ + callTimer = CountdownTimer(Duration(minutes: 1), Duration(seconds: 1)).listen(null) + ..onDone(() { + callTimer.cancel(); + }) + ..onData((data) { + var t = Helpers.timeFrom(duration: data.elapsed); + videoCallDurationStreamController.sink.add(t); + }); + } + + callDisconnected(){ + callTimer.cancel(); + videoCallDurationStreamController.sink.add(null); + } + @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; @@ -112,9 +130,6 @@ class _PatientProfileScreenState extends State PatientProfileHeaderNewDesignAppBar( patient, arrivalType ?? '0', patientType, videoCallDurationStream: videoCallDurationStream, - onVideoDurationTap: (){ - VideoChannel.show(); - }, isInpatient: isInpatient, isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && @@ -322,9 +337,7 @@ class _PatientProfileScreenState extends State onFailure: (String error) { DrAppToastMsg.showErrorToast(error); }, - onVideoDuration: (duration){ - videoCallDurationStreamController.sink.add(duration); - }, + onCallConnected: callConnected, onCallEnd: () { var asd=""; // WidgetsBinding.instance.addPostFrameCallback((_) { diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index a9c2b5e2..94e79b7e 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -12,18 +12,19 @@ class VideoChannel{ static const _channel = const MethodChannel("Dr.cloudSolution/videoCall"); static openVideoCallScreen({kApiKey, kSessionId, kToken, callDuration, warningDuration,int vcId,String tokenID, String generalId,int doctorId, Function() onCallEnd , - Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure, VoidCallback onHide, Function(String) onVideoDuration}) async { + Function(SessionStatusModel sessionStatusModel) onCallNotRespond ,Function(String error) onFailure, VoidCallback onCallConnected, VoidCallback onCallDisconnected}) async { - onHide = onHide ?? (){}; - onVideoDuration = onVideoDuration ?? (v){}; + onCallConnected = onCallConnected ?? (){}; + onCallDisconnected = onCallDisconnected ?? (){}; var result; try { _channel.setMethodCallHandler((call) { - if(call.method == 'onHide'){ - onHide(); - }else if(call.method == 'onVideoDuration'){ - onVideoDuration(call.arguments); + if(call.method == 'onCallConnected'){ + onCallConnected(); + } + if(call.method == 'onCallDisconnected'){ + onCallDisconnected(); } return true as dynamic; }); @@ -44,7 +45,6 @@ class VideoChannel{ ); if(result['callResponse'] == 'CallEnd') { onCallEnd(); - onVideoDuration(null); } else { SessionStatusModel sessionStatusModel = SessionStatusModel.fromJson(Platform.isIOS ?result['sessionStatus'] :json.decode(result['sessionStatus'])); @@ -56,10 +56,6 @@ class VideoChannel{ } } - - static show(){ - _channel.invokeMethod("showVideo"); - } } \ No newline at end of file diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index 634abd02..7232f0c9 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -270,4 +270,11 @@ class Helpers { var htmlRegex = RegExp("<(“[^”]*”|'[^’]*’|[^'”>])*>"); return htmlRegex.hasMatch(text); } + + static String timeFrom({Duration duration}) { + String twoDigits(int n) => n.toString().padLeft(2, "0"); + String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); + String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); + return "$twoDigitMinutes:$twoDigitSeconds"; + } } diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 69bb9758..f2a32e63 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -22,10 +22,9 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final bool isFromLiveCare; final Stream videoCallDurationStream; - final VoidCallback onVideoDurationTap; PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream, this.onVideoDurationTap}); + this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream}); @override Widget build(BuildContext context) { @@ -94,11 +93,9 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget StreamBuilder( stream: videoCallDurationStream, builder: (BuildContext context, AsyncSnapshot snapshot) { - if(snapshot.hasData) + if(snapshot.hasData && snapshot.data != null) return InkWell( onTap: (){ - if(onVideoDurationTap != null) - onVideoDurationTap(); }, child: Container( decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), diff --git a/pubspec.lock b/pubspec.lock index 77df9848..cac3f27b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -813,7 +813,7 @@ packages: source: hosted version: "0.1.8" quiver: - dependency: transitive + dependency: "direct main" description: name: quiver url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 973e8800..1429bc3e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -90,7 +90,7 @@ dependencies: speech_to_text: path: speech_to_text - + quiver: ^2.1.5 # Html Editor Enhanced html_editor_enhanced: ^1.3.0 From 6fca263109ff61765d0660ce9341508993c08330 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 14 Jun 2021 14:05:14 +0300 Subject: [PATCH 171/241] video_streaming draggable popup --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 8 +- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 30 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 290 ++++++++++++++++-- .../main/res/layout/activity_video_call.xml | 7 +- android/app/src/main/res/values/styles.xml | 17 + 5 files changed, 297 insertions(+), 55 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index b57f5732..f013d281 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -7,7 +7,7 @@ import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel -import io.flutter.embedding.android.FlutterFragment +import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall @@ -22,7 +22,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 - private val flutterFragment: FlutterFragment? = null + lateinit var dialogFragment: VideoCallFragment override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -78,7 +78,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler // startActivityForResult(intent, LAUNCH_VIDEO) val transaction = supportFragmentManager.beginTransaction() -// transaction.add() + dialogFragment = VideoCallFragment.newInstance(Bundle()) + dialogFragment.isCancelable = false + dialogFragment.show(transaction, "dialog") } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index be4ebfb8..0fb061f1 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -411,10 +411,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi finish(); } - public void onMinimizedClicked(View view) { - - } - public void onSwitchCameraClicked(View view) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked; @@ -424,6 +420,14 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } + public void onCallClicked(View view) { + disconnectSession(); + } + + public void onMinimizedClicked(View view) { + + } + public void onCameraClicked(View view) { if (mPublisher != null) { isCameraClicked = !isCameraClicked; @@ -433,15 +437,6 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } - public void onSpeckerClicked(View view) { - if (mSubscriber != null) { - isSpeckerClicked = !isSpeckerClicked; - mSubscriber.setSubscribeToAudio(!isSpeckerClicked); - int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; - mspeckerBtn.setImageResource(res); - } - } - public void onMicClicked(View view) { if (mPublisher != null) { @@ -452,8 +447,13 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi } } - public void onCallClicked(View view) { - disconnectSession(); + public void onSpeckerClicked(View view) { + if (mSubscriber != null) { + isSpeckerClicked = !isSpeckerClicked; + mSubscriber.setSubscribeToAudio(!isSpeckerClicked); + int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; + mspeckerBtn.setImageResource(res); + } } @Override diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index be343b89..d5a5d5da 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -3,24 +3,26 @@ package com.hmg.hmgDr.ui.fragment import android.Manifest import android.annotation.SuppressLint import android.app.Activity +import android.app.Dialog +import android.content.Context import android.content.Intent +import android.graphics.Color +import android.graphics.Point +import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView import android.os.Bundle import android.os.CountDownTimer import android.os.Handler import android.os.Looper import android.util.Log -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.* -import androidx.fragment.app.Fragment +import androidx.annotation.Nullable +import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.R -import com.hmg.hmgDr.ui.VideoCallActivity import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl @@ -31,10 +33,20 @@ import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks import java.util.* +import kotlin.math.ceil -class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, +class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { + var isFullScreen: Boolean = true + private var x_init_cord = 0 + private var y_init_cord:Int = 0 + private var x_init_margin:Int = 0 + private var y_init_margin:Int = 0 + private val szWindow: Point = Point() + private lateinit var mWindowManager: WindowManager + private var isLeft = true + lateinit var videoCallPresenter: VideoCallPresenter private var mSession: Session? = null @@ -61,11 +73,13 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen private var isSpeckerClicked = false private var isMicClicked = false - private var mCallBtn: ImageView? = null - private var mCameraBtn: ImageView? = null - private var mSwitchCameraBtn: ImageView? = null - private var mspeckerBtn: ImageView? = null - private var mMicBtn: ImageView? = null + private lateinit var videoCallContainer: LinearLayout + private lateinit var mCallBtn: ImageView + private lateinit var btnMinimize: ImageView + private lateinit var mCameraBtn: ImageView + private lateinit var mSwitchCameraBtn: ImageView + private lateinit var mspeckerBtn: ImageView + private lateinit var mMicBtn: ImageView private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null @@ -84,6 +98,45 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen requestPermissions() } + override fun onStart() { + super.onStart() + + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + + override fun getTheme(): Int { + return R.style.dialogTheme + } + + override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog { + val dialog: Dialog = super.onCreateDialog(savedInstanceState) + return dialog + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // This is done in a post() since the dialog must be drawn before locating. + requireView().post { + val dialogWindow = dialog!!.window + + if (dialog != null && dialogWindow != null) { + dialogWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)); + } + + // Make the dialog possible to be outside touch + dialogWindow!!.setFlags( + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + ) + dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + requireView().invalidate() + } + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -91,6 +144,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen Objects.requireNonNull(requireActivity().actionBar)!!.hide() initUI(view) + handleDragDialog() return view } @@ -121,6 +175,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen @SuppressLint("ClickableViewAccessibility") private fun initUI(view: View) { + videoCallContainer = view.findViewById(R.id.video_call_ll) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) @@ -136,11 +191,29 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) + mCallBtn.setOnClickListener { + onCallClicked(it) + } + btnMinimize = view.findViewById(R.id.btn_minimize) + btnMinimize.setOnClickListener { + onMinimizedClicked(it) + } mCameraBtn = view.findViewById(R.id.btn_camera) + mCameraBtn.setOnClickListener { + onCameraClicked(it) + } mSwitchCameraBtn = view.findViewById(R.id.btn_switch_camera) + mSwitchCameraBtn.setOnClickListener { + onSwitchCameraClicked(it) + } mspeckerBtn = view.findViewById(R.id.btn_specker) + mspeckerBtn.setOnClickListener { + onSpeckerClicked(it) + } mMicBtn = view.findViewById(R.id.btn_mic) - + mMicBtn.setOnClickListener { + onMicClicked(it) + } // progressBarLayout=findViewById(R.id.progressBar); // progressBar=findViewById(R.id.progress_bar); // progressBarTextView=findViewById(R.id.progress_bar_text); @@ -316,6 +389,20 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen requireActivity().finish() } + + override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { + if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { + val returnIntent = Intent() + returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) + requireActivity().setResult(Activity.RESULT_OK, returnIntent) + requireActivity().finish() + } + } + + override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + + override fun onFailure() {} + fun onSwitchCameraClicked(view: View?) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked @@ -325,6 +412,25 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } + fun onCallClicked(view: View?) { + disconnectSession() + } + + fun onMinimizedClicked(view: View?) { + if (isFullScreen) { + dialog?.window?.setLayout( + 400, + 600 + ) + } else { + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + isFullScreen = !isFullScreen + } + fun onCameraClicked(view: View?) { if (mPublisher != null) { isCameraClicked = !isCameraClicked @@ -334,6 +440,15 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } + fun onMicClicked(view: View?) { + if (mPublisher != null) { + isMicClicked = !isMicClicked + mPublisher!!.publishAudio = !isMicClicked + val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled + mMicBtn!!.setImageResource(res) + } + } + fun onSpeckerClicked(view: View?) { if (mSubscriber != null) { isSpeckerClicked = !isSpeckerClicked @@ -343,31 +458,144 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen } } - fun onMicClicked(view: View?) { - if (mPublisher != null) { - isMicClicked = !isMicClicked - mPublisher!!.publishAudio = !isMicClicked - val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled - mMicBtn!!.setImageResource(res) + @SuppressLint("ClickableViewAccessibility") + fun handleDragDialog(){ + mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager + getWindowManagerDefaultDisplay() + + videoCallContainer.setOnTouchListener { _, event -> + //Get Floating widget view params + //Get Floating widget view params + val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { +// y_cord_Destination = 0 + y_cord_Destination = + -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { + y_cord_Destination = + szWindow.y - (videoCallContainer.height + barHeight) + } + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move + + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination + + dialog!!.window!!.attributes = layoutParams + } + } + true } } - fun onCallClicked(view: View?) { - disconnectSession() + /* Reset position of Floating Widget view on dragging */ + private fun resetPosition(x_cord_now: Int) { + if (x_cord_now <= szWindow.x / 2) { + isLeft = true + moveToLeft(x_cord_now) + } else { + isLeft = false + moveToRight(x_cord_now) + } } - override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { - if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { - val returnIntent = Intent() - returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) - requireActivity().setResult(Activity.RESULT_OK, returnIntent) - requireActivity().finish() - } + /* Method to move the Floating widget view to Left */ + private fun moveToLeft(current_x_cord: Int) { + + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + + mParams.x = + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + val x = szWindow.x - current_x_cord + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() + mParams.x = + (szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } + + override fun onFinish() { + mParams.x = -(szWindow.x - videoCallContainer.width) + + dialog!!.window!!.attributes = mParams + } + }.start() } - override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + /* Method to move the Floating widget view to Right */ + private fun moveToRight(current_x_cord: Int) { +// var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes +// mParams.x = +// (szWindow.x + current_x_cord * current_x_cord - videoCallContainer.width).toInt() +// +// dialog!!.window!!.attributes = mParams + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + mParams.x = + (szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } - override fun onFailure() {} + override fun onFinish() { + mParams.x = szWindow.x - videoCallContainer.width + + dialog!!.window!!.attributes = mParams + } + }.start() + } + + private fun getWindowManagerDefaultDisplay() { + mWindowManager.getDefaultDisplay() + .getSize(szWindow) + } + + /* return status bar height on basis of device display metrics */ + private fun getStatusBarHeight(): Int { + return ceil( + (25 * requireActivity().applicationContext.resources.displayMetrics.density).toDouble() + ).toInt() + } companion object { @JvmStatic @@ -376,7 +604,7 @@ class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListen arguments = args } - private val TAG = VideoCallActivity::class.java.simpleName + private val TAG = VideoCallFragment::class.java.simpleName private const val RC_SETTINGS_SCREEN_PERM = 123 private const val RC_VIDEO_APP_PERM = 124 diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index a3c2ced1..b7ca8d8d 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,6 +1,7 @@ @@ -132,7 +132,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_alignParentEnd="true" - android:onClick="onCallClicked" android:scaleType="centerCrop" android:src="@drawable/call" /> @@ -141,7 +140,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_alignParentStart="true" - android:onClick="onMinimizedClicked" android:layout_marginEnd="@dimen/padding_space_small" android:scaleType="centerCrop" android:src="@drawable/ic_mini" /> @@ -151,7 +149,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_minimize" - android:onClick="onCameraClicked" android:scaleType="centerCrop" android:layout_marginEnd="@dimen/padding_space_small" android:src="@drawable/video_enabled" /> @@ -161,7 +158,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_camera" - android:onClick="onMicClicked" android:layout_marginEnd="@dimen/padding_space_small" android:scaleType="centerCrop" android:src="@drawable/mic_enabled" /> @@ -171,7 +167,6 @@ android:layout_width="@dimen/video_icon_size" android:layout_height="@dimen/video_icon_size" android:layout_toEndOf="@id/btn_mic" - android:onClick="onSpeckerClicked" android:scaleType="centerCrop" android:layout_marginEnd="@dimen/padding_space_small" android:src="@drawable/audio_enabled" /> diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 24355fae..e13b5b14 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -16,4 +16,21 @@ true @null + + + From 1edd375fd7002f8cd24e9f37ce918292fac4d5a9 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 16:30:55 +0300 Subject: [PATCH 172/241] first step from special clinic --- lib/config/config.dart | 1 + lib/core/service/home/dasboard_service.dart | 26 +++++++++++++-- lib/core/viewModel/dashboard_view_model.dart | 14 ++++++++ ...cial_clinical_care_List_Respose_Model.dart | 32 +++++++++++++++++++ lib/screens/home/home_screen.dart | 2 ++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 588976ba..851eb832 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -219,6 +219,7 @@ const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RE const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; +const GET_SPECIAL_CLINICAL_CARE_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareList"; var selectedPatientType = 1; diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index b35d24f2..8bb0e586 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -1,10 +1,14 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; + + List _specialClinicalCareList = []; + List get specialClinicalCareList => _specialClinicalCareList; bool hasVirtualClinic = false; String sServiceID; @@ -24,8 +28,6 @@ class DashboardService extends BaseService { super.error = error; }, body: { - // "VidaAuthTokenID": - // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyODA0IiwianRpIjoiZDYxZmM5MTQtZWFhYy00YjQ4LTgyMmEtMmE3OTNlZDMzZGYwIiwiZW1haWwiOiJNb2hhbWVkLlJlc3dhbkBjbG91ZHNvbHV0aW9uLXNhLmNvbSIsImlkIjoiMjgwNCIsIk5hbWUiOiJNVUhBTU1BRCBBWkFNIiwiRW1wbG95ZWVJZCI6IjE0ODUiLCJGYWNpbGl0eUdyb3VwSWQiOiIwMTAyNjYiLCJGYWNpbGl0eUlkIjoiMTUiLCJQaGFyYW1jeUZhY2lsaXR5SWQiOiI1NSIsIklTX1BIQVJNQUNZX0NPTk5FQ1RFRCI6IlRydWUiLCJEb2N0b3JJZCI6IjE0ODUiLCJTRVNTSU9OSUQiOiIyMTU3NTgwOCIsIkNsaW5pY0lkIjoiMyIsInJvbGUiOlsiU0VDVVJJVFkgQURNSU5JU1RSQVRPUlMiLCJTRVRVUCBBRE1JTklTVFJBVE9SUyIsIkNFTydTIiwiRVhFQ1VUSVZFIERJUkVDVE9SUyIsIk1BTkFHRVJTIiwiU1VQRVJWSVNPUlMiLCJDTElFTlQgU0VSVklDRVMgQ09PUkRJTkFUT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIFNVUEVSVklTT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIE1BTkdFUlMiLCJIRUFEIE5VUlNFUyIsIkRPQ1RPUlMiLCJDSElFRiBPRiBNRURJQ0FMIFNUQUZGUyIsIkJJTy1NRURJQ0FMIFRFQ0hOSUNJQU5TIiwiQklPLU1FRElDQUwgRU5HSU5FRVJTIiwiQklPLU1FRElDQUwgREVQQVJUTUVOVCBIRUFEUyIsIklUIEhFTFAgREVTSyIsIkFETUlOSVNUUkFUT1JTIiwiTEFCIEFETUlOSVNUUkFUT1IiLCJMQUIgVEVDSE5JQ0lBTiIsIkJVU0lORVNTIE9GRklDRSBTVEFGRiIsIkZJTkFOQ0UgQUNDT1VOVEFOVFMiLCJQSEFSTUFDWSBTVEFGRiIsIkFDQ09VTlRTIFNUQUZGIiwiTEFCIFJFQ0VQVElPTklTVCIsIkVSIE5VUlNFIiwiSU5QQVRJRU5UIEJJTExJTkcgU1VQRVJWSVNPUiIsIkxEUi1PUiBOVVJTRVMiLCJBRE1JU1NJT04gU1RBRkYiLCJIRUxQIERFU0sgQURNSU4iLCJBUFBST1ZBTCBTVEFGRiIsIklOUEFUSUVOVCBCSUxMSU5HIENPT1JESU5BVE9SIiwiQklMTElORyBTVEFGRiIsIkNPTlNFTlQgIiwiQ29uc2VudCAtIERlbnRhbCIsIldFQkVNUiJdLCJuYmYiOjE2MDgwMjg0NzQsImV4cCI6MTYwODg5MjQ3NCwiaWF0IjoxNjA4MDI4NDc0fQ.8OJcy6vUuPnNTi_qSjip8YCrFdaRLtJKbNKXcMtnQxk" }, ); } @@ -48,4 +50,24 @@ class DashboardService extends BaseService { }, ); } + Future getSpecialClinicalCareList() async { + hasError = false; + await getDoctorProfile(isGetProfile: true); + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareList.clear(); + response['List_SpecialClinicalCareList'].forEach((v) { + _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + }, + ); + } + } diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index bbbef0b6..fe160c3c 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -22,6 +23,9 @@ class DashboardViewModel extends BaseViewModel { String get sServiceID => _dashboardService.sServiceID; + List get specialClinicalCareList => _dashboardService.specialClinicalCareList; + + Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async { setState(ViewState.Busy); @@ -64,6 +68,16 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getSpecialClinicalCareList() async { + setState(ViewState.Busy); + await _dashboardService.getSpecialClinicalCareList(); + if (_dashboardService.hasError) { + error = _dashboardService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + Future changeClinic( int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); diff --git a/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart new file mode 100644 index 00000000..ec19abb0 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart @@ -0,0 +1,32 @@ +class GetSpecialClinicalCareListResponseModel { + int projectID; + int clinicID; + String clinicDescription; + String clinicDescriptionN; + bool isActive; + + GetSpecialClinicalCareListResponseModel( + {this.projectID, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.isActive}); + + GetSpecialClinicalCareListResponseModel.fromJson(Map json) { + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + isActive = json['IsActive']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['IsActive'] = this.isActive; + return data; + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 85ea3506..eba91cc2 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,6 +69,8 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); + + await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, From 3913f8936c14894c4871fb1790804e4fe44a2d23 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 14 Jun 2021 17:03:09 +0300 Subject: [PATCH 173/241] Scan QR Code fix --- lib/config/config.dart | 4 +- lib/core/service/patient/patient_service.dart | 57 ++++++-- lib/core/viewModel/patient_view_model.dart | 61 ++++---- lib/screens/qr_reader/QR_reader_screen.dart | 134 +++--------------- 4 files changed, 94 insertions(+), 162 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 492d7ada..f2dbbf18 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/service/patient/patient_service.dart b/lib/core/service/patient/patient_service.dart index e15cc8d1..25e9481b 100644 --- a/lib/core/service/patient/patient_service.dart +++ b/lib/core/service/patient/patient_service.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/get_clinic_by_project_id_request.dart'; @@ -12,6 +13,7 @@ import 'package:doctor_app_flutter/models/patient/get_list_stp_referral_frequenc import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result_req_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -22,20 +24,19 @@ import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_mode class PatientService extends BaseService { List _patientVitalSignList = []; List patientVitalSignOrderdSubList = []; + List inPatientList = List(); + List myInPatientList = List(); List get patientVitalSignList => _patientVitalSignList; List _patientLabResultOrdersList = []; - List get patientLabResultOrdersList => - _patientLabResultOrdersList; + List get patientLabResultOrdersList => _patientLabResultOrdersList; - List get patientPrescriptionsList => - _patientPrescriptionsList; + List get patientPrescriptionsList => _patientPrescriptionsList; List _patientPrescriptionsList = []; - List get prescriptionReportForInPatientList => - _prescriptionReportForInPatientList; + List get prescriptionReportForInPatientList => _prescriptionReportForInPatientList; List _prescriptionReportForInPatientList = []; List _patientRadiologyList = []; @@ -79,12 +80,9 @@ class PatientService extends BaseService { get referalFrequancyList => _referalFrequancyList; - DoctorsByClinicIdRequest _doctorsByClinicIdRequest = - DoctorsByClinicIdRequest(); - STPReferralFrequencyRequest _referralFrequencyRequest = - STPReferralFrequencyRequest(); - ClinicByProjectIdRequest _clinicByProjectIdRequest = - ClinicByProjectIdRequest(); + DoctorsByClinicIdRequest _doctorsByClinicIdRequest = DoctorsByClinicIdRequest(); + STPReferralFrequencyRequest _referralFrequencyRequest = STPReferralFrequencyRequest(); + ClinicByProjectIdRequest _clinicByProjectIdRequest = ClinicByProjectIdRequest(); ReferToDoctorRequest _referToDoctorRequest; Future getPatientList(patient, patientType, {isView}) async { @@ -138,6 +136,38 @@ class PatientService extends BaseService { return Future.value(localRes); } + Future getInPatient(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(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } + Future getLabResultOrders(patient) async { hasError = false; await baseAppClient.post( @@ -181,8 +211,7 @@ class PatientService extends BaseService { onSuccess: (dynamic response, int statusCode) { _prescriptionReportForInPatientList = []; response['List_PrescriptionReportForInPatient'].forEach((v) { - prescriptionReportForInPatientList - .add(PrescriptionReportForInPatient.fromJson(v)); + prescriptionReportForInPatientList.add(PrescriptionReportForInPatient.fromJson(v)); }); }, onFailure: (String error, int statusCode) { diff --git a/lib/core/viewModel/patient_view_model.dart b/lib/core/viewModel/patient_view_model.dart index de40afde..5bc6250f 100644 --- a/lib/core/viewModel/patient_view_model.dart +++ b/lib/core/viewModel/patient_view_model.dart @@ -2,9 +2,11 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/patient/patient_service.dart'; import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -17,51 +19,43 @@ import 'base_view_model.dart'; class PatientViewModel extends BaseViewModel { PatientService _patientService = locator(); - List get patientVitalSignList => - _patientService.patientVitalSignList; + List get inPatientList => _patientService.inPatientList; - List get patientVitalSignOrderdSubList => - _patientService.patientVitalSignOrderdSubList; + List get patientVitalSignList => _patientService.patientVitalSignList; - List get patientLabResultOrdersList => - _patientService.patientLabResultOrdersList; + List get patientVitalSignOrderdSubList => _patientService.patientVitalSignOrderdSubList; - List get patientPrescriptionsList => - _patientService.patientPrescriptionsList; + List get patientLabResultOrdersList => _patientService.patientLabResultOrdersList; + + List get patientPrescriptionsList => _patientService.patientPrescriptionsList; List get prescriptionReportForInPatientList => _patientService.prescriptionReportForInPatientList; - List get prescriptionReport => - _patientService.prescriptionReport; + List get prescriptionReport => _patientService.prescriptionReport; - List get patientRadiologyList => - _patientService.patientRadiologyList; + List get patientRadiologyList => _patientService.patientRadiologyList; List get labResultList => _patientService.labResultList; get insuranceApporvalsList => _patientService.insuranceApporvalsList; - List get patientProgressNoteList => - _patientService.patientProgressNoteList; + List get patientProgressNoteList => _patientService.patientProgressNoteList; List get clinicsList => _patientService.clinicsList; List get doctorsList => _patientService.doctorsList; - List get referralFrequencyList => - _patientService.referalFrequancyList; + List get referralFrequencyList => _patientService.referalFrequancyList; - Future getPatientList(patient, patientType, - {bool isBusyLocal = false, isView}) async { + Future getPatientList(patient, patientType, {bool isBusyLocal = false, isView}) async { var localRes; if (isBusyLocal) { setState(ViewState.BusyLocal); } else { setState(ViewState.Busy); } - localRes = await _patientService.getPatientList(patient, patientType, - isView: isView); + localRes = await _patientService.getPatientList(patient, patientType, isView: isView); if (_patientService.hasError) { error = _patientService.error; @@ -210,16 +204,12 @@ class PatientViewModel extends BaseViewModel { } List getDoctorNameList() { - var doctorNamelist = _patientService.doctorsList - .map((value) => value['DoctorName'].toString()) - .toList(); + var doctorNamelist = _patientService.doctorsList.map((value) => value['DoctorName'].toString()).toList(); return doctorNamelist; } List getClinicNameList() { - var clinicsNameslist = _patientService.clinicsList - .map((value) => value['ClinicDescription'].toString()) - .toList(); + var clinicsNameslist = _patientService.clinicsList.map((value) => value['ClinicDescription'].toString()).toList(); return clinicsNameslist; } @@ -234,9 +224,8 @@ class PatientViewModel extends BaseViewModel { } List getReferralNamesList() { - var referralNamesList = _patientService.referalFrequancyList - .map((value) => value['Description'].toString()) - .toList(); + var referralNamesList = + _patientService.referalFrequancyList.map((value) => value['Description'].toString()).toList(); return referralNamesList; } @@ -281,4 +270,18 @@ class PatientViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _patientService.getInPatient(requestModel, false); + if (_patientService.hasError) { + error = _patientService.error; + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } } diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index a411aaa7..848b3f9a 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -1,11 +1,8 @@ import 'package:barcode_scan_fix/barcode_scan.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/models/patient/patient_model.dart'; -import 'package:doctor_app_flutter/models/patient/topten_users_res_model.dart'; -import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -26,38 +23,9 @@ class QrReaderScreen extends StatefulWidget { } class _QrReaderScreenState extends State { - DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - - bool isLoading = false; - bool isError = false; - PatientModel patient = PatientModel( - ProjectID: 15, - ClinicID: 0, - DoctorID: 1485, - FirstName: "0", - MiddleName: "0", - LastName: "0", - PatientMobileNumber: "0", - PatientIdentificationID: "0", - PatientID: 0, - From: "0", - To: "0", - LanguageID: 2, - stamp: "2020-03-02T13:56:39.170Z", - IPAdress: "11.11.11.11", - VersionID: 5.5, - Channel: 9, - TokenID: "@dm!n", - SessionID: "5G0yXn0Jnq", - IsLoginForDoctorApp: true, - PatientOutSA: false); - List patientList = []; - String error = ''; - @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getClinicsList(), builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -95,26 +63,8 @@ class _QrReaderScreenState extends State { onPressed: () { _scanQrAndGetPatient(context, model); }, - loading: isLoading, icon: Image.asset('assets/images/qr_code_white.png'), ), - isError - ? Container( - margin: EdgeInsets.only(top: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Theme.of(context).errorColor.withOpacity(0.06), - ), - padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), - child: Row( - children: [ - Expanded( - child: AppText(error ?? TranslationBase.of(context).errorMessage, - color: Theme.of(context).errorColor)), - ], - ), - ) - : Container(), ], ), ), @@ -131,75 +81,25 @@ class _QrReaderScreenState extends State { var result = await BarcodeScanner.scan(); if (result != "") { List listOfParams = result.split(','); - String patientType = "1"; - setState(() { - isLoading = true; - isError = false; - patientList = []; - }); - String token = await sharedPref.getString(TOKEN); -// Map profile = await sharedPref.getObj(DOCTOR_PROFILE); -// DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); -// patient.PatientID = 8808; -// patient.TokenID = token; -// patient.setDoctorID = doctorProfile.projectID; -// patient.setClinicID = doctorProfile.clinicID; -// patient.setProjectID = doctorProfile.projectID; -// Provider.of(context, listen: false); - patient.PatientID = 8808; - patient.TokenID = token; - model.getPatientList(patient, "1", isBusyLocal: true).then((response) { - if (response['MessageStatus'] == 1) { - switch (patientType) { - case "0": - if (response['List_MyOutPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyOutPatient']).list; - isLoading = false; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - } - break; - case "1": - if (response['List_MyInPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyInPatient']).list; - isLoading = false; - error = ""; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - break; - } - } + int patientID = 0; + if (listOfParams[1].length != 0) patientID = int.parse(listOfParams[1]); + PatientSearchRequestModel patientSearchRequestModel = PatientSearchRequestModel( + patientID: patientID, + ); + + await model.getInPatientList(patientSearchRequestModel, isMyInpatient: true).then((d) { + if (model.state != ViewState.ErrorLocal) { + if (model.inPatientList.isEmpty) + DrAppToastMsg.showErrorToast('No patient'); + else + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { + "patient": model.inPatientList[0], + }); } else { - setState(() { - isLoading = false; - isError = true; - }); - DrAppToastMsg.showErrorToast(response['ErrorEndUserMessage'] ?? response['ErrorMessage']); + DrAppToastMsg.showErrorToast(model.error); } }).catchError((error) { - setState(() { - isLoading = false; - }); Helpers.showErrorToast(error.message); - //DrAppToastMsg.showErrorToast(error); }); } } From 48874c0efdca0100d79638ae031fce14c5953c20 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 14 Jun 2021 17:27:21 +0300 Subject: [PATCH 174/241] no message --- ios/Runner/Base.lproj/Main.storyboard | 172 ++++++++++++----------- ios/Runner/MainAppViewController.swift | 78 +++++++--- ios/Runner/VideoCallViewController.swift | 59 ++++---- 3 files changed, 183 insertions(+), 126 deletions(-) diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index cecbd930..c1c16274 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -39,79 +39,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + @@ -128,7 +67,7 @@ - + @@ -261,7 +201,7 @@ - + @@ -270,11 +210,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,7 +293,10 @@ + + + @@ -294,17 +305,19 @@ + - + + @@ -333,7 +346,6 @@ - diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index 87610042..ffca444c 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -13,9 +13,10 @@ class MainAppViewController: FlutterViewController{ var videoCallContainer:AADraggableView! var videoCallViewController:VideoCallViewController! var videoCallFlutterResult:FlutterResult? - var vdoCallViewMinConstraint:[NSLayoutConstraint]! - var vdoCallViewMaxConstraint:[NSLayoutConstraint]! - + var vdoCallViewFloatRectConstraint:[NSLayoutConstraint]! + var vdoCallViewFullConstraint:[NSLayoutConstraint]! + var vdoCallViewFloatCircleConstraint:[NSLayoutConstraint]! + override func viewDidLoad() { super.viewDidLoad() @@ -58,15 +59,15 @@ extension MainAppViewController : ICallProtocol{ view.addSubview(videoCallContainer) setVideoViewConstrints() - NSLayoutConstraint.activate(vdoCallViewMaxConstraint) - NSLayoutConstraint.deactivate(vdoCallViewMinConstraint) + NSLayoutConstraint.activate(vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(vdoCallViewFloatRectConstraint) ViewEmbedder.embed( withIdentifier: "videoCall", // Storyboard ID parent: self, container: self.videoCallContainer){ vc in self.videoCallViewController = vc as? VideoCallViewController - + } } @@ -82,8 +83,17 @@ extension MainAppViewController : ICallProtocol{ if let arguments = call.arguments as? NSDictionary{ showVideoCallView(true) - videoCallViewController.onFloat = { min in - self.floatVideoCallView(min) + videoCallViewController.onRectFloat = { min in + self.rectFloatVideoCallView(min) + if(min){ + self.videoCallContainer.repositionIfNeeded() + } + } + + videoCallViewController.onCircleFloat = { min in + self.circleFloatVideoCallView(min) + self.videoCallContainer.reposition = min ? .free : .edgesOnly + self.videoCallContainer.repositionIfNeeded() } videoCallViewController.onCallConnect = { self.videoCallChannel?.invokeMethod("onCallConnected",arguments: nil) @@ -99,16 +109,18 @@ extension MainAppViewController : ICallProtocol{ } - private func floatVideoCallView(_ value:Bool){ + private func rectFloatVideoCallView(_ value:Bool){ videoCallContainer.enable(value) UIView.animate(withDuration: 0.5) { if(value){ - NSLayoutConstraint.deactivate(self.vdoCallViewMaxConstraint) - NSLayoutConstraint.activate(self.vdoCallViewMinConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFloatRectConstraint) }else{ - NSLayoutConstraint.deactivate(self.vdoCallViewMinConstraint) - NSLayoutConstraint.activate(self.vdoCallViewMaxConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFullConstraint) } self.videoCallContainer.layer.cornerRadius = value ? 10 : 0 self.videoCallContainer.layer.borderColor = value ? UIColor.white.cgColor : nil @@ -117,6 +129,28 @@ extension MainAppViewController : ICallProtocol{ } } + private func circleFloatVideoCallView(_ value:Bool){ + videoCallContainer.enable(value) + + UIView.animate(withDuration: 0.5) { + if(value){ + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFloatCircleConstraint) + self.videoCallContainer.layer.cornerRadius = 35 + }else{ + NSLayoutConstraint.activate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + self.videoCallContainer.layer.cornerRadius = 10 + + } + self.videoCallContainer.layer.borderColor = value ? UIColor.white.cgColor : nil + self.videoCallContainer.layer.borderWidth = value ? 2 : 0 + self.view.layoutIfNeeded() + } + } + private func showVideoCallView(_ value:Bool){ UIView.animate(withDuration: 0.5) { self.videoCallContainer.isHidden = !value @@ -133,21 +167,31 @@ extension MainAppViewController : ICallProtocol{ func setVideoViewConstrints(){ + videoCallContainer.layer.shadowColor = UIColor.black.cgColor + videoCallContainer.layer.shadowOffset = CGSize(width: 1, height: 1) + videoCallContainer.layer.shadowRadius = 5 + let screen = UIScreen.main.bounds videoCallContainer.translatesAutoresizingMaskIntoConstraints = false - vdoCallViewMinConstraint = [ + vdoCallViewFullConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width), + videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height) + ] + vdoCallViewFloatRectConstraint = [ videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width/3), videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height/3.5) ] - vdoCallViewMaxConstraint = [ + vdoCallViewFloatCircleConstraint = [ videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor), videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor), - videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width), - videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height) + videoCallContainer.widthAnchor.constraint(equalToConstant: 70), + videoCallContainer.heightAnchor.constraint(equalToConstant: 70) ] } diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index 27268128..02a70a0c 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -34,8 +34,8 @@ class VideoCallViewController: UIViewController { var seconds = 30 var isUserConnect : Bool = false - var onFloat:((Bool)->Void)? = nil - var onMinimize:(()->Void)? = nil + var onRectFloat:((Bool)->Void)? = nil + var onCircleFloat:((Bool)->Void)? = nil var onCallConnect:(()->Void)? = nil var onCallDisconnect:(()->Void)? = nil @@ -50,13 +50,15 @@ class VideoCallViewController: UIViewController { @IBOutlet var minimizeConstraint: [NSLayoutConstraint]! @IBOutlet var maximisedConstraint: [NSLayoutConstraint]! + @IBOutlet weak var btnMinimize: UIButton! @IBOutlet weak var hideVideoBtn: UIButton! - @IBOutlet weak var draggableBoundryDefiner: UIView! var localVideoDraggable:AADraggableView? @IBOutlet weak var controlButtons: UIView! @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! @IBOutlet weak var localVideoMutedBg: UIView! + @IBOutlet weak var localVideoContainer: UIView! + @IBOutlet weak var topBar: UIView! @IBOutlet weak var lblCallDuration: UILabel! @IBOutlet weak var remoteVideo: UIView! @IBOutlet weak var localVideo: UIView!{ @@ -69,18 +71,31 @@ class VideoCallViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - localVideoDraggable?.respectedView = draggableBoundryDefiner + localVideoDraggable?.respectedView = localVideoContainer } + @objc func click(gesture:UIGestureRecognizer){ + gesture.view?.removeFromSuperview() + } + + @IBAction func onVideoContainerTapped(_ sender: Any) { + if(hideVideoBtn.isSelected){ + circleFloatBtnTapped(hideVideoBtn) + + }else if(btnMinimize.isSelected){ + btnMinimizeTapped(btnMinimize) + }else if(!btnMinimize.isSelected){ + // Swipe video here + } + } @IBAction func didClickMuteButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected publisher!.publishAudio = !sender.isSelected } - @IBAction func didClickSpeakerButton(_ sender: UIButton) { + @IBAction func didClickSpeakerButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected subscriber?.subscribeToAudio = !sender.isSelected - // resetHideButtonsTimer() } @IBAction func didClickVideoMuteButton(_ sender: UIButton) { @@ -92,7 +107,6 @@ class VideoCallViewController: UIViewController { } localVideo.isHidden = sender.isSelected localVideoMutedBg.isHidden = !sender.isSelected - // resetHideButtonsTimer() } @@ -104,7 +118,6 @@ class VideoCallViewController: UIViewController { } else { publisher!.cameraPosition = AVCaptureDevice.Position.back } - /// resetHideButtonsTimer() } @IBAction func hangUp(_ sender: UIButton) { @@ -112,14 +125,19 @@ class VideoCallViewController: UIViewController { sessionDisconnect() } - @IBAction func hideVideoBtnTapped(_ sender: Any) { - onMinimize?() + @IBAction func circleFloatBtnTapped(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + onCircleFloat?(sender.isSelected) + topBar.isHidden = sender.isSelected + controlButtons.isHidden = sender.isSelected + localVideo.isHidden = sender.isSelected + self.publisher?.view?.layoutIfNeeded() } var floated = false - @IBAction func onMinimize(_ sender: UIButton) { + @IBAction func btnMinimizeTapped(_ sender: UIButton) { floated = !floated - onFloat?(floated) + onRectFloat?(floated) sender.isSelected = floated NSLayoutConstraint.activate(floated ? minimizeConstraint : maximisedConstraint) @@ -171,7 +189,6 @@ class VideoCallViewController: UIViewController { self.DoctorId = params.doctorId ?? 0 self.baseUrl = params.baseUrl ?? "" - setupButtons() askForMicrophonePermission() requestCameraPermissionsIfNeeded() hideVideoMuted() @@ -238,13 +255,6 @@ class VideoCallViewController: UIViewController { } } - - func setupButtons() { - perform(#selector(hideControlButtons), with: nil, afterDelay: 3) - let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:))) - view.addGestureRecognizer(tapGestureRecognizer) - view.isUserInteractionEnabled = true - } // MARK: -Microphone Camera and Permission Request func askForMicrophonePermission() { @@ -481,12 +491,6 @@ extension VideoCallViewController: OTPublisherDelegate { func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { print("The publisher failed: \(error)") } - @objc func remoteVideoTapped(_ recognizer: UITapGestureRecognizer?) { - if controlButtons.isHidden { - controlButtons.isHidden = false - perform(#selector(hideControlButtons), with: nil, afterDelay: 3) - } - } } extension VideoCallViewController: OTSubscriberDelegate { @@ -497,8 +501,5 @@ extension VideoCallViewController: OTSubscriberDelegate { public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { print("The subscriber failed to connect to the stream.") } - @objc func hideControlButtons() { -// controlButtons.isHidden = true - } } From 363b55069faf22e4696ebf875f256caf0bca563c Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 18:04:20 +0300 Subject: [PATCH 175/241] first step form Special Clinic --- lib/config/config.dart | 1 + .../PatientSearchRequestModel.dart | 32 ++-- lib/core/service/home/dasboard_service.dart | 21 --- .../special_clinic_service.dart | 57 +++++++ .../viewModel/PatientSearchViewModel.dart | 42 +++++- lib/core/viewModel/dashboard_view_model.dart | 23 ++- lib/locator.dart | 2 + ...nical_care_mapping_List_Respose_Model.dart | 37 +++++ lib/screens/home/home_screen.dart | 3 +- .../patients/PatientsInPatientScreen.dart | 142 +++++++++++++++++- 10 files changed, 315 insertions(+), 45 deletions(-) create mode 100644 lib/core/service/special_clinics/special_clinic_service.dart create mode 100644 lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index c8eac881..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -226,6 +226,7 @@ const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoc const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; const ADD_REFERRED_REMARKS_NEW = "Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks_New"; const GET_SPECIAL_CLINICAL_CARE_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareList"; +const GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareMappingList"; var selectedPatientType = 1; diff --git a/lib/core/model/patient_muse/PatientSearchRequestModel.dart b/lib/core/model/patient_muse/PatientSearchRequestModel.dart index 437c5885..2918a393 100644 --- a/lib/core/model/patient_muse/PatientSearchRequestModel.dart +++ b/lib/core/model/patient_muse/PatientSearchRequestModel.dart @@ -11,20 +11,24 @@ class PatientSearchRequestModel { int searchType; String mobileNo; String identificationNo; + int nursingStationID; + int clinicID; PatientSearchRequestModel( - {this.doctorID =0, - this.firstName ="0", - this.middleName ="0", - this.lastName ="0", - this.patientMobileNumber ="0", - this.patientIdentificationID ="0", - this.patientID =0, - this.searchType =1, - this.mobileNo="", - this.identificationNo="0", - this.from ="0", - this.to ="0"}); + {this.doctorID = 0, + this.firstName = "0", + this.middleName = "0", + this.lastName = "0", + this.patientMobileNumber = "0", + this.patientIdentificationID = "0", + this.patientID = 0, + this.searchType = 1, + this.mobileNo = "", + this.identificationNo = "0", + this.from = "0", + this.to = "0", + this.clinicID, + this.nursingStationID = 0}); PatientSearchRequestModel.fromJson(Map json) { doctorID = json['DoctorID']; @@ -39,6 +43,8 @@ class PatientSearchRequestModel { searchType = json['SearchType']; mobileNo = json['MobileNo']; identificationNo = json['IdentificationNo']; + nursingStationID = json['NursingStationID']; + clinicID = json['ClinicID']; } Map toJson() { @@ -55,6 +61,8 @@ class PatientSearchRequestModel { data['SearchType'] = this.searchType; data['MobileNo'] = this.mobileNo; data['IdentificationNo'] = this.identificationNo; + data['NursingStationID'] = this.nursingStationID; + data['ClinicID'] = this.clinicID; return data; } } diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index 8bb0e586..ad3ec887 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -7,8 +7,6 @@ class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; - List _specialClinicalCareList = []; - List get specialClinicalCareList => _specialClinicalCareList; bool hasVirtualClinic = false; String sServiceID; @@ -50,24 +48,5 @@ class DashboardService extends BaseService { }, ); } - Future getSpecialClinicalCareList() async { - hasError = false; - await getDoctorProfile(isGetProfile: true); - await baseAppClient.post( - GET_SPECIAL_CLINICAL_CARE_LIST, - onSuccess: (dynamic response, int statusCode) { - - _specialClinicalCareList.clear(); - response['List_SpecialClinicalCareList'].forEach((v) { - _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); - });}, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, - body: { - }, - ); - } } diff --git a/lib/core/service/special_clinics/special_clinic_service.dart b/lib/core/service/special_clinics/special_clinic_service.dart new file mode 100644 index 00000000..49237331 --- /dev/null +++ b/lib/core/service/special_clinics/special_clinic_service.dart @@ -0,0 +1,57 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; + +class SpecialClinicsService extends BaseService { + + + List _specialClinicalCareList = []; + List get specialClinicalCareList => _specialClinicalCareList; + + List _specialClinicalCareMappingList = []; + List get specialClinicalCareMappingList => _specialClinicalCareMappingList; + Future getSpecialClinicalCareList() async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareList.clear(); + response['List_SpecialClinicalCareList'].forEach((v) { + _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + }, + ); + } + + + Future getSpecialClinicalCareMappingList(int clinicId) async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareMappingList.clear(); + response['List_SpecialClinicalCareMappingList'].forEach((v) { + _specialClinicalCareMappingList.add(GetSpecialClinicalCareMappingListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "ClinicID": clinicId, + "DoctorID":0, + "EditedBy":0 + }, + ); + } + +} diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index a0cd68d9..6b83461b 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -4,6 +4,8 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/patient/out_patient_service.dart'; import 'package:doctor_app_flutter/core/service/patient/patientInPatientService.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -12,8 +14,10 @@ import 'base_view_model.dart'; class PatientSearchViewModel extends BaseViewModel { OutPatientService _outPatientService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get patientList => _outPatientService.patientList; + List get specialClinicalCareMappingList => _specialClinicsService.specialClinicalCareMappingList; List filterData = []; @@ -143,15 +147,22 @@ class PatientSearchViewModel extends BaseViewModel { List filteredInPatientItems = List(); Future getInPatientList(PatientSearchRequestModel requestModel, - {bool isMyInpatient = false}) async { + {bool isMyInpatient = false, bool isLocalBusy = false}) async { await getDoctorProfile(); - setState(ViewState.Busy); - + if(isLocalBusy) { + setState(ViewState.BusyLocal); + } else{ + setState(ViewState.Busy); + } if (inPatientList.length == 0) await _inPatientService.getInPatientList(requestModel, false); if (_inPatientService.hasError) { error = _inPatientService.error; + if(isLocalBusy) { + setState(ViewState.ErrorLocal); + } else{ setState(ViewState.Error); + } } else { // setDefaultInPatientList(); setState(ViewState.Idle); @@ -166,6 +177,9 @@ class PatientSearchViewModel extends BaseViewModel { setState(ViewState.Idle); } + + + void clearPatientList() { _inPatientService.inPatientList = []; _inPatientService.myInPatientList = []; @@ -195,4 +209,26 @@ class PatientSearchViewModel extends BaseViewModel { notifyListeners(); } } + + + getSpecialClinicalCareMappingList(clinicId, + {bool isLocalBusy = false}) async { + if (isLocalBusy) { + setState(ViewState.BusyLocal); + } else { + setState(ViewState.Busy); + } + //TODO Elham* change clinic id to dynamic + await _specialClinicsService.getSpecialClinicalCareMappingList(221); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; + if (isLocalBusy) { + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Error); + } + } else { + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index fe160c3c..95028f52 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; @@ -15,6 +16,7 @@ import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); DashboardService _dashboardService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get dashboardItemsList => _dashboardService.dashboardItemsList; @@ -23,7 +25,7 @@ class DashboardViewModel extends BaseViewModel { String get sServiceID => _dashboardService.sServiceID; - List get specialClinicalCareList => _dashboardService.specialClinicalCareList; + List get specialClinicalCareList => _specialClinicsService.specialClinicalCareList; Future setFirebaseNotification(ProjectViewModel projectsProvider, @@ -70,9 +72,9 @@ class DashboardViewModel extends BaseViewModel { Future getSpecialClinicalCareList() async { setState(ViewState.Busy); - await _dashboardService.getSpecialClinicalCareList(); - if (_dashboardService.hasError) { - error = _dashboardService.error; + await _specialClinicsService.getSpecialClinicalCareList(); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; setState(ViewState.Error); } else setState(ViewState.Idle); @@ -99,4 +101,17 @@ class DashboardViewModel extends BaseViewModel { return value.toString(); } + + + bool isSpecialClinic(clinicId){ + bool isSpecial = false; + specialClinicalCareList.forEach((element) { + if(element.clinicID == 1){ + isSpecial = true; + } + }); + + return isSpecial; + + } } diff --git a/lib/locator.dart b/lib/locator.dart index 1c491b54..de493196 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -37,6 +37,7 @@ import 'core/service/patient_medical_file/sick_leave/sickleave_service.dart'; import 'core/service/patient_medical_file/soap/SOAP_service.dart'; import 'core/service/patient_medical_file/ucaf/patient-ucaf-service.dart'; import 'core/service/patient_medical_file/vital_sign/patient-vital-signs-service.dart'; +import 'core/service/special_clinics/special_clinic_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; import 'core/viewModel/LiveCarePatientViewModel.dart'; @@ -91,6 +92,7 @@ void setupLocator() { locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => SpecialClinicsService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart new file mode 100644 index 00000000..287f40f1 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart @@ -0,0 +1,37 @@ +class GetSpecialClinicalCareMappingListResponseModel { + int mappingProjectID; + int clinicID; + int nursingStationID; + bool isActive; + int projectID; + String description; + + GetSpecialClinicalCareMappingListResponseModel( + {this.mappingProjectID, + this.clinicID, + this.nursingStationID, + this.isActive, + this.projectID, + this.description}); + + GetSpecialClinicalCareMappingListResponseModel.fromJson( + Map json) { + mappingProjectID = json['MappingProjectID']; + clinicID = json['ClinicID']; + nursingStationID = json['NursingStationID']; + isActive = json['IsActive']; + projectID = json['ProjectID']; + description = json['Description']; + } + + Map toJson() { + final Map data = new Map(); + data['MappingProjectID'] = this.mappingProjectID; + data['ClinicID'] = this.clinicID; + data['NursingStationID'] = this.nursingStationID; + data['IsActive'] = this.isActive; + data['ProjectID'] = this.projectID; + data['Description'] = this.description; + return data; + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index f2a8da6a..294541b0 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,7 +69,6 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); - await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( @@ -356,7 +355,7 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(), + page: PatientInPatientScreen(specialClinic: model.specialClinicalCareList[0],), ), ); }, diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 60446887..1d8e91b9 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -1,17 +1,27 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.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/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'DischargedPatientPage.dart'; import 'InPatientPage.dart'; class PatientInPatientScreen extends StatefulWidget { + GetSpecialClinicalCareListResponseModel specialClinic; + + PatientInPatientScreen({Key key, this.specialClinic}); + @override _PatientInPatientScreenState createState() => _PatientInPatientScreenState(); } @@ -21,6 +31,9 @@ class _PatientInPatientScreenState extends State TabController _tabController; int _activeTab = 0; + int selectedMapId; + + @override void initState() { super.initState(); @@ -42,15 +55,23 @@ class _PatientInPatientScreenState extends State @override Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; + final screenSize = MediaQuery + .of(context) + .size; PatientSearchRequestModel requestModel = PatientSearchRequestModel(); + ProjectViewModel projectsProvider = Provider.of(context); + return BaseView( onModelReady: (model) async { model.clearPatientList(); + if (widget.specialClinic != null) + await model.getSpecialClinicalCareMappingList( + widget.specialClinic.clinicID); model.getInPatientList(requestModel); }, - builder: (_, model, w) => AppScaffold( + builder: (_, model, w) => + AppScaffold( baseViewModel: model, isShowAppBar: false, body: Column( @@ -72,12 +93,127 @@ class _PatientInPatientScreenState extends State ), Expanded( child: AppText( - TranslationBase.of(context).inPatient, + TranslationBase + .of(context) + .inPatient, fontSize: SizeConfig.textMultiplier * 2.8, fontWeight: FontWeight.bold, color: Color(0xFF2B353E), ), ), + if(model.specialClinicalCareMappingList.isNotEmpty && + widget.specialClinic != null) + Container( + width: MediaQuery + .of(context) + .size + .width * .3, + child: DropdownButtonHideUnderline( + child: DropdownButton( + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: selectedMapId == null ? model + .specialClinicalCareMappingList[0] + .nursingStationID : selectedMapId, + iconSize: 25, + elevation: 16, + selectedItemBuilder: + (BuildContext context) { + return model + .specialClinicalCareMappingList + .map((item) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .center, + children: [ + Container( + padding: + EdgeInsets.all(2), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: + Colors.red[800], + borderRadius: + BorderRadius + .circular( + 20), + ), + constraints: + BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Center( + child: AppText( + model + .specialClinicalCareMappingList + .length + .toString(), + color: + Colors.white, + fontSize: + projectsProvider + .isArabic + ? 10 + : 11, + textAlign: + TextAlign + .center, + ), + )), + ], + ), + AppText(item.description, + fontSize: 12, + color: Colors.black, + fontWeight: + FontWeight.bold, + textAlign: TextAlign.end), + ], + ); + }).toList(); + }, + onChanged: (newValue) async { + setState(() { + selectedMapId = newValue; + }); + model.clearPatientList(); + GifLoaderDialogUtils.showMyDialog( + context); + + PatientSearchRequestModel requestModel = PatientSearchRequestModel( + nursingStationID: selectedMapId, clinicID: 0); + await model.getInPatientList(requestModel, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog( + context); + if (model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + model.error); + } + }, + items: model + .specialClinicalCareMappingList + .map((item) { + return DropdownMenuItem( + child: AppText( + item.description, + textAlign: TextAlign.left, + ), + value: item.nursingStationID, + ); + }).toList(), + )), + ) ]), ), ), From 7b71bd752fd892334fa20a953ce033dd65a7ecce Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 14 Jun 2021 18:08:24 +0300 Subject: [PATCH 176/241] add to do --- lib/screens/patients/PatientsInPatientScreen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 1d8e91b9..fe908b8d 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -68,6 +68,8 @@ class _PatientInPatientScreenState extends State if (widget.specialClinic != null) await model.getSpecialClinicalCareMappingList( widget.specialClinic.clinicID); + + //TODO Elham* check why he call it without await and handel the special clinic part. model.getInPatientList(requestModel); }, builder: (_, model, w) => From 7f3ae19fd2394002b8d2407c298136b098a00a83 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 09:42:50 +0300 Subject: [PATCH 177/241] remove todo --- lib/screens/patients/PatientsInPatientScreen.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index fe908b8d..1d8e91b9 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -68,8 +68,6 @@ class _PatientInPatientScreenState extends State if (widget.specialClinic != null) await model.getSpecialClinicalCareMappingList( widget.specialClinic.clinicID); - - //TODO Elham* check why he call it without await and handel the special clinic part. model.getInPatientList(requestModel); }, builder: (_, model, w) => From 1c3391baed0787bf6833599d7443104a5c08544b Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 15 Jun 2021 12:04:37 +0300 Subject: [PATCH 178/241] Scan qr code refactoring --- lib/core/service/home/scan_qr_service.dart | 41 +++++++++++++++++++++ lib/core/viewModel/scan_qr_view_model.dart | 26 +++++++++++++ lib/locator.dart | 4 ++ lib/screens/qr_reader/QR_reader_screen.dart | 5 ++- 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 lib/core/service/home/scan_qr_service.dart create mode 100644 lib/core/viewModel/scan_qr_view_model.dart diff --git a/lib/core/service/home/scan_qr_service.dart b/lib/core/service/home/scan_qr_service.dart new file mode 100644 index 00000000..bc6c8820 --- /dev/null +++ b/lib/core/service/home/scan_qr_service.dart @@ -0,0 +1,41 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/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 ScanQrService extends BaseService { + List myInPatientList = List(); + List inPatientList = List(); + + Future getInPatient(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(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } +} diff --git a/lib/core/viewModel/scan_qr_view_model.dart b/lib/core/viewModel/scan_qr_view_model.dart new file mode 100644 index 00000000..ff934f79 --- /dev/null +++ b/lib/core/viewModel/scan_qr_view_model.dart @@ -0,0 +1,26 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class ScanQrViewModel extends BaseViewModel { + ScanQrService _scanQrService = locator(); + List get inPatientList => _scanQrService.inPatientList; + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _scanQrService.getInPatient(requestModel, false); + if (_scanQrService.hasError) { + error = _scanQrService.error; + + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } +} diff --git a/lib/locator.dart b/lib/locator.dart index 1c491b54..0b5d8c5c 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,10 +1,12 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; +import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; @@ -91,6 +93,7 @@ void setupLocator() { locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => ScanQrService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -118,4 +121,5 @@ void setupLocator() { locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => LiveCarePatientViewModel()); locator.registerFactory(() => PatientMedicalReportViewModel()); + locator.registerFactory(() => ScanQrViewModel()); } diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index 848b3f9a..c70563f9 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -25,7 +26,7 @@ class QrReaderScreen extends StatefulWidget { class _QrReaderScreenState extends State { @override Widget build(BuildContext context) { - return BaseView( + return BaseView( builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -74,7 +75,7 @@ class _QrReaderScreenState extends State { ); } - _scanQrAndGetPatient(BuildContext context, PatientViewModel model) async { + _scanQrAndGetPatient(BuildContext context, ScanQrViewModel model) async { /// When give qr we will change this method to get data /// var result = await BarcodeScanner.scan(); /// int patientID = get from qr result From 37e68539769ba73a3c924b564f4338d7d8a765b4 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 12:10:04 +0300 Subject: [PATCH 179/241] add special one first calling --- .../patients/PatientsInPatientScreen.dart | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 1d8e91b9..4971b636 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -65,9 +65,13 @@ class _PatientInPatientScreenState extends State return BaseView( onModelReady: (model) async { model.clearPatientList(); - if (widget.specialClinic != null) - await model.getSpecialClinicalCareMappingList( - widget.specialClinic.clinicID); + if (widget.specialClinic != null) { + await model + .getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); + requestModel.nursingStationID = + model.specialClinicalCareMappingList[0].nursingStationID; + requestModel.clinicID = 0; + } model.getInPatientList(requestModel); }, builder: (_, model, w) => @@ -101,19 +105,17 @@ class _PatientInPatientScreenState extends State color: Color(0xFF2B353E), ), ), - if(model.specialClinicalCareMappingList.isNotEmpty && - widget.specialClinic != null) + if (model.specialClinicalCareMappingList.isNotEmpty && + widget.specialClinic != null && + _activeTab != 2) Container( - width: MediaQuery - .of(context) - .size - .width * .3, + width: MediaQuery.of(context).size.width * .3, child: DropdownButtonHideUnderline( child: DropdownButton( - dropdownColor: Colors.white, - iconEnabledColor: Colors.black, - isExpanded: true, - value: selectedMapId == null ? model + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: selectedMapId == null ? model .specialClinicalCareMappingList[0] .nursingStationID : selectedMapId, iconSize: 25, From 883778d27813700ff6aaa82ffaf5bb95f813ab2e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 12:17:24 +0300 Subject: [PATCH 180/241] video call --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 41 ++- .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 8 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 310 +++++++++++++----- .../main/res/drawable/layout_rounded_bg.xml | 7 + .../main/res/layout/activity_video_call.xml | 96 +++--- android/app/src/main/res/values/dimens.xml | 8 +- .../viewModel/authentication_view_model.dart | 4 +- .../patient_profile_screen.dart | 1 + ...ent-profile-header-new-design-app-bar.dart | 21 +- 9 files changed, 359 insertions(+), 137 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt create mode 100644 android/app/src/main/res/drawable/layout_rounded_bg.xml diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index f013d281..d595be97 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -7,6 +7,7 @@ import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.ui.VideoCallResponseListener import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine @@ -15,7 +16,7 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant -class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler { +class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener { private val CHANNEL = "Dr.cloudSolution/videoCall" private var result: MethodChannel.Result? = null @@ -67,7 +68,6 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { // val videoCallActivity = VideoCallActivity() - // val intent = Intent(this, VideoCallActivity::class.java) // intent.putExtra("apiKey", apiKey) // intent.putExtra("sessionId", sessionId) @@ -77,14 +77,23 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + val transaction = supportFragmentManager.beginTransaction() - dialogFragment = VideoCallFragment.newInstance(Bundle()) - dialogFragment.isCancelable = false + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment.setCallListener(this) + dialogFragment.isCancelable = true dialogFragment.show(transaction, "dialog") } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) var asd = ""; if (requestCode == LAUNCH_VIDEO) { @@ -108,6 +117,28 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler result?.success(callResponse) } } + }*/ + + override fun onCallFinished(resultCode: Int, intent: Intent?) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() + + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() + + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes + + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + + result?.success(callResponse) + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt new file mode 100644 index 00000000..e32630b4 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -0,0 +1,8 @@ +package com.hmg.hmgDr.ui + +import android.content.Intent + +interface VideoCallResponseListener { + + fun onCallFinished(resultCode : Int, intent: Intent? = null) +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index d5a5d5da..dd4613bd 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -10,39 +10,38 @@ import android.graphics.Color import android.graphics.Point import android.graphics.drawable.ColorDrawable import android.opengl.GLSurfaceView -import android.os.Bundle -import android.os.CountDownTimer -import android.os.Handler -import android.os.Looper +import android.os.* import android.util.Log import android.view.* import android.widget.* import androidx.annotation.Nullable +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.fragment.app.DialogFragment -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.R import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.hmg.hmgDr.ui.VideoCallResponseListener import com.opentok.android.* import com.opentok.android.PublisherKit.PublisherListener import pub.devrel.easypermissions.AfterPermissionGranted import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks -import java.util.* import kotlin.math.ceil + class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { var isFullScreen: Boolean = true private var x_init_cord = 0 - private var y_init_cord:Int = 0 - private var x_init_margin:Int = 0 - private var y_init_margin:Int = 0 + private var y_init_cord: Int = 0 + private var x_init_margin: Int = 0 + private var y_init_margin: Int = 0 private val szWindow: Point = Point() private lateinit var mWindowManager: WindowManager private var isLeft = true @@ -58,9 +57,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var mVolRunnable: Runnable? = null private var mConnectedRunnable: Runnable? = null - private var mPublisherViewContainer: FrameLayout? = null - private var mSubscriberViewContainer: RelativeLayout? = null - private var controlPanel: RelativeLayout? = null + private lateinit var mPublisherViewContainer: FrameLayout + private lateinit var mPublisherViewIcon: View + private lateinit var mSubscriberViewContainer: FrameLayout + private lateinit var mSubscriberViewIcon: ImageView + private var controlPanel: ConstraintLayout? = null private var apiKey: String? = null private var sessionId: String? = null @@ -73,7 +74,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isSpeckerClicked = false private var isMicClicked = false - private lateinit var videoCallContainer: LinearLayout + private lateinit var parentView: View + private lateinit var videoCallContainer: ConstraintLayout + private lateinit var layoutName: RelativeLayout private lateinit var mCallBtn: ImageView private lateinit var btnMinimize: ImageView private lateinit var mCameraBtn: ImageView @@ -81,6 +84,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mspeckerBtn: ImageView private lateinit var mMicBtn: ImageView + private lateinit var patientName: TextView + private lateinit var cmTimer: Chronometer + var elapsedTime: Long = 0 + var resume = false + private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null private val progressBarTextView: TextView? = null @@ -89,6 +97,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isConnected = false private var sessionStatusModel: GetSessionStatusModel? = null + private var videoCallResponseListener: VideoCallResponseListener? =null override fun onCreate(savedInstanceState: Bundle?) { @@ -137,16 +146,20 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + fun setCallListener(videoCallResponseListener: VideoCallResponseListener){ + this.videoCallResponseListener = videoCallResponseListener + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater.inflate(R.layout.activity_video_call, container, false) + parentView = inflater.inflate(R.layout.activity_video_call, container, false) - Objects.requireNonNull(requireActivity().actionBar)!!.hide() - initUI(view) +// Objects.requireNonNull(requireActivity().actionBar)!!.hide() + initUI(parentView) handleDragDialog() - return view + return parentView } override fun onPause() { @@ -170,14 +183,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onDestroy() { disconnectSession() + cmTimer.stop() super.onDestroy() } @SuppressLint("ClickableViewAccessibility") private fun initUI(view: View) { - videoCallContainer = view.findViewById(R.id.video_call_ll) - mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) - mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + videoCallContainer = view.findViewById(R.id.video_call_ll) + layoutName = view.findViewById(R.id.layout_name) + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) + mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) arguments?.run { apiKey = getString("apiKey") @@ -188,7 +205,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session sessionStatusModel = getParcelable("sessionStatusModel") } - controlPanel = view.findViewById(R.id.control_panel) + patientName = view.findViewById(R.id.patient_name) + patientName.text = sessionStatusModel!!.patientName + + cmTimer = view.findViewById(R.id.cmTimer) + cmTimer.format = "mm:ss" + cmTimer.onChronometerTickListener = Chronometer.OnChronometerTickListener { arg0: Chronometer? -> + val minutes: Long + val seconds: Long + if (!resume) { + minutes = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 / 60 + seconds = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 % 60 + elapsedTime = SystemClock.elapsedRealtime() + } else { + minutes = (elapsedTime - cmTimer.base) / 1000 / 60 + seconds = (elapsedTime - cmTimer.base) / 1000 % 60 + elapsedTime = elapsedTime + 1000 + } + Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") + } + + controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) mCallBtn.setOnClickListener { @@ -295,17 +332,23 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) } mSession!!.publish(mPublisher) + + if (!resume) { + cmTimer.base = SystemClock.elapsedRealtime() + } + cmTimer.start() } override fun onDisconnected(session: Session) { Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) mSession = null + cmTimer.stop() } override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -316,7 +359,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } override fun onStreamDropped(session: Session, stream: Stream) { @@ -342,8 +385,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() - requireActivity().finish() +// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() +// requireActivity().finish() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -367,8 +410,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun disconnectSession() { if (mSession == null) { - requireActivity().setResult(Activity.RESULT_CANCELED) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) +// requireActivity().setResult(Activity.RESULT_CANCELED) + dialog?.dismiss() return } if (mSubscriber != null) { @@ -385,8 +429,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() - videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) - requireActivity().finish() +// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + dialog?.dismiss() } @@ -394,8 +438,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { val returnIntent = Intent() returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) - requireActivity().setResult(Activity.RESULT_OK, returnIntent) - requireActivity().finish() + videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) +// requireActivity().setResult(Activity.RESULT_OK, returnIntent) + dialog?.dismiss() } } @@ -403,7 +448,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onFailure() {} - fun onSwitchCameraClicked(view: View?) { + private fun onSwitchCameraClicked(view: View?) { if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked mPublisher!!.cycleCamera() @@ -412,11 +457,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onCallClicked(view: View?) { + private fun onCallClicked(view: View?) { disconnectSession() } - fun onMinimizedClicked(view: View?) { + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( 400, @@ -429,9 +474,89 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ) } isFullScreen = !isFullScreen + setViewsVisibility() + } + + private fun setViewsVisibility() { + initUI(parentView) + val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam : ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + +// val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() +// val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() +// val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() +// val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() +// val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() +// val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() +// val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() +// val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() +// val localPreviewLayoutIconParam : FrameLayout.LayoutParams +// val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + + val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() + val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() + val remotePreviewLayoutParam : FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + + val constraintSet = ConstraintSet() + //layoutParam.constrain +// constraintSet. + if (isFullScreen) { + layoutName.visibility = View.VISIBLE + mCameraBtn.visibility = View.VISIBLE + mSwitchCameraBtn.visibility = View.VISIBLE + mspeckerBtn.visibility = View.VISIBLE + mMicBtn.visibility = View.VISIBLE + mPublisherViewContainer.visibility = View.VISIBLE + +// layoutParam = ConstraintLayout.LayoutParams(iconSize, iconSize) + btnMinimizeLayoutParam.width = iconSize + btnMinimizeLayoutParam.height = iconSize + mCallBtnLayoutParam.width = iconSize + mCallBtnLayoutParam.height = iconSize +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) +// localPreviewLayoutParam.width = localPreviewIconSize +// localPreviewLayoutParam.height = localPreviewIconSize +// localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) + remotePreviewLayoutParam.width = remotePreviewIconSize + remotePreviewLayoutParam.height = remotePreviewIconSize + } else { + layoutName.visibility = View.GONE + mCameraBtn.visibility = View.GONE + mSwitchCameraBtn.visibility = View.GONE + mspeckerBtn.visibility = View.GONE + mMicBtn.visibility = View.GONE + mPublisherViewContainer.visibility = View.GONE + +// layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) + btnMinimizeLayoutParam.width = iconSizeSmall + btnMinimizeLayoutParam.height = iconSizeSmall + mCallBtnLayoutParam.width = iconSizeSmall + mCallBtnLayoutParam.height = iconSizeSmall + +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) +// localPreviewLayoutParam.width = localPreviewWidthSmall +// localPreviewLayoutParam.height = localPreviewWidthSmall +// localPreviewLayoutParam.setMargins(0,localPreviewMarginSmall, localPreviewMarginSmall, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) + remotePreviewLayoutParam.width = remotePreviewIconSizeSmall + remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + } + +// mPublisherViewContainer.layoutParams = localPreviewLayoutParam +// mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam + mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam + + btnMinimize.layoutParams = btnMinimizeLayoutParam + mCallBtn.layoutParams = mCallBtnLayoutParam + } - fun onCameraClicked(view: View?) { + private fun onCameraClicked(view: View?) { if (mPublisher != null) { isCameraClicked = !isCameraClicked mPublisher!!.publishVideo = !isCameraClicked @@ -440,7 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onMicClicked(view: View?) { + private fun onMicClicked(view: View?) { if (mPublisher != null) { isMicClicked = !isMicClicked mPublisher!!.publishAudio = !isMicClicked @@ -449,7 +574,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun onSpeckerClicked(view: View?) { + private fun onSpeckerClicked(view: View?) { if (mSubscriber != null) { isSpeckerClicked = !isSpeckerClicked mSubscriber!!.subscribeToAudio = !isSpeckerClicked @@ -458,64 +583,69 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } + @SuppressLint("ClickableViewAccessibility") - fun handleDragDialog(){ + fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager getWindowManagerDefaultDisplay() - videoCallContainer.setOnTouchListener { _, event -> - //Get Floating widget view params - //Get Floating widget view params - val layoutParams : WindowManager.LayoutParams = dialog!!.window!!.attributes - //get the touch location coordinates - val x_cord = event.rawX.toInt() - val y_cord = event.rawY.toInt() - val x_cord_Destination: Int - var y_cord_Destination: Int - - when (event.action) { - MotionEvent.ACTION_DOWN -> { - x_init_cord = x_cord - y_init_cord = y_cord - - //remember the initial position. - x_init_margin = layoutParams.x - y_init_margin = layoutParams.y - } - MotionEvent.ACTION_UP -> { - //Get the difference between initial coordinate and current coordinate - val x_diff: Int = x_cord - x_init_cord - val y_diff: Int = y_cord - y_init_cord - - y_cord_Destination = y_init_margin + y_diff - val barHeight: Int = getStatusBarHeight() - if (y_cord_Destination < 0) { + videoCallContainer.setOnTouchListener(dragListener) +// mSubscriberViewContainer.setOnTouchListener(dragListener) + } + + @SuppressLint("ClickableViewAccessibility") + val dragListener : View.OnTouchListener = View.OnTouchListener{ _, event -> + //Get Floating widget view params + //Get Floating widget view params + val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { // y_cord_Destination = 0 - y_cord_Destination = - -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) - } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { - y_cord_Destination = - szWindow.y - (videoCallContainer.height + barHeight) - } - layoutParams.y = y_cord_Destination - - //reset position if user drags the floating view - resetPosition(x_cord) + y_cord_Destination = + -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { + y_cord_Destination = + szWindow.y - (videoCallContainer.height + barHeight) } - MotionEvent.ACTION_MOVE -> { - val x_diff_move: Int = x_cord - x_init_cord - val y_diff_move: Int = y_cord - y_init_cord - x_cord_Destination = x_init_margin + x_diff_move - y_cord_Destination = y_init_margin + y_diff_move + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move - layoutParams.x = x_cord_Destination - layoutParams.y = y_cord_Destination + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination - dialog!!.window!!.attributes = layoutParams - } + dialog!!.window!!.attributes = layoutParams } - true } + true } /* Reset position of Floating Widget view on dragging */ @@ -532,16 +662,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session /* Method to move the Floating widget view to Left */ private fun moveToLeft(current_x_cord: Int) { - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes mParams.x = - (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() dialog!!.window!!.attributes = mParams val x = szWindow.x - current_x_cord object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() @@ -568,7 +698,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // dialog!!.window!!.attributes = mParams object : CountDownTimer(500, 5) { //get params of Floating Widget view - var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes override fun onTick(t: Long) { val step = (500 - t) / 5 mParams.x = diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml new file mode 100644 index 00000000..0c46f49b --- /dev/null +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index b7ca8d8d..0b3baff7 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,5 +1,6 @@ - + android:padding="@dimen/padding_space_medium" + app:layout_constraintTop_toTopOf="parent"> + tools:text="25:45" /> @@ -47,7 +50,8 @@ android:id="@+id/activity_clingo_video_call" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1" + app:layout_constraintBottom_toTopOf="@id/control_panel" + app:layout_constraintTop_toBottomOf="@+id/layout_name" tools:context=".ui.VideoCallActivity"> - - + - + - + android:padding="@dimen/padding_space_big" + app:layout_constraintBottom_toBottomOf="parent"> + android:src="@drawable/call" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/ic_mini" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:scaleType="centerCrop" + android:src="@drawable/video_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_minimize" + app:layout_constraintTop_toTopOf="parent" + /> + android:src="@drawable/mic_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_camera" + app:layout_constraintTop_toTopOf="parent" + /> - - - + android:scaleType="centerCrop" + android:src="@drawable/audio_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" + /> + + + diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 2d53d554..2a4d695f 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -3,21 +3,27 @@ 16dp 16dp 28dp + 12dp 24dp 60dp 54dp - 64dp + 52dp + 24dp 24dp 25dp 88dp + 40dp 117dp + 50dp 50dp + 25dp 100dp + 40dp 90dp diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 58df9331..189dea42 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -254,8 +254,8 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { - print("VerificationCode : " + - sendActivationCodeForDoctorAppResponseModel.verificationCode); + print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); + DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index e0053b81..d755af4a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -17,6 +17,7 @@ import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 995ac57a..f2a32e63 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -21,8 +21,10 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget final bool isDischargedPatient; final bool isFromLiveCare; + final Stream videoCallDurationStream; + PatientProfileHeaderNewDesignAppBar( - this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false}); + this.patient, this.patientType, this.arrivalType, {this.height = 0.0, this.isInpatient=false, this.isDischargedPatient=false, this.isFromLiveCare = false, this.videoCallDurationStream}); @override Widget build(BuildContext context) { @@ -88,6 +90,23 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget ), ), ), + StreamBuilder( + stream: videoCallDurationStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if(snapshot.hasData && snapshot.data != null) + return InkWell( + onTap: (){ + }, + child: Container( + decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.symmetric(vertical: 2, horizontal: 10), + child: Text(snapshot.data, style: TextStyle(color: Colors.white),), + ), + ); + else + return Container(); + }, + ), ]), ), Row(children: [ From fee36336d8e1967ea0cd14326980f74265500e8f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 14:40:11 +0300 Subject: [PATCH 181/241] fix out patient header --- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 1a47dd00..5cfdc1b6 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -273,7 +273,7 @@ class PatientProfileAppBar extends StatelessWidget ), ), - if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty) + if ( patient.appointmentDate != null && patient.appointmentDate.isNotEmpty && !isFromLabResult) Row( mainAxisAlignment: MainAxisAlignment.start, children: [ From 3cf4ef43488466248c6aed4bbfdafca1229012e7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 14:57:42 +0300 Subject: [PATCH 182/241] check if special in home page --- lib/core/viewModel/dashboard_view_model.dart | 8 ++++---- lib/screens/home/home_screen.dart | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 95028f52..f35a4a2a 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -103,15 +103,15 @@ class DashboardViewModel extends BaseViewModel { } - bool isSpecialClinic(clinicId){ - bool isSpecial = false; + GetSpecialClinicalCareListResponseModel getSpecialClinic(clinicId){ + GetSpecialClinicalCareListResponseModel special ; specialClinicalCareList.forEach((element) { if(element.clinicID == 1){ - isSpecial = true; + special = element; } }); - return isSpecial; + return special; } } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 294541b0..aaf4d9b9 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -288,7 +288,7 @@ class _HomeScreenState extends State { child: ListView( scrollDirection: Axis.horizontal, children: [ - ...homePatientsCardsWidget(model), + ...homePatientsCardsWidget(model, projectsProvider), ])), SizedBox( height: 20, @@ -306,7 +306,7 @@ class _HomeScreenState extends State { ); } - List homePatientsCardsWidget(DashboardViewModel model) { + List homePatientsCardsWidget(DashboardViewModel model,projectsProvider) { colorIndex = 0; List backgroundColors = List(3); @@ -355,7 +355,8 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(specialClinic: model.specialClinicalCareList[0],), + page: PatientInPatientScreen(specialClinic: model.getSpecialClinic(clinicId??projectsProvider + .doctorClinicsList[0].clinicID),), ), ); }, From f76bac898bc81ca10544ed7e107c6a9e68efb2a0 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Tue, 15 Jun 2021 15:20:33 +0300 Subject: [PATCH 183/241] make clinic id dynamic --- lib/core/viewModel/PatientSearchViewModel.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index 6b83461b..e0ee8948 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -218,8 +218,7 @@ class PatientSearchViewModel extends BaseViewModel { } else { setState(ViewState.Busy); } - //TODO Elham* change clinic id to dynamic - await _specialClinicsService.getSpecialClinicalCareMappingList(221); + await _specialClinicsService.getSpecialClinicalCareMappingList(clinicId); if (_specialClinicsService.hasError) { error = _specialClinicsService.error; if (isLocalBusy) { From 890a356d8c4afe3e931d0a6ed77ca19c79b8b1a1 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 15:52:28 +0300 Subject: [PATCH 184/241] video fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 42 +++++++++------ .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 53 +++++++++++-------- .../main/res/layout/activity_video_call.xml | 40 +++----------- 4 files changed, 66 insertions(+), 71 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index d595be97..d3c58371 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -3,6 +3,7 @@ package com.hmg.hmgDr import android.app.Activity import android.content.Intent import android.os.Bundle +import android.widget.Toast import androidx.annotation.NonNull import com.google.gson.GsonBuilder import com.hmg.hmgDr.Model.GetSessionStatusModel @@ -23,7 +24,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 - lateinit var dialogFragment: VideoCallFragment + private var dialogFragment: VideoCallFragment? = null override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) @@ -77,19 +78,23 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) - val arguments = Bundle() - arguments.putString("apiKey", apiKey) - arguments.putString("sessionId", sessionId) - arguments.putString("token", token) - arguments.putString("appLang", appLang) - arguments.putString("baseUrl", baseUrl) - arguments.putParcelable("sessionStatusModel", sessionStatusModel) - - val transaction = supportFragmentManager.beginTransaction() - dialogFragment = VideoCallFragment.newInstance(arguments) - dialogFragment.setCallListener(this) - dialogFragment.isCancelable = true - dialogFragment.show(transaction, "dialog") + if (dialogFragment == null){ + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + + val transaction = supportFragmentManager.beginTransaction() + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment?.let { + it.setCallListener(this) + it.isCancelable = true + it.show(transaction, "dialog") + } + } } @@ -120,6 +125,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { + dialogFragment = null + if (resultCode == Activity.RESULT_OK) { val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") val callResponse : HashMap = HashMap() @@ -132,8 +139,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, callResponse["sessionStatus"] = jsonRes this.result?.success(callResponse) - } - if (resultCode == Activity.RESULT_CANCELED) { + } else if (resultCode == Activity.RESULT_CANCELED) { val callResponse : HashMap = HashMap() callResponse["callResponse"] = "CallEnd" @@ -141,5 +147,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } } + override fun errorHandle(message: String) { + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + } + } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index e32630b4..d2ed15e0 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -5,4 +5,6 @@ import android.content.Intent interface VideoCallResponseListener { fun onCallFinished(resultCode : Int, intent: Intent? = null) + + fun errorHandle(message: String) } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index dd4613bd..6c07f462 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -103,8 +103,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onCreate(savedInstanceState: Bundle?) { requireActivity().setTheme(R.style.AppTheme) super.onCreate(savedInstanceState) - - requestPermissions() } override fun onStart() { @@ -155,8 +153,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session parentView = inflater.inflate(R.layout.activity_video_call, container, false) -// Objects.requireNonNull(requireActivity().actionBar)!!.hide() + // Objects.requireNonNull(requireActivity().actionBar)!!.hide() + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + } initUI(parentView) + requestPermissions() + handleDragDialog() return parentView @@ -196,15 +204,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) - arguments?.run { - apiKey = getString("apiKey") - sessionId = getString("sessionId") - token = getString("token") - appLang = getString("appLang") - baseUrl = getString("baseUrl") - sessionStatusModel = getParcelable("sessionStatusModel") - } - patientName = view.findViewById(R.id.patient_name) patientName.text = sessionStatusModel!!.patientName @@ -220,8 +219,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } else { minutes = (elapsedTime - cmTimer.base) / 1000 / 60 seconds = (elapsedTime - cmTimer.base) / 1000 % 60 - elapsedTime = elapsedTime + 1000 + elapsedTime += 1000 } + arg0?.text = "$minutes:$seconds" Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") } @@ -257,12 +257,19 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // progressBar.setVisibility(View.GONE); hiddenButtons() checkClientConnected() - mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> + + mSubscriberViewContainer.setOnClickListener { controlPanel!!.visibility = View.VISIBLE mVolHandler!!.removeCallbacks(mVolRunnable!!) mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) - true } + +// mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> +// controlPanel!!.visibility = View.VISIBLE +// mVolHandler!!.removeCallbacks(mVolRunnable!!) +// mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) +// true +// } if (appLang == "ar") { progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL } @@ -347,8 +354,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) -// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() -// requireActivity().finish() + + videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in session ") + dialog?.dismiss() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -385,8 +393,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") -// Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show() -// requireActivity().finish() + videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in publisher") + dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -408,6 +416,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession!!.subscribe(mSubscriber) } + override fun dismiss() { + videoCallResponseListener?.onCallFinished(1000) + super.dismiss() + } + private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) @@ -478,7 +491,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun setViewsVisibility() { - initUI(parentView) val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams @@ -553,7 +565,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session btnMinimize.layoutParams = btnMinimizeLayoutParam mCallBtn.layoutParams = mCallBtnLayoutParam - } private fun onCameraClicked(view: View?) { diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index 0b3baff7..586f5b60 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -54,30 +54,6 @@ app:layout_constraintTop_toBottomOf="@+id/layout_name" tools:context=".ui.VideoCallActivity"> - - - - - - + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" /> From bc661a6f38ada1f1470fc175cf334a578a67b4f0 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 15 Jun 2021 16:56:51 +0300 Subject: [PATCH 185/241] fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 47 +++++++++++------- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 2 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 23 +++++---- android/app/src/main/res/drawable/call.png | Bin 13229 -> 21324 bytes .../app/src/main/res/drawable/camera_back.png | Bin 0 -> 6409 bytes .../src/main/res/drawable/camera_front.png | Bin 0 -> 7100 bytes android/app/src/main/res/drawable/expand.png | Bin 0 -> 5366 bytes .../src/main/res/drawable/flip_disapled.png | Bin 6138 -> 0 bytes .../src/main/res/drawable/flip_enabled.png | Bin 6753 -> 0 bytes android/app/src/main/res/drawable/ic_mini.xml | 16 ------ .../src/main/res/drawable/mic_disabled.png | Bin 5783 -> 6537 bytes .../app/src/main/res/drawable/mic_enabled.png | Bin 6020 -> 5904 bytes .../app/src/main/res/drawable/reducing.png | Bin 0 -> 4953 bytes .../main/res/drawable/video_disanabled.png | Bin 5113 -> 6438 bytes .../src/main/res/drawable/video_enabled.png | Bin 5338 -> 5715 bytes .../main/res/layout/activity_video_call.xml | 29 +++++------ android/app/src/main/res/values/dimens.xml | 2 +- 17 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 android/app/src/main/res/drawable/camera_back.png create mode 100644 android/app/src/main/res/drawable/camera_front.png create mode 100644 android/app/src/main/res/drawable/expand.png delete mode 100644 android/app/src/main/res/drawable/flip_disapled.png delete mode 100644 android/app/src/main/res/drawable/flip_enabled.png delete mode 100644 android/app/src/main/res/drawable/ic_mini.xml create mode 100644 android/app/src/main/res/drawable/reducing.png diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index d3c58371..9d9581fe 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -43,27 +43,36 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, this.result = result this.call = call - if (call.method == "openVideoCall") { - val apiKey = call.argument("kApiKey") - val sessionId = call.argument("kSessionId") - val token = call.argument("kToken") - val appLang = call.argument("appLang") - val baseUrl = call.argument("baseUrl") + when (call.method) { + "openVideoCall" -> { + val apiKey = call.argument("kApiKey") + val sessionId = call.argument("kSessionId") + val token = call.argument("kToken") + val appLang = call.argument("appLang") + val baseUrl = call.argument("baseUrl") - // Session Status model - val VC_ID = call.argument("VC_ID") - val tokenID = call.argument("TokenID") - val generalId = call.argument("generalId") - val doctorId = call.argument("DoctorId") - val patientName = call.argument("patientName") + // Session Status model + val VC_ID = call.argument("VC_ID") + val tokenID = call.argument("TokenID") + val generalId = call.argument("generalId") + val doctorId = call.argument("DoctorId") + val patientName = call.argument("patientName") - val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) + val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) - openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) + openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) - } else { - result.notImplemented() + } + "closeVideoCall" -> { + dialogFragment?.onCallClicked() + } + "onCallConnected"->{ + + } + else -> { + result.notImplemented() + } } } @@ -94,6 +103,9 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, it.isCancelable = true it.show(transaction, "dialog") } + } else if (!dialogFragment!!.isVisible){ + val transaction = supportFragmentManager.beginTransaction() + dialogFragment!!.show(transaction, "dialog") } } @@ -148,7 +160,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } override fun errorHandle(message: String) { - Toast.makeText(this, message, Toast.LENGTH_LONG).show() + dialogFragment = null +// Toast.makeText(this, message, Toast.LENGTH_LONG).show() } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index 0fb061f1..daf372ed 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -415,7 +415,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked; mPublisher.cycleCamera(); - int res = isSwitchCameraClicked ? R.drawable.flip_disapled : R.drawable.flip_enabled; + int res = isSwitchCameraClicked ? R.drawable.camera_front : R.drawable.camera_back; mSwitchCameraBtn.setImageResource(res); } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 6c07f462..e0a92206 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -229,7 +229,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) mCallBtn.setOnClickListener { - onCallClicked(it) + onCallClicked() } btnMinimize = view.findViewById(R.id.btn_minimize) btnMinimize.setOnClickListener { @@ -355,8 +355,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in session ") - dialog?.dismiss() + videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") +// dialog?.dismiss() } override fun onStreamReceived(session: Session, stream: Stream) { @@ -393,8 +393,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - videoCallResponseListener?.errorHandle("onError: Error (" + opentokError.message + ") in publisher") - dialog?.dismiss() + videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") +// dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { @@ -465,12 +465,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (mPublisher != null) { isSwitchCameraClicked = !isSwitchCameraClicked mPublisher!!.cycleCamera() - val res = if (isSwitchCameraClicked) R.drawable.flip_disapled else R.drawable.flip_enabled - mSwitchCameraBtn!!.setImageResource(res) + val res = if (isSwitchCameraClicked) R.drawable.camera_front else R.drawable.camera_back + mSwitchCameraBtn.setImageResource(res) } } - private fun onCallClicked(view: View?) { + fun onCallClicked() { disconnectSession() } @@ -487,6 +487,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ) } isFullScreen = !isFullScreen + + val res = if (isFullScreen) R.drawable.reducing else R.drawable.expand + btnMinimize.setImageResource(res) setViewsVisibility() } @@ -518,7 +521,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName.visibility = View.VISIBLE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE - mspeckerBtn.visibility = View.VISIBLE +// mspeckerBtn.visibility = View.VISIBLE mMicBtn.visibility = View.VISIBLE mPublisherViewContainer.visibility = View.VISIBLE @@ -539,7 +542,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName.visibility = View.GONE mCameraBtn.visibility = View.GONE mSwitchCameraBtn.visibility = View.GONE - mspeckerBtn.visibility = View.GONE +// mspeckerBtn.visibility = View.GONE mMicBtn.visibility = View.GONE mPublisherViewContainer.visibility = View.GONE diff --git a/android/app/src/main/res/drawable/call.png b/android/app/src/main/res/drawable/call.png index fc00f4f942d7ef38336bf493a5e9ba2980692c55..52f8e267234d686e31be8a6e1b44287ab98364db 100644 GIT binary patch literal 21324 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 F@_+AV*hT;V literal 13229 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

*Md~6?Fz~6 zzsQ)=AsN)tmj4qmzOK4w*%;#<-M~yk%&+g{f$dc_+OBy)0BpCtlr&Bu-!3Bs<}4*f zZfoVhWSn-iuJyX^*p?C|nfOHjOt+U6dPAM~qLEnd#eDg>SW!QtLVVJ;4+( z#iu`WLE+kwkutepQjY+H*p8`kmPsRL7df6& z0S_-LB+~20W%oq7nX3*aIRZ>!qr1{QX-aZUq_|Mmpr*t)tb(4eE6majfd~*dFJjb& z)Xp(R(MT1z*0F){Me8Z)j@?Uu<97!H9}zT1`tWi$lBK;UBTyN#`BMGQ(+1uXK!yoahWIF>O91ir|9wpC+V6C*GELmgxN zU3e>iEOXQd;G_6zYgvgHVj$bmSs67k1VTpOQtqp*ZCr^M)S?PM(ZL4dts%D?210oDp>jJ)s< zbmVs%CWb%=2;htOWGCrN3^9|D|9jGyf9cl=M7uc{1n|LkbD!*FRA*vPy9{CHt^KyT z)1$DPJs@zoYY0`?;Ds0zCW9b`ZA~wbwd2qTe3kp4mwLSsBe&*V9qs@4d3iKeNDBn; zIl_5w;*}U;>`htrzBlWvAVZ)T0`JTBynZ2jB?fJffxIc5*Y21Y0z)9cYc{>Vo!>h# zawOQFGX2-EL!e`ItR({Y*hhV|ycc4K!M9}WJ5sORTOR;enb9JEZ@nX5>t&gs7h(Xl z3}&I_f)tXN7y>>Kz^5+cKIXIBX<5AygBoNw)3;t{3#OLa$+{vy5Aj~^TfJe>D>1NI z4PanoThx1dglktYTgkl-w&zjoofuT8hOqeOe2MP7VfNV&s6c?tfge{~_kL**V&qm| z)N$eeDSK~`6__dl_|9N!WP=eyOeZ#ErmE9+;8dTwwabYB)3UwIKvmT|7%`|^*T_ian8H@b$1! zh(YT`j(c_B4eAf_*~Ac-Lx8D%dJ2B;Gq{XK3|cC35XwC#-Qcr{A&?`$bS!HXqb&}P zN(?{{Ik4fV^f9T4A;1gLMqd;jofw55h#*hv{3pd{JFX=HpNbSr>yIwM5CbGcj;D0^ z>FB7K0b?NWkw`Jf;$4%*1w{-D7CC;b!_TD*&P~!sfWb8{T@LDf$iWc79M1^4=;Ac=t=h#c6)xZ`m?n!Fc0{^hs%yZIIom3xnz_QeK;RE4Ic) z?NlPj{Q~@7qz}ageB$=F4`7>5H|7lNw#%F7dBPlo16oQAgr1*{$RIma_y^nh$CKu z5X?4xEJ6ggdff$=WF1EYVb+SlIV zD4wJULRdw3MVMuagat6wM;7NG1V12RJh3*icEl(@S&@Y4U4H+;K;8CX-2sQS2L{x< z^)Jcs!<}Zj|E@JL%Fu`;59l)lLDy|P1Oi-@cK-j^DkBLoVpKdvk>s#0(~~?RO?5_# znI+!F!OI7t+Q%fDdlw^y1LAxxE#Ae5(E?Ht z1-uBkHlzhvLY)F;_6P!?kl~-}Hh@-}R~942%Fx}pQDk9ei_MJlI@CCY@c{$o85Ifa z{lEfcRWV|$id@ZoA`CrAK^Dlv=Ryg`=Ff|@6&B9;wkOQtIDgJ(oE{>4W8sic=t2G; X_h{;p&xF^300000NkvXXu0mjfo)PYq literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/camera_front.png b/android/app/src/main/res/drawable/camera_front.png new file mode 100644 index 0000000000000000000000000000000000000000..332ab0f54dc44ca81ed878c6788b6accf5b35039 GIT binary patch literal 7100 zcmV;t8$;xYP)Px#IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa40RR91#-IZL z1ONa40RR91$^ZZW0E2h5SpWbVGD$>1RCodHoeQvCRe8rxlu7{6fI#RN;X*CBM5Wpg zpi)Rus)T|<$h2S$6>BHp$TR`9(^7DzlK_gAklHG*aiCBN)-c#&2^HZ2RvrP`4iX+k zyacLXkVb)oB9i`phqEsGp1a>?Ki1yo`)0no_g;HFzV+Yhf7g4RX&sYN5ZJbD+glXz z9O8n=cLa|f8M)t?-aMq(sAj-(ubx^oAxtZO$tU}TEX!RRdg!+ z;J1&I!auurri9nKmeNv>^R)qm=Ov8wg;j4-WZ;Un2=t+qKS5!v`Z9`J+Lk4R6H?i=Ez4Ni|M6aOf^MkM)u8!}X69*h`0G)0DebPE|!h%rn8F|L+E zk{=FJ#-s8&)Wi@O_7pHDNFl?)Q6LSO``yYfB>B2X^7N49eImO4(t2Wu5R4*0 zhSQ|J4z0?xMhK+%vUIfw!YEg3rM1KmA!h2UeO7v^bf?yS!Fn?GqLTfp^h+YhGxeBI zZmO*#h6piBko~#z6VmDB!Z-A>za#`MlYT)2d8$olw1yZW#E$wfe<7uo*uG64sR4QU zKiPP`^z$OfmIm0HXksgfAyOQzoKm&FBQeM3p-cpxROFu&Ilfh9B2~oQ=%GpxVqfXM z2&fyRMv5v*One%AgB$oJe4BW$e!p#GjUmvj+2nV*!aCQyI!84K_l=Uq5ksV~W>cez zSmy^acX`vASB)Wt2*C&w{fLvLCe1_Oa+ys3gOM!nr4hssDOl9U`knW9kEj_Khrk1R zdA!K+Sez#x-g)2o7AZa^pze_xDSRj~gW140yubHN2aBoX(B9S<)^sZQ%hwtMwM*^95Fy?u6t0q< zSUVbKfDZ^rRy~U>^EO5a@4YwwiaTD6uT?a-;vtLlhnp7>l)*PEcXvuz`($DWq(y+5<51Nc&!-JAsK3f;43UEE zrr(qrDF*#&!xx^K<2se0%J%SALJVbyn(6D(-xrG5;y|T-my`nyObh{E5a1w%_p8?6XxCgaXpQj|rD~+e1-%6- z5dq5N-wYCeZepmmI9UnL8zgZHYY3Exz`?yTnk$K1O(`Y#W~KH+>2A4FwLpeIH3)Es z!oF%!y^uAzyfwxuC1j+?injT$8UaqDIV(@1nQIKy7PFPmgHr2TTp07AP_!MH)oSkIx7&>6eNascH;GwobXVPItm5f8vQJI``gt zZ)fAijhz=?d@;dyF|T*pX{XNU=xArooH?Dn_ujjhNZTFDH&tseh!iV{#1JXwDu(sa zM8B~qwfNFWIsW+LyCf+*^7cfyO<5TgIUbG6Qet5j zF|JVrC&WcE%Z;C-H{R$K1Vebz*Q^>2@oen(kz|QHXpI*Bio*M9q?Alx8_)(O7NuBRcE1;1g1igzdzSvt* zU@mKMQNyJzj7kF6TQRr^J{dVuOkB#(yOhOSjG1Rr^7)cB@qZY`| z9&v$(_1%?MUfGzeTdfiKsb==dc&LZCX41)_A%@(M+Tz(~pN&OfhaGn4jEszQ7$quG z7zG<2AMb44x-~KxY^ByLS1R*EQ`Sa%o zohIFH*|Np!5wuChR{s!M)~66dRSRu^qpP>i{}gY!>84mC4?q0y*!N|=OiFv*x^-nH z-{iP|Pi1~e>u3rwl*8YbPVv~}oEKp`qdTmHiW2%3yYJ2x<9dX3QoHRIy$zp^`r5T? z>oLynRCktnQ<_s@o$t`9#qYf3vyOsJGlP*Gu3^H6&-(T26Gx&JEy}b(EG(&k-KaHK zvlS)0qaz+yyX?5*j@=P8u0ymakuuNHrwN&~Bt%up_IksapVKFNwCskVOFGb8lZIW> zW}S}jnl)=`>0bnGWN={FvSmT1f$ph+7|lBDu*2Fus`Zk9nxWAt4o>JwKQR`__14#3 zwd?PuO`Ez)B+6I;%Yr>R-aZJ;rMOxnuZ_&foN~%3wKf;?+MY7pLJ?!k`R(sxEO0N{ zbY=DHiWMtLSr$%#@r4w8Gn#btcZwGNp@5-pD~Sut=Yn8dttSSZW|oGRArwI0RM;?`5; zwb!Ss(AepytPH2Oq==f6Hpf*~5OPxZ-|-=PT# znUZQ6nv|^7YKcr7l+YzcuYd8ZGPi5fGsyhJIp>@cn~kbhz{VQm@k?sn3of`IcI7VS zpL_1PZTaW&jB1QM$&(wE`VHMTo)ly#X(cJ7IPbjkyzMlT2VaCGE?|{3{9D!lM-4cz zd1-`n9WlBrslkxKlZ;ydOY@1LOdo_%Bbs~t8n+&+F1wS4f8#K(%jN;n9VM(=E7g4% zATlq4QmEpVdC;e*YoQ-Rpf*G4{KnY{m~J@+ZFsaUyRn6|!7gfrE_ng_mh{!&!a7Hc z5ddhqQ262`Zt+}PxIy00=V7^e*8i#$Hkv4|nS$+E*DTRTARd}RgU+{*eiSjlCkgvO zFswN22$-fv zJ}rg`{<_3?gL>g~z-J|Rw$~{Tpq5}_F>A9aMbuNgxP_7Z1i*%VHy1c=zq<2d*Ul_B z0V((~82e4V0ZRmvVf-hL+VC`B^r68?i^)vVb`nJj-p9Rj;qBVx!hR5=75$4kKPUy0 z=2IO4IY`@)qe^1dk>85a9HsMZ#25hWJfxUAcW!rRlVMoIb);zqA#|Gg@18VS+4bD} z133mAc?!liGW5$q!kURSn-n1)tnOvmf%SNK80_+Ilu5{!XB2BwGmXRn&w%nPr zfFQ7^5hG_opwP08C{5D^GB8{kMTjU9@Xrt{;Tctmn@1oHY{^o~M5Sx)of$@qoTY$* znlwb|mY}#AAZJotLY;KdNgbMCkTGe+Yu ziT*>Xh!Z?PFybU`lTs0wZp6reuUn=O71WU;X|^~je4IOR8ad(+D&$?47}ojDh-Fd} z>eN$DEpeTjkGyTq_QMn()7 zB?=q;p$S#=$r%)UI^0RMRK_fr_jm-Xj}ebg_**)`9Gw&F1hapFwtvex((M(!Xy0y&85pOyR3T#u4~q$51q~@ixJbzlcbBS(;evzcg zb(>N{j=^BrA9Ri)F7={n3euoPD{IMlTppVGj^WzPO*Ovlb{93=OOwx+z3vV9W}6`f zN1&T{hycyCq!T)l%yxaBqDYpMUQ6D;L?6S5;qlkxFf)Evoc>0Zr63TBecEV|0|FjH zRitTMVpvnENJtBgi$ZOac?E--99_35WyDAZ%6tqL0-LQVmGgtsv|;kCe?~egI{x#I zj*eQ>CJG?G+^vt1^?N`F+WdKjQVGkdT+Vv6c7ImnEA{`94cBJCn{BKdO_PTdE*Zi? zEEBI0us%lG&%+*!q7FPr+x$vvn-Bit7FPOTUq&0c#CSSmprQ1hc5io^!HHXI)v|e# zr|Eo;xA|ihkvBToMK14-D`0u;#Xh#%a#SXVFmujr(aYc2w;uM}Bjl&dr7?Li86ey^ zeT;_(h+rs!(rGSAn2Bcpc9B9e@60pL>`nqg5bUKd`PSDYerG3qaIG(O)aj2FI=FnP`@#NBz7o%|B|5B1gd7s$y3&x%{^13Kt&TPCu>m zs?O?sN)LOtD08)E1riK$x_H_Q#GO{cl67j3GMYJc{$58~Y;yX03Qo|JLaaIU8V-g1 zrNFwA1q+L`FCv;sNvD+*SzGia-`2-27mOGse%`R-_=`%8njmSUjQ&i^MvIDqFD{-* z#2AnBY47qOKvRaTsYTZu)D*;ACj5_}TVpUPg;*csH5@YkW#0oMG)a3U=yPyT8y#{+rm_lQ zAy=B^C^Vt0w#bU`g#Sszctp-WmA-A_wcVsbfX*%ZC04FnnMe)_HAAZu@Oks*btmEC z`T#5);h3KF>({3u1O~fptk&sH_4)ceJtv1JaO~C?8lKXK?Y8gg`B)rHvLQg>h8%RZ z(+C9NXnz#xpYx!ZMCUq>U`HI;^29krVeWtn_qu2=92woUwg$RriQ9!s)Dhw1_{6UboHBG^ElI|e{ zBuz>?DV{vjsht zy`>KU$(aAhnto`6IUVB$3CLR=WX+kCuwY|B$9`hCenunbGko7(86*~yf)pl45Qb;n zY&NwFLK6=4^6`CA z`#Wjxf{%If#ilsy=mRBT?@K;H?07+Ll=(?Ag&3+*UXhQ< zp-Gr~lbLWsLd*KJFuz(*NT>WM>CCYAzPl}7zI<#SBh#7M) zaYM8u!n_JI?+ulo$nLj?)fl0~Ad@1;MY^2Aeba;;ZfQ>qSJ^iU`zp?2@BK&HJ&8T;w-pmfpCl2;7`uNR0VeTSVqeASim#_y+TFDx z#ffpTry<6Hir^k;qTjfLe0WFg!DJQ78;l_7zKC1d%R$r)uO(cD+0#8w#JJBngk4h= zcGVi|6!^%n2%74~YE}r6WoWXgdCh9K8^UI(d&3t8hGqRGkz!HUi=bOtVi3`5M_L3! z+r1&sJOmbs7-LChry>TCsMer4H7_Ybdv6GMjKJL@#UW|zOB${X#&JRL!R`%#1|o1_ zTAQ=f82qpdL$|ZjMsEHL0gn*i2a*_~<%eMsC3TI_i!e3g5>qx0hCsCltWHY`%t~Ej z;932QH|fH@@KK&k41tCqz}d_Ph!`)YwKsK*L4>`CKb1Ce^JfTng21U+NP*3nh(Q1) zaEmV2a&KY?Gynl+xyQ2FnW-t|B3F}YmhLx5cXn=eH3U3FfU^teaI@(ylVq+jh`pE4 z=Q5>ao(+NO5%^plQebAT8iRnUH6Rtkx7HB{5EI`JxK{=pEMmNx$FN*A1_|{Nw2pWl z)GbUE2+-lqMGB0|O$-7nVLIYhaBpG=c!at4TFO_xDTpac*`s z1ZqTJTxq{o#Q51DHVjl_kgyEctP7hya#vf#V`2ytfBub*J=T=Vn(!ph5(`qqIICVsw9XbpiCX3GWLT4C2r!BFhbmh%)k~97iGkJ10G;u_DlG>V@vtHAmnu_*ceeXMET!|^p9s(D zkbg~=kB7Z8H$xyL0#}F>C#Uo~khdy{!HMbrD*eDf7F*z9Mc`&-{3sFQl_~(Jj2L7_ zwFX;Zzbid}XA?spB?1q~-=QK!Wk0iBDKP*+qF)&OSXX(fy=`}o?7y?3o zvT$6lY}5uwt;8VL0^nuoM|68>Z75j6z94WZWkH(iMDj9?uALYza{^9sijGRy*Fmplomk)Ia!?9q)(%I3mY8bzzOwdw4c! zEduPP_^?RvxNkZ1rYRK!MnFBL=Yyn|2i@(yRR~9(y{6Sy<+el6 z-R>KUfR|0Del)!&1_p~9Y>~ZMYE3HuX|8zNbn1uH%cfMnk*aRLFE?vi^#jwaXRn)1 z{ZKZd#t0g%+T&d2jAI!EeP-pKC16>M3YGYa*ZYi8PEsVCS~E-Z0X-hIYq*xS_HuS@1(Q! zEf_s)yfnHg6^6c=R}kcEDZknA#xOtTRu}@D0C=VJd=Y{lnQx7>ju`ICh#>pu{xi}) zmQHu>b}a;fmlVs_r00ncPZbiQXOXm)7!GFxtpMg9rjCmP;YY+nl>yQy~BeR!c7uAs|QVWoU@uzN84UlkPtu{j7ABbGK_K z0yLA@BXh9`LGx*7Wax+y{IVhmv*$~tCrOzTG3j(376^2xuM`=c99BSvni#>4E|SdE zGX!ByWRKvxA-Lb9JTl}B8P*R$eiO53#OQ-a1ldkbAC&%)^jK+IN3>`f{j-$XVVwx^ zimoO-1dJFlML{Itm!X(hKfI@`@ZDb8MA<5%?~>jwy+eAZ$go9MlMn=q7$KlUIf*Ec zf+m+E%AvY{OO*eb-G8q1|6K|RAj3T(0uyp3DG)GXqyQ<(i--b#Bht|jt*W2$6Qxau zxnIXcghGDvT5%7Z7%@uvhi#gNhr! mX+1852pd%RaWg3xf&T}6i~Sqo1LoNP0000nh=E0B!cu_6e&`q_t1L@O^Oge1O%l?Q+kym zMnyn+3sMyUv4HaU-pqS{?Csv(?%d7p?C#Ak(a=DP2?B=z001VuHtzO0A3djGF#Y*z zb~5gN&S)Oq*1`f_Oz>`ls%&0Kn#s$6<^EY4)rcGx#*w!)RpH(5hG9&>3wV?J^)-96xe}pkt1q1sSR~ z)>c4uAhK1V;$*{UOj%qu2UjVZ9QjmEv)T?z$e zckeBY7v@i2`*`i)gHH>^Tlrfd-?mie77n-M%dX(riM_qOop#HSaa}xH4=C2~S55ck z*7u0Yqq-DRjU#s66D40h-@ODD!D05F1c&L|7rfZh1zSh$a`am(=<-M@Q9Ho{CF?jSD3yXR!;u+X9M zlL|V)f6S|D0;;V%LpzfF8GTjX96Z^Xm_4Y2;b<_I=Rbuh8}!;f|hRgrm4@qi_W8F-J* z{$Jta&qoqDNod5#FyQlbLsi<$_4poJyFb1e)WuV)dbgkpuLr3{aBw5@(Ot9d3!vxUml52!b;JV{WZ*d0@W9r#826) zZ6Cp=JT~*wczwIHXfi@*#f}By6{GU!>yvwE(P^DyP5#NvmIWVGAlg2%ePI_xNi)v_ z@^l;*RHv%k@=oEa$yqoWmvXXc|Hrw~*UaC|l$>#qexXX+r=nAx$uu|QkAQ|9NNN=CWUe@T0Hb)AA|SZO*#@U9WGZx z6DC}6^Mye@(|n@bRV7m?<)Oz22;es?bT!oJ$*{bK2@g$6tm@0uEbB;QKp7yRjt1QI z-EuR4XjL^1`_m)mO*;$j78$+c^SB%k8JkeNl&T%0E(VeuE~56C2v_(i%a=u>)HDq% zE7>27N(cc>qs46}1RKW_&y&wbv|(1cnjY!gv=5$702|QSFTRl>DQ}>YS;*QXXNkPA zDG~6O3+D0JA_PjIRTALc_zmsPVthbbjO8oDSd|P{FU-=^O2AWU$0$3HA7s;W zOhk;SsRT{Q8RcJ#MDgDJE-#0Jx!tLVvOw%h@^-hsKei}>pLvPmh&)U22lAJMun1ky z-CnM_V!sB}BVc)YOkRN5Ph&a=aT6R$uOS^i?WA7|qeCeIidBFMp95 zml|tRBkmuH)t;9jHxp|*R#;xX!U~xo0;H{%V{-c4%2Xrw1#Q}o%pAD+yy_wkSPz4A z&oUW+oJVc{uf)GAi8yduOwWCnLKQh)*N{y*Emg3Vf>cl;Q@n8;v_7SWBYQd#$yG_0 zICwMtK*Nj^4>Ki7>TwgVqR*22Jzi>N-)xnuu@?62glcmW``?@Vc6i``S3ZiemlSED zv1k)IWi78@OilrqQc9ALGj8}OmrAYni}ac#RMk#_GISa8=P(OyFj-EP{|&wP?~+A= z&`DNQ`HoIJpu0(pt#kBQTjt=`^AOwgvm4_`Z7w^f9V~W*`bU~h?qxj`Zp!^2E%6g9 z0tvi4q;^u=Ha!Fn?(N~1-e)s@nAN7e6PgDNWSP(#g6`T99w*I}7sW?ulBzbhl}%Z= zE(~|E47a~gfdsR5v2^givgD<`qa0ut`E4ynYbb@=XlHX1eM{Z*=79|9FQsN*e=Qew zuQxsjt&h47+}e0s=q6@TTlM4T&uN>`%+6rNSf{P+?PqTv5t2L)eu>$JYJERIH?vo3 zVLW9Zu__nX387UFX6j4jBL1Du=1PQCRKaDON3&-;f(~6BhY#`}mQpY8hr@z%o3 zxS@qS#KA5X+(9uQmnjF0W4}7u_Zv9{HWOi*x@BbfmCkzxtLLpfSKRz|b@2d?>KXp% z$B&?iG zC{bE=0iXSh@r!efX`LkPMTrP9Ivc%7N~3{%lc0sQIL@?rm+uKMn%m&LX1d=`(e5C! z(QVI!_jUN7Kq{6jEMBBu7HJ2X-rEpw%}5t5m-~$FdSqaFHH= zV-V=Rgb!1dSs3~pDG={XvhbVMr#K9!EDLA$s!A-m=UiKWkf!xGQ_(-5ji9NyAgmSK zSz%r}$_k{@jP&T*`s1q~!d5hIO;M+|KwUVAPmR*-J(@o;L4L28~q>yW9X<-1o9l59B@vP~!&EnUhV} zzNNZi_or>K{;;15t^V&dIdfLB7L>PFS-HYjHl`CW@TJ9a#G&2px7>KG#`~9PGM{+p zwZ|=Bo@VdiFhk;5)h}nj38<-U&s-5a?y7b+iXC5TvMz2^kcTcP;WCC4v+KkFmCMWa^!I0~6v?1MRECaow}MBgjm*G#`FxU#Wkfez_MC+jNe10rKehEf$2-1^_`-Owa==`1{5=$mZ$S$5!DF)3Nf7vvx z=KMMNQ{y;`IhufuHr&|ad}dpEq&6vtZ;vT$w{Jw*G-@3?4;yBI;(e+SK8`Tkq}ude zA8*V}K|#A@)N`9BDZ7Tv21VoinmF%{4<4BV-=(en>kP6PBty*nmT)j(iyqK1I@oV8 z@fFwC7;PEetRkPAndovK8ObK(`Q^xErwDD_2>;;}hbC!?%QqS*EKlj%1IzSA`#a-W@(P@nA|Q%D>)hW)~z6KskIvCJlDlQZMK`}P_f&79L31R4q4yiM!_7Sr#Sy7r2WAmc zaqrhXCTXG=hDV9zmO&wHlUcu|GlCcuHszsN{}NmtshnNa;8^VP_fFXS+1hvV=?Vnz zGw(f2wKzj14+Mcm)$#+nAnSH4&?;8yZ-GG3%dzTdVC8pT&^r%()t|j^y;FsjHVkKzsFM{JKX=uK*+e@|WUgZ`l=$q><{nEzaL)9STKYwONFT}C26 zr{KxTD{<(8%3mw@8%hRgM>r%EyxV{Z3Fy6-FUi7x_Oi_f+$!}8O>nJizm#LpJ8M?e z58ax%uic#-O64)VkKP#1XZ_W#o*2oEWn=1uO^SDmajOLTMu{ayFmzLPx3@*Z5zht9 z-WiSaI`g&II>e!F0Qva%etg@mxtVKHa#c%<^81?nO4@XAu(>eApS~eX?HcMk6k*OG zWn-nZnjomN^g09a@XN$=3A1`KL_<<8Cj2A(S3zfH&WytBE;==>XQsi?ZDC=-k1BRJ z*~oB)l%7Z$(P6DCL0_@Gj|Bz3ehF;VV=Xgk8#95YzvYcRiHLM9cE})D_<@Rhvz=0D z?3D@r*q2qSB3ex15D&H^IiIOz#f}**B)3JlBI&9J@x6r1s>|{qQ z83b0Ib=e`7#=t7PKQROArf86cmp~jX5J3pxfhN+bq%EWGTSqb~I85kp_7AIgV`{w4 z`83pB6&Pg1>U#e|OfQKhZK~8+xo*EsmE(5}#cjSH!p#4jWhs28{xiv^%k9h2@$r;N zt=UR}rN$`|-xnSc{$^yhA-3ls+U2qvuGADUW|}F!>dz7@R=)oeW_|J&cd5CpkKqnU z5qPLh5-T@Loh+|MK%Lo0-Rg{=YozHDq5FuQMJF|=bB(Z+R}+zd8`zG zrZ^#nwUqhteWxQ)CBY!rE9Rd!7|aGHvLo=ORuNe+Du8Qslq9$YpZtwQXn}0v_h>QMGt3l6 zrcS*`>4B2O1YgUyR^`TEg~*;9yf(I*^#{7ckTs+XAp!+92=6b>zDL zo?S6^U>ed3^WoeottEubh%3(S6yEr9X}VA$hXX>ijYc(j1iELTU-y+>rzFbp8gXOE z`XG9*zrIjvj@($a?cywm5W*PkXqA9%O<{;b z-2zQuE!RE&nz6cRNY!Z-)CIn$_z!`tm`O)7E%_V-S=$C{BT*>`uqaQDmhg{{x~}lW zj4znG-z%FH{nqp%LZ?Z+XI!^7D`uh+%f@lB(W}cx{3v2R4@_iZvExzV_n6r37})W2 z#g(!sgkK;TmCm(Eu>eI7JuQBa*;!8`bVx{MH7wQy3W!i$9h;MI)d0_E+DXouEsGwt z=v5f7-AGc;MYL0LKZLO2)qW~L+bPAagGV~_c1qm;K@jVFGfZODN6Zw(RB#u`_pq^YwT zMcHEGO1iMVJz2sg0wAl=;OUU3MwJk`0Q^zPf!)ILDalVBXzU(Q#=g0)1&!TacSCPn zs5Cp7U~WG3y0KIq$Tt*Gd{SRm`sn<}>A~qxMU8JZ#FZZMCSlSCHZT;eN5Uc?U~Nsb zVL+(r>Z##ay30y}0}wEiZXa^vNOqI)if#2naQ%ZW0QKN$Z4*|fbOVh6JAQ3sObcTS zmh-J7A7+<`0Ij&G!xUZh4AX1PMNtj6p@Yl7zWr8 zOsVNLakHxwbA_Q2t*-9Rile&hG!FknrZD;1*a4kS<-ZC6!H@bg0#uJa{&SpdP3rM9 zgmZ=j_PADGVmEOu<0`^DVzxVhZSuNQ2NPHwFKx-qSkeEL10M|Y?%s24gyF6x$Zbg5 z4u{Jh?VV3AanLVZC+Dkr_x>7bHc?GBS`fHNzNP)jBxh;4Ue^ahP|ND(J2Im>G~D=( zNHvO}#}qBi8|R0;MLd}MyHHAMg)WEqhf!?RPcYC+t)e11SCU$XFz`!*zXnR4tgLrG zQ+a!L;GY@*CIJXN1%BA4*>FeW4;frOUv@ZHSza(CIdZ?jG-@k@6VUw9 z1s+kduLaJaXxqF}e#io?g;Nm2gxbZhs!Ua&58J=3paOP*GL$;!`U(#qPF8P;+3!co zwJ+@H8cbLDfg)4(w*QNf(VJl^qZF(L+Usz`( zw3aauj|b%9eTr!5s=24U0|!Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91b)W+P1ONa40RR91bpQYW0OHItO#lEFWJyFpRCodHoe8uR#hJ&8ecxpB zfh;OK1Oa7ddn;0_22znenStLYp=7e+ROfaKSlc?uRhMXBSamY9mG#MesIKxB{ zR2DHV3@Qo;JQQUWWK}>mS?2#Mx|_PqefQn_ZufonzIVTK>Q;4icUATGzg=DR)%Sf> z#}qi7K7G2q9-)^LdMMpSp@kQkdvR06hZPPg9P(n)`xQP?DEC91I(2p{U9eQAkXkMP z8>+p-6|VL|f5iY8H39T0g(Y5iOF$owx{|oc%X?4-WT_th28C-B$`p9xa!tJ9uPZE8 zcuoLs$aMoUsV^@<6_9Q95R(*cQy7-&fsPzMVLsh=*nGP8klDWPOT}NBFAg6!}m&9K-Se$)4krKFd)o<6Q@p_cRt!>{%^x) z7RbFZfEcbbeB4$b1Mtw&j%HAg4yJzHq-0{29+ z3*yeJ7ElG~C_UKY3QR=;I;QX5ODngUg)6t19r`}zJC*1=JZ3;wGkQQ5(@5Xz5Utno zGy%IPlpp(HPC*rzC3>Qn3X|O@JACYfdGVdi=J^$y%mEE@3XNK7ur*;wcQbBKH`BBc z9Z&+z(b05)yCWet#)F)IDlqvQ->vYV0zv^xfcZafeQXxIyTyEYG=I8SzkQj;%^Ei_ zV+VFM-yD8X7+i!L_bEIoa8G7hZl>4A4ypj{qDJv=y~1tWvJXBrvlp#5pMQDG&8`vY z*3BB3+eckuMqJt{{5)?cW3qtV8a@%_ajc*U&Clw1ear=#|2ni!>DvYD^G;r*$yh)Ym<`lQMu5{5Y#pagpEh%reQ4$_|HPa)S*;`f zNEujJVfE|PH4}$jXeN*7Y3kMq*nL{}F}9c?a3lZj1hrJwxOC48(000ZoXhVO6Dq@kHMp`RHn0fs~6N{MmC3luujA_;=b@0YB% z-7UvOI?DmN<6E!3MBQUFux)DZiIe*Wcg^Ru}t%%;x{Wc$3e=Kk&-Tbg?(4Kb~o z1&dO=u_LnSimME&0A)}_S7E=Q0Q!@s-!eP*=fBK0-~KV@w`pd6@i)U=VEM+D3E0h5 zX=~7-XL7RuW!l0h*8)nH%Ntq*G!rhKy%xT~Kltbod|l}A+0RQm&KOix)Ig;(54F=4 z21R^Bi(PKoJWqNd{DY71(-hFqUQkeaU^jb!SC4~|NXp_aay3NK-NQ9KC`PW$Z{WhVRg!aizl<=0HRg+ z>=AsQe|0Di-FkH7&uQc_A# z^{*JEy8|ULG!|;p0(VNz<>(~*hVKqd_Hc2s5|ihszWJwhBj-@#w1iGkKF&vn_v$Fk zf{RSI4lRY%s2G57Yc!c^R|KyIGsZkapfNW%K6fq&!wU@;uEw1 zDhhP7Bl~qWSN371l|7A@R(+o?R;H4DVKJ8g4&dQXfRmGVM&##a=#?I)W6bjmwk=bC zy)<@Hh!!$By77vO&ETFLO#4<%Ouf1l{ny-<<~Gd$>$A^~Sn(a*p!3G$v>|*hp15Xn=M#7(fST}1=q<&98-rg~IkK&^XNrG0p$sIJ8O&lhoy@hv{n?pKHPx`vZXs_;>_f z;1*CA)Z6?s82rXb%rV>QA79ASp>*FA1Q>F#nJz!j`SNGdZqpBS{2_qveY`jdhe4xrc1l#=C*4t$=l}# zuWK(y(bLjMetl5;+bsRy8m>?YS@n`t+sq27ukO^S^^`t{9a=XrgD&o1MqPG+!Fx(N z)UbX%3uMCNFP$5!;hGR$7RUPfxVBeYtkoJ08sqTwmy2iRANwzVe&6grbS$B|U0)nA zYc}sQe|mGHnL4(w`KwFLPdH!b2jB&6Na#duz?0Fh)ovgMZ=8il%-0^Av*H{;-DhE- z^UMEUY2Rcwzb2$Zxb;c|^{m!f!8|K(<{A5wK)RB$?N2QDz--$SXy>K8wop#u7T2Lf zQ1O>rX!NHyHrnnd-FBm$H}|y!UD|YS&D-ljxLHtp`mMzQav>4g>s66aGmv6XRZ}R0 zTTi;*z`rRTtqX~;HL1!XKEi~}yABl6qo!aJD=T z;nt#{LB*kRRS8E`HHA`xdaSU%GbpK{w3aEMTH2+3^Gt8c+v|@c;+FWPqA^!UghF;z zgb9PB?B-3@3+ZtyY-TKl8?(v6+Ve~0@cz?^n~ikcN`u)YZ8TUYr;1*5F@c~ zOQ8{ZPIq75-}UpC@)7PBbE)atJ{TLOytYtIhHyI!sDU^l?k)-K`{oj=^R`4u!{z7i z$2Sg2X%~ZUdwc;pD;iNYAtK?Q5Wz|Kl>5Ey<< zuE%eZ{R`f`;&7tHeld?v9bsO1@9Zj#k#M4e22%rdZnT!CTI9eOYV4q{R*xCwbpB|l z#{7pgCqDf2i#S+o%M9Um$OqM)3?Uv#Bd}AMI_^@_*>O1zuyK%Y@Kl{fPZ%+wH`Gdg z^r6zuZOqSa9d4d{d9Br~kK?&RxE-YXIYi(yRq!zSehTg&4L=NinEzrR5a;pJ+$LP@4(pU zdUgt=vXQkngxh}J z)Q|kq*_|*7V)MIiUC|>bYU`eZ<{y6drtO0Ed5hSGk9`%KFXTk3=fJb-LsB*M7abTN z{`K(aHTpxieFUgMU&wZoQ4khc{s?!=?t|tZpI&Z03Hbotxj&dmMNwt7l~LJqu*&<} zg&&xco;H02`@?0`{t#~E381onXcWZYz^DJ>+md8=D3-r!0;TgD=sfwmm(-8J_BMoD z2-J%A3C)QAZo8emSQ5&>uVG~-4GA~o;Q{Th%s(R*@jsMxoX>}~F(~%2k*`DLs>^Pw zZU;+@qN31mUB5LLd)e)=k{J{q)gtw;=daOJGCegEr_p(lq}{Zi=ctHKFMZ&ap=Q8E z==K?P!KVzG8c`B>IiuhG;7RujtvVCQdxr)&+0t`wejI#5FogQ2?_3eyi^W!fCH4c) ztdL{HBiUA&)B9;J?XJj@oDGG(^Yz~5pTAdT*ks73CtqG?HtvX42ob`|;%Mb{`q$mB zihoMwFTc0dJn`Zhl3CGpgS(mUUfU<3j1RW#Gk;iGZpzOZ%-Zva@Yu-^u^NAZbbTTv z6dv;d>Mx(EyX702%;y6GLv}-EKUJh#{y>ptF~ylBg*O~rMNLy>xb28O@7J69fDh^j zRrV?sVw*AT-)u7L`ca_1V{{+WKm!Gra4o)g^>*``95(32S z`>CZC+Aq7XtsIbaGy^Ygr>#iNUE9SkGGaph5OL6BKe)=>GyN)oy37X^sRJKE`^BB| z*pkSMq}Y*gss;+7Zo)nv-Kdfb9auDalt z6kSXD(dSp0rFxU1q(ME}TemvybSGRshQ8}G$YM@Q;EmpW){$}e@}$RX-ZR8AaAI!w zoB6BFl1iSXVg0&RR*O3uq%#BtcO{Zhmk7vCGA#CGxk)SaGHLH$*6uKi-rr^pDy&J z>^7KHHGrmVIIUbMQQ*6>IuDzCgzJm?*yWST20u&gn_8+ID_z2u!1w-jQ6P}^u8lNe z-qyQI8#}n@FV{6aI<*Sq#FoF*|&2}K|Ol>q+QW)S2Y-%bkzjDtGtXc)nQ=3 z9FUkvccu;}89cd!G^jF(kb8YTrNPG`a0@65>Rg@ql|n-V&m|J@$LSy|Xhj7Hy43ZW z(-M*qo8Ivq27JDY&4@jz7;BfVk3;5`HAR6NT%3gg%qqYwpaf9$3hz}HJYQ$O$rVhb zf468|aB;pRSlS}ER9_R-d*m9=1(bE%nzS$vE)LBHH|IF;`QYZw@()H2=#o;I%fBw4 zVx(A?UDz&Y(kt(8wd=S+Mu8`oc7cmS0bYKdFZ=b6wM1myjIJaDaovO=-Gg(5kZ_0j z%jAmh2?^b65`l*!MqTOQmGFq?fa;xn$iE8dOuD`j{Clc1=G)0gb+LRuAVkSlLRFp5 z60RE@z{8;cCnqm)O5>l_sP3T9mNHK8${=#RE;QM3`2S2aEI4w}Q zTLo@abi0BT(hQcyT=Dw~XQC(g3V%I<-?w}G_w!Q5X@g2BD)@OtGyM{8z4{U}Ojg`Q zijD*D6TUh$)8o67l{%TA`H=e3GiN12L=SSQ!WHD8IrpzI3!nNrfWZeC_g{mv= ztK-)cta&tA2tS*$hbAUG#KvB){2&MWF0<_8t!C8SyBLwV~ie6H%s(|~` z;Q*st{5m<`P~On%vjvo@A_0|xysmhGl2&&St@+kNAd; z&8Exs3nD&SteacKw1DlVTNf(y@{7Rg>#-MBOFi?rpH*vPM1Rv{2EsPo4l&AQP_)^} z%PJWusI)}Dwo^1u!OmmJ!v<#Ny!T9b45smvUkHS79$Bs<`lH#*Lz%WPn~01e2bGoy z*anIoR$!UP)`0~Y_AGSAY)(*Hi1kpqTUJ{f;XI;0By%$aXhwpCbodqvsD8x)cY@Nh z70&bXwrRVKSqs+IiqSEnTNb#T^-$P=a2{DM1It(_R#0iNfJO5d?TMf}CLdGz*^Ac4 zZtYE7xh9mv&?yS3pwJAuTUJ|G9Epu$2bGo!So{Ort?-~i;B1#UEqb~*X~fpE&(7~c@>pmrplI-@0A(37R>}#e{u2n?5~cZ;ur?bI;Ld+%vw2~~rpSFj1eL^? zz!c)TA>GY*DO!iXq*i*V=>iiClAKUZLG_a^)4~khdSnjLA#YebDoj^GXfMf+niIif$Bf0z-6WA28DYR2Kf1YjH?26UBt@@ z+i6zE*4h|3<0A>iSdN*-3~xCjEszM7VlB>Mhyi$qL@J?|_5`J#KGI@5Uts?P|4+g9mG z3b!c?^YfF%Sh%r&DBDf4J0Y9d;j@8!8?+G*jy~At18<&Jkz@J9#r>%1TbCla0LJ!snB2HtVc&3L_{outx{O30FZA9NV?jBpn?K5 z8Ak;)epi_q`Jt!Mtm`7=a083@M-&hQxB&ohu*4L^1_8KR>4K&I2m8+~Wa9pEW&i*H M07*qoM6N<$f_}5^H~;_u diff --git a/android/app/src/main/res/drawable/flip_enabled.png b/android/app/src/main/res/drawable/flip_enabled.png deleted file mode 100644 index 152dc10e559c1d207f693225258f9a4ca77723f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6753 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 diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml deleted file mode 100644 index 29df8da2..00000000 --- a/android/app/src/main/res/drawable/ic_mini.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/android/app/src/main/res/drawable/mic_disabled.png b/android/app/src/main/res/drawable/mic_disabled.png index 3603df754eb3df74c1cf7730a90df21bfa5f7337..266cb6c72418b5aba18b32c421c2b4e75f05e47e 100644 GIT binary patch literal 6537 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 VdluGjNo@cC002ovPDHLkV1l9-OF94m diff --git a/android/app/src/main/res/drawable/mic_enabled.png b/android/app/src/main/res/drawable/mic_enabled.png index 5d9aa6770cc43554a3767cf6b1c45fd3a8851410..ef7617f7ac43e7d7f55f48bcc1df718661b48f00 100644 GIT binary patch literal 5904 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 Bb}|3} diff --git a/android/app/src/main/res/drawable/reducing.png b/android/app/src/main/res/drawable/reducing.png new file mode 100644 index 0000000000000000000000000000000000000000..59f2c9e6faa03d35596a52689b19f99db9e09036 GIT binary patch literal 4953 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 PzPNO?j5Ob>+lTxQOg$37 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/video_disanabled.png b/android/app/src/main/res/drawable/video_disanabled.png index 5c20c7bdecf06cb8401b40b1a27bce46cf35c4a9..d6ccbe7ad12d75da1c17e054c8af03e00273c8ef 100644 GIT binary patch literal 6438 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 diff --git a/android/app/src/main/res/drawable/video_enabled.png b/android/app/src/main/res/drawable/video_enabled.png index 23331e3083cbd75a5c17e37bbdd3e89a291141f7..6fcbe75041fb80538006600a8620f7081c215d2d 100644 GIT binary patch literal 5715 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 Becu28 literal 5338 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 he`HdmC}gyD$L5b3dLYnWBmD1P5u&cAR- @@ -89,18 +90,6 @@ android:src="@drawable/video_off_fill" /> - - @@ -152,6 +141,17 @@ app:layout_constraintStart_toEndOf="@id/btn_camera" app:layout_constraintTop_toTopOf="parent" /> + + diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 2a4d695f..0694f5f4 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -29,7 +29,7 @@ 14sp 16sp - 24sp + 22sp 4dp From 259a63384e658cbaf18a722c57f9d234e2b363b9 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 09:53:28 +0300 Subject: [PATCH 186/241] fix draggable bugs --- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 5 +- .../hmgDr/ui/fragment/VideoCallFragment.kt | 68 ++++++++++-------- ...ideo_disanabled.png => video_disabled.png} | Bin lib/config/config.dart | 4 +- 4 files changed, 42 insertions(+), 35 deletions(-) rename android/app/src/main/res/drawable/{video_disanabled.png => video_disabled.png} (100%) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java index daf372ed..75590b76 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java @@ -20,7 +20,6 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; -import android.widget.Toast; import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; import com.hmg.hmgDr.Model.GetSessionStatusModel; @@ -63,7 +62,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi private Runnable mVolRunnable, mConnectedRunnable; private FrameLayout mPublisherViewContainer; - private RelativeLayout mSubscriberViewContainer; + private FrameLayout mSubscriberViewContainer; private RelativeLayout controlPanel; private String apiKey; @@ -432,7 +431,7 @@ public class VideoCallActivity extends AppCompatActivity implements EasyPermissi if (mPublisher != null) { isCameraClicked = !isCameraClicked; mPublisher.setPublishVideo(!isCameraClicked); - int res = isCameraClicked ? R.drawable.video_disanabled : R.drawable.video_enabled; + int res = isCameraClicked ? R.drawable.video_disabled : R.drawable.video_enabled; mCameraBtn.setImageResource(res); } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index e0a92206..95f54ca8 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -17,6 +17,7 @@ import android.widget.* import androidx.annotation.Nullable import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel @@ -97,8 +98,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var isConnected = false private var sessionStatusModel: GetSessionStatusModel? = null - private var videoCallResponseListener: VideoCallResponseListener? =null - + private var videoCallResponseListener: VideoCallResponseListener? = null + private lateinit var mDetector: GestureDetectorCompat override fun onCreate(savedInstanceState: Bundle?) { requireActivity().setTheme(R.style.AppTheme) @@ -144,12 +145,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - fun setCallListener(videoCallResponseListener: VideoCallResponseListener){ + fun setCallListener(videoCallResponseListener: VideoCallResponseListener) { this.videoCallResponseListener = videoCallResponseListener } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + savedInstanceState: Bundle?): View { parentView = inflater.inflate(R.layout.activity_video_call, container, false) @@ -166,10 +167,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session requestPermissions() handleDragDialog() + mDetector = GestureDetectorCompat(context, MyGestureListener { showControlPanelTemporarily() }) return parentView } + override fun onPause() { super.onPause() if (mSession == null) { @@ -258,18 +261,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session hiddenButtons() checkClientConnected() - mSubscriberViewContainer.setOnClickListener { - controlPanel!!.visibility = View.VISIBLE - mVolHandler!!.removeCallbacks(mVolRunnable!!) - mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) - } - -// mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? -> -// controlPanel!!.visibility = View.VISIBLE -// mVolHandler!!.removeCallbacks(mVolRunnable!!) -// mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) -// true -// } if (appLang == "ar") { progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL } @@ -474,7 +465,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } - private fun onMinimizedClicked(view: View?) { + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( 400, @@ -494,10 +485,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun setViewsVisibility() { - val iconSize : Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() - val iconSizeSmall : Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() - val btnMinimizeLayoutParam : ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams - val mCallBtnLayoutParam : ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + val iconSize: Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall: Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams // val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() // val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() @@ -512,7 +503,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() - val remotePreviewLayoutParam : FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + val remotePreviewLayoutParam: FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams val constraintSet = ConstraintSet() //layoutParam.constrain @@ -574,7 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (mPublisher != null) { isCameraClicked = !isCameraClicked mPublisher!!.publishVideo = !isCameraClicked - val res = if (isCameraClicked) R.drawable.video_disanabled else R.drawable.video_enabled + val res = if (isCameraClicked) R.drawable.video_disabled else R.drawable.video_enabled mCameraBtn!!.setImageResource(res) } } @@ -604,12 +595,13 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session getWindowManagerDefaultDisplay() videoCallContainer.setOnTouchListener(dragListener) -// mSubscriberViewContainer.setOnTouchListener(dragListener) + mSubscriberViewContainer.setOnTouchListener(dragListener) } @SuppressLint("ClickableViewAccessibility") - val dragListener : View.OnTouchListener = View.OnTouchListener{ _, event -> - //Get Floating widget view params + val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> + mDetector.onTouchEvent(event) + //Get Floating widget view params val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes //get the touch location coordinates @@ -636,11 +628,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val barHeight: Int = getStatusBarHeight() if (y_cord_Destination < 0) { // y_cord_Destination = 0 - y_cord_Destination = - -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) +// y_cord_Destination = +// -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + y_cord_Destination = - (szWindow.y/2) } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { - y_cord_Destination = - szWindow.y - (videoCallContainer.height + barHeight) +// y_cord_Destination = szWindow.y - (videoCallContainer.height + barHeight) + y_cord_Destination = (szWindow.y/2) } layoutParams.y = y_cord_Destination @@ -662,6 +655,12 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session true } + private fun showControlPanelTemporarily() { + controlPanel!!.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + /* Reset position of Floating Widget view on dragging */ private fun resetPosition(x_cord_now: Int) { if (x_cord_now <= szWindow.x / 2) { @@ -741,6 +740,15 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ).toInt() } + private class MyGestureListener(val onTabCall: () -> Unit) : GestureDetector.SimpleOnGestureListener() { + + override fun onSingleTapConfirmed(event: MotionEvent): Boolean { + onTabCall() + return true + } + + } + companion object { @JvmStatic fun newInstance(args: Bundle) = diff --git a/android/app/src/main/res/drawable/video_disanabled.png b/android/app/src/main/res/drawable/video_disabled.png similarity index 100% rename from android/app/src/main/res/drawable/video_disanabled.png rename to android/app/src/main/res/drawable/video_disabled.png diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; From 1ed22e68e3f96b113d569abeeef5f441e5652ae1 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 10:13:58 +0300 Subject: [PATCH 187/241] video fix bugs --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 95f54ca8..f7f70e40 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -325,7 +325,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.i(TAG, "Session Connected") mPublisher = Publisher.Builder(requireContext()).build() mPublisher!!.setPublisherListener(this) - mPublisherViewContainer!!.addView(mPublisher!!.view) + mPublisherViewContainer.addView(mPublisher!!.view) if (mPublisher!!.getView() is GLSurfaceView) { (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) } @@ -490,42 +490,37 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams -// val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() -// val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() -// val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() + val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() + val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() + val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() // val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() // val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() // val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() // val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() // val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() // val localPreviewLayoutIconParam : FrameLayout.LayoutParams -// val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() val remotePreviewLayoutParam: FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams - val constraintSet = ConstraintSet() - //layoutParam.constrain -// constraintSet. if (isFullScreen) { layoutName.visibility = View.VISIBLE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE // mspeckerBtn.visibility = View.VISIBLE mMicBtn.visibility = View.VISIBLE - mPublisherViewContainer.visibility = View.VISIBLE -// layoutParam = ConstraintLayout.LayoutParams(iconSize, iconSize) btnMinimizeLayoutParam.width = iconSize btnMinimizeLayoutParam.height = iconSize mCallBtnLayoutParam.width = iconSize mCallBtnLayoutParam.height = iconSize // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) -// localPreviewLayoutParam.width = localPreviewIconSize -// localPreviewLayoutParam.height = localPreviewIconSize -// localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) + localPreviewLayoutParam.width = localPreviewWidth + localPreviewLayoutParam.height = localPreviewHeight + localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) remotePreviewLayoutParam.width = remotePreviewIconSize remotePreviewLayoutParam.height = remotePreviewIconSize @@ -535,7 +530,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSwitchCameraBtn.visibility = View.GONE // mspeckerBtn.visibility = View.GONE mMicBtn.visibility = View.GONE - mPublisherViewContainer.visibility = View.GONE +// mPublisherViewContainer.visibility = View.GONE +// mPublisherViewIcon.visibility = View.GONE // layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) btnMinimizeLayoutParam.width = iconSizeSmall @@ -543,6 +539,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mCallBtnLayoutParam.width = iconSizeSmall mCallBtnLayoutParam.height = iconSizeSmall + localPreviewLayoutParam.width = 0 + localPreviewLayoutParam.height = 0 + localPreviewLayoutParam.setMargins(0,localPreviewMargin / 2, localPreviewMargin/ 2, 0) // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) // localPreviewLayoutParam.width = localPreviewWidthSmall @@ -553,7 +552,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSizeSmall } -// mPublisherViewContainer.layoutParams = localPreviewLayoutParam + mPublisherViewContainer.layoutParams = localPreviewLayoutParam // mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam From 7c7aa781aa67e9d68f0e989f9d70e4f7f6b0763b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 11:12:48 +0300 Subject: [PATCH 188/241] video fix bugs --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 74 ++++++++++--------- .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 6 +- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index 9d9581fe..7ddc03e4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -20,6 +20,7 @@ import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, VideoCallResponseListener { private val CHANNEL = "Dr.cloudSolution/videoCall" + private lateinit var methodChannel: MethodChannel private var result: MethodChannel.Result? = null private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 @@ -29,15 +30,10 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(this) + methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) + methodChannel.setMethodCallHandler(this) } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - } - - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { this.result = result @@ -67,7 +63,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, "closeVideoCall" -> { dialogFragment?.onCallClicked() } - "onCallConnected"->{ + "onCallConnected" -> { } else -> { @@ -87,7 +83,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // intent.putExtra("sessionStatusModel", sessionStatusModel) // startActivityForResult(intent, LAUNCH_VIDEO) - if (dialogFragment == null){ + if (dialogFragment == null) { val arguments = Bundle() arguments.putString("apiKey", apiKey) arguments.putString("sessionId", sessionId) @@ -103,47 +99,47 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, it.isCancelable = true it.show(transaction, "dialog") } - } else if (!dialogFragment!!.isVisible){ + } else if (!dialogFragment!!.isVisible) { val transaction = supportFragmentManager.beginTransaction() dialogFragment!!.show(transaction, "dialog") } } - /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - var asd = ""; - if (requestCode == LAUNCH_VIDEO) { - if (resultCode == Activity.RESULT_OK) { - val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") - val callResponse : HashMap = HashMap() + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + var asd = ""; + if (requestCode == LAUNCH_VIDEO) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() - val sessionStatus : HashMap = HashMap() - val gson = GsonBuilder().serializeNulls().create() + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() - callResponse["callResponse"] = "CallNotRespond" - val jsonRes = gson.toJson(result) - callResponse["sessionStatus"] = jsonRes + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes - this.result?.success(callResponse) - } - if (resultCode == Activity.RESULT_CANCELED) { - val callResponse : HashMap = HashMap() - callResponse["callResponse"] = "CallEnd" + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) - } - } - }*/ + result?.success(callResponse) + } + } + }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { dialogFragment = null if (resultCode == Activity.RESULT_OK) { - val result : SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") - val callResponse : HashMap = HashMap() + val result: SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse: HashMap = HashMap() - val sessionStatus : HashMap = HashMap() + val sessionStatus: HashMap = HashMap() val gson = GsonBuilder().serializeNulls().create() callResponse["callResponse"] = "CallNotRespond" @@ -152,9 +148,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, this.result?.success(callResponse) } else if (resultCode == Activity.RESULT_CANCELED) { - val callResponse : HashMap = HashMap() + val callResponse: HashMap = HashMap() callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) } } @@ -164,5 +159,12 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // Toast.makeText(this, message, Toast.LENGTH_LONG).show() } + override fun minimizeVideoEvent(isMinimize: Boolean) { + if (isMinimize) + methodChannel.invokeMethod("onCallConnected", null) + else + methodChannel.invokeMethod("onCallDisconnected", null) + } + } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index d2ed15e0..eceed01e 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -7,4 +7,6 @@ interface VideoCallResponseListener { fun onCallFinished(resultCode : Int, intent: Intent? = null) fun errorHandle(message: String) + + fun minimizeVideoEvent(isMinimize : Boolean) } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index f7f70e40..03883361 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -420,13 +420,13 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session return } if (mSubscriber != null) { - mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) mSubscriber!!.destroy() mSubscriber = null } if (mPublisher != null) { - mPublisherViewContainer!!.removeView(mPublisher!!.view) + mPublisherViewContainer.removeView(mPublisher!!.view) mSession!!.unpublish(mPublisher) mPublisher!!.destroy() mPublisher = null @@ -482,6 +482,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val res = if (isFullScreen) R.drawable.reducing else R.drawable.expand btnMinimize.setImageResource(res) setViewsVisibility() + + videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) } private fun setViewsVisibility() { From c1ed1dc737fbdb27c0b5c2353a10296f0693d4b8 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 11:13:35 +0300 Subject: [PATCH 189/241] add loader --- lib/screens/patients/InPatientPage.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/screens/patients/InPatientPage.dart b/lib/screens/patients/InPatientPage.dart index e9e2c2d1..ec2a8107 100644 --- a/lib/screens/patients/InPatientPage.dart +++ b/lib/screens/patients/InPatientPage.dart @@ -1,9 +1,12 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.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/patient_card/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_container.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; @@ -59,7 +62,7 @@ class _InPatientPageState extends State { model.filterSearchResults(value); }), ), - model.filteredInPatientItems.length > 0 + model.state == ViewState.Idle?model.filteredInPatientItems.length > 0 ? Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 16.0), @@ -154,6 +157,13 @@ class _InPatientPageState extends State { error: TranslationBase.of(context).noDataAvailable)), ), + ): Center( + child: Container( + height: 300, + width: 300, + child: Image.asset( + "assets/images/progress-loading-red.gif"), + ), ), ], ), From 5312c221d129d5a0200e7e8cb7b35800fa4e6014 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 11:14:32 +0300 Subject: [PATCH 190/241] video fix bugs --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 03883361..1dc3d267 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -19,6 +19,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.R @@ -358,7 +359,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) -// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } override fun onStreamDropped(session: Session, stream: Stream) { @@ -433,7 +434,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() -// videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) dialog?.dismiss() } @@ -589,7 +590,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } } - @SuppressLint("ClickableViewAccessibility") fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager From c1de90877749e897f4d456cf2825a96bd02452cf Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 16 Jun 2021 11:16:27 +0300 Subject: [PATCH 191/241] no message --- ios/Runner/Base.lproj/Main.storyboard | 161 +++++++++++--------- ios/Runner/Extensions.swift | 13 +- ios/Runner/MainAppViewController.swift | 30 ++-- ios/Runner/VideoCallRequestParameters.swift | 4 +- ios/Runner/VideoCallViewController.swift | 91 ++++++----- 5 files changed, 167 insertions(+), 132 deletions(-) diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index c1c16274..2bdee5a2 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -41,18 +41,94 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -210,76 +286,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -300,23 +309,25 @@ + + + - - + diff --git a/ios/Runner/Extensions.swift b/ios/Runner/Extensions.swift index c73f49e2..b79c8deb 100644 --- a/ios/Runner/Extensions.swift +++ b/ios/Runner/Extensions.swift @@ -9,12 +9,19 @@ import AADraggableView extension AADraggableView{ func enable(_ enable:Bool){ - if enable == false{ + isEnabled = enable + if enable == false{ gestureRecognizers?.forEach({ gest in removeGestureRecognizer(gest) }) - }else{ - isEnabled = true } } } + +extension UIView{ + func hidden(_ hidden:Bool, rootView:UIView){ + UIView.transition(with: rootView, duration: 0.5, options: .transitionCrossDissolve, animations: { + self.isHidden = hidden + }) + } +} diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift index ffca444c..c7b7a18d 100644 --- a/ios/Runner/MainAppViewController.swift +++ b/ios/Runner/MainAppViewController.swift @@ -72,9 +72,7 @@ extension MainAppViewController : ICallProtocol{ } private func showVideo(show:Bool){ - UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: { - self.videoCallContainer.isHidden = !show - }) + self.videoCallContainer.hidden(!show, rootView: view) } private func startVideoCall(result: @escaping FlutterResult, call:FlutterMethodCall) { @@ -83,23 +81,19 @@ extension MainAppViewController : ICallProtocol{ if let arguments = call.arguments as? NSDictionary{ showVideoCallView(true) - videoCallViewController.onRectFloat = { min in - self.rectFloatVideoCallView(min) - if(min){ - self.videoCallContainer.repositionIfNeeded() - } + videoCallViewController.onRectFloat = { isRectFloat in + self.rectFloatVideoCallView(isRectFloat) } - videoCallViewController.onCircleFloat = { min in - self.circleFloatVideoCallView(min) - self.videoCallContainer.reposition = min ? .free : .edgesOnly - self.videoCallContainer.repositionIfNeeded() + videoCallViewController.onCircleFloat = { isCircleFloat in + self.circleFloatVideoCallView(isCircleFloat) } videoCallViewController.onCallConnect = { self.videoCallChannel?.invokeMethod("onCallConnected",arguments: nil) } videoCallViewController.onCallDisconnect = { self.showVideoCallView(false) + self.videoCallViewController.minimizeVideoState(state: false) self.videoCallChannel?.invokeMethod("onCallDisconnected",arguments: nil) } videoCallViewController.callBack = self @@ -130,7 +124,7 @@ extension MainAppViewController : ICallProtocol{ } private func circleFloatVideoCallView(_ value:Bool){ - videoCallContainer.enable(value) + videoCallContainer.reposition = value ? .sticky : .edgesOnly UIView.animate(withDuration: 0.5) { if(value){ @@ -152,9 +146,7 @@ extension MainAppViewController : ICallProtocol{ } private func showVideoCallView(_ value:Bool){ - UIView.animate(withDuration: 0.5) { - self.videoCallContainer.isHidden = !value - } + self.videoCallContainer.hidden(!value, rootView: view) } func sessionDone(res: Any) { @@ -182,14 +174,14 @@ extension MainAppViewController : ICallProtocol{ videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height) ] vdoCallViewFloatRectConstraint = [ - videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 40), videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width/3), videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height/3.5) ] vdoCallViewFloatCircleConstraint = [ - videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor), - videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 40), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), videoCallContainer.widthAnchor.constraint(equalToConstant: 70), videoCallContainer.heightAnchor.constraint(equalToConstant: 70) ] diff --git a/ios/Runner/VideoCallRequestParameters.swift b/ios/Runner/VideoCallRequestParameters.swift index 2366c562..543d7e8b 100644 --- a/ios/Runner/VideoCallRequestParameters.swift +++ b/ios/Runner/VideoCallRequestParameters.swift @@ -12,7 +12,8 @@ class VideoCallRequestParameters{ var generalId:String? var doctorId:Int? var baseUrl:String? - + var patientName:String? + init(dictionary:NSDictionary){ self.apiKey = dictionary["kApiKey"] as? String self.sessionId = dictionary["kSessionId"] as? String @@ -23,5 +24,6 @@ class VideoCallRequestParameters{ self.generalId = dictionary["generalId"] as? String self.doctorId = dictionary["DoctorId"] as? Int self.baseUrl = dictionary["baseUrl"] as? String + self.patientName = dictionary["patientName"] as? String } } diff --git a/ios/Runner/VideoCallViewController.swift b/ios/Runner/VideoCallViewController.swift index 02a70a0c..83865c6e 100644 --- a/ios/Runner/VideoCallViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -57,14 +57,15 @@ class VideoCallViewController: UIViewController { @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! @IBOutlet weak var localVideoMutedBg: UIView! + @IBOutlet weak var btnScreenTap: UIButton! @IBOutlet weak var localVideoContainer: UIView! @IBOutlet weak var topBar: UIView! @IBOutlet weak var lblCallDuration: UILabel! - @IBOutlet weak var remoteVideo: UIView! - @IBOutlet weak var localVideo: UIView!{ + @IBOutlet weak var fullVideoView: UIView! + @IBOutlet weak var smallVideoView: UIView!{ didSet{ - localVideo.layer.borderColor = UIColor.white.cgColor - localVideoDraggable = localVideo?.superview as? AADraggableView + smallVideoView.layer.borderColor = UIColor.white.cgColor + localVideoDraggable = smallVideoView?.superview as? AADraggableView localVideoDraggable?.reposition = .edgesOnly } } @@ -78,16 +79,28 @@ class VideoCallViewController: UIViewController { gesture.view?.removeFromSuperview() } - @IBAction func onVideoContainerTapped(_ sender: Any) { + @IBAction func btnOnScreenTapped(_ sender: Any) { if(hideVideoBtn.isSelected){ circleFloatBtnTapped(hideVideoBtn) }else if(btnMinimize.isSelected){ btnMinimizeTapped(btnMinimize) - }else if(!btnMinimize.isSelected){ - // Swipe video here } } + + @IBAction func btnSwipeVideoTapped(_ sender: Any) { +// let smallVdoRender = smallVideoView.subviews.first +// let fullVdoRender = fullVideoView.subviews.first +// if let vdo = smallVdoRender{ +// fullVideoView.addSubview(vdo) +// } +// if let vdo = fullVdoRender{ +// smallVideoView.addSubview(vdo) +// } +// +// layoutVideoRenderViews() + } + @IBAction func didClickMuteButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected publisher!.publishAudio = !sender.isSelected @@ -105,7 +118,7 @@ class VideoCallViewController: UIViewController { } else { publisher!.publishVideo = true } - localVideo.isHidden = sender.isSelected + smallVideoView.isHidden = sender.isSelected localVideoMutedBg.isHidden = !sender.isSelected } @@ -130,36 +143,41 @@ class VideoCallViewController: UIViewController { onCircleFloat?(sender.isSelected) topBar.isHidden = sender.isSelected controlButtons.isHidden = sender.isSelected - localVideo.isHidden = sender.isSelected + smallVideoView.isHidden = sender.isSelected self.publisher?.view?.layoutIfNeeded() } - var floated = false @IBAction func btnMinimizeTapped(_ sender: UIButton) { - floated = !floated - onRectFloat?(floated) - sender.isSelected = floated + minimizeVideoState(state: !sender.isSelected) + btnScreenTap.isHidden = !sender.isSelected + } + + func minimizeVideoState(state:Bool){ + btnMinimize.isSelected = state + onRectFloat?(state) - NSLayoutConstraint.activate(floated ? minimizeConstraint : maximisedConstraint) - NSLayoutConstraint.deactivate(floated ? maximisedConstraint : minimizeConstraint) - localVideoDraggable?.enable(!floated) + NSLayoutConstraint.activate(state ? minimizeConstraint : maximisedConstraint) + NSLayoutConstraint.deactivate(state ? maximisedConstraint : minimizeConstraint) + localVideoDraggable?.enable(!state) - lblRemoteUsername.isHidden = floated - hideVideoBtn.isHidden = !floated + lblRemoteUsername.isHidden = state + hideVideoBtn.isHidden = !state lblCallDuration.superview?.isHidden = !hideVideoBtn.isHidden - let min_ = floated UIView.animate(withDuration: 0.5) { - self.videoMuteBtn.isHidden = min_ - self.micMuteBtn.isHidden = min_ - self.camSwitchBtn.isHidden = min_ - - let localVdoSize = self.localVideo.bounds.size - let remoteVdoSize = self.remoteVideo.bounds.size - self.publisher?.view?.frame = CGRect(x: 0, y: 0, width: localVdoSize.width, height: localVdoSize.height) - self.subscriber?.view?.frame = CGRect(x: 0, y: 0, width: remoteVdoSize.width, height: remoteVdoSize.height) - self.publisher?.view?.layoutIfNeeded() - self.subscriber?.view?.layoutIfNeeded() + self.videoMuteBtn.isHidden = state + self.micMuteBtn.isHidden = state + self.camSwitchBtn.isHidden = state + self.layoutVideoRenderViews() + } + } + + func layoutVideoRenderViews(){ + if let publisherVdoSize = publisher?.view?.superview?.bounds.size{ + publisher?.view?.frame = CGRect(x: 0, y: 0, width: publisherVdoSize.width, height: publisherVdoSize.height) + } + if let subscriberVdoSize = subscriber?.view?.superview?.bounds.size{ + subscriber?.view?.frame = CGRect(x: 0, y: 0, width: subscriberVdoSize.width, height: subscriberVdoSize.height) } } @@ -179,6 +197,9 @@ class VideoCallViewController: UIViewController { } func start(params:VideoCallRequestParameters){ + lblRemoteUsername.text = params.patientName ?? "- - -" + btnScreenTap.isHidden = true + hideVideoBtn.isHidden = true self.kApiKey = params.apiKey ?? "" self.kSessionId = params.sessionId ?? "" @@ -193,6 +214,7 @@ class VideoCallViewController: UIViewController { requestCameraPermissionsIfNeeded() hideVideoMuted() setupSession() + } private func changeCallStatus(callStatus:Int){ @@ -397,10 +419,11 @@ extension VideoCallViewController: OTSessionDelegate { showAlert(error?.localizedDescription) } - publisher?.view!.frame = CGRect(x: 0, y: 0, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) + publisher?.view?.tag = 11 publisher?.view?.layer.cornerRadius = 5 publisher?.view?.clipsToBounds = true - localVideo.addSubview((publisher?.view)!) + smallVideoView.addSubview((publisher?.view)!) + layoutVideoRenderViews() } func sessionDidDisconnect(_ session: OTSession) { @@ -440,9 +463,9 @@ extension VideoCallViewController: OTSessionDelegate { guard let subscriberView = subscriber.view else { return } - - subscriberView.frame = CGRect(x: 0, y: 0, width: remoteVideo.bounds.width, height: remoteVideo.bounds.height) - remoteVideo.addSubview(subscriberView) + subscriberView.tag = 22 + fullVideoView.addSubview(subscriberView) + layoutVideoRenderViews() startUpdateCallDuration() onCallConnect?() From 0868de7961ab6053cd50e61216fd7b471498ef09 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 14:05:04 +0300 Subject: [PATCH 192/241] video fix bugs --- android/app/src/main/AndroidManifest.xml | 1 - .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 28 +- .../com/hmg/hmgDr/ui/VideoCallActivity.java | 481 ------------------ .../hmg/hmgDr/ui/VideoCallResponseListener.kt | 2 + .../hmgDr/ui/fragment/VideoCallFragment.kt | 34 +- .../src/main/res/drawable/circle_shape.xml | 14 + .../main/res/drawable/layout_rounded_bg.xml | 14 +- 7 files changed, 64 insertions(+), 510 deletions(-) delete mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java create mode 100644 android/app/src/main/res/drawable/circle_shape.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0e71249f..bf0d3766 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,7 +27,6 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:label="HMG Doctor"> - = HashMap() callResponse["callResponse"] = "CallEnd" @@ -166,5 +167,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, methodChannel.invokeMethod("onCallDisconnected", null) } + override fun onBackPressed() { + super.onBackPressed() + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java deleted file mode 100644 index 75590b76..00000000 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ /dev/null @@ -1,481 +0,0 @@ -package com.hmg.hmgDr.ui; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.opengl.GLSurfaceView; -import android.os.Bundle; -import android.os.CountDownTimer; -import android.os.Handler; -import android.os.SystemClock; -import android.util.Log; -import android.view.View; -import android.widget.Chronometer; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; -import com.hmg.hmgDr.Model.GetSessionStatusModel; -import com.hmg.hmgDr.Model.SessionStatusModel; -import com.hmg.hmgDr.R; -import com.opentok.android.Session; -import com.opentok.android.Stream; -import com.opentok.android.Publisher; -import com.opentok.android.PublisherKit; -import com.opentok.android.Subscriber; -import com.opentok.android.BaseVideoRenderer; -import com.opentok.android.OpentokError; -import com.opentok.android.SubscriberKit; - -import java.util.List; -import java.util.Objects; - -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, - Session.SessionListener, - Publisher.PublisherListener, - Subscriber.VideoListener, VideoCallContract.VideoCallView { - - private static final String TAG = VideoCallActivity.class.getSimpleName(); - - VideoCallContract.VideoCallPresenter videoCallPresenter; - - private static final int RC_SETTINGS_SCREEN_PERM = 123; - private static final int RC_VIDEO_APP_PERM = 124; - - - private Session mSession; - private Publisher mPublisher; - private Subscriber mSubscriber; - - private Handler mVolHandler, mConnectedHandler; - private Runnable mVolRunnable, mConnectedRunnable; - - private FrameLayout mPublisherViewContainer; - private FrameLayout mSubscriberViewContainer; - private RelativeLayout controlPanel; - - private String apiKey; - private String sessionId; - private String token; - private String appLang; - private String baseUrl; - - private boolean isSwitchCameraClicked; - private boolean isCameraClicked; - private boolean isSpeckerClicked; - private boolean isMicClicked; - - private TextView patientName; - private Chronometer cmTimer; - long elapsedTime; - Boolean resume = false; - - private ImageView mCallBtn; - private ImageView btnMinimize; - private ImageView mCameraBtn; - private ImageView mSwitchCameraBtn; - private ImageView mspeckerBtn; - private ImageView mMicBtn; - - private ProgressBar progressBar; - private CountDownTimer countDownTimer; - private TextView progressBarTextView; - private RelativeLayout progressBarLayout; - - private boolean isConnected = false; - - private GetSessionStatusModel sessionStatusModel; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - setTheme(R.style.AppTheme); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_video_call); - Objects.requireNonNull(getSupportActionBar()).hide(); - initUI(); - requestPermissions(); - } - - @Override - protected void onPause() { - super.onPause(); - - if (mSession == null) { - return; - } - mSession.onPause(); - - if (isFinishing()) { - disconnectSession(); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (mSession == null) { - return; - } - mSession.onResume(); - } - - @Override - protected void onDestroy() { - disconnectSession(); - cmTimer.stop(); - super.onDestroy(); - } - - @SuppressLint("ClickableViewAccessibility") - private void initUI() { - mPublisherViewContainer = findViewById(R.id.local_video_view_container); - mSubscriberViewContainer = findViewById(R.id.remote_video_view_container); - - apiKey = getIntent().getStringExtra("apiKey"); - sessionId = getIntent().getStringExtra("sessionId"); - token = getIntent().getStringExtra("token"); - appLang = getIntent().getStringExtra("appLang"); - baseUrl = getIntent().getStringExtra("baseUrl"); - sessionStatusModel = getIntent().getParcelableExtra("sessionStatusModel"); - - controlPanel = findViewById(R.id.control_panel); - - videoCallPresenter = new VideoCallPresenterImpl(this, baseUrl); - - patientName = findViewById(R.id.patient_name); - patientName.setText(sessionStatusModel.getPatientName()); - - cmTimer = findViewById(R.id.cmTimer); - cmTimer.setFormat("mm:ss"); - cmTimer.setOnChronometerTickListener(arg0 -> { - long minutes; - long seconds; - if (!resume) { - minutes = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) / 60; - seconds = ((SystemClock.elapsedRealtime() - cmTimer.getBase()) / 1000) % 60; - elapsedTime = SystemClock.elapsedRealtime(); - } else { - minutes = ((elapsedTime - cmTimer.getBase()) / 1000) / 60; - seconds = ((elapsedTime - cmTimer.getBase()) / 1000) % 60; - elapsedTime = elapsedTime + 1000; - } - Log.d(TAG, "onChronometerTick: " + minutes + " : " + seconds); - }); - - mCallBtn = findViewById(R.id.btn_call); - btnMinimize = findViewById(R.id.btn_minimize); - mCameraBtn = findViewById(R.id.btn_camera); - mSwitchCameraBtn = findViewById(R.id.btn_switch_camera); - mspeckerBtn = findViewById(R.id.btn_specker); - mMicBtn = findViewById(R.id.btn_mic); - - // progressBarLayout=findViewById(R.id.progressBar); - // progressBar=findViewById(R.id.progress_bar); -// progressBarTextView=findViewById(R.id.progress_bar_text); -// progressBar.setVisibility(View.GONE); - - hiddenButtons(); - - checkClientConnected(); - - mSubscriberViewContainer.setOnTouchListener((v, event) -> { - controlPanel.setVisibility(View.VISIBLE); - mVolHandler.removeCallbacks(mVolRunnable); - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - return true; - }); - - if (appLang.equals("ar")) { - progressBarLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); - } - - } - - private void checkClientConnected() { - mConnectedHandler = new Handler(); - mConnectedRunnable = () -> { - if (!isConnected) { - videoCallPresenter.callClintConnected(sessionStatusModel); - } - }; - mConnectedHandler.postDelayed(mConnectedRunnable, 55 * 1000); - - } - - private void hiddenButtons() { - mVolHandler = new Handler(); - mVolRunnable = () -> controlPanel.setVisibility(View.GONE); - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - - @Override - public void onPermissionsGranted(int requestCode, List perms) { - Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size()); - } - - @Override - public void onPermissionsDenied(int requestCode, List perms) { - Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); - - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new AppSettingsDialog.Builder(this) - .setTitle(getString(R.string.title_settings_dialog)) - .setRationale(getString(R.string.rationale_ask_again)) - .setPositiveButton(getString(R.string.setting)) - .setNegativeButton(getString(R.string.cancel)) - .setRequestCode(RC_SETTINGS_SCREEN_PERM) - .build() - .show(); - } - } - - @AfterPermissionGranted(RC_VIDEO_APP_PERM) - private void requestPermissions() { - String[] perms = {Manifest.permission.INTERNET, Manifest.permission.CAMERA,}; - if (EasyPermissions.hasPermissions(this, perms)) { - try { - mSession = new Session.Builder(this, apiKey, sessionId).build(); - mSession.setSessionListener(this); - mSession.connect(token); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, perms); - } - } - - @Override - public void onConnected(Session session) { - Log.i(TAG, "Session Connected"); - - mPublisher = new Publisher.Builder(this).build(); - mPublisher.setPublisherListener(this); - - mPublisherViewContainer.addView(mPublisher.getView()); - - if (mPublisher.getView() instanceof GLSurfaceView) { - ((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true); - } - - mSession.publish(mPublisher); - - if (!resume) { - cmTimer.setBase(SystemClock.elapsedRealtime()); - } - cmTimer.start(); - } - - @Override - public void onDisconnected(Session session) { - Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId()); - - mSession = null; - cmTimer.stop(); - } - - @Override - public void onError(Session session, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId()); - - // Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - //finish(); - } - - @Override - public void onStreamReceived(Session session, Stream stream) { - Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId()); - if (mSubscriber != null) { - isConnected = true; - return; - } - isConnected = true; - subscribeToStream(stream); - if(mConnectedHandler!=null && mConnectedRunnable!=null) - mConnectedHandler.removeCallbacks(mConnectedRunnable); - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - } - - @Override - public void onStreamDropped(Session session, Stream stream) { - Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId()); - - if (mSubscriber == null) { - return; - } - - if (mSubscriber.getStream().equals(stream)) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSubscriber.destroy(); - mSubscriber = null; - } - disconnectSession(); - } - - @Override - public void onStreamCreated(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created"); - } - - @Override - public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed"); - } - - @Override - public void onError(PublisherKit publisherKit, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher"); - - // Toast.makeText(this, "onError: Error (" + opentokError.getMessage() + ") in publisher", Toast.LENGTH_LONG).show(); - // finish(); - } - - @Override - public void onVideoDataReceived(SubscriberKit subscriberKit) { - mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL); - mSubscriberViewContainer.addView(mSubscriber.getView()); - } - - @Override - public void onVideoDisabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoEnabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoDisableWarning(SubscriberKit subscriberKit) { - - } - - @Override - public void onVideoDisableWarningLifted(SubscriberKit subscriberKit) { - - } - - private void subscribeToStream(Stream stream) { - mSubscriber = new Subscriber.Builder(VideoCallActivity.this, stream).build(); - mSubscriber.setVideoListener(this); - mSession.subscribe(mSubscriber); - } - - private void disconnectSession() { - if (mSession == null) { - setResult(Activity.RESULT_CANCELED); - finish(); - return; - } - - if (mSubscriber != null) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSession.unsubscribe(mSubscriber); - mSubscriber.destroy(); - mSubscriber = null; - } - - if (mPublisher != null) { - mPublisherViewContainer.removeView(mPublisher.getView()); - mSession.unpublish(mPublisher); - mPublisher.destroy(); - mPublisher = null; - } - mSession.disconnect(); - if (countDownTimer != null) { - countDownTimer.cancel(); - } - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(16,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - finish(); - } - - public void onSwitchCameraClicked(View view) { - if (mPublisher != null) { - isSwitchCameraClicked = !isSwitchCameraClicked; - mPublisher.cycleCamera(); - int res = isSwitchCameraClicked ? R.drawable.camera_front : R.drawable.camera_back; - mSwitchCameraBtn.setImageResource(res); - } - } - - public void onCallClicked(View view) { - disconnectSession(); - } - - public void onMinimizedClicked(View view) { - - } - - public void onCameraClicked(View view) { - if (mPublisher != null) { - isCameraClicked = !isCameraClicked; - mPublisher.setPublishVideo(!isCameraClicked); - int res = isCameraClicked ? R.drawable.video_disabled : R.drawable.video_enabled; - mCameraBtn.setImageResource(res); - } - } - - public void onMicClicked(View view) { - - if (mPublisher != null) { - isMicClicked = !isMicClicked; - mPublisher.setPublishAudio(!isMicClicked); - int res = isMicClicked ? R.drawable.mic_disabled : R.drawable.mic_enabled; - mMicBtn.setImageResource(res); - } - } - - public void onSpeckerClicked(View view) { - if (mSubscriber != null) { - isSpeckerClicked = !isSpeckerClicked; - mSubscriber.setSubscribeToAudio(!isSpeckerClicked); - int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; - mspeckerBtn.setImageResource(res); - } - } - - @Override - public void onCallSuccessful(SessionStatusModel sessionStatusModel) { - if (sessionStatusModel.getSessionStatus() == 2 || sessionStatusModel.getSessionStatus() == 3) { - Intent returnIntent = new Intent(); - returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } else if( sessionStatusModel.getSessionStatus() == 4 ){ - isConnected = true; - if(mConnectedHandler!=null && mConnectedRunnable!=null) - mConnectedHandler.removeCallbacks(mConnectedRunnable); - } - } - - @Override - public void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel) { - - } - - @Override - public void onFailure() { - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt index eceed01e..204568a4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -9,4 +9,6 @@ interface VideoCallResponseListener { fun errorHandle(message: String) fun minimizeVideoEvent(isMinimize : Boolean) + + fun onBackHandle(){} } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 1dc3d267..f7e6c4b2 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -16,7 +16,6 @@ import android.view.* import android.widget.* import androidx.annotation.Nullable import androidx.constraintlayout.widget.ConstraintLayout -import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel @@ -39,7 +38,7 @@ import kotlin.math.ceil class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, SubscriberKit.VideoListener, VideoCallView { - var isFullScreen: Boolean = true + private var isFullScreen: Boolean = true private var x_init_cord = 0 private var y_init_cord: Int = 0 private var x_init_margin: Int = 0 @@ -48,7 +47,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mWindowManager: WindowManager private var isLeft = true - lateinit var videoCallPresenter: VideoCallPresenter + private lateinit var videoCallPresenter: VideoCallPresenter private var mSession: Session? = null private var mPublisher: Publisher? = null @@ -88,8 +87,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var patientName: TextView private lateinit var cmTimer: Chronometer - var elapsedTime: Long = 0 - var resume = false + private var elapsedTime: Long = 0 + private var resume = false private val progressBar: ProgressBar? = null private val countDownTimer: CountDownTimer? = null @@ -122,6 +121,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog { val dialog: Dialog = super.onCreateDialog(savedInstanceState) + + // Add back button listener + // Add back button listener + dialog.setOnKeyListener { _, keyCode, keyEvent -> + // getAction to make sure this doesn't double fire + if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) { + videoCallResponseListener?.onBackHandle() + false // Capture onKey + } else true + // Don't capture + } + return dialog } @@ -438,7 +449,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session dialog?.dismiss() } - override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { val returnIntent = Intent() @@ -523,7 +533,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) localPreviewLayoutParam.width = localPreviewWidth localPreviewLayoutParam.height = localPreviewHeight - localPreviewLayoutParam.setMargins(0,localPreviewMargin, localPreviewMargin, 0) + localPreviewLayoutParam.setMargins(0, localPreviewMargin, localPreviewMargin, 0) // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) remotePreviewLayoutParam.width = remotePreviewIconSize remotePreviewLayoutParam.height = remotePreviewIconSize @@ -544,7 +554,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session localPreviewLayoutParam.width = 0 localPreviewLayoutParam.height = 0 - localPreviewLayoutParam.setMargins(0,localPreviewMargin / 2, localPreviewMargin/ 2, 0) + localPreviewLayoutParam.setMargins(0, localPreviewMargin / 2, localPreviewMargin / 2, 0) // localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) //// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) // localPreviewLayoutParam.width = localPreviewWidthSmall @@ -591,7 +601,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } @SuppressLint("ClickableViewAccessibility") - fun handleDragDialog() { + private fun handleDragDialog() { mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager getWindowManagerDefaultDisplay() @@ -600,7 +610,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } @SuppressLint("ClickableViewAccessibility") - val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> + private val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> mDetector.onTouchEvent(event) //Get Floating widget view params @@ -631,10 +641,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // y_cord_Destination = 0 // y_cord_Destination = // -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) - y_cord_Destination = - (szWindow.y/2) + y_cord_Destination = -(szWindow.y / 2) } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { // y_cord_Destination = szWindow.y - (videoCallContainer.height + barHeight) - y_cord_Destination = (szWindow.y/2) + y_cord_Destination = (szWindow.y / 2) } layoutParams.y = y_cord_Destination diff --git a/android/app/src/main/res/drawable/circle_shape.xml b/android/app/src/main/res/drawable/circle_shape.xml new file mode 100644 index 00000000..2cb09469 --- /dev/null +++ b/android/app/src/main/res/drawable/circle_shape.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml index 0c46f49b..ce73e763 100644 --- a/android/app/src/main/res/drawable/layout_rounded_bg.xml +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -1,7 +1,13 @@ - - - - + + + + From 746f44157ed9f20db0b991b96b70c6cd4d22f706 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 16 Jun 2021 14:54:10 +0300 Subject: [PATCH 193/241] Add video call service --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 2 + lib/core/service/NavigationService.dart | 10 +- lib/core/service/VideoCallService.dart | 88 +++++++++++++++ lib/landing_page.dart | 3 +- lib/locator.dart | 2 + lib/routes.dart | 3 + lib/screens/live_care/end_call_screen.dart | 44 +++++--- .../patient_profile_screen.dart | 102 ++++++++++-------- .../profile/patient-profile-app-bar.dart | 9 +- lib/widgets/shared/app_scaffold_widget.dart | 8 +- 10 files changed, 203 insertions(+), 68 deletions(-) create mode 100644 lib/core/service/VideoCallService.dart diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index f7e6c4b2..9a2deab6 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -370,6 +370,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } isConnected = true subscribeToStream(stream) + if (mConnectedHandler != null && mConnectedRunnable != null) + mConnectedHandler!!.removeCallbacks(mConnectedRunnable!!) videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) } diff --git a/lib/core/service/NavigationService.dart b/lib/core/service/NavigationService.dart index 426ace4d..26191ffc 100644 --- a/lib/core/service/NavigationService.dart +++ b/lib/core/service/NavigationService.dart @@ -3,9 +3,15 @@ import 'package:flutter/material.dart'; class NavigationService { final GlobalKey navigatorKey = new GlobalKey(); - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); + Future navigateTo(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushNamed(routeName,arguments: arguments); } + + Future pushReplacementNamed(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushReplacementNamed(routeName,arguments: arguments); + } + + Future pushNamedAndRemoveUntil(String routeName) { return navigatorKey.currentState.pushNamedAndRemoveUntil(routeName,(asd)=>false); } diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart new file mode 100644 index 00000000..af832aad --- /dev/null +++ b/lib/core/service/VideoCallService.dart @@ -0,0 +1,88 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; + +import '../../locator.dart'; +import '../../routes.dart'; +import 'NavigationService.dart'; + +class VideoCallService extends BaseService{ + + StartCallRes startCallRes; + PatiantInformtion patient; + LiveCarePatientServices _liveCarePatientServices = locator(); + + openVideo(StartCallRes startModel,PatiantInformtion patientModel,VoidCallback onCallConnected, VoidCallback onCallDisconnected)async{ + this.startCallRes = startModel; + this.patient = patientModel; + DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); + await VideoChannel.openVideoCallScreen( + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//startCallRes.openTokenID, + kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",//startCallRes.openSessionID, + kApiKey: '47247954',//'46209962', + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), + tokenID: await sharedPref.getString(TOKEN), + generalId: GENERAL_ID, + doctorId: doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + },onCallConnected: onCallConnected, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) async { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + }else + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + } else { + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + } + + }); + + }); + }); + } + Future endCall(int vCID, bool isPatient) async { + hasError = false; + // await getDoctorProfile(isGetProfile: true); + EndCallReq endCallReq = new EndCallReq(); + endCallReq.doctorId = doctorProfile.doctorID; + endCallReq.generalid = 'Cs2020@2016\$2958'; + endCallReq.vCID = vCID; + endCallReq.isDestroy = isPatient; + //await _liveCarePatientServices.endCall(endCallReq); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + } + } + +} \ No newline at end of file diff --git a/lib/landing_page.dart b/lib/landing_page.dart index cd7a8171..5bce4f71 100644 --- a/lib/landing_page.dart +++ b/lib/landing_page.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/screens/home/home_screen.dart'; import 'package:doctor_app_flutter/screens/qr_reader/QR_reader_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_drawer_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/bottom_nav_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/user-guid/app_showcase_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -33,7 +34,7 @@ class _LandingPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return AppScaffold( appBar: currentTab != 0 ? AppBar( elevation: 0, diff --git a/lib/locator.dart b/lib/locator.dart index 1e4bcb4c..d74fad8b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -11,6 +11,7 @@ import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; import 'core/service/NavigationService.dart'; +import 'core/service/VideoCallService.dart'; import 'core/service/home/dasboard_service.dart'; import 'core/service/home/doctor_reply_service.dart'; import 'core/service/home/schedule_service.dart'; @@ -96,6 +97,7 @@ void setupLocator() { locator.registerLazySingleton(() => NavigationService()); locator.registerLazySingleton(() => ScanQrService()); locator.registerLazySingleton(() => SpecialClinicsService()); + locator.registerLazySingleton(() => VideoCallService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); diff --git a/lib/routes.dart b/lib/routes.dart index 33aa5636..0826c76e 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/root_page.dart'; +import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/medical-file/health_summary_page.dart'; import 'package:doctor_app_flutter/screens/patients/ECGPage.dart'; import 'package:doctor_app_flutter/screens/patients/insurance_approval_screen_patient.dart'; @@ -37,6 +38,7 @@ const String LOGIN = 'login'; const String VERIFICATION_METHODS = 'verification-methods'; const String PATIENTS = 'patients/patients'; const String PATIENTS_PROFILE = 'patients/patients-profile'; +const String PATIENTS_END_Call = 'patients/patients-profile/endCall'; const String IN_PATIENTS_PROFILE = 'inpatients/patients-profile'; const String LAB_RESULT = 'patients/lab_result'; const String HEALTH_SUMMARY = 'patients/health-summary'; @@ -88,6 +90,7 @@ var routes = { PATIENT_MEDICAL_REPORT: (_) => MedicalReportPage(), PATIENT_MEDICAL_REPORT_INSERT: (_) => AddVerifyMedicalReport(), PATIENT_MEDICAL_REPORT_DETAIL: (_) => MedicalReportDetailPage(), + PATIENTS_END_Call: (_) => EndCallScreen(), CREATE_EPISODE: (_) => UpdateSoapIndex( isUpdate: true, ), diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 76e87a87..d355473d 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -23,9 +23,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; class EndCallScreen extends StatefulWidget { - final PatiantInformtion patient; - const EndCallScreen({Key key, this.patient}) : super(key: key); + + const EndCallScreen({Key key,}) : super(key: key); @override _EndCallScreenState createState() => _EndCallScreenState(); @@ -33,7 +33,7 @@ class EndCallScreen extends StatefulWidget { class _EndCallScreenState extends State { bool isInpatient = false; - + PatiantInformtion patient; bool isDischargedPatient = false; bool isSearchAndOut = false; String patientType; @@ -43,6 +43,13 @@ class _EndCallScreenState extends State { LiveCarePatientViewModel liveCareModel; + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final routeArgs = ModalRoute.of(context).settings.arguments as Map; + patient = routeArgs['patient']; + } + @override Widget build(BuildContext context) { final List cardsList = [ @@ -53,7 +60,7 @@ class _EndCallScreenState extends State { onTap: () async { GifLoaderDialogUtils.showMyDialog(context); await liveCareModel - .startCall(isReCall: false, vCID: widget.patient.vcId) + .startCall(isReCall: false, vCID: patient.vcId) .then((value) async { await liveCareModel.getDoctorProfile(); GifLoaderDialogUtils.hideDialog(context); @@ -64,8 +71,8 @@ class _EndCallScreenState extends State { kToken: liveCareModel.startCallRes.openTokenID, kSessionId: liveCareModel.startCallRes.openSessionID, kApiKey: '46209962', - vcId: widget.patient.vcId, - patientName: widget.patient.fullName ?? (widget.patient.firstName != null ? "${widget.patient.firstName} ${widget.patient.lastName}" : "-"), + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await liveCareModel.getToken(), generalId: GENERAL_ID, doctorId: liveCareModel.doctorProfile.doctorID, @@ -76,7 +83,7 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId, + patient.vcId, false, ); GifLoaderDialogUtils.hideDialog(context); @@ -89,7 +96,7 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId, + patient.vcId, sessionStatusModel.sessionStatus == 3, ); GifLoaderDialogUtils.hideDialog(context); @@ -116,14 +123,14 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.getAlternativeServices(widget.patient.vcId); + await liveCareModel.getAlternativeServices(patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } else { showAlternativesDialog(context, liveCareModel, (bool isConfirmed) async { GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.endCallWithCharge(widget.patient.vcId, isConfirmed); + await liveCareModel.endCallWithCharge(patient.vcId, isConfirmed); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); @@ -147,7 +154,7 @@ class _EndCallScreenState extends State { () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.sendSMSInstruction(widget.patient.vcId); + await liveCareModel.sendSMSInstruction(patient.vcId); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); @@ -169,7 +176,7 @@ class _EndCallScreenState extends State { context, MaterialPageRoute( builder: (BuildContext context) => - LivaCareTransferToAdmin(patient: widget.patient))); + LivaCareTransferToAdmin(patient: patient))); }, isInPatient: isInpatient, isDartIcon: true, @@ -186,10 +193,14 @@ class _EndCallScreenState extends State { backgroundColor: Theme.of(context).scaffoldBackgroundColor, isShowAppBar: true, appBar: PatientProfileAppBar( - widget.patient, + patient, + onPressed: (){ + Navigator.pop(context); + + }, isInpatient: isInpatient, - height: (widget.patient.patientStatusType != null && - widget.patient.patientStatusType == 43) + height: (patient.patientStatusType != null && + patient.patientStatusType == 43) ? 210 : isDischargedPatient ? 240 @@ -232,7 +243,7 @@ class _EndCallScreenState extends State { staggeredTileBuilder: (int index) => StaggeredTile.fit(1), itemBuilder: (BuildContext context, int index) => PatientProfileButton( - patient: widget.patient, + patient: patient, patientType: patientType, arrivalType: arrivalType, from: from, @@ -331,6 +342,7 @@ class _EndCallScreenState extends State { ), AppButton( onPressed: () { + Navigator.of(context).pop(); Navigator.of(context).pop(); okFunction(false); }, diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index d755af4a..9aa95d16 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/VideoCallService.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; @@ -25,6 +26,7 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:quiver/async.dart'; +import '../../../../locator.dart'; import '../../../../routes.dart'; class PatientProfileScreen extends StatefulWidget { @@ -91,6 +93,9 @@ class _PatientProfileScreenState extends State if(routeArgs.containsKey("isFromLiveCare")) { isFromLiveCare = routeArgs['isFromLiveCare']; } + if(routeArgs.containsKey("isCallFinished")) { + isCallFinished = routeArgs['isCallFinished']; + } if (isInpatient) _activeTab = 0; else @@ -333,9 +338,9 @@ class _PatientProfileScreenState extends State if(isCallFinished) { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) => - EndCallScreen(patient:patient))); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => EndCallScreen(patient:patient))); + var asd = ""; } else { GifLoaderDialogUtils.showMyDialog(context); // await model.startCall( isReCall : false, vCID: patient.vcId); @@ -349,49 +354,54 @@ class _PatientProfileScreenState extends State patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, - kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, - kApiKey: '47247954',//46209962 - vcId: patient.vcId, - patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - },onCallConnected: callConnected, - onCallEnd: () { - var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // - // }); - }); + locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + + // await VideoChannel.openVideoCallScreen( + // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, + // kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, + // kApiKey: '47247954',//46209962 + // vcId: patient.vcId, + // patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), + // tokenID: await model.getToken(), + // generalId: GENERAL_ID, + // doctorId: model.doctorProfile.doctorID, + // onFailure: (String error) { + // DrAppToastMsg.showErrorToast(error); + // },onCallConnected: callConnected, + // onCallEnd: () { + // var asd=""; + // WidgetsBinding.instance.addPostFrameCallback((_) { + // GifLoaderDialogUtils.showMyDialog(context); + // model.endCall(patient.vcId, false,).then((value) { + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal) { + // DrAppToastMsg.showErrorToast(model.error); + // } + // setState(() { + // isCallFinished = true; + // }); + // }); + // }); + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient))); + // }, + // onCallNotRespond: (SessionStatusModel sessionStatusModel) { + // var asd=""; + // // WidgetsBinding.instance.addPostFrameCallback((_) { + // // GifLoaderDialogUtils.showMyDialog(context); + // // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + // // GifLoaderDialogUtils.hideDialog(context); + // // if (model.state == ViewState.ErrorLocal) { + // // DrAppToastMsg.showErrorToast(model.error); + // // } + // // setState(() { + // // isCallFinished = true; + // // }); + // // }); + // // + // // }); + // }); } } diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5cfdc1b6..de374f04 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -33,6 +33,7 @@ class PatientProfileAppBar extends StatelessWidget final String clinic; final bool isAppointmentHeader; final bool isFromLabResult; + final VoidCallback onPressed; PatientProfileAppBar( this.patient, @@ -52,7 +53,7 @@ class PatientProfileAppBar extends StatelessWidget this.episode, this.visitDate, this.isAppointmentHeader = false, - this.isFromLabResult = false}); + this.isFromLabResult = false, this.onPressed}); @override @@ -93,7 +94,11 @@ class PatientProfileAppBar extends StatelessWidget IconButton( icon: Icon(Icons.arrow_back_ios), color: Color(0xFF2B353E), //Colors.black, - onPressed: () => Navigator.pop(context), + onPressed: () { + if(onPressed!=null) + onPressed(); + Navigator.pop(context); + }, ), Expanded( child: AppText( diff --git a/lib/widgets/shared/app_scaffold_widget.dart b/lib/widgets/shared/app_scaffold_widget.dart index e957b5d4..b930c21a 100644 --- a/lib/widgets/shared/app_scaffold_widget.dart +++ b/lib/widgets/shared/app_scaffold_widget.dart @@ -19,8 +19,11 @@ class AppScaffold extends StatelessWidget { final Widget bottomSheet; final Color backgroundColor; final Widget appBar; + final Widget drawer; + final Widget bottomNavigationBar; final String subtitle; final bool isHomeIcon; + final bool extendBody; AppScaffold( {this.appBarTitle = '', this.body, @@ -30,7 +33,7 @@ class AppScaffold extends StatelessWidget { this.bottomSheet, this.backgroundColor, this.isHomeIcon = true, - this.appBar, this.subtitle}); + this.appBar, this.subtitle, this.drawer, this.extendBody = false, this.bottomNavigationBar}); @override Widget build(BuildContext context) { @@ -42,6 +45,9 @@ class AppScaffold extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor ?? Colors.white, + drawer: drawer, + extendBody: extendBody, + bottomNavigationBar: bottomNavigationBar, appBar: isShowAppBar ? appBar ?? AppBar( From 7614b4aa5c7406da5c3c209f6057e65c04ca8661 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 16 Jun 2021 15:12:25 +0300 Subject: [PATCH 194/241] fix the video call issues --- lib/config/config.dart | 4 ++-- lib/core/service/VideoCallService.dart | 10 +++++----- lib/core/viewModel/authentication_view_model.dart | 2 +- lib/screens/home/home_screen.dart | 2 +- lib/screens/patients/PatientsInPatientScreen.dart | 13 ++++++------- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index eb361798..8241b36c 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index af832aad..0ae61a55 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//startCallRes.openTokenID, - kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",//startCallRes.openSessionID, - kApiKey: '47247954',//'46209962', + kToken: startCallRes.openTokenID, + kSessionId: startCallRes.openSessionID, + kApiKey: '46209962',//'46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -73,13 +73,13 @@ class VideoCallService extends BaseService{ } Future endCall(int vCID, bool isPatient) async { hasError = false; - // await getDoctorProfile(isGetProfile: true); + await getDoctorProfile(isGetProfile: true); EndCallReq endCallReq = new EndCallReq(); endCallReq.doctorId = doctorProfile.doctorID; endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - //await _liveCarePatientServices.endCall(endCallReq); + await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 189dea42..9da1933a 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -255,7 +255,7 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); - DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); + // DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index aaf4d9b9..d448083f 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -69,7 +69,7 @@ class _HomeScreenState extends State { await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); - await model.getSpecialClinicalCareList(); + // await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 4971b636..ae0fbb59 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -65,13 +65,12 @@ class _PatientInPatientScreenState extends State return BaseView( onModelReady: (model) async { model.clearPatientList(); - if (widget.specialClinic != null) { - await model - .getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); - requestModel.nursingStationID = - model.specialClinicalCareMappingList[0].nursingStationID; - requestModel.clinicID = 0; - } + // if (widget.specialClinic != null) { + // await model.getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); + // requestModel.nursingStationID = + // model.specialClinicalCareMappingList[0].nursingStationID; + // requestModel.clinicID = 0; + // } model.getInPatientList(requestModel); }, builder: (_, model, w) => From 78903043d95aa89cc135ee4dbf0788bbadfbc3d7 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:18:54 +0300 Subject: [PATCH 195/241] fix header --- .../patients/profile/lab_result/laboratory_result_page.dart | 2 +- lib/screens/patients/profile/lab_result/labs_home_page.dart | 1 - lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index d6b4d2bc..e58d4ef5 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -40,7 +40,7 @@ class _LaboratoryResultPageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( widget.patient, - + isInpatient:widget.isInpatient, isFromLabResult: true, appointmentDate: widget.patientLabOrders.orderDate, ), diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index b2bfa2fd..7da55967 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -54,7 +54,6 @@ class _LabsHomePageState extends State { isShowAppBar: true, appBar: PatientProfileAppBar( patient, - isInpatient: isInpatient, ), body: SingleChildScrollView( diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 5cfdc1b6..497e8ad5 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? 160 : isAppointmentHeader ? 290 : 170 + ? isInpatient ? (isFromLabResult?170:175) : isAppointmentHeader ? 290 : 175 : height); } From b9711fce653035bc97f559f8a1e01b1554172f7d Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:35:48 +0300 Subject: [PATCH 196/241] fix header from lab result details --- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index 497e8ad5..e39cd5f6 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? (isFromLabResult?170:175) : isAppointmentHeader ? 290 : 175 + ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 175 : height); } From 4e6237f2ce31ad216349d267fff1ed149e0ed0d2 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 16 Jun 2021 16:47:03 +0300 Subject: [PATCH 197/241] fix header from lab --- lib/config/config.dart | 4 ++-- lib/widgets/patients/profile/patient-profile-app-bar.dart | 2 +- pubspec.lock | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart index e39cd5f6..83186b02 100644 --- a/lib/widgets/patients/profile/patient-profile-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -551,6 +551,6 @@ class PatientProfileAppBar extends StatelessWidget @override Size get preferredSize => Size(double.maxFinite, height == 0 - ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 175 + ? isInpatient ? (isFromLabResult?200:170) : isAppointmentHeader ? 290 : 170 : height); } diff --git a/pubspec.lock b/pubspec.lock index 25596d43..77df9848 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From edca552f789024cae097bb67b91056776225459e Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 16 Jun 2021 17:18:12 +0300 Subject: [PATCH 198/241] video fix bugs --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 62 ++++++++++++++++++- .../src/main/res/drawable/circle_shape.xml | 6 +- android/app/src/main/res/drawable/ic_mini.xml | 5 ++ .../main/res/layout/activity_video_call.xml | 22 ++++++- android/app/src/main/res/values/colors.xml | 4 ++ lib/config/config.dart | 4 +- lib/core/service/VideoCallService.dart | 6 +- 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_mini.xml diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 9a2deab6..68db00fb 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -16,6 +16,7 @@ import android.view.* import android.widget.* import androidx.annotation.Nullable import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat import androidx.fragment.app.DialogFragment import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel @@ -39,6 +40,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session SubscriberKit.VideoListener, VideoCallView { private var isFullScreen: Boolean = true + private var isCircle: Boolean = false private var x_init_cord = 0 private var y_init_cord: Int = 0 private var x_init_margin: Int = 0 @@ -78,6 +80,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var parentView: View private lateinit var videoCallContainer: ConstraintLayout private lateinit var layoutName: RelativeLayout + private lateinit var layoutMini: RelativeLayout + private lateinit var icMini: ImageButton private lateinit var mCallBtn: ImageView private lateinit var btnMinimize: ImageView private lateinit var mCameraBtn: ImageView @@ -179,7 +183,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session requestPermissions() handleDragDialog() - mDetector = GestureDetectorCompat(context, MyGestureListener { showControlPanelTemporarily() }) + mDetector = GestureDetectorCompat(context, MyGestureListener({ showControlPanelTemporarily() }, { miniCircleDoubleTap() })) return parentView } @@ -214,6 +218,8 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun initUI(view: View) { videoCallContainer = view.findViewById(R.id.video_call_ll) layoutName = view.findViewById(R.id.layout_name) + layoutMini = view.findViewById(R.id.layout_mini) + icMini = view.findViewById(R.id.ic_mini) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) @@ -240,6 +246,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") } + icMini.setOnClickListener { + onMiniCircleClicked() + } + controlPanel = view.findViewById(R.id.control_panel) videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) mCallBtn = view.findViewById(R.id.btn_call) @@ -478,6 +488,39 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } + private fun miniCircleDoubleTap(){ + if (isCircle){ + onMiniCircleClicked() + } + } + + private fun onMiniCircleClicked(){ + if (isCircle) { + dialog?.window?.setLayout( + 400, + 600 + ) + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) + } else { + dialog?.window?.setLayout( + 200, + 200 + ) + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + } + isCircle = !isCircle + + if(isCircle){ + controlPanel?.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel?.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } + } + private fun onMinimizedClicked(view: View?) { if (isFullScreen) { dialog?.window?.setLayout( @@ -522,6 +565,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session if (isFullScreen) { layoutName.visibility = View.VISIBLE + layoutMini.visibility = View.GONE mCameraBtn.visibility = View.VISIBLE mSwitchCameraBtn.visibility = View.VISIBLE // mspeckerBtn.visibility = View.VISIBLE @@ -541,6 +585,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSize } else { layoutName.visibility = View.GONE + layoutMini.visibility = View.VISIBLE mCameraBtn.visibility = View.GONE mSwitchCameraBtn.visibility = View.GONE // mspeckerBtn.visibility = View.GONE @@ -565,6 +610,14 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session // remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) remotePreviewLayoutParam.width = remotePreviewIconSizeSmall remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + + if(isCircle){ + controlPanel?.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel?.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } } mPublisherViewContainer.layoutParams = localPreviewLayoutParam @@ -753,13 +806,18 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session ).toInt() } - private class MyGestureListener(val onTabCall: () -> Unit) : GestureDetector.SimpleOnGestureListener() { + private class MyGestureListener(val onTabCall: () -> Unit, val miniCircleDoubleTap: () -> Unit) : GestureDetector.SimpleOnGestureListener() { override fun onSingleTapConfirmed(event: MotionEvent): Boolean { onTabCall() return true } + override fun onDoubleTap(e: MotionEvent?): Boolean { + miniCircleDoubleTap() + return super.onDoubleTap(e) + } + } companion object { diff --git a/android/app/src/main/res/drawable/circle_shape.xml b/android/app/src/main/res/drawable/circle_shape.xml index 2cb09469..27b49f9b 100644 --- a/android/app/src/main/res/drawable/circle_shape.xml +++ b/android/app/src/main/res/drawable/circle_shape.xml @@ -3,10 +3,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> - - + - + + + diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index 6dbdaa1f..efc97746 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -47,12 +47,32 @@ + + + + + diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 29782be0..f52c2cf2 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -5,6 +5,10 @@ #fc3850 #e4e9f2 + #80757575 + #00ffffff + + #827b92 #484258 diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 0ae61a55..114d627f 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: startCallRes.openTokenID, - kSessionId: startCallRes.openSessionID, - kApiKey: '46209962',//'46209962', + kToken:"T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", //startCallRes.openTokenID, + kSessionId: "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",//startCallRes.openSessionID, + kApiKey:'47247954',// '46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), From b8de9c9a14f98e41e90264e437c6533d6690bcf3 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 10:11:19 +0300 Subject: [PATCH 199/241] circle screen fix bug, and mini screen design --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 6 ++- .../hmgDr/ui/fragment/VideoCallFragment.kt | 28 +++++----- android/app/src/main/res/drawable/ic_mini.xml | 2 +- .../main/res/layout/activity_video_call.xml | 53 +++++++++---------- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index af19306d..fcc3f2e3 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -151,7 +151,11 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, } else if (resultCode == Activity.RESULT_CANCELED) { val callResponse: HashMap = HashMap() callResponse["callResponse"] = "CallEnd" - result?.success(callResponse) + try { + result?.success(callResponse) + } catch (e : Exception){ + Log.e("onVideoCallFinished", "${e.message}.") + } } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 68db00fb..51ce1948 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -64,7 +64,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private lateinit var mPublisherViewIcon: View private lateinit var mSubscriberViewContainer: FrameLayout private lateinit var mSubscriberViewIcon: ImageView - private var controlPanel: ConstraintLayout? = null + private lateinit var controlPanel: ConstraintLayout private var apiKey: String? = null private var sessionId: String? = null @@ -300,7 +300,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun hiddenButtons() { mVolHandler = Handler() - mVolRunnable = Runnable { controlPanel!!.visibility = View.GONE } + mVolRunnable = Runnable { controlPanel.visibility = View.GONE } mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) } @@ -496,27 +496,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun onMiniCircleClicked(){ if (isCircle) { + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) dialog?.window?.setLayout( 400, 600 ) - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) } else { + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) dialog?.window?.setLayout( 200, 200 ) - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) } isCircle = !isCircle if(isCircle){ - controlPanel?.visibility = View.GONE + controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { - controlPanel?.visibility = View.VISIBLE + controlPanel.visibility = View.VISIBLE layoutMini.visibility = View.VISIBLE } } @@ -612,10 +612,10 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.height = remotePreviewIconSizeSmall if(isCircle){ - controlPanel?.visibility = View.GONE + controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { - controlPanel?.visibility = View.VISIBLE + controlPanel.visibility = View.VISIBLE layoutMini.visibility = View.VISIBLE } } @@ -722,9 +722,11 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun showControlPanelTemporarily() { - controlPanel!!.visibility = View.VISIBLE - mVolHandler!!.removeCallbacks(mVolRunnable!!) - mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + if (!isCircle){ + controlPanel.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } } /* Reset position of Floating Widget view on dragging */ diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml index 300a9358..128a7430 100644 --- a/android/app/src/main/res/drawable/ic_mini.xml +++ b/android/app/src/main/res/drawable/ic_mini.xml @@ -1,5 +1,5 @@ - + diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index efc97746..a7470da3 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -37,9 +37,9 @@ android:id="@+id/cmTimer" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:padding="4dp" android:textColor="@color/white" android:textSize="16sp" - android:padding="4dp" android:textStyle="bold" tools:text="25:45" /> @@ -47,39 +47,38 @@ - - - - - + app:layout_constraintTop_toBottomOf="@+id/layout_name"> + + + + + android:src="@drawable/camera_back" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" /> Date: Thu, 17 Jun 2021 10:14:00 +0300 Subject: [PATCH 200/241] fix drop video call issue --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 4 ++-- lib/config/config.dart | 4 ++-- .../model/patient_muse/PatientSearchRequestModel.dart | 3 ++- lib/core/service/VideoCallService.dart | 8 ++++---- lib/core/viewModel/scan_qr_view_model.dart | 2 +- .../profile/profile_screen/patient_profile_screen.dart | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 9a2deab6..66777d93 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -358,7 +358,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") // dialog?.dismiss() } @@ -398,7 +398,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") // dialog?.dismiss() } diff --git a/lib/config/config.dart b/lib/config/config.dart index 8241b36c..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/model/patient_muse/PatientSearchRequestModel.dart b/lib/core/model/patient_muse/PatientSearchRequestModel.dart index 2918a393..c2658c9f 100644 --- a/lib/core/model/patient_muse/PatientSearchRequestModel.dart +++ b/lib/core/model/patient_muse/PatientSearchRequestModel.dart @@ -12,7 +12,7 @@ class PatientSearchRequestModel { String mobileNo; String identificationNo; int nursingStationID; - int clinicID; + int clinicID=0; PatientSearchRequestModel( {this.doctorID = 0, @@ -63,6 +63,7 @@ class PatientSearchRequestModel { data['IdentificationNo'] = this.identificationNo; data['NursingStationID'] = this.nursingStationID; data['ClinicID'] = this.clinicID; + data['ProjectID'] = 0; return data; } } diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 0ae61a55..b3bc3c8d 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: startCallRes.openTokenID, - kSessionId: startCallRes.openSessionID, - kApiKey: '46209962',//'46209962', + kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//tartCallRes.openTokenID, + kSessionId: '1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg',//startCallRes.openSessionID, + kApiKey: '47247954',//'46209962', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -79,7 +79,7 @@ class VideoCallService extends BaseService{ endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - await _liveCarePatientServices.endCall(endCallReq); + // await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/scan_qr_view_model.dart b/lib/core/viewModel/scan_qr_view_model.dart index ff934f79..86e975e3 100644 --- a/lib/core/viewModel/scan_qr_view_model.dart +++ b/lib/core/viewModel/scan_qr_view_model.dart @@ -13,7 +13,7 @@ class ScanQrViewModel extends BaseViewModel { await getDoctorProfile(); setState(ViewState.Busy); - await _scanQrService.getInPatient(requestModel, false); + await _scanQrService.getInPatient(requestModel, true); if (_scanQrService.hasError) { error = _scanQrService.error; diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 9aa95d16..d0117b40 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -343,14 +343,14 @@ class _PatientProfileScreenState extends State var asd = ""; } else { GifLoaderDialogUtils.showMyDialog(context); - // await model.startCall( isReCall : false, vCID: patient.vcId); + // await model.startCall( isReCall : false, vCID: patient.vcId); if(model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { await model.getDoctorProfile(); - // patient.appointmentNo = model.startCallRes.appointmentNo; + // patient.appointmentNo = model.startCallRes.appointmentNo; patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); From 3c2abb66c62d2ba59218a7ef77bcd9622059a66b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 10:29:52 +0300 Subject: [PATCH 201/241] add video call permissions --- .../com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 52bafdfb..833855a0 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -329,7 +329,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session @AfterPermissionGranted(RC_VIDEO_APP_PERM) private fun requestPermissions() { - val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA) + val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.CALL_PHONE) if (EasyPermissions.hasPermissions(requireContext(), *perms)) { try { mSession = Session.Builder(context, apiKey, sessionId).build() @@ -496,19 +496,19 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private fun onMiniCircleClicked(){ if (isCircle) { - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) dialog?.window?.setLayout( 400, 600 ) + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) } else { - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) dialog?.window?.setLayout( 200, 200 ) + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) } isCircle = !isCircle From 654a86a9b64d7cf8c58d8232c9d17916e276fdc4 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 17 Jun 2021 12:17:56 +0300 Subject: [PATCH 202/241] Add App Permissions Utils --- lib/core/service/VideoCallService.dart | 1 + .../patient_profile_screen.dart | 6 +- lib/util/NotificationPermissionUtils.dart | 42 +++++++++ lib/widgets/dialog/AskPermissionDialog.dart | 90 +++++++++++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 lib/util/NotificationPermissionUtils.dart create mode 100644 lib/widgets/dialog/AskPermissionDialog.dart diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index b3bc3c8d..53739c9c 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -70,6 +70,7 @@ class VideoCallService extends BaseService{ }); }); + } Future endCall(int vCID, bool isPatient) async { hasError = false; diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index d0117b40..ea61359a 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -13,6 +13,7 @@ import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/NotificationPermissionUtils.dart'; import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; @@ -354,7 +355,10 @@ class _PatientProfileScreenState extends State patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); - locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + }); + // await VideoChannel.openVideoCallScreen( // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, diff --git a/lib/util/NotificationPermissionUtils.dart b/lib/util/NotificationPermissionUtils.dart new file mode 100644 index 00000000..8950fae3 --- /dev/null +++ b/lib/util/NotificationPermissionUtils.dart @@ -0,0 +1,42 @@ +import 'package:doctor_app_flutter/widgets/dialog/AskPermissionDialog.dart'; +import 'package:doctor_app_flutter/widgets/transitions/slide_up_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +class AppPermissionsUtils { + + static requestVideoCallPermission({BuildContext context, String type,Function onTapGrant}) async { + + var cameraPermission = Permission.camera; + var microphonePermission = Permission.microphone; + PermissionStatus permissionCameraStatus = await cameraPermission.status; + PermissionStatus permissionMicrophoneStatus = await microphonePermission.status; + + if (permissionCameraStatus.isPermanentlyDenied || permissionMicrophoneStatus.isPermanentlyDenied) { + await _showPermissionDialog(context, type,onTapGrant); + } else if (!permissionCameraStatus.isGranted || !permissionMicrophoneStatus.isGranted) { + permissionCameraStatus = await cameraPermission.request(); + permissionMicrophoneStatus = await microphonePermission.request(); + if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } else if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } + + static _showPermissionDialog(BuildContext context, String type,Function onTapGrant) async { + Navigator.push( + context, SlideUpPageRoute(widget: AskPermissionDialog(type: type,onTapGrant: onTapGrant,))); + } + + static Future isVideoCallPermissionGranted() async { + PermissionStatus permissionCameraStatus = await Permission.camera.status; + PermissionStatus permissionMicrophoneStatus = await Permission.microphone.status; + return permissionCameraStatus.isGranted && permissionMicrophoneStatus.isGranted; + } +} diff --git a/lib/widgets/dialog/AskPermissionDialog.dart b/lib/widgets/dialog/AskPermissionDialog.dart new file mode 100644 index 00000000..58718373 --- /dev/null +++ b/lib/widgets/dialog/AskPermissionDialog.dart @@ -0,0 +1,90 @@ +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/secondary_button.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class AskPermissionDialog extends StatefulWidget { + final String type; + final Function onTapGrant; + + AskPermissionDialog({this.type, this.onTapGrant}); + + @override + _AskPermissionDialogState createState() => _AskPermissionDialogState(); +} + +class _AskPermissionDialogState extends State { + getText() { + return "Turn on your Camera, Microphone to start video call"; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 0.5, + actions: [ + Padding( + padding: EdgeInsets.only(right: 18.0), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: Feedback.wrapForTap(() { + Navigator.pop(context); + }, context), + child: + Icon(EvaIcons.close, color: Theme.of(context).primaryColor), + ), + ) + ], + ), + body: Container( + margin: EdgeInsets.symmetric(horizontal: 48), + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + "🙋‍♀", + style: "headline1", + color: Colors.black, + ), + AppText( + "Don't miss out!", + style: "headline4", + color: Colors.black, + ), + SizedBox( + height: 8, + ), + AppText( + getText(), + color: Colors.grey, + style: "bodyText2", + textAlign: TextAlign.center, + ), + SizedBox( + height: MediaQuery.of(context).size.height / 6, + ), + AppButton( + fontColor: Theme.of(context).backgroundColor, + color: Colors.red[700], + title: "Turn On Camera, Microphone", + onPressed: () async { + openAppSettings().then((value) { + Navigator.pop(context); + widget.onTapGrant(); + }); + }, + ), + ], + ), + ), + ), + ); + } +} From c67f3d10ad1b43b2d9e7c7e289e5384f297da1c8 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 13:54:50 +0300 Subject: [PATCH 203/241] fix circle video stream --- .../hmgDr/ui/fragment/VideoCallFragment.kt | 96 +++-- .../hmg/hmgDr/util/DynamicVideoRenderer.kt | 379 ++++++++++++++++++ .../util/ThumbnailCircleVideoRenderer.kt | 357 +++++++++++++++++ .../main/res/layout/activity_video_call.xml | 13 +- 4 files changed, 817 insertions(+), 28 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 833855a0..5b98b27d 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -27,6 +27,8 @@ import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView import com.hmg.hmgDr.ui.VideoCallPresenterImpl import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.util.DynamicVideoRenderer +import com.hmg.hmgDr.util.ThumbnailCircleVideoRenderer import com.opentok.android.* import com.opentok.android.PublisherKit.PublisherListener import pub.devrel.easypermissions.AfterPermissionGranted @@ -60,6 +62,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session private var mVolRunnable: Runnable? = null private var mConnectedRunnable: Runnable? = null + private lateinit var thumbnail_container: FrameLayout private lateinit var mPublisherViewContainer: FrameLayout private lateinit var mPublisherViewIcon: View private lateinit var mSubscriberViewContainer: FrameLayout @@ -220,6 +223,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session layoutName = view.findViewById(R.id.layout_name) layoutMini = view.findViewById(R.id.layout_mini) icMini = view.findViewById(R.id.ic_mini) + thumbnail_container = view.findViewById(R.id.thumbnail_container) mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) @@ -345,12 +349,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onConnected(session: Session?) { Log.i(TAG, "Session Connected") - mPublisher = Publisher.Builder(requireContext()).build() + mPublisher = Publisher.Builder(requireContext()) +// .name("publisher") +// .renderer(ThumbnailCircleVideoRenderer(requireContext())) + .build() mPublisher!!.setPublisherListener(this) - mPublisherViewContainer.addView(mPublisher!!.view) - if (mPublisher!!.getView() is GLSurfaceView) { - (mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true) + if (mPublisher!!.view is GLSurfaceView) { + (mPublisher!!.view as GLSurfaceView).setZOrderOnTop(true) } + + mPublisherViewContainer.addView(mPublisher!!.view) mSession!!.publish(mPublisher) if (!resume) { @@ -368,7 +376,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(session: Session, opentokError: OpentokError) { Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) - // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") // dialog?.dismiss() } @@ -391,7 +399,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session return } if (mSubscriber!!.stream == stream) { - mSubscriberViewContainer!!.removeView(mSubscriber!!.view) + mSubscriberViewContainer.removeView(mSubscriber!!.view) mSubscriber!!.destroy() mSubscriber = null } @@ -408,13 +416,49 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") - // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") // dialog?.dismiss() } override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) - mSubscriberViewContainer!!.addView(mSubscriber!!.view) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(mSubscriber!!.view) +// switchToThumbnailCircle() + } + + fun switchToThumbnailCircle() { + thumbnail_container.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(true) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) + thumbnail_container.addView(view) + } + } + switchToFullScreenView() + }, 4000) + } + + fun switchToFullScreenView() { + mSubscriberViewContainer.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(false) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(view) + } + } + switchToThumbnailCircle() + }, 4000) } override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {} @@ -426,7 +470,9 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {} private fun subscribeToStream(stream: Stream) { - mSubscriber = Subscriber.Builder(requireContext(), stream).build() + mSubscriber = Subscriber.Builder(requireContext(), stream) + .renderer(DynamicVideoRenderer(requireContext())) + .build() mSubscriber!!.setVideoListener(this) mSession!!.subscribe(mSubscriber) } @@ -488,31 +534,29 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session disconnectSession() } - private fun miniCircleDoubleTap(){ - if (isCircle){ + private fun miniCircleDoubleTap() { + if (isCircle) { onMiniCircleClicked() } } - private fun onMiniCircleClicked(){ + private fun onMiniCircleClicked() { if (isCircle) { dialog?.window?.setLayout( 400, 600 ) - videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) - mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.remoteBackground)) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) } else { dialog?.window?.setLayout( - 200, - 200 + 300, + 300 ) - videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) - mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) } isCircle = !isCircle - if(isCircle){ + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { @@ -548,16 +592,16 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams - val localPreviewMargin : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() - val localPreviewWidth : Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() - val localPreviewHeight : Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() + val localPreviewMargin: Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() + val localPreviewWidth: Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() + val localPreviewHeight: Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() // val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() // val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() // val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() // val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() // val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() // val localPreviewLayoutIconParam : FrameLayout.LayoutParams - val localPreviewLayoutParam : RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + val localPreviewLayoutParam: RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() @@ -611,7 +655,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session remotePreviewLayoutParam.width = remotePreviewIconSizeSmall remotePreviewLayoutParam.height = remotePreviewIconSizeSmall - if(isCircle){ + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE } else { @@ -651,7 +695,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session isSpeckerClicked = !isSpeckerClicked mSubscriber!!.subscribeToAudio = !isSpeckerClicked val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled - mspeckerBtn!!.setImageResource(res) + mspeckerBtn.setImageResource(res) } } @@ -722,7 +766,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } private fun showControlPanelTemporarily() { - if (!isCircle){ + if (!isCircle) { controlPanel.visibility = View.VISIBLE mVolHandler!!.removeCallbacks(mVolRunnable!!) mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt new file mode 100644 index 00000000..1a307eb5 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt @@ -0,0 +1,379 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + +/* +* https://nhancv.medium.com/android-how-to-make-a-circular-view-as-a-thumbnail-of-opentok-27992aee15c9 +* to solve make circle video stream +* */ + +class DynamicVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface DynamicVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setDynamicVideoRendererMetadataListener(metadataListener: DynamicVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + fun enableThumbnailCircle(enable: Boolean) { + mRenderer.requestEnableThumbnailCircle = enable + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var requestEnableThumbnailCircle = false + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform int enableCircle; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + if (enableCircle > 0) { + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); + } + else { + gl_FragColor = vec4(r, g, b, 1.0); + } +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun enableThumbnailCircle(enable: Boolean) { + GLES20.glUseProgram(mProgram) + val enableCircleLocation = GLES20.glGetUniformLocation(mProgram, "enableCircle") + GLES20.glUniform1i(enableCircleLocation, if (enable) 1 else 0) + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: DynamicVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + enableThumbnailCircle(requestEnableThumbnailCircle) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt new file mode 100644 index 00000000..b9b5a245 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt @@ -0,0 +1,357 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + + +class ThumbnailCircleVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface ThumbnailCircleVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setThumbnailCircleVideoRendererMetadataListener(metadataListener: ThumbnailCircleVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: ThumbnailCircleVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index a7470da3..a54e57b3 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -97,8 +97,7 @@ android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_marginTop="@dimen/local_preview_margin_top" - android:layout_marginEnd="@dimen/local_preview_margin_top" - android:background="@color/localBackground"> + android:layout_marginEnd="@dimen/local_preview_margin_top"> + + Date: Thu, 17 Jun 2021 15:43:49 +0300 Subject: [PATCH 204/241] fix disconected stream --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index 5b98b27d..d89c939c 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -371,6 +371,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) mSession = null cmTimer.stop() + disconnectSession() } override fun onError(session: Session, opentokError: OpentokError) { @@ -477,11 +478,6 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession!!.subscribe(mSubscriber) } - override fun dismiss() { - videoCallResponseListener?.onCallFinished(1000) - super.dismiss() - } - private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) @@ -489,6 +485,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session dialog?.dismiss() return } + if (mSubscriber != null) { mSubscriberViewContainer.removeView(mSubscriber!!.view) mSession!!.unsubscribe(mSubscriber) @@ -503,6 +500,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session } mSession!!.disconnect() countDownTimer?.cancel() + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) dialog?.dismiss() } From 02f43d6e61ed77836baa035df98f108b96d23431 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 16:08:03 +0300 Subject: [PATCH 205/241] fix timer issue --- .../kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 4 +++- .../profile/profile_screen/patient_profile_screen.dart | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index d89c939c..be1ed9d4 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -365,6 +365,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session cmTimer.base = SystemClock.elapsedRealtime() } cmTimer.start() + videoCallResponseListener?.minimizeVideoEvent(true) } override fun onDisconnected(session: Session) { @@ -372,6 +373,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session mSession = null cmTimer.stop() disconnectSession() + videoCallResponseListener?.minimizeVideoEvent(false) } override fun onError(session: Session, opentokError: OpentokError) { @@ -581,7 +583,7 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session btnMinimize.setImageResource(res) setViewsVisibility() - videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) +// videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) } private fun setViewsVisibility() { diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index ea61359a..0a05b596 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -105,7 +105,7 @@ class _PatientProfileScreenState extends State StreamSubscription callTimer; callConnected(){ - callTimer = CountdownTimer(Duration(minutes: 1), Duration(seconds: 1)).listen(null) + callTimer = CountdownTimer(Duration(minutes: 90), Duration(seconds: 1)).listen(null) ..onDone(() { callTimer.cancel(); }) From c585cbb5be345162bb171e34bcd352f9f4c2c181 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Thu, 17 Jun 2021 16:35:43 +0300 Subject: [PATCH 206/241] fix timer issue --- .../hmg/hmgDr/ui/fragment/VideoCallFragment.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt index be1ed9d4..35e28b23 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -546,16 +546,27 @@ class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.Session 400, 600 ) - (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) } else { dialog?.window?.setLayout( 300, 300 ) - (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) } isCircle = !isCircle + if (mSubscriber != null) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(isCircle) + } else { + if (isCircle) { + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + } else { + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + } + + } + if (isCircle) { controlPanel.visibility = View.GONE layoutMini.visibility = View.GONE From 61c94f85b271affbeb16ba41ec10b3c7ee5a1982 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Thu, 17 Jun 2021 16:47:31 +0300 Subject: [PATCH 207/241] fix the end call --- lib/core/service/VideoCallService.dart | 8 +-- .../viewModel/patient-referral-viewmodel.dart | 2 +- lib/models/patient/patiant_info_model.dart | 11 ++-- lib/screens/live_care/end_call_screen.dart | 11 +++- .../patient_profile_screen.dart | 56 ++---------------- lib/screens/procedures/ProcedureCard.dart | 59 +------------------ 6 files changed, 28 insertions(+), 119 deletions(-) diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 53739c9c..f72544a0 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -27,9 +27,9 @@ class VideoCallService extends BaseService{ this.patient = patientModel; DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//tartCallRes.openTokenID, - kSessionId: '1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg',//startCallRes.openSessionID, - kApiKey: '47247954',//'46209962', + kToken: startCallRes.openTokenID,//"T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", + kSessionId:startCallRes.openSessionID,//1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg + kApiKey: '46209962',//'47247954' vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await sharedPref.getString(TOKEN), @@ -80,7 +80,7 @@ class VideoCallService extends BaseService{ endCallReq.generalid = 'Cs2020@2016\$2958'; endCallReq.vCID = vCID; endCallReq.isDestroy = isPatient; - // await _liveCarePatientServices.endCall(endCallReq); + await _liveCarePatientServices.endCall(endCallReq); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error; } diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 9e852978..0351db77 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -240,7 +240,7 @@ class PatientReferralViewModel extends BaseViewModel { patientID: patient.patientId, roomID: patient.roomId, referralClinic: clinicID, - admissionNo: patient.appointmentNo, + admissionNo: int.parse(patient.admissionNo), referralDoctor: doctorID, patientTypeID: patient.patientType, referringDoctorRemarks: remarks, diff --git a/lib/models/patient/patiant_info_model.dart b/lib/models/patient/patiant_info_model.dart index 71d46dc9..29dc6198 100644 --- a/lib/models/patient/patiant_info_model.dart +++ b/lib/models/patient/patiant_info_model.dart @@ -224,10 +224,13 @@ class PatiantInformtion { isSigned: json['isSigned'], medicationOrders: json['medicationOrders'], nationality: json['nationality'] ?? json['NationalityNameN'], - patientMRN: json['patientMRN'] ?? json['PatientMRN']?? ( - json["PatientID"] != null ? - int.parse(json["PatientID"].toString()) - : int.parse(json["patientID"].toString())), + patientMRN: json['patientMRN'] ?? + json['PatientMRN'] ?? + (json["PatientID"] != null + ? int?.parse(json["PatientID"].toString()) + : json["patientID"] != null ? int?.parse( + json["patientID"].toString()) : json["patientId"] != null ? int + ?.parse(json["patientId"].toString()) : ''), visitType: json['visitType'] ?? json['visitType'] ?? json['visitType'], nationalityFlagURL: json['NationalityFlagURL'] ?? json['NationalityFlagURL'], diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index d355473d..d3db12b6 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -23,9 +23,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:hexcolor/hexcolor.dart'; class EndCallScreen extends StatefulWidget { + final PatiantInformtion patient; - - const EndCallScreen({Key key,}) : super(key: key); + const EndCallScreen({Key key, this.patient,}) : super(key: key); @override _EndCallScreenState createState() => _EndCallScreenState(); @@ -42,11 +42,18 @@ class _EndCallScreenState extends State { String to; LiveCarePatientViewModel liveCareModel; + @override + void initState() { + super.initState(); + if(widget.patient!=null) + patient = widget.patient; + } @override void didChangeDependencies() { super.didChangeDependencies(); final routeArgs = ModalRoute.of(context).settings.arguments as Map; + if(routeArgs.containsKey('patient')) patient = routeArgs['patient']; } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index ea61359a..03def2f7 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -339,19 +339,18 @@ class _PatientProfileScreenState extends State if(isCallFinished) { - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => EndCallScreen(patient:patient))); - var asd = ""; + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) => EndCallScreen(patient:patient))); } else { GifLoaderDialogUtils.showMyDialog(context); - // await model.startCall( isReCall : false, vCID: patient.vcId); + await model.startCall( isReCall : false, vCID: patient.vcId); if(model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Helpers.showErrorToast(model.error); } else { await model.getDoctorProfile(); - // patient.appointmentNo = model.startCallRes.appointmentNo; + patient.appointmentNo = model.startCallRes.appointmentNo; patient.episodeNo = 0; GifLoaderDialogUtils.hideDialog(context); @@ -360,53 +359,6 @@ class _PatientProfileScreenState extends State }); - // await VideoChannel.openVideoCallScreen( - // kToken: "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==",//model.startCallRes.openTokenID, - // kSessionId:"1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg",// model.startCallRes.openSessionID, - // kApiKey: '47247954',//46209962 - // vcId: patient.vcId, - // patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), - // tokenID: await model.getToken(), - // generalId: GENERAL_ID, - // doctorId: model.doctorProfile.doctorID, - // onFailure: (String error) { - // DrAppToastMsg.showErrorToast(error); - // },onCallConnected: callConnected, - // onCallEnd: () { - // var asd=""; - // WidgetsBinding.instance.addPostFrameCallback((_) { - // GifLoaderDialogUtils.showMyDialog(context); - // model.endCall(patient.vcId, false,).then((value) { - // GifLoaderDialogUtils.hideDialog(context); - // if (model.state == ViewState.ErrorLocal) { - // DrAppToastMsg.showErrorToast(model.error); - // } - // setState(() { - // isCallFinished = true; - // }); - // }); - // }); - // Navigator.push(context, MaterialPageRoute( - // builder: (BuildContext context) => - // EndCallScreen(patient:patient))); - // }, - // onCallNotRespond: (SessionStatusModel sessionStatusModel) { - // var asd=""; - // // WidgetsBinding.instance.addPostFrameCallback((_) { - // // GifLoaderDialogUtils.showMyDialog(context); - // // model.endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { - // // GifLoaderDialogUtils.hideDialog(context); - // // if (model.state == ViewState.ErrorLocal) { - // // DrAppToastMsg.showErrorToast(model.error); - // // } - // // setState(() { - // // isCallFinished = true; - // // }); - // // }); - // // - // // }); - // }); - } } diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index d998ca58..31611b67 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -18,7 +18,7 @@ class ProcedureCard extends StatelessWidget { final int categoryID; final PatiantInformtion patient; final int doctorID; - + final bool isInpatient; const ProcedureCard({ Key key, this.onTap, @@ -26,7 +26,7 @@ class ProcedureCard extends StatelessWidget { this.categoryID, this.categoryName, this.patient, - this.doctorID, + this.doctorID, this.isInpatient = false, }) : super(key: key); @override @@ -132,36 +132,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).doctorName + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.doctorName.toString(), - // fontSize: 12, - // bold: true, - // ), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).clinic + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.clinicDescription ?? "", - // bold: true, - // fontSize: 12, - // ), - // ], - // ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -222,27 +192,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - /*Container( - alignment: Alignment.centerRight, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FlowChartPage( - filterName: entityList.procedureName, - patient: patient, - ), - ), - ); - }, - child: AppText( - TranslationBase.of(context).showMoreBtn, - textDecoration: TextDecoration.underline, - color: Colors.blue, - ), - ), - ),*/ Padding( padding: const EdgeInsets.all(8.0), child: Row( @@ -254,9 +203,7 @@ class ProcedureCard extends StatelessWidget { fontSize: 12, ), ), - if ((entityList.categoryID == 2 || - entityList.categoryID == 4) && - doctorID == entityList.doctorID) + if ((entityList.categoryID == 2 || entityList.categoryID == 4) && doctorID == entityList.doctorID && !isInpatient) InkWell( child: Icon(DoctorApp.edit), onTap: onTap, From 7fed1c58f3716468f92dc5115093c5a0eb6696ba Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 21 Jun 2021 09:21:21 +0300 Subject: [PATCH 208/241] working to open video stream from service --- android/app/src/main/AndroidManifest.xml | 3 + .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 73 ++++++++++++++--- .../Service/VideoStreamContainerService.kt | 30 +++++++ .../hmgDr/ui/fragment/VideoCallFragment.kt | 33 ++++++-- lib/core/service/VideoCallService.dart | 80 ++++++++++++------- .../viewModel/authentication_view_model.dart | 2 +- .../patient_profile_screen.dart | 11 +-- 7 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamContainerService.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index bf0d3766..0ac76ea8 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -40,6 +40,9 @@ + + + 60dp 54dp - 52dp + 48dp 24dp @@ -33,9 +33,15 @@ 4dp - 8sp + 8dp 16dp 24dp + 36dp + 60dp + 80dp + 40dp + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index e13b5b14..dae5749f 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,10 +1,12 @@ + + @@ -25,12 +27,17 @@ true - true + true + true + false @null match_parent match_parent + + @android:style/Animation.Dialog + From a7c5e1afde3633edbf5af998d74ee67d7a2efede Mon Sep 17 00:00:00 2001 From: mosazaid Date: Sun, 27 Jun 2021 17:50:08 +0300 Subject: [PATCH 228/241] finish solve keybaord issue --- .../main/kotlin/com/hmg/hmgDr/MainActivity.kt | 83 ++++++++++--------- lib/core/service/VideoCallService.dart | 13 ++- .../viewModel/authentication_view_model.dart | 2 +- .../live_care/live_care_patient_screen.dart | 30 +++---- .../patient_profile_screen.dart | 11 ++- 5 files changed, 69 insertions(+), 70 deletions(-) diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index f14dd823..f8b3f3ae 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -16,6 +16,7 @@ import com.hmg.hmgDr.Model.GetSessionStatusModel import com.hmg.hmgDr.Model.SessionStatusModel import com.hmg.hmgDr.Service.VideoStreamContainerService import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.ui.fragment.VideoCallFragment import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall @@ -32,6 +33,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, private var call: MethodCall? = null private val LAUNCH_VIDEO: Int = 1 + private var dialogFragment: VideoCallFragment? = null private var serviceIntent: Intent? = null private var videoStreamService: VideoStreamContainerService? = null private var bound = false @@ -105,7 +107,7 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, putExtras(arguments) startService(this) } - bindService() +// bindService() } /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -135,9 +137,8 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, }*/ override fun onCallFinished(resultCode: Int, intent: Intent?) { - // TODO uncomment it - /*if (resultCode == Activity.RESULT_OK) { + if (resultCode == Activity.RESULT_OK) { val result: SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") val callResponse: HashMap = HashMap() @@ -162,10 +163,10 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, Log.e("onVideoCallFinished", "${e.message}.") } } - */ - stopService(serviceIntent) - unbindService() - videoStreamService!!.serviceRunning = false + +// stopService(serviceIntent) +// unbindService() +// videoStreamService!!.serviceRunning = false } override fun minimizeVideoEvent(isMinimize: Boolean) { @@ -189,40 +190,40 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // unbindService() // } - private fun bindService() { - serviceIntent?.run { - if (videoStreamService != null && !videoStreamService!!.serviceRunning){ - startService(this) - } - bindService(this, serviceConnection, Context.BIND_AUTO_CREATE) - videoStreamService?.serviceRunning = true - } - } - - private fun unbindService() { - if (bound) { - videoStreamService!!.videoCallResponseListener = null // unregister - videoStreamService!!.mActivity = null - unbindService(serviceConnection) - bound = false - } - } - - private val serviceConnection: ServiceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, service: IBinder?) { - val binder: VideoStreamContainerService.VideoStreamBinder = - service as VideoStreamContainerService.VideoStreamBinder - videoStreamService = binder.service - bound = true - videoStreamService!!.videoCallResponseListener = this@MainActivity // register - videoStreamService!!.mActivity = this@MainActivity // register - } - - override fun onServiceDisconnected(name: ComponentName?) { - bound = false - } - - } +// private fun bindService() { +// serviceIntent?.run { +// if (videoStreamService != null && !videoStreamService!!.serviceRunning){ +// startService(this) +// } +// bindService(this, serviceConnection, Context.BIND_AUTO_CREATE) +// videoStreamService?.serviceRunning = true +// } +// } +// +// private fun unbindService() { +// if (bound) { +// videoStreamService!!.videoCallResponseListener = null // unregister +// videoStreamService!!.mActivity = null +// unbindService(serviceConnection) +// bound = false +// } +// } +// +// private val serviceConnection: ServiceConnection = object : ServiceConnection { +// override fun onServiceConnected(name: ComponentName?, service: IBinder?) { +// val binder: VideoStreamContainerService.VideoStreamBinder = +// service as VideoStreamContainerService.VideoStreamBinder +// videoStreamService = binder.service +// bound = true +// videoStreamService!!.videoCallResponseListener = this@MainActivity // register +// videoStreamService!!.mActivity = this@MainActivity // register +// } +// +// override fun onServiceDisconnected(name: ComponentName?) { +// bound = false +// } +// +// } // code to hide soft keyboard fun hideSoftKeyBoard(editBox: EditText?) { diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart index 82ace4b4..58caf079 100644 --- a/lib/core/service/VideoCallService.dart +++ b/lib/core/service/VideoCallService.dart @@ -29,13 +29,12 @@ class VideoCallService extends BaseService { DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); await VideoChannel.openVideoCallScreen( - kToken: - "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", - // startCallRes.openTokenID, - kSessionId: - "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", - //startCallRes.openSessionID, - kApiKey: '47247954',//'46209962' + kToken: startCallRes.openTokenID, + // "T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", + kSessionId: startCallRes.openSessionID, + // "1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg", + + kApiKey:'46209962', //'47247954', vcId: patient.vcId, patientName: patient.fullName ?? (patient.firstName != null diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a161c861..cae415da 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -255,7 +255,7 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess(SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); - DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); + // DrAppToastMsg.showSuccesToast("_VerificationCode_ : " + sendActivationCodeForDoctorAppResponseModel.verificationCode); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 100679cc..911687c9 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -173,21 +173,21 @@ class _LiveCarePatientScreenState extends State { child: AppLoaderWidget( containerColor: Colors.transparent, )), - AppButton( - fontWeight: FontWeight.w700, - color:Colors.green[600], - title: TranslationBase.of(context).initiateCall, - disabled: model.state == ViewState.BusyLocal, - onPressed: () async { - AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ - locator().openVideo(model.startCallRes, PatiantInformtion( - vcId: 454353, - fullName: "test mosa" - ), callConnected, callDisconnected); - }); - - }, - ), + // AppButton( + // fontWeight: FontWeight.w700, + // color:Colors.green[600], + // title: TranslationBase.of(context).initiateCall, + // disabled: model.state == ViewState.BusyLocal, + // onPressed: () async { + // AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + // locator().openVideo(model.startCallRes, PatiantInformtion( + // vcId: 454353, + // fullName: "test mosa" + // ), callConnected, callDisconnected); + // }); + // + // }, + // ), ], ), ), diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index 19dd6b98..4dc49b15 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -306,12 +306,11 @@ class _PatientProfileScreenState extends State with Single // builder: (BuildContext context) => // EndCallScreen(patient:patient))); - // TODO MOSA REMOVE THIS - AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ - locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); - }); + // AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + // locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + // }); - /* if(isCallFinished) { + if(isCallFinished) { Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) => EndCallScreen(patient:patient))); } else { @@ -333,7 +332,7 @@ class _PatientProfileScreenState extends State with Single locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); }); } - }*/ + } }, ), From 783c74108b81221ae6ed64642603fe64c8408892 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 10:52:28 +0300 Subject: [PATCH 229/241] video isRecord change --- android/app/src/main/res/layout/activity_video_call.xml | 2 +- .../profile/profile_screen/patient_profile_screen.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index 8dc33094..03c55729 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -121,8 +121,8 @@ android:id="@+id/record_icon" android:layout_width="@dimen/local_back_icon_size" android:layout_height="@dimen/local_back_icon_size" - android:layout_gravity="center" android:scaleType="centerCrop" + android:layout_margin="5dp" android:src="@drawable/ic_record" /> diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index d8410da1..a1da7882 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -309,7 +309,7 @@ class _PatientProfileScreenState extends State with Single // .openVideo( // model.startCallRes, // patient, - // false, callConnected, // model.startCallRes.isRecording + // model.startCallRes != null ? model.startCallRes.isRecording : true, callConnected, // callDisconnected); // }); if (isCallFinished) { @@ -349,7 +349,7 @@ class _PatientProfileScreenState extends State with Single .openVideo( model.startCallRes, patient, - /*model.startCallRes != null ? model.startCallRes.isRecording : */ true + model.startCallRes != null ? model.startCallRes.isRecording : true , callConnected, callDisconnected); }); From 1e35b70b010d716930053baf45c973f811cb2a7a Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Mon, 28 Jun 2021 12:13:40 +0300 Subject: [PATCH 230/241] medical report fix --- .../PatientMedicalReportViewModel.dart | 19 +- lib/core/viewModel/base_view_model.dart | 14 +- lib/locator.dart | 2 +- .../AddVerifyMedicalReport.dart | 215 ++++++++++-------- .../medical_report/MedicalReportPage.dart | 57 +++-- 5 files changed, 168 insertions(+), 139 deletions(-) diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index 7866fa69..ac5ecdeb 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -24,19 +24,8 @@ class PatientMedicalReportViewModel extends BaseViewModel { setState(ViewState.Idle); } - bool hasOnHold() { - bool hasHold = false; - medicalReportList.forEach((element) { - if (element.status == 1) { - hasHold = true; - } - }); - - return hasHold; - } - Future getMedicalReportTemplate() async { - setState(ViewState.BusyLocal); + setState(ViewState.Busy); await _service.getMedicalReportTemplate(); if (_service.hasError) { error = _service.error; @@ -62,7 +51,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } @@ -73,7 +62,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } @@ -84,7 +73,7 @@ class PatientMedicalReportViewModel extends BaseViewModel { error = _service.error; setState(ViewState.ErrorLocal); } else - getMedicalReportList(patient); + await getMedicalReportList(patient); setState(ViewState.Idle); } } diff --git a/lib/core/viewModel/base_view_model.dart b/lib/core/viewModel/base_view_model.dart index 9d7032aa..794706a6 100644 --- a/lib/core/viewModel/base_view_model.dart +++ b/lib/core/viewModel/base_view_model.dart @@ -19,12 +19,12 @@ class BaseViewModel extends ChangeNotifier { void setState(ViewState viewState) { _state = viewState; + notifyListeners(); } Future getDoctorProfile({bool isGetProfile = false}) async { - if(isGetProfile) - { + if (isGetProfile) { Map profile = await sharedPref.getObj(DOCTOR_PROFILE); if (profile != null) { doctorProfile = DoctorProfileModel.fromJson(profile); @@ -46,10 +46,10 @@ class BaseViewModel extends ChangeNotifier { return doctorProfile; } } - - setDoctorProfile(DoctorProfileModel doctorProfile)async { - await sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); - this.doctorProfile = doctorProfile; - notifyListeners(); + + setDoctorProfile(DoctorProfileModel doctorProfile) async { + await sharedPref.setObj(DOCTOR_PROFILE, doctorProfile); + this.doctorProfile = doctorProfile; + notifyListeners(); } } diff --git a/lib/locator.dart b/lib/locator.dart index e2c578df..d74fad8b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -124,6 +124,6 @@ void setupLocator() { locator.registerFactory(() => PatientSearchViewModel()); locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => LiveCarePatientViewModel()); - locator.registerLazySingleton(() => PatientMedicalReportViewModel()); + locator.registerFactory(() => PatientMedicalReportViewModel()); locator.registerFactory(() => ScanQrViewModel()); } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 304b39ac..4a6be6c8 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -1,13 +1,10 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.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/screens/patients/profile/medical_report/MedicalReportPage.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; @@ -15,9 +12,27 @@ import 'package:doctor_app_flutter/widgets/shared/text_fields/html_rich_editor.d import 'package:flutter/material.dart'; import 'package:html_editor_enhanced/html_editor.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:provider/provider.dart'; class AddVerifyMedicalReport extends StatefulWidget { + final PatiantInformtion patient; + final String patientType; + final String arrivalType; + final MedicalReportModel medicalReport; + final PatientMedicalReportViewModel model; + final MedicalReportStatus status; + final String medicalNote; + + const AddVerifyMedicalReport( + {Key key, + this.patient, + this.patientType, + this.arrivalType, + this.medicalReport, + this.model, + this.status, + this.medicalNote}) + : super(key: key); + @override _AddVerifyMedicalReportState createState() => _AddVerifyMedicalReportState(); } @@ -25,121 +40,121 @@ class AddVerifyMedicalReport extends StatefulWidget { class _AddVerifyMedicalReportState extends State { @override Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - PatientMedicalReportViewModel patientMedicalReportViewModel = routeArgs['model']; - PatiantInformtion patient = routeArgs['patient']; - MedicalReportStatus status = routeArgs['status'] as MedicalReportStatus; - MedicalReportModel medicalReport = routeArgs.containsKey("medicalReport") ? routeArgs['medicalReport'] : null; + String txtOfMedicalReport; return BaseView( - onModelReady: (_) => patientMedicalReportViewModel.getMedicalReportTemplate(), + onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBarTitle: status == MedicalReportStatus.ADD + appBarTitle: widget.status == MedicalReportStatus.ADD ? TranslationBase.of(context).medicalReportAdd : TranslationBase.of(context).medicalReportVerify, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: model.state == ViewState.BusyLocal - ? AppLoaderWidget() - : Column( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.all(16), - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // if (model.medicalReportTemplate.length > 0) - HtmlRichEditor( - initialText: (medicalReport != null - ? medicalReport.reportDataHtml - : model.medicalReportTemplate[0].templateText.length > 0 - ? model.medicalReportTemplate[0].templateText - : ""), - hint: "Write the medical report ", - height: MediaQuery.of(context).size.height * 0.75, - ), - ], + body: Column( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.all(16), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (model.medicalReportTemplate.length > 0) + HtmlRichEditor( + initialText: (widget.medicalReport != null + ? widget.medicalNote + : widget.model.medicalReportTemplate[0].templateText.length > 0 + ? widget.model.medicalReportTemplate[0].templateText + : ""), + hint: "Write the medical report ", + height: MediaQuery.of(context).size.height * 0.75, ), - ), - ), + ], ), - ], + ), ), ), - ), - Container( - padding: EdgeInsets.all(16.0), - color: Colors.white, - child: Row( - children: [ - Expanded( - child: AppButton( - title: status == MedicalReportStatus.ADD - ? TranslationBase.of(context).save - : TranslationBase.of(context).save, - color: Color(0xffEAEAEA), - fontColor: Colors.black, - // disabled: progressNoteController.text.isEmpty, - fontWeight: FontWeight.w700, - onPressed: () async { - String txtOfMedicalReport = await HtmlEditor.getText(); + ], + ), + ), + ), + Container( + padding: EdgeInsets.all(16.0), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: AppButton( + title: widget.status == MedicalReportStatus.ADD + ? TranslationBase.of(context).save + : TranslationBase.of(context).save, + color: Color(0xffEAEAEA), + fontColor: Colors.black, + // disabled: progressNoteController.text.isEmpty, + fontWeight: FontWeight.w700, + onPressed: () async { + txtOfMedicalReport = await HtmlEditor.getText(); - if (txtOfMedicalReport.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - medicalReport != null - ? model.updateMedicalReport( - patient, - txtOfMedicalReport, - medicalReport != null ? medicalReport.lineItemNo : null, - medicalReport != null ? medicalReport.invoiceNo : null) - : model.addMedicalReport(patient, txtOfMedicalReport); - //model.getMedicalReportList(patient); + if (txtOfMedicalReport.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + widget.medicalReport != null + ? widget.model.updateMedicalReport( + widget.patient, + txtOfMedicalReport, + widget.medicalReport != null ? widget.medicalReport.lineItemNo : null, + widget.medicalReport != null ? widget.medicalReport.invoiceNo : null) + : widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); + //model.getMedicalReportList(patient); - Navigator.pop(context); + Navigator.pop(context); - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - } - }, - ), - ), - SizedBox( - width: 8, - ), - if (medicalReport != null) - Expanded( - child: AppButton( - title: status == MedicalReportStatus.ADD - ? TranslationBase.of(context).add - : TranslationBase.of(context).verify, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - GifLoaderDialogUtils.showMyDialog(context); - await model.verifyMedicalReport(patient, medicalReport); - GifLoaderDialogUtils.hideDialog(context); - Navigator.pop(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - }, - ), - ), - ], + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(widget.model.error); + } + } else { + DrAppToastMsg.showErrorToast("Please enter medical note"); + } + }, ), ), + SizedBox( + width: 8, + ), + if (widget.medicalReport != null) + Expanded( + child: AppButton( + title: widget.status == MedicalReportStatus.ADD + ? TranslationBase.of(context).add + : TranslationBase.of(context).verify, + color: Color(0xff359846), + fontWeight: FontWeight.w700, + onPressed: () async { + txtOfMedicalReport = await HtmlEditor.getText(); + if (txtOfMedicalReport.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.model.verifyMedicalReport(widget.patient, widget.medicalReport); + GifLoaderDialogUtils.hideDialog(context); + Navigator.pop(context); + if (widget.model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(widget.model.error); + } + } else { + DrAppToastMsg.showErrorToast("Please enter medical note"); + } + }, + ), + ), ], ), + ), + ], + ), )); } diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 10cb4be6..22645520 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -40,6 +40,7 @@ class _MedicalReportPageState extends State { return BaseView( onModelReady: (model) async { await model.getMedicalReportList(patient); + await model.getMedicalReportTemplate(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, @@ -79,13 +80,25 @@ class _MedicalReportPageState extends State { // Helpers.showErrorToast("Please Verified the on hold report to be able to add new one"); // } else - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'type': MedicalReportStatus.ADD, - 'model': model, - }); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + model: model, + status: MedicalReportStatus.ADD, + )), + ); + + // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + // 'patient': patient, + // 'patientType': patientType, + // 'arrivalType': arrivalType, + // 'type': MedicalReportStatus.ADD, + // 'model': model, + // }); }, label: TranslationBase.of(context).createNewMedicalReport, ), @@ -95,13 +108,25 @@ class _MedicalReportPageState extends State { (index) => InkWell( onTap: () { if (model.medicalReportList[index].status == 1) { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - 'patient': patient, - 'patientType': patientType, - 'arrivalType': arrivalType, - 'medicalReport': model.medicalReportList[index], - 'model': model, - }); + // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + // 'patient': patient, + // 'patientType': patientType, + // 'arrivalType': arrivalType, + // 'medicalReport': model.medicalReportList[index], + // 'model': model, + // }); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddVerifyMedicalReport( + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + medicalReport: model.medicalReportList[index], + model: model, + medicalNote: model.medicalReportList[index].reportDataHtml, + )), + ); } else { Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, @@ -138,8 +163,8 @@ class _MedicalReportPageState extends State { ), AppText( projectViewModel.isArabic - ? model.medicalReportList[index].doctorNameN - : model.medicalReportList[index].doctorName, + ? model.medicalReportList[index].doctorNameN ?? "" + : model.medicalReportList[index].doctorName ?? "", fontSize: 1.9 * SizeConfig.textMultiplier, fontWeight: FontWeight.w700, color: Color(0xFF2E303A), From d839fd3545754b844b6fbbe9db801069c256521d Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 12:19:02 +0300 Subject: [PATCH 231/241] outpatirnt referral changes --- .../viewModel/patient-referral-viewmodel.dart | 3 + .../referral/referred-patient-screen.dart | 13 +- .../referred_patient_detail_in-paint.dart | 195 ++++++++++-------- pubspec.lock | 14 +- 4 files changed, 128 insertions(+), 97 deletions(-) diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 0351db77..08b3feb2 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -322,6 +322,7 @@ class PatientReferralViewModel extends BaseViewModel { patient.doctorId = referredPatient.doctorID; patient.doctorName = referredPatient.doctorName; patient.patientId = referredPatient.patientID; + patient.patientMRN = referredPatient.patientID; patient.firstName = referredPatient.firstName; patient.middleName = referredPatient.middleName; patient.lastName = referredPatient.lastName; @@ -339,6 +340,8 @@ class PatientReferralViewModel extends BaseViewModel { patient.nationalityFlagURL = referredPatient.nationalityFlagURL; patient.age = referredPatient.age; patient.clinicDescription = referredPatient.clinicDescription; + patient.appointmentNo = referredPatient.appointmentNo; + return patient; } diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index c95a28d8..8dce7d60 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -12,8 +12,13 @@ import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -class ReferredPatientScreen extends StatelessWidget { +class ReferredPatientScreen extends StatefulWidget { + @override + _ReferredPatientScreenState createState() => _ReferredPatientScreenState(); +} + +class _ReferredPatientScreenState extends State { PatientType patientType = PatientType.IN_PATIENT; @override @@ -30,7 +35,9 @@ class ReferredPatientScreen extends StatelessWidget { margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( (patientType) async { - this.patientType = patientType; + setState(() { + this.patientType = patientType; + }); GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { await model.getMyReferredPatient(isFirstTime: false); @@ -75,7 +82,7 @@ class ReferredPatientScreen extends StatelessWidget { context, FadePage( page: ReferredPatientDetailScreen( - model.getReferredPatientItem(index)), + model.getReferredPatientItem(index), this.patientType), ), ); }, diff --git a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart index b3f11c51..f6d3b8d7 100644 --- a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -18,8 +19,9 @@ import '../../../../routes.dart'; class ReferredPatientDetailScreen extends StatelessWidget { final MyReferredPatientModel referredPatient; + final PatientType patientType; - ReferredPatientDetailScreen(this.referredPatient); + ReferredPatientDetailScreen(this.referredPatient, this.patientType); @override Widget build(BuildContext context) { @@ -74,7 +76,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { .pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", - "isInpatient": true, + "isInpatient": + patientType == PatientType.IN_PATIENT, "arrivalType": "1", "from": AppDateUtils.convertDateToFormat( DateTime.now(), 'yyyy-MM-dd'), @@ -93,14 +96,15 @@ class ReferredPatientDetailScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( - onTap: (){ + onTap: () { PatiantInformtion patient = - model.getPatientFromReferral(referredPatient); + model.getPatientFromReferral(referredPatient); Navigator.of(context) .pushNamed(PATIENTS_PROFILE, arguments: { "patient": patient, "patientType": "1", - "isInpatient": true, + "isInpatient": + patientType == PatientType.IN_PATIENT, "arrivalType": "1", "from": AppDateUtils.convertDateToFormat( DateTime.now(), 'yyyy-MM-dd'), @@ -236,36 +240,37 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), - if(referredPatient - .frequencyDescription != null) - Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .frequency + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient - .frequencyDescription, + if (referredPatient + .frequencyDescription != + null) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .frequency + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 14, - color: Color(0XFF2E303A), + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - ), - ], - ), + Expanded( + child: AppText( + referredPatient + .frequencyDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 14, + color: Color(0XFF2E303A), + ), + ), + ], + ), ], ), ), @@ -303,56 +308,65 @@ class ReferredPatientDetailScreen extends StatelessWidget { ) ], ), - if(referredPatient.priorityDescription != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).priority + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - referredPatient.priorityDescription, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 14, - color: Color(0XFF2E303A), - ), - ], - ), - if(referredPatient.mAXResponseTime != null) - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .maxResponseTime + - ": ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - referredPatient.mAXResponseTime != null?AppDateUtils.convertDateFromServerFormat( - referredPatient.mAXResponseTime, - "dd MMM,yyyy"):'', + if (referredPatient.priorityDescription != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).priority + + ": ", fontFamily: 'Poppins', - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, fontSize: - 1.8 * SizeConfig.textMultiplier, + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + AppText( + referredPatient.priorityDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 14, color: Color(0XFF2E303A), ), - ), - ], - ), + ], + ), + if (referredPatient.mAXResponseTime != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .maxResponseTime + + ": ", + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + Expanded( + child: AppText( + referredPatient.mAXResponseTime != + null + ? AppDateUtils + .convertDateFromServerFormat( + referredPatient + .mAXResponseTime, + "dd MMM,yyyy") + : '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + ), + ], + ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -518,11 +532,15 @@ class ReferredPatientDetailScreen extends StatelessWidget { color: Color(0XFF2E303A), ), AppText( - referredPatient - .referredDoctorRemarks == null ?'':referredPatient - .referredDoctorRemarks.isNotEmpty - ? referredPatient.referredDoctorRemarks - : TranslationBase.of(context).notRepliedYet, + referredPatient.referredDoctorRemarks == + null + ? '' + : referredPatient.referredDoctorRemarks + .isNotEmpty + ? referredPatient + .referredDoctorRemarks + : TranslationBase.of(context) + .notRepliedYet, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.6 * SizeConfig.textMultiplier, @@ -538,6 +556,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ), ), + if (patientType == PatientType.IN_PATIENT) Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: AppButton( @@ -548,9 +567,11 @@ class ReferredPatientDetailScreen extends StatelessWidget { fontSize: 1.8, hPadding: 8, vPadding: 12, - disabled: referredPatient.referredDoctorRemarks == null? true: referredPatient.referredDoctorRemarks.isNotEmpty - ? false - : true, + disabled: referredPatient.referredDoctorRemarks == null + ? true + : referredPatient.referredDoctorRemarks.isNotEmpty + ? false + : true, onPressed: () async { await model.verifyReferralDoctorRemarks(referredPatient); if (model.state == ViewState.ErrorLocal) { diff --git a/pubspec.lock b/pubspec.lock index 18379111..a408ffd5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "14.0.0" + version: "12.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.41.2" + version: "0.40.6" archive: dependency: transitive description: @@ -119,7 +119,7 @@ packages: name: build_web_compilers url: "https://pub.dartlang.org" source: hosted - version: "2.15.3" + version: "2.12.2" built_collection: dependency: transitive description: @@ -280,7 +280,7 @@ packages: name: dart_style url: "https://pub.dartlang.org" source: hosted - version: "1.3.12" + version: "1.3.10" date_time_picker: dependency: "direct main" description: @@ -629,7 +629,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.4" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: @@ -921,7 +921,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.2" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: @@ -1119,5 +1119,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.11.0-162.0 <=2.11.0-213.1.beta" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" From 1af52dc5b7567480d6872b45937233425ecacfff Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:02:36 +0300 Subject: [PATCH 232/241] fix referral patient --- .../referral/MyReferralPatientModel.dart | 81 +- .../patient/MyReferralPatientService.dart | 8 +- .../patient-doctor-referral-service.dart | 15 +- .../viewModel/patient-referral-viewmodel.dart | 8 +- .../referral/AddReplayOnReferralPatient.dart | 58 -- .../referral/my-referral-detail-screen.dart | 757 ++++++++---------- .../my-referral-inpatient-screen.dart | 25 +- .../referral_patient_detail_in-paint.dart | 4 +- .../referral/referred-patient-screen.dart | 1 + .../profile_medical_info_widget_search.dart | 650 ++++----------- 10 files changed, 603 insertions(+), 1004 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index ce8a6447..09b3769e 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -57,11 +57,33 @@ class MyReferralPatientModel { bool isDoctorLate; bool isDoctorResponse; String nationalityFlagURL; + + + + + + + + + + + + + + String nursingStationName; String priorityDescription; String referringClinicDescription; String referringDoctorName; int referalStatus; + String sourceSetupID; + int sourceProjectId; + String targetSetupID; + int targetProjectId; + int targetClinicID; + int targetDoctorID; + int sourceAppointmentNo; + int targetAppointmentNo; MyReferralPatientModel( {this.rowID, @@ -104,27 +126,27 @@ class MyReferralPatientModel { this.referralResponseOn, this.priority, this.frequency, - this.mAXResponseTime, - this.episodeID, - this.appointmentNo, - this.appointmentDate, - this.appointmentType, - this.patientMRN, - this.createdOn, - this.clinicID, - this.nationalityID, - this.age, - this.doctorImageURL, - this.frequencyDescription, - this.genderDescription, - this.isDoctorLate, - this.isDoctorResponse, - this.nationalityFlagURL, - this.nursingStationName, - this.priorityDescription, - this.referringClinicDescription, - this.referringDoctorName, - this.referalStatus}); + this.mAXResponseTime, + this.episodeID, + this.appointmentNo, + this.appointmentDate, + this.appointmentType, + this.patientMRN, + this.createdOn, + this.clinicID, + this.nationalityID, + this.age, + this.doctorImageURL, + this.frequencyDescription, + this.genderDescription, + this.isDoctorLate, + this.isDoctorResponse, + this.nationalityFlagURL, + this.nursingStationName, + this.priorityDescription, + this.referringClinicDescription, + this.referringDoctorName, + this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; @@ -201,7 +223,14 @@ class MyReferralPatientModel { priorityDescription = json['PriorityDescription']; referringClinicDescription = json['ReferringClinicDescription']; referringDoctorName = json['ReferringDoctorName']; - } + sourceSetupID = json['SourceSetupID']; + sourceProjectId = json['SourceProjectId']; + targetSetupID = json['TargetSetupID']; + targetProjectId = json['TargetProjectId']; + targetClinicID = json['TargetClinicID']; + targetDoctorID = json['TargetDoctorID']; + sourceAppointmentNo = json['SourceAppointmentNo']; + targetAppointmentNo = json['TargetAppointmentNo']; } Map toJson() { final Map data = new Map(); @@ -266,6 +295,14 @@ class MyReferralPatientModel { data['PriorityDescription'] = this.priorityDescription; data['ReferringClinicDescription'] = this.referringClinicDescription; data['ReferringDoctorName'] = this.referringDoctorName; + data['SourceSetupID'] = this.sourceSetupID; + data['SourceProjectId'] = this.sourceProjectId; + data['TargetSetupID'] = this.targetSetupID; + data['TargetProjectId'] = this.targetProjectId; + data['TargetClinicID'] = this.targetClinicID; + data['TargetDoctorID'] = this.targetDoctorID; + data['SourceAppointmentNo'] = this.sourceAppointmentNo; + data['TargetAppointmentNo'] = this.targetAppointmentNo; return data; } diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index 87fcdd23..35729def 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -100,20 +100,22 @@ class MyReferralInPatientService extends BaseService { ); } - Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referralStatus) async { hasError = false; await getDoctorProfile(); AddReferredRemarksRequestModel _requestAddReferredDoctorRemarks = AddReferredRemarksRequestModel( editedBy: doctorProfile.doctorID, projectID: doctorProfile.projectID, referredDoctorRemarks: referredDoctorRemarks, - referalStatus: referalStatus); + referalStatus: referralStatus); _requestAddReferredDoctorRemarks.projectID = referral.projectID; + + //TODO Check this in case out patient _requestAddReferredDoctorRemarks.admissionNo = int.parse(referral.admissionNo); _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; - _requestAddReferredDoctorRemarks.referalStatus = referalStatus; + _requestAddReferredDoctorRemarks.referalStatus = referralStatus; // _requestAddReferredDoctorRemarks.patientID = referral.patientID; // _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index 81529590..cded130e 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/lookups/hospital_lookup.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/get_clinic_by_project_id_request.dart'; @@ -242,18 +243,18 @@ class PatientReferralService extends LookupService { } Future responseReferral( - PendingReferral pendingReferral, bool isAccepted) async { + MyReferralPatientModel referralPatient, bool isAccepted) async { hasError = false; DoctorProfileModel doctorProfile = await getDoctorProfile(); Map body = Map(); - body['PatientMRN'] = pendingReferral.patientID; - body['AppointmentNo'] = pendingReferral.targetAppointmentNo; - body['SetupID'] = pendingReferral.targetSetupID; - body['ProjectID'] = pendingReferral.targetProjectId; + body['PatientMRN'] = referralPatient.patientID; + body['AppointmentNo'] = referralPatient.targetAppointmentNo; + body['SetupID'] = referralPatient.targetSetupID; + body['ProjectID'] = referralPatient.targetProjectId; body['IsAccepted'] = isAccepted; - body['PatientName'] = pendingReferral.patientName; - body['ReferralResponse'] = pendingReferral.remarksFromSource; + body['PatientName'] = referralPatient.patientName; + body['ReferralResponse'] = referralPatient.referringDoctorRemarks; body['DoctorName'] = doctorProfile.doctorName; await baseAppClient.post( diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 0351db77..6c1c0115 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -203,9 +203,9 @@ class PatientReferralViewModel extends BaseViewModel { getMyReferralPatientService(); } - Future responseReferral(PendingReferral pendingReferral, bool isAccepted) async { + Future responseReferral(MyReferralPatientModel referralPatient, bool isAccepted) async { setState(ViewState.Busy); - await _referralPatientService.responseReferral(pendingReferral, isAccepted); + await _referralPatientService.responseReferral(referralPatient, isAccepted); if (_referralPatientService.hasError) { error = _referralPatientService.error; setState(ViewState.ErrorLocal); @@ -392,9 +392,9 @@ class PatientReferralViewModel extends BaseViewModel { return patient; } - Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referralStatus) async { setState(ViewState.Busy); - await _myReferralService.replayReferred(referredDoctorRemarks, referral, referalStatus); + await _myReferralService.replayReferred(referredDoctorRemarks, referral, referralStatus); if (_myReferralService.hasError) { error = _myReferralService.error; setState(ViewState.ErrorLocal); diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index 56ff85c4..e4b8700c 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -149,14 +149,6 @@ class _AddReplayOnReferralPatientState extends State DrAppToastMsg.showSuccesToast("Has been rejected"); Navigator.of(context).pop(); Navigator.of(context).pop(); - - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), - // ), - // ); } } else { Helpers.showErrorToast("You can't add empty reply"); @@ -190,14 +182,6 @@ class _AddReplayOnReferralPatientState extends State DrAppToastMsg.showSuccesToast("Your Reply Added Successfully"); Navigator.of(context).pop(); Navigator.of(context).pop(); - - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), - // ), - // ); } } else { Helpers.showErrorToast("You can't add empty reply"); @@ -214,48 +198,6 @@ class _AddReplayOnReferralPatientState extends State ], ), ), - // Container( - // margin: EdgeInsets.all(5), - // child: AppButton( - // title: 'Submit Reply', - // color: Color(0xff359846), - // fontWeight: FontWeight.w700, - // onPressed: () async { - // setState(() { - // isSubmitted = true; - // }); - // if (replayOnReferralController.text.isNotEmpty) { - // GifLoaderDialogUtils.showMyDialog(context); - // await widget.patientReferralViewModel.replay( - // replayOnReferralController.text.trim(), - // widget.myReferralInPatientModel); - // if (widget.patientReferralViewModel.state == - // ViewState.ErrorLocal) { - // Helpers.showErrorToast( - // widget.patientReferralViewModel.error); - // } else { - // GifLoaderDialogUtils.hideDialog(context); - // DrAppToastMsg.showSuccesToast( - // "Your Reply Added Successfully"); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // - // Navigator.push( - // context, - // FadePage( - // page: ReplySummeryOnReferralPatient( - // widget.myReferralInPatientModel, - // replayOnReferralController.text.trim()), - // ), - // ); - // } - // } else { - // Helpers.showErrorToast("You can't add empty reply"); - // setState(() { - // isSubmitted = false; - // }); - // } - // })), ], ), ), diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index 447a3739..ffcd871a 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -1,8 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/PendingReferral.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; @@ -13,476 +13,411 @@ 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/buttons/app_buttons_widget.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; // ignore: must_be_immutable class MyReferralDetailScreen extends StatelessWidget { - PendingReferral pendingReferral; + final MyReferralPatientModel referralPatient; + + const MyReferralDetailScreen({Key key, this.referralPatient}) + : super(key: key); @override Widget build(BuildContext context) { - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - pendingReferral = routeArgs['referral']; + // final routeArgs = ModalRoute.of(context).settings.arguments as Map; + // pendingReferral = routeArgs['referral']; return BaseView( - onModelReady: (model) => model.getPatientDetails( - AppDateUtils.convertStringToDateFormat( - DateTime.now() /*.subtract(Duration(days: 350))*/ .toString(), - "yyyy-MM-dd"), - AppDateUtils.convertStringToDateFormat( - DateTime.now().toString(), "yyyy-MM-dd"), - pendingReferral.patientID, - pendingReferral.sourceAppointmentNo), + onModelReady: (model) => model.getDoctorProfile(), builder: (_, model, w) => AppScaffold( - baseViewModel: model, - appBarTitle: TranslationBase.of(context).referPatient, - isShowAppBar: false, - body: model.patientArrivalList != null && - model.patientArrivalList.length > 0 - ? Column( - 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: Column( + baseViewModel: model, + appBarTitle: TranslationBase.of(context).referPatient, + isShowAppBar: false, + body: Column( + 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: Column( + children: [ + Container( + padding: EdgeInsets.only(left: 12.0), + child: Row(children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Colors.black, //Colors.black, + onPressed: () => Navigator.pop(context), + ), + Expanded( + child: AppText( + (Helpers.capitalize(referralPatient.firstName + " "+ + referralPatient.lastName)), + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + referralPatient.gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + ]), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( + Padding( padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - (Helpers.capitalize(model - .patientArrivalList[0] - .patientDetails - .fullName)), - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), + child: Container( + width: 60, + height: 60, + child: Image.asset( + referralPatient.gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, ), - model.patientArrivalList[0].patientDetails - .gender == - 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - ]), + ), ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - pendingReferral.patientDetails.gender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + AppText( + referralPatient.referralStatus != null + ? model.getReferralStatusNameByCode( + referralPatient.referralStatus, + context) + : "", + fontFamily: 'Poppins', + fontSize: 1.9 * SizeConfig.textMultiplier, + fontWeight: FontWeight.w700, + color: referralPatient.referralStatus == 1 + ? Color(0xffc4aa54) + : referralPatient.referralStatus == + 46 || + referralPatient + .referralStatus == + 2 + ? Colors.green[700] + : Colors.red[700], + ), + AppText( + AppDateUtils.getDayMonthYearDateFormatted( + referralPatient.referralDate), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 2.0 * SizeConfig.textMultiplier, + color: Color(0XFF28353E), + ) + ], ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.start, children: [ AppText( - pendingReferral.referralStatus != null - ? pendingReferral.referralStatus - : "", - fontFamily: 'Poppins', - fontSize: - 1.9 * SizeConfig.textMultiplier, - fontWeight: FontWeight.w700, - color: pendingReferral - .referralStatus != - null - ? pendingReferral - .referralStatus == - 'Pending' - ? Color(0xffc4aa54) - : pendingReferral - .referralStatus == - 'Accepted' - ? Colors.green[700] - : Colors.red[700] - : Colors.grey[500], - ), - AppText( - pendingReferral.referredOn - .split(" ")[0], + TranslationBase.of(context) + .fileNumber, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: - 2.0 * SizeConfig.textMultiplier, - color: Color(0XFF28353E), - ) - ], - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .fileNumber, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF575757), - ), - AppText( - "${pendingReferral.patientID}", - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], + 1.7 * SizeConfig.textMultiplier, + color: Color(0XFF575757), ), AppText( - pendingReferral.referredOn - .split(" ")[1], + "${referralPatient.patientID}", fontFamily: 'Poppins', - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF575757), - ) + color: Color(0XFF2E303A), + ), ], ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Expanded( - child: Column( + AppText( + AppDateUtils.getTimeHHMMA(referralPatient.referralDate), + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: + 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF575757), + ) + ], + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + children: [ + + //todo Elham* return this + // Row( + // mainAxisAlignment: + // MainAxisAlignment.start, + // children: [ + // AppText( + // TranslationBase.of(context) + // .referredFrom, + // fontFamily: 'Poppins', + // fontWeight: FontWeight.w600, + // fontSize: 1.7 * + // SizeConfig.textMultiplier, + // color: Color(0XFF575757), + // ), + // AppText( + // referralPatient.projectID == model.doctorProfile.projectID + // ? TranslationBase.of( + // context) + // .sameBranch + // : TranslationBase.of( + // context) + // .otherBranch, + // fontFamily: 'Poppins', + // fontWeight: FontWeight.w700, + // fontSize: 1.8 * + // SizeConfig + // .textMultiplier, + // color: Color(0XFF2E303A), + // ), + // ], + // ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .referredFrom, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig - .textMultiplier, - color: Color(0XFF575757), - ), - AppText( - pendingReferral - .isReferralDoctorSameBranch - ? TranslationBase.of( - context) - .sameBranch - : TranslationBase.of( - context) - .otherBranch, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, - color: Color(0XFF2E303A), - ), - ], + AppText( + TranslationBase.of(context) + .remarks + + " : ", + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), ), - Row( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context) - .remarks + - " : ", - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.7 * - SizeConfig - .textMultiplier, - color: Color(0XFF575757), - ), - Expanded( - child: AppText( - pendingReferral - .remarksFromSource, - fontFamily: 'Poppins', - fontWeight: - FontWeight.w700, - fontSize: 1.8 * - SizeConfig - .textMultiplier, - color: Color(0XFF2E303A), - ), - ), - ], + Expanded( + child: AppText( + referralPatient.referringDoctorRemarks?? + '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), - ), - Row( - children: [ - AppText( - pendingReferral.patientDetails - .nationalityName != - null - ? pendingReferral - .patientDetails - .nationalityName - : "", - fontWeight: FontWeight.bold, - color: Color(0xFF2E303A), - fontSize: 1.4 * - SizeConfig.textMultiplier, - ), - pendingReferral - .nationalityFlagUrl != - null - ? ClipRRect( - borderRadius: - BorderRadius.circular( - 20.0), - child: Image.network( - pendingReferral - .nationalityFlagUrl, - height: 25, - width: 30, - errorBuilder: - (BuildContext context, - Object exception, - StackTrace - stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], + ], + ), ), Row( - crossAxisAlignment: - CrossAxisAlignment.start, children: [ - Container( - margin: EdgeInsets.only( - left: 10, right: 0), - child: Image.asset( - 'assets/images/patient/ic_ref_arrow_up.png', - height: 50, - width: 30, - ), + AppText( + referralPatient.nationalityName != + null + ? referralPatient.nationalityName + : "", + fontWeight: FontWeight.bold, + color: Color(0xFF2E303A), + fontSize: + 1.4 * SizeConfig.textMultiplier, ), - Container( - margin: EdgeInsets.only( - left: 0, - top: 25, - right: 0, - bottom: 0), - padding: EdgeInsets.only( - left: 4.0, right: 4.0), - child: Container( - width: 40, - height: 40, - child: CircleAvatar( - radius: 25.0, - backgroundImage: NetworkImage( - pendingReferral - .doctorImageUrl), - backgroundColor: - Colors.transparent, - ), - ), + referralPatient.nationalityFlagURL != + null + ? ClipRRect( + borderRadius: + BorderRadius.circular(20.0), + child: Image.network( + referralPatient + .nationalityFlagURL, + height: 25, + width: 30, + errorBuilder: (BuildContext + context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: + EdgeInsets.only(left: 10, right: 0), + child: Image.asset( + 'assets/images/patient/ic_ref_arrow_up.png', + height: 50, + width: 30, + ), + ), + Container( + margin: EdgeInsets.only( + left: 0, + top: 25, + right: 0, + bottom: 0), + padding: EdgeInsets.only( + left: 4.0, right: 4.0), + child: Container( + width: 40, + height: 40, + child: CircleAvatar( + radius: 25.0, + backgroundImage: NetworkImage( + referralPatient.doctorImageURL), + backgroundColor: Colors.transparent, ), - Expanded( - flex: 4, - child: Container( - margin: EdgeInsets.only( - left: 10, - top: 25, - right: 10, - bottom: 0), - child: Column( - children: [ - AppText( - pendingReferral - .referredByDoctorInfo, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.7 * - SizeConfig.textMultiplier, - color: Color(0XFF2E303A), - ), - ], + ), + ), + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.only( + left: 10, + top: 25, + right: 10, + bottom: 0), + child: Column( + children: [ + AppText( + referralPatient.doctorName, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF2E303A), ), - ), + ], ), - ], + ), ), ], ), - ), - ], + ], + ), ), ], ), - ), - ), - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 16, - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16), - child: SizedBox( - child: ProfileMedicalInfoWidgetSearch( - patient: model.patientArrivalList[0], - patientType: "7", - from: null, - to: null, - ), - ), - ), - ], - ), - ), - ), + ], ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Row( + ), + ), + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).accept, - color: Color(0xFF4BA821), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral( - pendingReferral, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgAccept); - Navigator.pop(context); - Navigator.pop(context); - } - }, - ), - ), SizedBox( - width: 8, + height: 16, ), - Expanded( - child: AppButton( - title: TranslationBase.of(context).reject, - color: Color(0xFFB9382C), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral( - pendingReferral, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgReject); - Navigator.pop(context); - Navigator.pop(context); - } - }, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: SizedBox( + child: ProfileMedicalInfoWidgetSearch( + patient: model + .getPatientFromReferralO(referralPatient), + patientType: "7", + isInpatient: false, + from: null, + to: null, + ), ), ), ], ), ), - ], - ) - : Column( - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - "", - fontSize: SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.bold, - - fontFamily: 'Poppins', - ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context).accept, + color: Color(0xFF4BA821), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + onPressed: () async { + await model.responseReferral(referralPatient, true); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgAccept); + Navigator.pop(context); + Navigator.pop(context); + } + }, ), - ]), - ), - Container( - child: Center( - child: AppText( - TranslationBase.of(context).patientNoDetailErrMsg, - color: HexColor("#B8382B"), - fontWeight: FontWeight.bold, - fontSize: 16, + ), + SizedBox( + width: 8, + ), + Expanded( + child: AppButton( + title: TranslationBase.of(context).reject, + color: Color(0xFFB9382C), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + onPressed: () async { + await model.responseReferral(referralPatient, false); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgReject); + Navigator.pop(context); + Navigator.pop(context); + } + }, ), ), - ), - ], + ], + ), ), - ), + ], + )), ); } } diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 3ebd7896..48299bf2 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -1,6 +1,7 @@ import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/referral/my-referral-detail-screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referral_patient_detail_in-paint.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referred-patient-screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -13,6 +14,8 @@ import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'my-referral-patient-screen.dart'; + class MyReferralInPatientScreen extends StatelessWidget { PatientType patientType = PatientType.IN_PATIENT; @@ -70,12 +73,22 @@ class MyReferralInPatientScreen extends StatelessWidget { model.myReferralPatients.length, (index) => InkWell( onTap: () { - Navigator.push( - context, - FadePage( - page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), - ), - ); + if(patientType == PatientType.OUT_PATIENT) { + Navigator.push( + context, + FadePage( + page: MyReferralDetailScreen(referralPatient: model.myReferralPatients[index]), + ), + ); + } else{ + Navigator.push( + context, + FadePage( + page: ReferralPatientDetailScreen(model.myReferralPatients[index], model), + ), + ); + } + }, child: PatientReferralItemWidget( referralStatus: model.getReferralStatusNameByCode( diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 66e01364..50bd0a9e 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -433,7 +433,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ], ), ), - if (referredPatient.referredDoctorRemarks.isNotEmpty) + if (referredPatient.referredDoctorRemarks!= null && referredPatient.referredDoctorRemarks.isNotEmpty) Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), @@ -492,7 +492,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { widget: AddReplayOnReferralPatient( patientReferralViewModel: patientReferralViewModel, myReferralInPatientModel: referredPatient, - isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, + isEdited: referredPatient.referredDoctorRemarks!=null && referredPatient.referredDoctorRemarks.isNotEmpty, ), ), ); diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index c95a28d8..3aa43855 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -79,6 +79,7 @@ class ReferredPatientScreen extends StatelessWidget { ), ); }, + /// TODO Elham* check why we call fun to access attribute child: PatientReferralItemWidget( referralStatus: model .getReferredPatientItem(index) diff --git a/lib/widgets/patients/profile/profile_medical_info_widget_search.dart b/lib/widgets/patients/profile/profile_medical_info_widget_search.dart index ac33eb82..573ada32 100644 --- a/lib/widgets/patients/profile/profile_medical_info_widget_search.dart +++ b/lib/widgets/patients/profile/profile_medical_info_widget_search.dart @@ -46,500 +46,168 @@ class ProfileMedicalInfoWidgetSearch extends StatelessWidget { height: MediaQuery.of(context).size.height * 1.0, width: double.infinity, child: Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - toolbarHeight: 55, - elevation: 0, - bottom: TabBar( - controller: _tabController, - indicator: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(10), // Creates border - color: Color(0xffD02126), - ), - //isScrollable: true, - - //indicatorWeight: 4.0, - indicatorColor: Colors.red[500], - - // labelPadding: - // EdgeInsets.symmetric(horizontal: 13.0, vertical: 2.0), - unselectedLabelColor: Color(0xff5A6168), - labelColor: Colors.white, - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.35, - height: MediaQuery.of(context).size.height * 0.06, - child: Center( - child: Text('Inpatient Info'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.35, - height: MediaQuery.of(context).size.height * 0.06, - child: Center( - child: Text('OutPatient Info'), - ), - ), - ]), - ), - body: Padding( - padding: const EdgeInsets.symmetric(vertical: 15.0), - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - GridView.count( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1 / 1.0, - crossAxisCount: 3, - children: [ - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: TranslationBase.of(context).vital, - nameLine2: TranslationBase.of(context).signs, - route: VITAL_SIGN_DETAILS, - isInPatient: true, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: LAB_RESULT, - isInPatient: true, - nameLine1: TranslationBase.of(context).lab, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/lab_results.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInPatient: isInpatient, - route: RADIOLOGY_PATIENT, - nameLine1: TranslationBase.of(context).radiology, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PRESCRIPTION_NEW, - nameLine1: TranslationBase.of(context).patient, - nameLine2: TranslationBase.of(context).prescription, - icon: 'patient/order_prescription.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PROGRESS_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: TranslationBase.of(context).progress, - nameLine2: TranslationBase.of(context).note, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_NOTE, - isDischargedPatient: isDischargedPatient, - nameLine1: "Order", //"Text", - nameLine2: - "Sheet", //TranslationBase.of(context).orders, - icon: 'patient/Progress_notes.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PROCEDURE, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).procedures, - icon: 'patient/Order_Procedures.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: HEALTH_SUMMARY, - nameLine1: "Health", - //TranslationBase.of(context).medicalReport, - nameLine2: "Summary", - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: HEALTH_SUMMARY, - nameLine1: "Medical", //Health - //TranslationBase.of(context).medicalReport, - nameLine2: "Report", //Report - //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: REFER_IN_PATIENT_TO_DOCTOR, - isInPatient: true, - nameLine1: TranslationBase.of(context).referral, - nameLine2: TranslationBase.of(context).patient, - icon: 'patient/refer_patient.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_INSURANCE_APPROVALS_NEW, - nameLine1: TranslationBase.of(context).insurance, - nameLine2: TranslationBase.of(context).approvals, - icon: 'patient/vital_signs.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isDisable: true, - route: null, - nameLine1: "Discharge", - nameLine2: "Summery", - icon: 'patient/patient_sick_leave.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ADD_SICKLEAVE, - nameLine1: TranslationBase.of(context).patientSick, - nameLine2: TranslationBase.of(context).leave, - icon: 'patient/patient_sick_leave.png'), - ], - ), - GridView.count( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1 / 1.0, - crossAxisCount: 3, - children: [ - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - from: from, - to: to, - nameLine1: TranslationBase.of(context).vital, - nameLine2: TranslationBase.of(context).signs, - route: VITAL_SIGN_DETAILS, - icon: 'patient/vital_signs.png'), - // if (selectedPatientType != 7) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: HEALTH_SUMMARY, - nameLine1: - "Health", //TranslationBase.of(context).medicalReport, - nameLine2: - "Summary", //TranslationBase.of(context).summaryReport, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: LAB_RESULT, - nameLine1: TranslationBase.of(context).lab, - nameLine2: TranslationBase.of(context).result, - icon: 'patient/lab_results.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - isInPatient: isInpatient, - route: RADIOLOGY_PATIENT, - nameLine1: TranslationBase.of(context).radiology, - nameLine2: TranslationBase.of(context).service, - icon: 'patient/health_summary.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_ECG, - nameLine1: TranslationBase.of(context).patient, - nameLine2: "ECG", - icon: 'patient/patient_sick_leave.png'), - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PRESCRIPTION_NEW, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).prescription, - icon: 'patient/order_prescription.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_PROCEDURE, - nameLine1: TranslationBase.of(context).orders, - nameLine2: TranslationBase.of(context).procedures, - icon: 'patient/Order_Procedures.png'), - //if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_INSURANCE_APPROVALS_NEW, - nameLine1: TranslationBase.of(context).insurance, - nameLine2: TranslationBase.of(context).service, - icon: 'patient/vital_signs.png'), - // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ADD_SICKLEAVE, - nameLine1: TranslationBase.of(context).patientSick, - nameLine2: TranslationBase.of(context).leave, - icon: 'patient/patient_sick_leave.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_UCAF_REQUEST, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).patient, - nameLine2: TranslationBase.of(context).ucaf, - icon: 'patient/ucaf.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: REFER_PATIENT_TO_DOCTOR, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).referral, - nameLine2: TranslationBase.of(context).patient, - icon: 'patient/refer_patient.png'), - if (patient.appointmentNo != null && - patient.appointmentNo != 0) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PATIENT_ADMISSION_REQUEST, - isDisable: - patient.patientStatusType != 43 ? true : false, - nameLine1: TranslationBase.of(context).admission, - nameLine2: TranslationBase.of(context).request, - icon: 'patient/admission_req.png'), - if (isInpatient) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: PROGRESS_NOTE, - nameLine1: TranslationBase.of(context).progress, - nameLine2: TranslationBase.of(context).note, - icon: 'patient/Progress_notes.png'), - if (isInpatient) - PatientProfileButton( - key: key, - patient: patient, - patientType: patientType, - arrivalType: arrivalType, - route: ORDER_NOTE, - nameLine1: "Order", //"Text", - nameLine2: "Sheet", - icon: 'patient/Progress_notes.png'), - ], - ), - ], - ), + body: GridView.count( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + crossAxisSpacing: 8, + mainAxisSpacing: 10, + childAspectRatio: 1 / 1.0, + crossAxisCount: 3, + children: [ + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + from: from, + to: to, + nameLine1: TranslationBase.of(context).vital, + nameLine2: TranslationBase.of(context).signs, + route: VITAL_SIGN_DETAILS, + icon: 'patient/vital_signs.png'), + // if (selectedPatientType != 7) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: HEALTH_SUMMARY, + nameLine1: + "Health", //TranslationBase.of(context).medicalReport, + nameLine2: + "Summary", //TranslationBase.of(context).summaryReport, + icon: 'patient/health_summary.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: LAB_RESULT, + nameLine1: TranslationBase.of(context).lab, + nameLine2: TranslationBase.of(context).result, + icon: 'patient/lab_results.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + isInPatient: isInpatient, + route: RADIOLOGY_PATIENT, + nameLine1: TranslationBase.of(context).radiology, + nameLine2: TranslationBase.of(context).service, + icon: 'patient/health_summary.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_ECG, + nameLine1: TranslationBase.of(context).patient, + nameLine2: "ECG", + icon: 'patient/patient_sick_leave.png'), + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_PRESCRIPTION_NEW, + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).prescription, + icon: 'patient/order_prescription.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_PROCEDURE, + nameLine1: TranslationBase.of(context).orders, + nameLine2: TranslationBase.of(context).procedures, + icon: 'patient/Order_Procedures.png'), + //if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_INSURANCE_APPROVALS_NEW, + nameLine1: TranslationBase.of(context).insurance, + nameLine2: TranslationBase.of(context).service, + icon: 'patient/vital_signs.png'), + // if (int.parse(patientType) == 7 || int.parse(patientType) == 6) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ADD_SICKLEAVE, + nameLine1: TranslationBase.of(context).patientSick, + nameLine2: TranslationBase.of(context).leave, + icon: 'patient/patient_sick_leave.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_UCAF_REQUEST, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).patient, + nameLine2: TranslationBase.of(context).ucaf, + icon: 'patient/ucaf.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: REFER_PATIENT_TO_DOCTOR, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).referral, + nameLine2: TranslationBase.of(context).patient, + icon: 'patient/refer_patient.png'), + if (patient.appointmentNo != null && + patient.appointmentNo != 0) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PATIENT_ADMISSION_REQUEST, + isDisable: + patient.patientStatusType != 43 ? true : false, + nameLine1: TranslationBase.of(context).admission, + nameLine2: TranslationBase.of(context).request, + icon: 'patient/admission_req.png'), + if (isInpatient) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: PROGRESS_NOTE, + nameLine1: TranslationBase.of(context).progress, + nameLine2: TranslationBase.of(context).note, + icon: 'patient/Progress_notes.png'), + if (isInpatient) + PatientProfileButton( + key: key, + patient: patient, + patientType: patientType, + arrivalType: arrivalType, + route: ORDER_NOTE, + nameLine1: "Order", //"Text", + nameLine2: "Sheet", + icon: 'patient/Progress_notes.png'), + ], ), ), ), - - // GridView.count( - // shrinkWrap: true, - // physics: NeverScrollableScrollPhysics(), - // crossAxisSpacing: 10, - // mainAxisSpacing: 10, - // childAspectRatio: 1 / 1.0, - // crossAxisCount: 3, - // children: [ - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // from: from, - // to: to, - // nameLine1: TranslationBase.of(context).vital, - // nameLine2: TranslationBase.of(context).signs, - // route: VITAL_SIGN_DETAILS, - // icon: 'patient/vital_signs.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: MEDICAL_FILE, - // nameLine1: - // "Health", //TranslationBase.of(context).medicalReport, - // nameLine2: - // "Summary", //TranslationBase.of(context).summaryReport, - // icon: 'patient/health_summary.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: LAB_RESULT, - // nameLine1: TranslationBase.of(context).lab, - // nameLine2: TranslationBase.of(context).result, - // icon: 'patient/lab_results.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // isInPatient: isInpatient, - // route: RADIOLOGY_PATIENT, - // nameLine1: TranslationBase.of(context).radiology, - // nameLine2: TranslationBase.of(context).service, - // icon: 'patient/health_summary.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PATIENT_ECG, - // nameLine1: TranslationBase.of(context).patient, - // nameLine2: "ECG", - // icon: 'patient/patient_sick_leave.png'), - // (int.parse(patientType) == 7 || - // int.parse(patientType) == 6) - // ? PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PRESCRIPTION_NEW, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: - // TranslationBase.of(context).prescription, - // icon: 'patient/order_prescription.png') - // : PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PRESCRIPTION_NEW, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: - // TranslationBase.of(context).prescription, - // icon: 'patient/order_prescription.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_PROCEDURE, - // nameLine1: TranslationBase.of(context).orders, - // nameLine2: TranslationBase.of(context).procedures, - // icon: 'patient/Order_Procedures.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PATIENT_INSURANCE_APPROVALS_NEW, - // nameLine1: TranslationBase.of(context).insurance, - // nameLine2: TranslationBase.of(context).service, - // icon: 'patient/vital_signs.png'), - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: SHOW_SICKLEAVE, - // nameLine1: TranslationBase.of(context).patientSick, - // nameLine2: TranslationBase.of(context).leave, - // icon: 'patient/patient_sick_leave.png'), - // if (patient.admissionNo != null && - // patient.admissionNo != "0") - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: PROGRESS_NOTE, - // nameLine1: TranslationBase.of(context).progress, - // nameLine2: TranslationBase.of(context).note, - // icon: 'patient/Progress_notes.png'), - // if (patient.admissionNo != null && - // patient.admissionNo != "0") - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: ORDER_NOTE, - // nameLine1: "Order", //"Text", - // nameLine2: "Sheet", - // icon: 'patient/Progress_notes.png'), - // if (patient.appointmentNo != null && - // patient.appointmentNo != 0) - // PatientProfileButton( - // key: key, - // patient: patient, - // patientType: patientType, - // arrivalType: arrivalType, - // route: REFER_PATIENT_TO_DOCTOR, - // // isDisable: patient.patientStatusType != 43 ? true : false, - // nameLine1: TranslationBase.of(context).referral, - // nameLine2: TranslationBase.of(context).patient, - // icon: 'patient/refer_patient.png'), - // ], - // ), ), ); } From 33f032b6c40aea1f95bd7992ea87fdf4d602e860 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:05:47 +0300 Subject: [PATCH 233/241] return from part on header --- .../referral/my-referral-detail-screen.dart | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index ffcd871a..b20b29bb 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -174,37 +174,36 @@ class MyReferralDetailScreen extends StatelessWidget { child: Column( children: [ - //todo Elham* return this - // Row( - // mainAxisAlignment: - // MainAxisAlignment.start, - // children: [ - // AppText( - // TranslationBase.of(context) - // .referredFrom, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w600, - // fontSize: 1.7 * - // SizeConfig.textMultiplier, - // color: Color(0XFF575757), - // ), - // AppText( - // referralPatient.projectID == model.doctorProfile.projectID - // ? TranslationBase.of( - // context) - // .sameBranch - // : TranslationBase.of( - // context) - // .otherBranch, - // fontFamily: 'Poppins', - // fontWeight: FontWeight.w700, - // fontSize: 1.8 * - // SizeConfig - // .textMultiplier, - // color: Color(0XFF2E303A), - // ), - // ], - // ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context) + .referredFrom, + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.7 * + SizeConfig.textMultiplier, + color: Color(0XFF575757), + ), + AppText( + referralPatient.targetProjectId ==referralPatient.sourceProjectId + ? TranslationBase.of( + context) + .sameBranch + : TranslationBase.of( + context) + .otherBranch, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * + SizeConfig + .textMultiplier, + color: Color(0XFF2E303A), + ), + ], + ), Row( mainAxisAlignment: MainAxisAlignment.start, From 74294bfaf54e14add86e3fdcad91ea4312bc7026 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 13:23:09 +0300 Subject: [PATCH 234/241] finish fix referral --- .../referral/MyReferralPatientModel.dart | 23 ++-- .../patient-doctor-referral-service.dart | 2 +- .../referral/my-referral-detail-screen.dart | 105 +++++++++--------- .../my-referral-inpatient-screen.dart | 11 +- 4 files changed, 71 insertions(+), 70 deletions(-) diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 09b3769e..4f00f455 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -57,20 +57,6 @@ class MyReferralPatientModel { bool isDoctorLate; bool isDoctorResponse; String nationalityFlagURL; - - - - - - - - - - - - - - String nursingStationName; String priorityDescription; String referringClinicDescription; @@ -84,6 +70,7 @@ class MyReferralPatientModel { int targetDoctorID; int sourceAppointmentNo; int targetAppointmentNo; + String remarksFromSource; MyReferralPatientModel( {this.rowID, @@ -146,7 +133,7 @@ class MyReferralPatientModel { this.priorityDescription, this.referringClinicDescription, this.referringDoctorName, - this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID}); + this.referalStatus, this.sourceSetupID, this.sourceAppointmentNo, this.sourceProjectId, this.targetProjectId, this.targetAppointmentNo, this.targetClinicID, this.targetSetupID, this.targetDoctorID, this.remarksFromSource}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; @@ -230,7 +217,10 @@ class MyReferralPatientModel { targetClinicID = json['TargetClinicID']; targetDoctorID = json['TargetDoctorID']; sourceAppointmentNo = json['SourceAppointmentNo']; - targetAppointmentNo = json['TargetAppointmentNo']; } + targetAppointmentNo = json['TargetAppointmentNo']; + remarksFromSource = json['RemarksFromSource']; + + } Map toJson() { final Map data = new Map(); @@ -303,6 +293,7 @@ class MyReferralPatientModel { data['TargetDoctorID'] = this.targetDoctorID; data['SourceAppointmentNo'] = this.sourceAppointmentNo; data['TargetAppointmentNo'] = this.targetAppointmentNo; + data['RemarksFromSource'] = this.remarksFromSource; return data; } diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index cded130e..5b659631 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -254,7 +254,7 @@ class PatientReferralService extends LookupService { body['ProjectID'] = referralPatient.targetProjectId; body['IsAccepted'] = isAccepted; body['PatientName'] = referralPatient.patientName; - body['ReferralResponse'] = referralPatient.referringDoctorRemarks; + body['ReferralResponse'] = referralPatient.remarksFromSource; body['DoctorName'] = doctorProfile.doctorName; await baseAppClient.post( diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index b20b29bb..e5cc40da 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -361,60 +361,63 @@ class MyReferralDetailScreen extends StatelessWidget { ), ), ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).accept, - color: Color(0xFF4BA821), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral(referralPatient, true); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgAccept); - Navigator.pop(context); - Navigator.pop(context); - } - }, + if (referralPatient.referralStatus != 46) + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context).accept, + color: Color(0xFF4BA821), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + disabled: model.state == ViewState.Busy, + onPressed: () async { + await model.responseReferral(referralPatient, true); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgAccept); + Navigator.pop(context); + Navigator.pop(context); + } + }, + ), ), - ), - SizedBox( - width: 8, - ), - Expanded( - child: AppButton( - title: TranslationBase.of(context).reject, - color: Color(0xFFB9382C), - fontColor: Colors.white, - fontSize: 1.6, - hPadding: 8, - vPadding: 12, - onPressed: () async { - await model.responseReferral(referralPatient, false); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - DrAppToastMsg.showSuccesToast( - TranslationBase.of(context) - .referralSuccessMsgReject); - Navigator.pop(context); - Navigator.pop(context); - } - }, + SizedBox( + width: 8, ), - ), - ], + Expanded( + child: AppButton( + title: TranslationBase.of(context).reject, + color: Color(0xFFB9382C), + fontColor: Colors.white, + fontSize: 1.6, + hPadding: 8, + vPadding: 12, + disabled: model.state == ViewState.Busy, + onPressed: () async { + await model.responseReferral(referralPatient, false); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast( + TranslationBase.of(context) + .referralSuccessMsgReject); + Navigator.pop(context); + Navigator.pop(context); + } + }, + ), + ), + ], + ), ), - ), ], )), ); diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 48299bf2..cb6c1e5f 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -16,7 +16,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'my-referral-patient-screen.dart'; -class MyReferralInPatientScreen extends StatelessWidget { +class MyReferralInPatientScreen extends StatefulWidget { + @override + _MyReferralInPatientScreenState createState() => _MyReferralInPatientScreenState(); +} + +class _MyReferralInPatientScreenState extends State { PatientType patientType = PatientType.IN_PATIENT; @override @@ -33,7 +38,9 @@ class MyReferralInPatientScreen extends StatelessWidget { margin: EdgeInsets.only(top: 70), child: PatientTypeRadioWidget( (patientType) async { - this.patientType = patientType; + setState(() { + this.patientType = patientType; + }); GifLoaderDialogUtils.showMyDialog(context); if (patientType == PatientType.IN_PATIENT) { await model.getMyReferralPatientService(localBusy: true); From 0c730e827080e2e4ff4906d3b05bfe04c1a6d89f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:16:49 +0300 Subject: [PATCH 235/241] change the status condition --- .../patients/profile/referral/my-referral-detail-screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index e5cc40da..fdbf9859 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -361,7 +361,7 @@ class MyReferralDetailScreen extends StatelessWidget { ), ), ), - if (referralPatient.referralStatus != 46) + if (referralPatient.referralStatus == 1) Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Row( From 93c7797ed4ec8287dca890c431ba5c751d79c04f Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:22:03 +0300 Subject: [PATCH 236/241] recall the service --- .../patients/profile/referral/my-referral-detail-screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart index fdbf9859..4cc5effd 100644 --- a/lib/screens/patients/profile/referral/my-referral-detail-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-detail-screen.dart @@ -383,6 +383,7 @@ class MyReferralDetailScreen extends StatelessWidget { DrAppToastMsg.showSuccesToast( TranslationBase.of(context) .referralSuccessMsgAccept); + model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); } @@ -409,6 +410,7 @@ class MyReferralDetailScreen extends StatelessWidget { DrAppToastMsg.showSuccesToast( TranslationBase.of(context) .referralSuccessMsgReject); + model.getMyReferralOutPatientService(); Navigator.pop(context); Navigator.pop(context); } From 0006a4de57b40929cd67ac3cbf82be443c2f3215 Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 28 Jun 2021 14:23:49 +0300 Subject: [PATCH 237/241] remove comment --- .../patients/profile/referral/referred-patient-screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index dec6108f..8dce7d60 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -86,7 +86,6 @@ class _ReferredPatientScreenState extends State { ), ); }, - /// TODO Elham* check why we call fun to access attribute child: PatientReferralItemWidget( referralStatus: model .getReferredPatientItem(index) From e8f9c958b12f94213bb32c11f449e15b6bab18fe Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 28 Jun 2021 17:15:47 +0300 Subject: [PATCH 238/241] Fix medical report issues --- lib/config/config.dart | 4 ++-- .../viewModel/PatientMedicalReportViewModel.dart | 12 ++++++++---- lib/core/viewModel/project_view_model.dart | 4 ++-- .../medical_report/AddVerifyMedicalReport.dart | 4 ++-- .../medical_report/MedicalReportPage.dart | 16 +--------------- 5 files changed, 15 insertions(+), 25 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 2d8e4ea2..d6836827 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]"; const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_DATE = "[0-9/]"; const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh"; const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList"; const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient"; diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index ac5ecdeb..e7d343b4 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -60,10 +60,12 @@ class PatientMedicalReportViewModel extends BaseViewModel { await _service.addMedicalReport(patient, htmlText); if (_service.hasError) { error = _service.error; + await getMedicalReportList(patient); setState(ViewState.ErrorLocal); } else - await getMedicalReportList(patient); - setState(ViewState.Idle); + { await getMedicalReportList(patient); + setState(ViewState.Idle); + } } Future updateMedicalReport(PatiantInformtion patient, String htmlText, int limitNumber, String invoiceNumber) async { @@ -71,9 +73,11 @@ class PatientMedicalReportViewModel extends BaseViewModel { await _service.updateMedicalReport(patient, htmlText, limitNumber, invoiceNumber); if (_service.hasError) { error = _service.error; + await getMedicalReportList(patient); setState(ViewState.ErrorLocal); } else - await getMedicalReportList(patient); - setState(ViewState.Idle); + { + await getMedicalReportList(patient); + setState(ViewState.Idle);} } } diff --git a/lib/core/viewModel/project_view_model.dart b/lib/core/viewModel/project_view_model.dart index f464df0e..e7b7a80f 100644 --- a/lib/core/viewModel/project_view_model.dart +++ b/lib/core/viewModel/project_view_model.dart @@ -107,8 +107,8 @@ class ProjectViewModel with ChangeNotifier { return Future.value(localRes); } catch (error) { - print(error); - throw error; + //print(error); + //throw error; } } diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 4a6be6c8..b3714edd 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -103,12 +103,12 @@ class _AddVerifyMedicalReportState extends State { if (txtOfMedicalReport.isNotEmpty) { GifLoaderDialogUtils.showMyDialog(context); widget.medicalReport != null - ? widget.model.updateMedicalReport( + ?await widget.model.updateMedicalReport( widget.patient, txtOfMedicalReport, widget.medicalReport != null ? widget.medicalReport.lineItemNo : null, widget.medicalReport != null ? widget.medicalReport.invoiceNo : null) - : widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); + : await widget.model.addMedicalReport(widget.patient, txtOfMedicalReport); //model.getMedicalReportList(patient); Navigator.pop(context); diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 22645520..a5c367de 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -92,29 +92,15 @@ class _MedicalReportPageState extends State { )), ); - // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - // 'patient': patient, - // 'patientType': patientType, - // 'arrivalType': arrivalType, - // 'type': MedicalReportStatus.ADD, - // 'model': model, - // }); }, label: TranslationBase.of(context).createNewMedicalReport, ), - if (model.state != ViewState.ErrorLocal) + // if (model.state != ViewState.ErrorLocal)ß ...List.generate( model.medicalReportList.length, (index) => InkWell( onTap: () { if (model.medicalReportList[index].status == 1) { - // Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { - // 'patient': patient, - // 'patientType': patientType, - // 'arrivalType': arrivalType, - // 'medicalReport': model.medicalReportList[index], - // 'model': model, - // }); Navigator.push( context, MaterialPageRoute( From 405a363e2854af505af6a5ba6e60ef3c3455465c Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 28 Jun 2021 17:32:50 +0300 Subject: [PATCH 239/241] referral change --- .../viewModel/patient-referral-viewmodel.dart | 8 +-- .../patient-referral-item-widget.dart | 49 +++++++++++++------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index 2e3a6605..4240e848 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -303,13 +303,13 @@ class PatientReferralViewModel extends BaseViewModel { String getReferralStatusNameByCode(int statusCode, BuildContext context) { switch (statusCode) { case 1: - return TranslationBase.of(context).pending /*referralStatusHold*/; + return TranslationBase.of(context).referralStatusHold /*pending*/; case 2: - return TranslationBase.of(context).accepted /*referralStatusActive*/; + return TranslationBase.of(context).referralStatusActive /* accepted*/; case 4: - return TranslationBase.of(context).rejected /*referralStatusCancelled*/; + return TranslationBase.of(context).referralStatusCancelled /*rejected*/; case 46: - return TranslationBase.of(context).accepted /*referralStatusCompleted*/; + return TranslationBase.of(context).referralStatusCompleted /*accepted*/; case 63: return TranslationBase.of(context).rejected /*referralStatusNotSeen*/; default: diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index a898e39c..6d573cc4 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -44,7 +44,9 @@ class PatientReferralItemWidget extends StatelessWidget { this.doctorAvatar, this.referralDoctorName, this.clinicDescription, - this.infoIcon,this.isReferralClinic=false,this.referralClinic}); + this.infoIcon, + this.isReferralClinic = false, + this.referralClinic}); @override Widget build(BuildContext context) { @@ -58,9 +60,13 @@ class PatientReferralItemWidget extends StatelessWidget { child: CardWithBgWidget( bgColor: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 || referralStatusCode == 2 + : referralStatusCode == 2 ? Colors.green[700] - : Colors.red[700], + : referralStatusCode == 46 + ? Colors.green[900] + : referralStatusCode == 4 + ? Colors.red[700] + : Colors.red[900], hasBorder: false, widget: Container( // padding: EdgeInsets.only(left: 20, right: 0, bottom: 0), @@ -78,9 +84,13 @@ class PatientReferralItemWidget extends StatelessWidget { fontWeight: FontWeight.w700, color: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 || referralStatusCode == 2 + : referralStatusCode == 2 ? Colors.green[700] - : Colors.red[700], + : referralStatusCode == 46 + ? Colors.green[900] + : referralStatusCode == 4 + ? Colors.red[700] + : Colors.red[900], ), AppText( referredDate, @@ -158,7 +168,10 @@ class PatientReferralItemWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( - isSameBranch ? TranslationBase.of(context).referredFrom :TranslationBase.of(context).refClinic, + isSameBranch + ? TranslationBase.of(context) + .referredFrom + : TranslationBase.of(context).refClinic, fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.7 * SizeConfig.textMultiplier, @@ -166,7 +179,13 @@ class PatientReferralItemWidget extends StatelessWidget { ), Expanded( child: AppText( - !isReferralClinic? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch: " "+referralClinic, + !isReferralClinic + ? isSameBranch + ? TranslationBase.of(context) + .sameBranch + : TranslationBase.of(context) + .otherBranch + : " " + referralClinic, fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -217,7 +236,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Expanded( child: AppText( - remark??"", + remark ?? "", fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -261,13 +280,13 @@ class PatientReferralItemWidget extends StatelessWidget { }, )) : Container( - child: Image.asset( - patientGender == 1 - ? 'assets/images/male_avatar.png' - : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), + child: Image.asset( + patientGender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), ), ), Expanded( From 4c8f79c87e92c1302e80f6d8575f6ba67422c45f Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 28 Jun 2021 17:58:50 +0300 Subject: [PATCH 240/241] Fix medical report issues --- .../medical_report/PatientMedicalReportService.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart index 01a09592..dfb9c3ae 100644 --- a/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart +++ b/lib/core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart @@ -15,9 +15,8 @@ class PatientMedicalReportService extends BaseService { body['AdmissionNo'] = patient.admissionNo; body['SetupID'] = doctorProfile.setupID; body['ProjectID'] = doctorProfile.projectID; - + medicalReportList = []; await baseAppClient.postPatient(PATIENT_MEDICAL_REPORT_GET_LIST, onSuccess: (dynamic response, int statusCode) { - medicalReportList.clear(); if (response['DAPP_ListMedicalReportList'] != null) { response['DAPP_ListMedicalReportList'].forEach((v) { medicalReportList.add(MedicalReportModel.fromJson(v)); From eb40cc819d15a3632b6c15c16aebbcca5311ef83 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 30 Jun 2021 10:51:42 +0300 Subject: [PATCH 241/241] fix video call --- lib/models/livecare/start_call_res.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/models/livecare/start_call_res.dart b/lib/models/livecare/start_call_res.dart index e3c1a54f..44921d5f 100644 --- a/lib/models/livecare/start_call_res.dart +++ b/lib/models/livecare/start_call_res.dart @@ -24,7 +24,7 @@ class StartCallRes { isAuthenticated = json['IsAuthenticated']; messageStatus = json['MessageStatus']; appointmentNo = json['AppointmentNo']; - isRecording = json['isRecording']; + isRecording = json['IsRecordedSession'] ?? false; } Map toJson() { @@ -35,7 +35,7 @@ class StartCallRes { data['IsAuthenticated'] = this.isAuthenticated; data['MessageStatus'] = this.messageStatus; data['AppointmentNo'] = this.appointmentNo; - data['isRecording'] = this.isRecording; + data['IsRecordedSession'] = this.isRecording ?? false; return data; } }