diff --git a/lib/config/config.dart b/lib/config/config.dart index 698ff8df..a34848d5 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -220,6 +220,12 @@ const ADD_WEIGHT_PRESSURE_RESULT='Services/Patients.svc/REST/Patient_AddWeightMe const ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID='Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID'; +const GET_CALL_INFO_HOURS_RESULT = 'Services/Doctors.svc/REST/GetCallInfoHoursResult'; +const GET_CALL_REQUEST_TYPE_LOV = 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; +const GET_DOCTOR_RESPONSE = 'Services/Patients.svc/REST/GetDoctorResponse'; +const UPDATE_READ_STATUS = 'Services/Patients.svc/REST/UpdateReadStatus'; +const INSERT_CALL_INFO = 'Services/Doctors.svc/REST/InsertCallInfo'; + const TIMER_MIN = 10; diff --git a/lib/core/model/ask_doctor/AskDoctorReqTypes.dart b/lib/core/model/ask_doctor/AskDoctorReqTypes.dart new file mode 100644 index 00000000..b306f97b --- /dev/null +++ b/lib/core/model/ask_doctor/AskDoctorReqTypes.dart @@ -0,0 +1,92 @@ +class AskDoctorReqTypes { + dynamic setupID; + int parameterGroup; + int parameterType; + int parameterCode; + String description; + dynamic descriptionN; + dynamic alias; + dynamic aliasN; + dynamic prefix; + dynamic suffix; + dynamic isColorCodingRequired; + dynamic backColor; + dynamic foreColor; + bool isBuiltIn; + bool isActive; + int createdBy; + String createdOn; + dynamic editedBy; + dynamic editedOn; + dynamic rowVer; + + AskDoctorReqTypes( + {this.setupID, + this.parameterGroup, + this.parameterType, + this.parameterCode, + this.description, + this.descriptionN, + this.alias, + this.aliasN, + this.prefix, + this.suffix, + this.isColorCodingRequired, + this.backColor, + this.foreColor, + this.isBuiltIn, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn, + this.rowVer}); + + AskDoctorReqTypes.fromJson(Map json) { + setupID = json['SetupID']; + parameterGroup = json['ParameterGroup']; + parameterType = json['ParameterType']; + parameterCode = json['ParameterCode']; + description = json['Description']; + descriptionN = json['DescriptionN']; + alias = json['Alias']; + aliasN = json['AliasN']; + prefix = json['Prefix']; + suffix = json['Suffix']; + isColorCodingRequired = json['IsColorCodingRequired']; + backColor = json['BackColor']; + foreColor = json['ForeColor']; + isBuiltIn = json['IsBuiltIn']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + rowVer = json['RowVer']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ParameterGroup'] = this.parameterGroup; + data['ParameterType'] = this.parameterType; + data['ParameterCode'] = this.parameterCode; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + data['Alias'] = this.alias; + data['AliasN'] = this.aliasN; + data['Prefix'] = this.prefix; + data['Suffix'] = this.suffix; + data['IsColorCodingRequired'] = this.isColorCodingRequired; + data['BackColor'] = this.backColor; + data['ForeColor'] = this.foreColor; + data['IsBuiltIn'] = this.isBuiltIn; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['RowVer'] = this.rowVer; + return data; + } +} diff --git a/lib/core/model/ask_doctor/DoctorResponse.dart b/lib/core/model/ask_doctor/DoctorResponse.dart new file mode 100644 index 00000000..0dcd41b0 --- /dev/null +++ b/lib/core/model/ask_doctor/DoctorResponse.dart @@ -0,0 +1,76 @@ +class DoctorResponse { + int projectID; + int transactionNo; + int patientID; + int doctorID; + int requestType; + String requestTypeDescription; + dynamic requestTypeDescriptionN; + int status; + String remarks; + String createdOn; + dynamic readStatus; + String doctorName; + bool isDoctorRespond; + bool isPatientRead; + List transactions; + + DoctorResponse( + {this.projectID, + this.transactionNo, + this.patientID, + this.doctorID, + this.requestType, + this.requestTypeDescription, + this.requestTypeDescriptionN, + this.status, + this.remarks, + this.createdOn, + this.readStatus, + this.doctorName, + this.isDoctorRespond, + this.isPatientRead, + this.transactions}); + + DoctorResponse.fromJson(Map json) { + projectID = json['ProjectID']; + transactionNo = json['TransactionNo']; + patientID = json['PatientID']; + doctorID = json['DoctorID']; + requestType = json['RequestType']; + requestTypeDescription = json['RequestTypeDescription']; + requestTypeDescriptionN = json['RequestTypeDescriptionN']; + status = json['Status']; + remarks = json['Remarks']; + createdOn = json['CreatedOn']; + readStatus = json['ReadStatus']; + doctorName = json['DoctorName']; + isDoctorRespond = json['IsDoctorRespond']; + isPatientRead = json['IsPatientRead']; + if (json['Transactions'] != null) { + transactions = json['Transactions']; + } + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['TransactionNo'] = this.transactionNo; + data['PatientID'] = this.patientID; + data['DoctorID'] = this.doctorID; + data['RequestType'] = this.requestType; + data['RequestTypeDescription'] = this.requestTypeDescription; + data['RequestTypeDescriptionN'] = this.requestTypeDescriptionN; + data['Status'] = this.status; + data['Remarks'] = this.remarks; + data['CreatedOn'] = this.createdOn; + data['ReadStatus'] = this.readStatus; + data['DoctorName'] = this.doctorName; + data['IsDoctorRespond'] = this.isDoctorRespond; + data['IsPatientRead'] = this.isPatientRead; + if (this.transactions != null) { + data['Transactions'] = this.transactions.map((v) => v.toJson()).toList(); + } + return data; + } +} diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8fde2166..289112ee 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -67,8 +67,7 @@ class BaseAppClient { if (user != null) { body['TokenID'] = token; - body['PatientID'] = - body['PatientID'] != null ? body['PatientID'] : user['PatientID']; + body['PatientID'] = user['PatientID']; body['PatientOutSA'] = user['OutSA']; body['SessionID'] = getSessionId(token); } diff --git a/lib/core/service/medical/ask_doctor_services.dart b/lib/core/service/medical/ask_doctor_services.dart new file mode 100644 index 00000000..9a819a6e --- /dev/null +++ b/lib/core/service/medical/ask_doctor_services.dart @@ -0,0 +1,106 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/ask_doctor/AskDoctorReqTypes.dart'; +import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class AskDoctorService extends BaseService { + List askDoctorReqTypes = List(); + List doctorResponseList = List(); + + Future getCallInfoHoursResult({int projectId, int doctorId}) async { + hasError = false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['DoctorID'] = doctorId; + body['ProjectID'] = projectId; + + await baseAppClient.post(GET_CALL_INFO_HOURS_RESULT, + onSuccess: (dynamic response, int statusCode) { + ///OKAY + var asd=""; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getCallRequestTypeLOV() async { + hasError =false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + await baseAppClient.post(GET_CALL_REQUEST_TYPE_LOV, + onSuccess: (dynamic response, int statusCode) { + askDoctorReqTypes.clear(); + response['ListReqTypes'].forEach((reqType) { + askDoctorReqTypes.add(AskDoctorReqTypes.fromJson(reqType)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getDoctorResponse() async { + hasError =false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['from'] = + "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} 00:00:00"; + body['from'] = + "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}:00"; + await baseAppClient.post(GET_DOCTOR_RESPONSE, + onSuccess: (dynamic response, int statusCode) { + doctorResponseList.clear(); + response['List_DoctorResponse'].forEach((reqType) { + doctorResponseList.add(DoctorResponse.fromJson(reqType)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future updateReadStatus({int transactionNo}) async { + hasError =false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['TransactionNo'] = transactionNo; + await baseAppClient.post(UPDATE_READ_STATUS, + onSuccess: (dynamic response, int statusCode) { + //TODO fix it + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + + Future sendRequestLOV({DoctorList doctorList,String requestType,String remark}) async { + hasError =false; + Map body = Map(); + body['ProjectID'] = doctorList.projectID; + body['SetupID'] = doctorList.setupID; + body['DoctorID'] = doctorList.doctorID; + body['PatientMobileNumber'] = user.mobileNumber; + body['IsMessageSent'] = false; + body['RequestDate'] = DateUtil.yearMonthDay(DateTime.now()); + body['RequestTime'] = DateUtil.time(DateTime.now()); + body['Remarks'] = remark; + body['Status'] = 2;// 4 for testing only.."cancelled status insert" else should be changed to 1 in live version + body['CreatedBy'] = 102; + body['CreatedOn'] = DateUtil.yearMonthDay(DateTime.now()); + body['EditedBy'] = 102; + body['EditedOn'] = DateUtil.yearMonthDay(DateTime.now()); + body['isDentalAllowedBackend'] = false; + await baseAppClient.post(INSERT_CALL_INFO, + onSuccess: (dynamic response, int statusCode) { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + +} diff --git a/lib/core/service/medical/my_doctor_service.dart b/lib/core/service/medical/my_doctor_service.dart index 4df3ce8a..f2ba067a 100644 --- a/lib/core/service/medical/my_doctor_service.dart +++ b/lib/core/service/medical/my_doctor_service.dart @@ -15,22 +15,8 @@ class MyDoctorService extends BaseService { RequestPatientDoctorAppointment patientDoctorAppointmentRequest = RequestPatientDoctorAppointment( - top: 0, - versionID: 5.5, - beforeDays: 0, - exludType: 4, - channel: 3, - languageID: 2, - iPAdress: '10.20.10.20', - generalid: 'Cs2020@2016\$2958', - patientOutSA: 0, - sessionID: 'TMRhVmkGhOsvamErw', - isDentalAllowedBackend: false, - deviceTypeID: 1, - patientID: 1231755, - tokenID: '@dm!n', - patientType: 1, - patientTypeID: 1); + isDentalAllowedBackend: false, + ); RequestDoctorRating _requestDoctorRating = RequestDoctorRating( channel: 3, @@ -44,7 +30,12 @@ class MyDoctorService extends BaseService { generalid: 'Cs2020@2016\$2958', isDentalAllowedBackend: false); - Future getPatientDoctorAppointmentList() async { + Future getPatientDoctorAppointmentList({int top = 0, int beforeDays = 0,int exludType=4}) async { + hasError = false; + patientDoctorAppointmentRequest.top = top; + patientDoctorAppointmentRequest.beforeDays = beforeDays; + patientDoctorAppointmentRequest.exludType = exludType; + await baseAppClient.post(GET_MY_DOCTOR, onSuccess: (dynamic response, int statusCode) { patientDoctorAppointmentList.clear(); @@ -75,7 +66,8 @@ class MyDoctorService extends BaseService { deviceTypeID: 2, ); - Future getDoctorProfileAndRating({int doctorId,int clinicID,int projectID }) async { + Future getDoctorProfileAndRating( + {int doctorId, int clinicID, int projectID}) async { ///GET DOCTOR PROFILE _requestDoctorProfile.doctorID = doctorId; _requestDoctorProfile.clinicID = clinicID; @@ -89,8 +81,6 @@ class MyDoctorService extends BaseService { doctorList.doctorTitle = doctorProfile.doctorTitleForProfile; doctorList.name = doctorProfile.doctorName; doctorList.projectName = doctorProfile.projectName; - - }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModels/base_view_model.dart b/lib/core/viewModels/base_view_model.dart index 8e228512..3d7122bd 100644 --- a/lib/core/viewModels/base_view_model.dart +++ b/lib/core/viewModels/base_view_model.dart @@ -18,9 +18,11 @@ class BaseViewModel extends ChangeNotifier { void setState(ViewState viewState) { _state = viewState; - // this.removeListener(() { }); - if(hasListeners) - notifyListeners(); + + if (viewState == ViewState.Busy || viewState == ViewState.BusyLocal) + error = ""; + + if (hasListeners) notifyListeners(); } BaseViewModel() { @@ -39,7 +41,7 @@ class BaseViewModel extends ChangeNotifier { @override void dispose() { - removeListener(() { }); + removeListener(() {}); super.dispose(); } } diff --git a/lib/core/viewModels/medical/ask_doctor_view_model.dart b/lib/core/viewModels/medical/ask_doctor_view_model.dart new file mode 100644 index 00000000..629df0a9 --- /dev/null +++ b/lib/core/viewModels/medical/ask_doctor_view_model.dart @@ -0,0 +1,110 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/ask_doctor/AskDoctorReqTypes.dart'; +import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; +import 'package:diplomaticquarterapp/core/service/medical/ask_doctor_services.dart'; +import 'package:diplomaticquarterapp/core/service/medical/my_doctor_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; + +class AskDoctorViewModel extends BaseViewModel { + AskDoctorService _askDoctorService = locator(); + MyDoctorService _myDoctorService = locator(); + + List patientDoctorAppointmentListHospital = + List(); + + List get askDoctorReqTypes => + _askDoctorService.askDoctorReqTypes; + + List get doctorResponseList => + _askDoctorService.doctorResponseList; + + Future getMyDoctor() async { + setState(ViewState.Busy); + await _myDoctorService.getPatientDoctorAppointmentList( + top: 25, beforeDays: 15); + if (_myDoctorService.hasError) { + error = _myDoctorService.error; + setState(ViewState.Error); + } else + var asd = ""; + _myDoctorService.patientDoctorAppointmentList.forEach((element) { + List doctorByClinic = + patientDoctorAppointmentListHospital + .where((elementClinic) => + elementClinic.filterName == element.projectName) + .toList(); + + if (doctorByClinic.length != 0) { + patientDoctorAppointmentListHospital[ + patientDoctorAppointmentListHospital.indexOf(doctorByClinic[0])] + .patientDoctorAppointmentList + .add(element); + } else { + patientDoctorAppointmentListHospital.add(PatientDoctorAppointmentList( + filterName: element.projectName, + patientDoctorAppointment: element)); + } + + setState(ViewState.Idle); + }); + } + + Future getCallRequestTypeLOVs() async { + setState(ViewState.Busy); + await _askDoctorService.getCallRequestTypeLOV(); + if (_askDoctorService.hasError) { + error = _askDoctorService.error; + setState(ViewState.ErrorLocal); + AppToast.showErrorToast(message: error); + } else + setState(ViewState.Idle); + } + + Future getCallInfoHoursResult({int projectId, int doctorId}) async { + setState(ViewState.Busy); + await _askDoctorService.getCallInfoHoursResult( + projectId: projectId, doctorId: doctorId); + if (_askDoctorService.hasError) { + error = _askDoctorService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + getDoctorResponse() async { + setState(ViewState.Busy); + await _askDoctorService.getDoctorResponse(); + if (_askDoctorService.hasError) { + error = _askDoctorService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future updateReadStatus({int transactionNo}) async { + setState(ViewState.Busy); + await _askDoctorService.updateReadStatus(transactionNo: transactionNo); + if (_askDoctorService.hasError) { + error = _askDoctorService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future sendRequestLOV( + {DoctorList doctorList, String requestType, String remark}) async { + setState(ViewState.BusyLocal); + await _askDoctorService.sendRequestLOV( + doctorList: doctorList, requestType: requestType, remark: remark); + if (_askDoctorService.hasError) { + error = _askDoctorService.error; + setState(ViewState.ErrorLocal); + AppToast.showErrorToast(message: error); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/locator.dart b/lib/locator.dart index 79e92a63..406dee3e 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -15,6 +15,7 @@ import 'core/service/medical/BloodSugarService.dart'; import 'core/service/medical/EyeService.dart'; import 'core/service/medical/PatientSickLeaveService.dart'; import 'core/service/medical/WeightPressureService.dart'; +import 'core/service/medical/ask_doctor_services.dart'; import 'core/service/medical/labs_service.dart'; import 'core/service/medical/medical_service.dart'; import 'core/service/medical/my_balance_service.dart'; @@ -31,6 +32,7 @@ import 'core/service/medical/reports_service.dart'; import 'core/viewModels/hospital_view_model.dart'; import 'core/viewModels/medical/ActiveMedicationsViewModel.dart'; import 'core/viewModels/medical/EyeViewModel.dart'; +import 'core/viewModels/medical/ask_doctor_view_model.dart'; import 'core/viewModels/medical/blood_pressure_view_model.dart'; import 'core/viewModels/medical/labs_view_model.dart'; import 'core/viewModels/medical/medical_view_model.dart'; @@ -83,6 +85,7 @@ void setupLocator() { locator.registerLazySingleton(() => WeightService()); locator.registerLazySingleton(() => EyeService()); locator.registerLazySingleton(() => ActiveMedicationsService()); + locator.registerLazySingleton(() => AskDoctorService()); /// View Model locator.registerFactory(() => HospitalViewModel()); @@ -110,5 +113,5 @@ void setupLocator() { locator.registerFactory(() => WeightPressureViewMode()); locator.registerFactory(() => EyeViewModel()); locator.registerFactory(() => ActiveMedicationsViewModel()); - + locator.registerFactory(() => AskDoctorViewModel()); } diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index d3150459..cad9da25 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -13,6 +13,7 @@ class DoctorView extends StatelessWidget { final DoctorList doctor; + DoctorView({@required this.doctor}); @override diff --git a/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart new file mode 100644 index 00000000..2551ebc9 --- /dev/null +++ b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart @@ -0,0 +1,32 @@ +import 'package:diplomaticquarterapp/core/model/ask_doctor/DoctorResponse.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; + +class ViewDoctorResponsesPage extends StatelessWidget { + final DoctorResponse doctorResponse; + + const ViewDoctorResponsesPage({Key key, this.doctorResponse}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.updateReadStatus(transactionNo: doctorResponse.transactionNo), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + appBarTitle: ' View Doctor Responses', + baseViewModel: model, + body: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart new file mode 100644 index 00000000..e934c78d --- /dev/null +++ b/lib/pages/medical/ask_doctor/ask_doctor_home_page.dart @@ -0,0 +1,125 @@ +import 'dart:ui'; + +import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'ask_doctor_page.dart'; +import 'doctor_response.dart'; + +class AskDoctorHomPage extends StatefulWidget { + @override + _AskDoctorHomPageState createState() => _AskDoctorHomPageState(); +} + +class _AskDoctorHomPageState extends State + with SingleTickerProviderStateMixin { + TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).prescriptions, + body: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight(65.0), + child: Stack( + children: [ + Positioned( + bottom: 1, + left: 0, + right: 0, + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + color: Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.8), + height: 70.0, + ), + ), + ), + Center( + child: Container( + height: 60.0, + margin: EdgeInsets.only(top: 10.0), + width: MediaQuery.of(context).size.width * 0.9, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.9), + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: true, + controller: _tabController, + indicatorWeight: 5.0, + //indicatorSize: TabBarIndicatorSize.label, + indicatorColor: Colors.red[800], + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + Tab( + child: Container( + width: MediaQuery.of(context).size.width * 0.36, + child: Center( + child: Texts('ASK Doctor'), + ), + ), + ), + Tab(child: Container( + width: MediaQuery.of(context).size.width * 0.36, + child: Center( + child: Texts('Doctor Responses',textAlign: TextAlign.start,), + ), + ),) + ], + ), + ), + ), + ), + ], + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + AskDoctorPage(), + DoctorResponse() + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart new file mode 100644 index 00000000..1aa0004b --- /dev/null +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -0,0 +1,243 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/ask_doctor/request_type.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:rating_bar/rating_bar.dart'; +import 'package:smart_progress_bar/smart_progress_bar.dart'; + +class AskDoctorPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getMyDoctor(), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.all(10), + child: Column( + children: [ + SizedBox( + height: 70, + ), + ...List.generate( + model.patientDoctorAppointmentListHospital.length, + (index) => AppExpandableNotifier( + title: + model.patientDoctorAppointmentListHospital[index].filterName, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: + model.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList.map((doctor) { + return InkWell( + onTap: () { + model + .getCallInfoHoursResult( + doctorId: doctor.doctorID, + projectId: doctor.projectID) + .then((value) { + if (model.state != ViewState.ErrorLocal && + model.state != ViewState.Error) { + // Navigator.pop(context); + Navigator.push( + context, + FadePage( + page: RequestTypePage(doctorList: doctor,), + ), + ); + } else { + AppToast.showErrorToast(message: model.error); + } + }); + + ///.showProgressBar( + // text: "Loading", + // backgroundColor: + // Colors.blue.withOpacity(0.6)) + }, + child: Card( + margin: + EdgeInsets.fromLTRB(10.0, 16.0, 10.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + decoration: BoxDecoration(), + padding: EdgeInsets.all(7.0), + width: MediaQuery.of(context).size.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: ClipRRect( + borderRadius: + BorderRadius.circular(100.0), + child: Image.network( + doctor.doctorImageURL, + fit: BoxFit.fill, + height: 60.0, + width: 60.0), + ), + ), + Expanded( + flex: 4, + child: Container( + width: + MediaQuery.of(context).size.width * + 0.55, + margin: EdgeInsets.fromLTRB( + 20.0, 10.0, 10.0, 0.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + if (doctor.doctorTitle != null) + Text( + doctor.doctorTitle + + " " + + doctor.name, + style: TextStyle( + fontSize: 14.0, + color: Colors.grey[700], + letterSpacing: 1.0)), + Container( + margin: EdgeInsets.only(top: 3.0), + child: Text(doctor.clinicName, + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + Container( + margin: EdgeInsets.only(top: 3.0), + child: Text(doctor.projectName, + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + if (doctor.speciality != null) + Container( + margin: EdgeInsets.only( + top: 3.0, bottom: 3.0), + child: Text( + getDoctorSpeciality( + doctor.speciality) + .trim(), + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + doctor.nearestFreeSlot != null + ? Container( + margin: EdgeInsets.only( + top: 3.0, bottom: 3.0), + child: Text( + getDate(doctor + .nearestFreeSlot), + style: TextStyle( + fontSize: 14.0, + fontWeight: + FontWeight.bold, + color: Colors + .green[600], + letterSpacing: + 1.0)), + ) + : Container(), + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + RatingBar.readOnly( + initialRating: doctor + .actualDoctorRate + .toDouble(), + size: 20.0, + filledColor: + Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: + Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + Container( + child: Image.network( + doctor.nationalityFlagURL, + width: 25.0, + height: 25.0), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + }).toList(), + )), + ) + ], + ), + ), + ), + ), + ); + } + + String getDoctorSpeciality(List docSpecial) { + String docSpeciality = ""; + docSpecial.forEach((v) { + docSpeciality = docSpeciality + v + "\n"; + }); + return docSpeciality; + } + + String getDate(String date) { + DateTime dateObj = DateUtil.convertStringToDate(date); + return DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString() + + " " + + dateObj.hour.toString() + + ":" + + getMinute(dateObj); + } + + String getMinute(DateTime dateObj) { + if (dateObj.minute == 0) { + return dateObj.minute.toString() + "0"; + } else { + return dateObj.minute.toString(); + } + } +} + +/** + * + */ diff --git a/lib/pages/medical/ask_doctor/doctor_response.dart b/lib/pages/medical/ask_doctor/doctor_response.dart new file mode 100644 index 00000000..6993eb5b --- /dev/null +++ b/lib/pages/medical/ask_doctor/doctor_response.dart @@ -0,0 +1,178 @@ +import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'ViewDoctorResponsesPage.dart'; + +class DoctorResponse extends StatelessWidget { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) => model.getDoctorResponse(), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 65, + ), + AppExpandableNotifier( + header: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts('New'), + Container( + width: 30, + height: 30, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.red[800], + ), + child: Center( + child: Texts( + '${model.doctorResponseList.length}', + color: Colors.white, + ), + ), + ) + ], + ), + ), + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: model.doctorResponseList.map( + (doctor) { + return InkWell( + onTap: () { + ///go to page ViewDoctorResponsesPage + Navigator.push( + context, + FadePage( + page: ViewDoctorResponsesPage(doctorResponse: doctor,), + ), + ); + }, + child: Container( + height: 70, + margin: EdgeInsets.only(top: 8,bottom: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.white, + border: Border.all(color: Colors.grey[300]), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('${doctor.doctorName}'), + SizedBox(height: 5,), + Texts('${doctor.requestTypeDescription}'), + ], + ), + ), + ), + Icon(projectViewModel.isArabic + ? Icons.arrow_forward_ios + : Icons.arrow_back_ios) + ], + ), + ), + ); + }, + ).toList(), + ), + ), + AppExpandableNotifier( + header: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts('All'), + Container( + width: 30, + height: 30, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.red[800], + ), + child: Center( + child: Texts( + '${model.doctorResponseList.length}', + color: Colors.white, + ), + ), + ) + ], + ), + ), + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: model.doctorResponseList.map( + (doctor) { + return InkWell( + onTap: () {}, + child: Container( + height: 70, + margin: EdgeInsets.only(top: 8,bottom: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.white, + border: Border.all(color: Colors.grey[300]), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('${doctor.doctorName}'), + SizedBox(height: 5,), + Texts('${doctor.requestTypeDescription}'), + ], + ), + ), + ), + Icon(projectViewModel.isArabic + ? Icons.arrow_forward_ios + : Icons.arrow_back_ios) + ], + ), + ), + ); + }, + ).toList(), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/ask_doctor/request_type.dart b/lib/pages/medical/ask_doctor/request_type.dart new file mode 100644 index 00000000..cbf2e606 --- /dev/null +++ b/lib/pages/medical/ask_doctor/request_type.dart @@ -0,0 +1,132 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/ask_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class RequestTypePage extends StatefulWidget { + final DoctorList doctorList; + + RequestTypePage({Key key, this.doctorList}); + + @override + _RequestTypePageState createState() => _RequestTypePageState(); +} + +class _RequestTypePageState extends State { + String selected = ""; + int parameterCode = -1; + String question = ""; + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getCallRequestTypeLOVs(), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + appBarTitle: 'Request Type', + baseViewModel: model, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...List.generate( + model.askDoctorReqTypes.length, + (index) => Container( + width: double.maxFinite, + height: 55, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.0)), + margin: EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + setState(() { + selected = model.askDoctorReqTypes[index].description; + parameterCode = + model.askDoctorReqTypes[index].parameterCode; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + model.askDoctorReqTypes[index].description), + ), + Radio( + value: model.askDoctorReqTypes[index].description, + groupValue: selected, + activeColor: Colors.red[800], + onChanged: (value) { + setState(() { + selected = value; + parameterCode = model + .askDoctorReqTypes[index].parameterCode; + }); + }, + ), + ], + ), + ), + ), + ), + if (parameterCode == 6) + Container( + margin: EdgeInsets.only(left: 10, right: 10), + child: NewTextFields( + hintText: 'Enter the question here...', + minLines: 2, + maxLines: 15, + onChanged: (value) { + setState(() { + question = value; + }); + }, + ), + ), + Container( + width: double.maxFinite, + height: MediaQuery.of(context).size.height * 0.2, + ), + ], + ), + ), + ), + bottomSheet: Container( + width: double.maxFinite, + height: MediaQuery.of(context).size.height * 0.1, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: SecondaryButton( + label: 'Send', + loading: model.state == ViewState.BusyLocal, + textColor: Colors.white, + onTap: () { + model.sendRequestLOV( + doctorList: widget.doctorList, + requestType: parameterCode.toString(), + remark: question).then((value) { + if(model.state!=ViewState.ErrorLocal|| model.state!=ViewState.Error){ + Navigator.pop(context); + } + AppToast.showErrorToast(message: "The question add fine "); + + }); + }, + color: Colors.grey[800], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/medical_profile_page.dart b/lib/pages/medical/medical_profile_page.dart index cf9738df..2ac3b4de 100644 --- a/lib/pages/medical/medical_profile_page.dart +++ b/lib/pages/medical/medical_profile_page.dart @@ -25,6 +25,7 @@ import 'package:diplomaticquarterapp/pages/insurance/insurance_card_screen.dart' import 'package:provider/provider.dart'; import '../../locator.dart'; import 'active_medications/ActiveMedicationsPage.dart'; +import 'ask_doctor/ask_doctor_home_page.dart'; import 'balance/my_balance_page.dart'; import 'doctor/doctor_home_page.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; @@ -434,11 +435,17 @@ class _MedicalProfilePageState extends State { ), Expanded( flex: 1, - child: MedicalProfileItem( - title: TranslationBase.of(context).askYour, - imagePath: 'medical_history_icon.png', - subTitle: TranslationBase.of(context) - .askYourSubtitle, + child: InkWell( + onTap: (){ + Navigator.push(context, + FadePage(page: AskDoctorHomPage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).askYour, + imagePath: 'medical_history_icon.png', + subTitle: TranslationBase.of(context) + .askYourSubtitle, + ), ), ), ]), diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index a150086c..65d018bf 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -26,6 +26,16 @@ class DateUtil { return start + "$milliseconds" + end; } + static String yearMonthDay(DateTime dateTime){ + String dateFormat = '${dateTime.year}-${dateTime.month}-${dateTime.day}'; + return dateFormat; + } + + static String time(DateTime dateTime){ + String dateFormat = '${dateTime.hour}:${dateTime.minute}:00'; + return dateFormat; + } + /// check Date /// [dateString] String we want to convert static String checkDate(DateTime checkedTime) { diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart index 353846e1..0f6de09f 100644 --- a/lib/widgets/others/app_expandable_notifier.dart +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -11,9 +11,10 @@ class AppExpandableNotifier extends StatelessWidget { final Widget bodyWidget; final String title; final Widget collapsed; + final Widget header; AppExpandableNotifier( - {this.headerWidget, this.bodyWidget, this.title, this.collapsed}); + {this.headerWidget, this.bodyWidget, this.title, this.collapsed,this.header}); @override Widget build(BuildContext context) { @@ -35,7 +36,7 @@ class AppExpandableNotifier extends StatelessWidget { headerAlignment: ExpandablePanelHeaderAlignment.center, tapBodyToCollapse: true, ), - header: Padding( + header: header ?? Padding( padding: EdgeInsets.all(10), child: Text( title?? 'Details',