From f25d18353f4c08c98d11b04ee91602412126ad1f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 27 Sep 2020 10:22:32 +0300 Subject: [PATCH 1/7] icons updated --- lib/pages/ContactUs/findus/hospitrals_page.dart | 2 +- lib/pages/ContactUs/findus/pharmacies_page.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/ContactUs/findus/hospitrals_page.dart b/lib/pages/ContactUs/findus/hospitrals_page.dart index 9b1e2f5f..12e7baac 100644 --- a/lib/pages/ContactUs/findus/hospitrals_page.dart +++ b/lib/pages/ContactUs/findus/hospitrals_page.dart @@ -57,7 +57,7 @@ class _HospitalsPageState extends State { child: Image.network(model.FindusHospitalModelList[index].projectImageURL.toString())), Container(child: Texts('${model.FindusHospitalModelList[index].locationName}')),//model.cOCItemList[index].cOCTitl IconButton( - icon: Icon(Icons.person_pin_circle_outlined), + icon: Icon(Icons.location_on, color: Colors.red[900]), tooltip: 'Increase volume by 10', onPressed: () { setState(() { diff --git a/lib/pages/ContactUs/findus/pharmacies_page.dart b/lib/pages/ContactUs/findus/pharmacies_page.dart index 68e3c8bc..cf3f5972 100644 --- a/lib/pages/ContactUs/findus/pharmacies_page.dart +++ b/lib/pages/ContactUs/findus/pharmacies_page.dart @@ -80,7 +80,7 @@ class _PharmaciesPageState extends State { ), Container(child: Texts('${model.FindusPharmaciesModelList[index].locationName}')),//model.cOCItemList[index].cOCTitl IconButton( - icon: Icon(Icons.person_pin_circle_outlined), + icon: Icon(Icons.location_on, color: Colors.red[900]), tooltip: 'Increase volume by 10', onPressed: () { setState(() { From c9256a654ade4cffc63dac3c8079eb4c2e70cbe9 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 29 Sep 2020 18:01:42 +0300 Subject: [PATCH 2/7] LiveCare Scheduling updates --- lib/config/localized_values.dart | 1 + lib/config/shared_pref_kay.dart | 1 + .../Appointments/PatientShareResposne.dart | 16 +- .../LiveCareScheduleClinicsListResponse.dart | 64 +++ lib/pages/BookAppointment/BookConfirm.dart | 79 +++- lib/pages/BookAppointment/BookSuccess.dart | 73 ++-- lib/pages/BookAppointment/DoctorProfile.dart | 13 +- lib/pages/BookAppointment/SearchResults.dart | 4 +- .../components/DocAvailableAppointments.dart | 49 ++- .../components/SearchByDoctor.dart | 1 + .../BookAppointment/widgets/BranchView.dart | 4 +- .../BookAppointment/widgets/DoctorView.dart | 4 +- .../LiveChat/hospitalsLivechat_page.dart | 2 +- .../widgets/AppointmentActions.dart | 5 +- lib/pages/ToDoList/ToDo.dart | 30 +- lib/pages/livecare/livecare_home.dart | 2 + .../livecare_scheduling_clinic_list.dart | 0 .../schedule_clinic_card.dart | 51 +++ lib/pages/livecare/livecare_type_select.dart | 224 +++++++++++ lib/pages/livecare/widgets/clinic_list.dart | 378 ++++++++++++++---- .../appointment_services/GetDoctorsList.dart | 135 +++++++ .../livecare_services/livecare_provider.dart | 75 ++++ lib/uitl/translations_delegate_base.dart | 2 + 23 files changed, 1075 insertions(+), 138 deletions(-) create mode 100644 lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart create mode 100644 lib/pages/livecare/livecare_scheduling/livecare_scheduling_clinic_list.dart create mode 100644 lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart create mode 100644 lib/pages/livecare/livecare_type_select.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index ac7ee547..6053dd4a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -47,6 +47,7 @@ const Map> localizedValues = { }, 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, + 'confirmLiveCare': {'en': 'Confirm LiveCare', 'ar': 'تأكيد لايف كير'}, 'appointment': {'en': 'Appointment', 'ar': 'الموعد'}, 'confirmLater': {'en': 'Confirm Later', 'ar': 'تأكيد لاحقا'}, 'todoList': {'en': 'Todo List', 'ar': 'مهامي'}, diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 61e36022..8087a7f1 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -14,3 +14,4 @@ const FAMILY_FILE = 'family-file'; const USER_LAT = 'user-lat'; const USER_LONG = 'user-long'; const IS_GO_TO_PARKING = 'IS_GO_TO_PARKING'; +const IS_LIVECARE_APPOINTMENT = 'is_livecare_appointment'; diff --git a/lib/models/Appointments/PatientShareResposne.dart b/lib/models/Appointments/PatientShareResposne.dart index e4a05e04..e3a596d6 100644 --- a/lib/models/Appointments/PatientShareResposne.dart +++ b/lib/models/Appointments/PatientShareResposne.dart @@ -13,17 +13,17 @@ class PatientShareResponse { String doctorImageURL; String doctorNameObj; List doctorSpeciality; - Null errCode; + dynamic errCode; int groupID; bool iSAllowOnlineCheckedIN; - Null insurancePolicyNo; + dynamic insurancePolicyNo; bool isExcludedForOnlineCheckin; int isFollowup; bool isLiveCareAppointment; bool isOnlineCheckedIN; String message; int nextAction; - Null patientCardID; + dynamic patientCardID; int patientID; dynamic patientShare; dynamic patientShareWithTax; @@ -32,20 +32,20 @@ class PatientShareResponse { String patientType; int paymentAmount; String paymentDate; - Null paymentMethodName; - Null paymentReferenceNumber; + dynamic paymentMethodName; + dynamic paymentReferenceNumber; int policyId; String policyName; String procedureName; int projectID; String projectName; - Null setupID; + dynamic setupID; int sourceType; String startTime; int status; int statusCode; - Null statusDesc; - Null subPolicyNo; + dynamic statusDesc; + dynamic subPolicyNo; int userID; PatientShareResponse( diff --git a/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart b/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart new file mode 100644 index 00000000..8951370c --- /dev/null +++ b/lib/models/LiveCare/LiveCareScheduleClinicsListResponse.dart @@ -0,0 +1,64 @@ +class LiveCareScheduleClinicsListResponse { + List clinicsHaveScheduleList; + + LiveCareScheduleClinicsListResponse({this.clinicsHaveScheduleList}); + + LiveCareScheduleClinicsListResponse.fromJson(Map json) { + if (json['ClinicsHaveScheduleList'] != null) { + clinicsHaveScheduleList = new List(); + json['ClinicsHaveScheduleList'].forEach((v) { + clinicsHaveScheduleList.add(new ClinicsHaveScheduleList.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.clinicsHaveScheduleList != null) { + data['ClinicsHaveScheduleList'] = + this.clinicsHaveScheduleList.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ClinicsHaveScheduleList { + int clinicID; + int serviceID; + int projectID; + String clinicDesc; + String clinicDescN; + String projectDesc; + String projectDescN; + + ClinicsHaveScheduleList( + {this.clinicID, + this.serviceID, + this.projectID, + this.clinicDesc, + this.clinicDescN, + this.projectDesc, + this.projectDescN}); + + ClinicsHaveScheduleList.fromJson(Map json) { + clinicID = json['ClinicID']; + serviceID = json['ServiceID']; + projectID = json['ProjectID']; + clinicDesc = json['ClinicDesc']; + clinicDescN = json['ClinicDescN']; + projectDesc = json['ProjectDesc']; + projectDescN = json['ProjectDescN']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicID'] = this.clinicID; + data['ServiceID'] = this.serviceID; + data['ProjectID'] = this.projectID; + data['ClinicDesc'] = this.clinicDesc; + data['ClinicDescN'] = this.clinicDescN; + data['ProjectDesc'] = this.projectDesc; + data['ProjectDescN'] = this.projectDescN; + return data; + } +} diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 88ecdb6b..8647b2f0 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -24,10 +24,12 @@ class BookConfirm extends StatefulWidget { String appoDateFormatted = ""; String appoTimeFormatted = ""; + bool isLiveCareAppointment; BookConfirm( {@required this.doctor, @required this.selectedDate, + @required this.isLiveCareAppointment, @required this.selectedTime}); DoctorsListService service; @@ -358,7 +360,11 @@ class _BookConfirmState extends State { disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), onPressed: () { - insertAppointment(context, widget.doctor); + if (!widget.isLiveCareAppointment) { + insertAppointment(context, widget.doctor); + } else { + insertLiveCareScheduledAppointment(context, widget.doctor); + } }, child: Text(TranslationBase.of(context).bookNow, style: TextStyle(fontSize: 18.0)), @@ -375,7 +381,11 @@ class _BookConfirmState extends State { service.cancelAppointment(appo, context).then((res) { if (res['MessageStatus'] == 1) { Future.delayed(new Duration(milliseconds: 1500), () { - insertAppointment(context, docObject); + if (!widget.isLiveCareAppointment) { + insertAppointment(context, widget.doctor); + } else { + insertLiveCareScheduledAppointment(context, widget.doctor); + } }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); @@ -434,6 +444,55 @@ class _BookConfirmState extends State { text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } + insertLiveCareScheduledAppointment(context, DoctorList docObject) { + AppoitmentAllHistoryResultList appo; + widget.service + .insertLiveCareScheduleAppointment( + docObject.doctorID, + docObject.clinicID, + docObject.projectID, + docObject.serviceID, + widget.selectedTime, + widget.selectedDate, + context) + .then((res) { + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: "Appointment Booked Successfully"); + print(res['AppointmentNo']); + + Future.delayed(new Duration(milliseconds: 1800), () { + getLiveCareAppointmentPatientShare(context, res['AppointmentNo'], + docObject.clinicID, docObject.projectID, docObject); + }); + } else { + appo = new AppoitmentAllHistoryResultList(); + appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; + appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; + appo.projectID = res['SameClinicApptList'][0]['ProjectID']; + appo.endTime = res['SameClinicApptList'][0]['EndTime']; + appo.startTime = res['SameClinicApptList'][0]['StartTime']; + appo.doctorID = res['SameClinicApptList'][0]['DoctorID']; + appo.isLiveCareAppointment = true; + appo.originalClinicID = 0; + appo.originalProjectID = 0; + appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate']; + + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {cancelAppointment(docObject, appo, context)}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + AppToast.showErrorToast(message: err); + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { widget.service @@ -448,6 +507,21 @@ class _BookConfirmState extends State { text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } + getLiveCareAppointmentPatientShare(context, String appointmentNo, + int clinicID, int projectID, DoctorList docObject) { + widget.service + .getLiveCareAppointmentPatientShare( + appointmentNo, clinicID, projectID, context) + .then((res) { + print(res); + widget.patientShareResponse = new PatientShareResponse.fromJson(res); + navigateToBookSuccess(context, docObject, widget.patientShareResponse); + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + String getTime(DateTime dateTime) { final DateFormat formatter = DateFormat('HH:mm'); setState(() { @@ -502,7 +576,6 @@ class _BookConfirmState extends State { Future navigateToBookSuccess(context, DoctorList docObject, PatientShareResponse patientShareResponse) async { - Navigator.push( context, MaterialPageRoute( diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 7a19ea28..2f7bde88 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -39,12 +39,6 @@ class _BookSuccessState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUser authUser; - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -184,6 +178,9 @@ class _BookSuccessState extends State { case 30: return _getQRAppo(); break; + case 50: + return _getConfirmAppo(); + break; } } @@ -204,6 +201,9 @@ class _BookSuccessState extends State { case 30: return 'QR Code'; break; + case 50: + return 'Confirm LiveCare'; + break; } } @@ -286,8 +286,19 @@ class _BookSuccessState extends State { textColor: Colors.white, disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), - onPressed: () {}, - child: Text(TranslationBase.of(context).confirm.toUpperCase(), + onPressed: () { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.clinicID = widget.docObject.clinicID; + appo.projectID = widget.docObject.projectID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + confirmAppointment(appo); + }, + child: Text( + widget.patientShareResponse.isLiveCareAppointment + ? TranslationBase.of(context) + .confirmLiveCare + .toUpperCase() + : TranslationBase.of(context).confirm.toUpperCase(), style: TextStyle(fontSize: 18.0)), ), ), @@ -321,6 +332,23 @@ class _BookSuccessState extends State { return Container(); } + confirmAppointment(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service + .confirmAppointment( + appo.appointmentNo, appo.clinicID, appo.projectID, context) + .then((res) { + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + navigateToHome(context); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + Widget _getPayNowAppo() { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -543,7 +571,8 @@ class _BookSuccessState extends State { } }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { @@ -560,22 +589,12 @@ class _BookSuccessState extends State { appo.appointmentNo.toString()); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } -// -// Future navigateToQR( -// context, String appoQR, PatientShareResponse patientShareResponse) async { -// Navigator.push( -// context, -// MaterialPageRoute( -// builder: (context) => QRCode( -// patientShareResponse: patientShareResponse, -// appoQR: appoQR, -// ))).then((value) {}); -// } - - addAdvancedNumberRequest(String advanceNumber, String paymentReference, - String appointmentID) { + + addAdvancedNumberRequest( + String advanceNumber, String paymentReference, String appointmentID) { DoctorsListService service = new DoctorsListService(); service .addAdvancedNumberRequest( @@ -585,7 +604,8 @@ class _BookSuccessState extends State { getAppoQR(context); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Widget _getQRAppo() { @@ -742,7 +762,8 @@ class _BookSuccessState extends State { navigateToQR(context, res['AppointmentQR']); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Future navigateToQR(context, String appoQR) async { diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index d3b6fc7c..2c7e723a 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -10,7 +11,7 @@ import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:rating_bar/rating_bar.dart'; -import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; + import 'BookConfirm.dart'; import 'components/DocAvailableAppointments.dart'; import 'components/DocInfo.dart'; @@ -19,9 +20,12 @@ class DoctorProfile extends StatefulWidget { DoctorList doctor; DoctorProfileList docProfileList; final bool isOpenAppt; + bool isLiveCareAppointment; + DoctorProfile( {@required this.doctor, @required this.docProfileList, + @required this.isLiveCareAppointment, this.isOpenAppt = false}); AuthenticatedUser authUser; @@ -35,6 +39,7 @@ class _DoctorProfileState extends State TabController _tabController; bool showFooterButton = false; var event = RobotProvider(); + @override void initState() { _tabController = new TabController( @@ -54,6 +59,7 @@ class _DoctorProfileState extends State }); _tabController = new TabController(length: 2, vsync: this); widget.authUser = new AuthenticatedUser(); + widget.doctor.speciality = widget.docProfileList.specialty; getPatientData(); super.initState(); } @@ -190,7 +196,9 @@ class _DoctorProfileState extends State physics: NeverScrollableScrollPhysics(), children: [ DoctorInformation(docProfileList: widget.docProfileList), - DocAvailableAppointments(doctor: widget.doctor) + DocAvailableAppointments( + doctor: widget.doctor, + isLiveCareAppointment: widget.isLiveCareAppointment) ], controller: _tabController, ), @@ -245,6 +253,7 @@ class _DoctorProfileState extends State MaterialPageRoute( builder: (context) => BookConfirm( doctor: widget.doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, selectedDate: DocAvailableAppointments.selectedDate, selectedTime: DocAvailableAppointments.selectedTime))); } diff --git a/lib/pages/BookAppointment/SearchResults.dart b/lib/pages/BookAppointment/SearchResults.dart index 2b5fac17..1ed1b6a0 100644 --- a/lib/pages/BookAppointment/SearchResults.dart +++ b/lib/pages/BookAppointment/SearchResults.dart @@ -9,9 +9,10 @@ import 'package:flutter/material.dart'; class SearchResults extends StatefulWidget { List doctorsList = []; List patientDoctorAppointmentListHospital; + bool isLiveCareAppointment; SearchResults( - {@required this.doctorsList, this.patientDoctorAppointmentListHospital}); + {@required this.doctorsList, this.patientDoctorAppointmentListHospital, @required this.isLiveCareAppointment}); @override _SearchResultsState createState() => _SearchResultsState(); @@ -53,6 +54,7 @@ class _SearchResultsState extends State { .map((doctor) { return DoctorView( doctor: doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, ); }).toList(), )), diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index 3c5e49ff..aca0884f 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -2,12 +2,13 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:table_calendar/table_calendar.dart'; import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:table_calendar/table_calendar.dart'; import '../../../uitl/date_uitl.dart'; @@ -17,8 +18,10 @@ class DocAvailableAppointments extends StatefulWidget { static DateTime selectedAppoDateTime; static String selectedDate; static String selectedTime; + bool isLiveCareAppointment; - DocAvailableAppointments({@required this.doctor}); + DocAvailableAppointments( + {@required this.doctor, @required this.isLiveCareAppointment}); @override _DocAvailableAppointmentsState createState() => @@ -31,6 +34,8 @@ class _DocAvailableAppointmentsState extends State AnimationController _animationController; CalendarController _calendarController; + AppSharedPreferences sharedPref = new AppSharedPreferences(); + var selectedDate = ""; dynamic selectedDateJSON; dynamic jsonFreeSlots; @@ -56,8 +61,13 @@ class _DocAvailableAppointmentsState extends State _selectedDay: ['Event A0'] }; - WidgetsBinding.instance - .addPostFrameCallback((_) => getDoctorFreeSlots(context, widget.doctor)); + WidgetsBinding.instance.addPostFrameCallback((_) async { + if (widget.isLiveCareAppointment) + getDoctorScheduledFreeSlots(context, widget.doctor); + else { + getDoctorFreeSlots(context, widget.doctor); + } + }); _calendarController = CalendarController(); _animationController = AnimationController( @@ -323,8 +333,8 @@ class _DocAvailableAppointmentsState extends State getDoctorFreeSlots(context, DoctorList docObject) { DoctorsListService service = new DoctorsListService(); service - .getDoctorFreeSlots( - docObject.doctorID, docObject.clinicID, docObject.projectID, context) + .getDoctorFreeSlots(docObject.doctorID, docObject.clinicID, + docObject.projectID, context) .then((res) { if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { @@ -340,7 +350,32 @@ class _DocAvailableAppointmentsState extends State } }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + + getDoctorScheduledFreeSlots(context, DoctorList docObject) { + DoctorsListService service = new DoctorsListService(); + service + .getDoctorScheduledFreeSlots(docObject.doctorID, docObject.clinicID, + docObject.projectID, docObject.serviceID, context) + .then((res) { + if (res['MessageStatus'] == 1) { + if (res['PatientER_DoctorFreeSlots'].length != 0) { + freeSlotsResponse = res['PatientER_DoctorFreeSlots']; + print("res['PatientER_DoctorFreeSlots']"); + print(res['PatientER_DoctorFreeSlots'].length); + _getJSONSlots().then((value) => { + setState(() => {_events.clear(), _events = value}) + }); + } else {} + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Widget _buildEventsMarker(DateTime date, List events) { diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index 1e7deb38..80288085 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -162,6 +162,7 @@ class _SearchByDoctorState extends State { context, MaterialPageRoute( builder: (context) => SearchResults( + isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))); diff --git a/lib/pages/BookAppointment/widgets/BranchView.dart b/lib/pages/BookAppointment/widgets/BranchView.dart index 88912a3f..76741874 100644 --- a/lib/pages/BookAppointment/widgets/BranchView.dart +++ b/lib/pages/BookAppointment/widgets/BranchView.dart @@ -128,8 +128,8 @@ class _ExpandableListViewState extends State { widget.doctorsList2[index].projectName.toString() ? DoctorView( //AJ note - doctor: widget.doctorsList2[index] - + doctor: widget.doctorsList2[index], + isLiveCareAppointment: false, // widget.doctorsList2[index] ) : Container(); diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index d3150459..441b7e10 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -11,9 +11,10 @@ import '../DoctorProfile.dart'; class DoctorView extends StatelessWidget { final DoctorList doctor; + bool isLiveCareAppointment; - DoctorView({@required this.doctor}); + DoctorView({@required this.doctor, @required this.isLiveCareAppointment}); @override Widget build(BuildContext context) { @@ -185,6 +186,7 @@ class DoctorView extends StatelessWidget { MaterialPageRoute( builder: (context) => DoctorProfile( doctor: docObject, + isLiveCareAppointment: isLiveCareAppointment, docProfileList: docProfile, isOpenAppt: isAppo, ))); diff --git a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart index 66ad31ee..dec4cb7d 100644 --- a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart +++ b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart @@ -113,7 +113,7 @@ class _HospitalsLiveChatPageState extends State { IconButton( icon: Icon( Icons - .arrow_forward_rounded, + .arrow_forward_ios, color: tappedIndex == index ? Colors.white diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 19e82086..b0330282 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -356,14 +356,15 @@ class _AppointmentActionsState extends State { print(res); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - Navigator.of(context).pop(); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)).then((value) { + Navigator.of(context).pop(); + }); } openAppointmentRadiology() { diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index dc96864a..f83a62d5 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -284,7 +284,7 @@ class _ToDoState extends State { break; case 50: - return "assets/images/new-design/liveCare_logo_icon.png"; + return "assets/images/new-design/confirm_button.png"; break; default: @@ -297,14 +297,15 @@ class _ToDoState extends State { case 10: confirmAppointment(appo); break; - case 20: getPatientShare(context, appo); break; - case 30: getAppoQR(context, appo); break; + case 50: + confirmAppointment(appo); + break; } } @@ -334,7 +335,7 @@ class _ToDoState extends State { break; case 50: - return TranslationBase.of(context).livecare; + return TranslationBase.of(context).confirmLiveCare; break; default: @@ -444,7 +445,8 @@ class _ToDoState extends State { }).catchError((err) { print(err); AppToast.showErrorToast(message: err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } getPatientShare(context, AppoitmentAllHistoryResultList appo) { @@ -457,7 +459,8 @@ class _ToDoState extends State { openPaymentDialog(appo, widget.patientShareResponse); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } getAppoQR(context, AppoitmentAllHistoryResultList appo) { @@ -478,7 +481,8 @@ class _ToDoState extends State { navigateToQR(context, res['AppointmentQR'], patientShareResponse); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Future navigateToQR( @@ -592,7 +596,8 @@ class _ToDoState extends State { } }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { @@ -610,7 +615,8 @@ class _ToDoState extends State { appo); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } addAdvancedNumberRequest(String advanceNumber, String paymentReference, @@ -624,7 +630,8 @@ class _ToDoState extends State { getAppoQR(context, appo); }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Future navigateToPaymentMethod( @@ -670,6 +677,7 @@ class _ToDoState extends State { } }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } } diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index f3129823..fc5c4eab 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -8,6 +8,8 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'livecare_type_select.dart'; + class LiveCareHome extends StatefulWidget { static bool showFooterButton = true; diff --git a/lib/pages/livecare/livecare_scheduling/livecare_scheduling_clinic_list.dart b/lib/pages/livecare/livecare_scheduling/livecare_scheduling_clinic_list.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart new file mode 100644 index 00000000..4309cc62 --- /dev/null +++ b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart @@ -0,0 +1,51 @@ +import 'package:diplomaticquarterapp/models/LiveCare/LiveCareScheduleClinicsListResponse.dart'; +import 'package:flutter/material.dart'; + +class ScheduleClinicCard extends StatefulWidget { + bool isSelected; + final ClinicsHaveScheduleList clinicsHaveScheduleList; + var languageID; + + ScheduleClinicCard( + {this.isSelected, + this.languageID, + @required this.clinicsHaveScheduleList}); + + @override + _ScheduleClinicCardState createState() => _ScheduleClinicCardState(); +} + +class _ScheduleClinicCardState extends State { + @override + Widget build(BuildContext context) { + return Container( + child: Card( + margin: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 8.0), + color: widget.isSelected ? Colors.blue : Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + width: MediaQuery.of(context).size.width * 0.8, + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Text( + widget.languageID == 'ar' + ? widget.clinicsHaveScheduleList.clinicDescN + : widget.clinicsHaveScheduleList.clinicDesc, + style: TextStyle( + fontSize: 16.0, + color: + widget.isSelected ? Colors.white : Colors.black)), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart new file mode 100644 index 00000000..d8978d8e --- /dev/null +++ b/lib/pages/livecare/livecare_type_select.dart @@ -0,0 +1,224 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class LiveCareTypeSelect extends StatefulWidget { + @override + _LiveCareTypeSelectState createState() => _LiveCareTypeSelectState(); +} + +class _LiveCareTypeSelectState extends State { + var languageID; + AppSharedPreferences sharedPref = AppSharedPreferences(); + + @override + void initState() { + getLanguageID(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + leading: InkWell( + onTap: () { + Navigator.pop(context, null); + }, + child: Icon( + Icons.close, + color: Colors.white, + ), + ), + title: Text(TranslationBase.of(context).bookAppo, + style: TextStyle(color: Colors.white)), + ), + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 20.0, right: 20.0), + child: Column( + children: [ + Container( + alignment: Alignment.center, + margin: EdgeInsets.only(top: 15.0, bottom: 10.0), + child: Image.asset( + languageID == 'ar' + ? "assets/images/new-design/liveCare_ar_bg.png" + : "assets/images/new-design/liveCare_en_bg.png", + width: 120), + ), + Container( + alignment: Alignment.center, + child: Text("LiveCare Service", + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 20.0))), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.center, + child: Text( + "is to obtain medical advice with a specialist doctor Via a video call", + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18.0))), + Container( + margin: EdgeInsets.only(top: 15.0), + alignment: Alignment.centerLeft, + child: Text("WHY LIVECARE?", + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 20.0))), + Container( + margin: EdgeInsets.only(top: 20.0, left: 20.0), + child: Row( + children: [ + SvgPicture.asset("assets/images/new-design/check_icon.svg", + width: 25), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.all(10.0), + child: Text( + "No need to wait, you will get Medical consultation immediately via Video call.", + overflow: TextOverflow.clip, + style: TextStyle(fontSize: 14.0)), + ) + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 5.0, left: 20.0), + child: Row( + children: [ + SvgPicture.asset("assets/images/new-design/check_icon.svg", + width: 25), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.all(10.0), + child: Text("The doctor will see your medical file.", + overflow: TextOverflow.clip, + style: TextStyle(fontSize: 14.0)), + ) + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 5.0, left: 20.0), + child: Row( + children: [ + SvgPicture.asset("assets/images/new-design/check_icon.svg", + width: 25), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.all(10.0), + child: Text("Free Prescription delivery service.", + overflow: TextOverflow.clip, + style: TextStyle(fontSize: 14.0)), + ) + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 20.0), + child: Text( + "** The service is included with some insurance companies according to the terms and conditions With our best wishes for health and wellness", + style: TextStyle(fontSize: 16.0))), + InkWell( + onTap: (){ + Navigator.pop(context, "immediate"); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.red[900], + borderRadius: BorderRadius.all(Radius.circular(10.0))), + height: 120.0, + margin: EdgeInsets.only(top: 20.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 20.0), + child: SvgPicture.asset( + "assets/images/new-design/liveCare_logo_icon_white.svg", + width: 80), + ), + Container( + width: MediaQuery.of(context).size.width * 0.6, + margin: EdgeInsets.fromLTRB(30.0, 20.0, 0.0, 0.0), + child: Column( + children: [ + Text("Get Medical consultation immediately", + overflow: TextOverflow.clip, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + color: Colors.white)), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.centerLeft, + child: Text("Instant video call", + style: TextStyle( + fontSize: 18.0, color: Colors.white)), + ) + ], + ), + ), + ], + )), + ), + InkWell( + onTap: (){ + Navigator.pop(context, "schedule"); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.grey[700], + borderRadius: BorderRadius.all(Radius.circular(10.0))), + height: 120.0, + margin: EdgeInsets.only(top: 20.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 20.0), + child: Image.asset( + "assets/images/new-design/calendar.png", + width: 70), + ), + Container( + width: MediaQuery.of(context).size.width * 0.6, + margin: EdgeInsets.fromLTRB(30.0, 30.0, 0.0, 0.0), + child: Column( + children: [ + Container( + alignment: Alignment.centerLeft, + child: Text("Book Appointment", + overflow: TextOverflow.clip, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + color: Colors.white)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.centerLeft, + child: Text("Schedule Video Call", + style: TextStyle( + fontSize: 18.0, color: Colors.white)), + ) + ], + ), + ), + ], + )), + ), + ], + ), + ), + ), + ); + } + + getLanguageID() async { + var languageID = await sharedPref.getString(APP_LANGUAGE); + setState(() { + this.languageID = languageID; + }); + } +} diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 9100a64e..c1f5eb75 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -1,9 +1,14 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/LiveCareScheduleClinicsListResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_scheduling/schedule_clinic_card.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_type_select.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCareInfoDialog.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePaymentDialog.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_card.dart'; @@ -30,8 +35,11 @@ class _clinic_listState extends State { int currentSelectedIndex = 0; LiveCareClinicsListResponse liveCareClinicsListResponse; + LiveCareScheduleClinicsListResponse liveCareScheduleClinicsListResponse; + bool isDataLoaded = false; var languageID; + var currentSelectedLiveCareType; int selectedClinicID = 1; String selectedClinicName = "-"; @@ -46,11 +54,13 @@ class _clinic_listState extends State { @override void initState() { liveCareClinicsListResponse = new LiveCareClinicsListResponse(); + liveCareScheduleClinicsListResponse = + new LiveCareScheduleClinicsListResponse(); + WidgetsBinding.instance.addPostFrameCallback((_) { -// Future.delayed(new Duration(milliseconds: 1200), () { - getLiveCareClinicsList(); -// }); + openLiveCareSelectionDialog(); }); + getLanguageID(); super.initState(); } @@ -58,77 +68,9 @@ class _clinic_listState extends State { @override Widget build(BuildContext context) { return SingleChildScrollView( - child: Column( - children: [ - isDataLoaded - ? Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.all(15.0), - child: Text("Online Clinics: ", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: liveCareClinicsListResponse - .patientERGetClinicsList.length, - itemBuilder: (context, index) { - return InkWell( - onTap: () { - updateSelectedIndex(liveCareClinicsListResponse - .patientERGetClinicsList[index]); - }, - child: ClinicCard( - isSelected: selectedClinicID == - liveCareClinicsListResponse - .patientERGetClinicsList[index] - .serviceID - ? true - : false, - patientERGetClinicsList: - liveCareClinicsListResponse - .patientERGetClinicsList[index], - languageID: languageID, - ), - ); - }, - ), - Container( - height: 10.0, - ), - ], - ), - ) - : Container(), - isDataLoaded ? Container( - width: MediaQuery.of(context).size.width, - height: 50.0, - margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), - child: ButtonTheme( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - minWidth: MediaQuery.of(context).size.width * 0.7, - height: 45.0, - child: RaisedButton( - color: new Color(0xFF60686b), - textColor: Colors.white, - disabledTextColor: Colors.white, - disabledColor: new Color(0xFFbcc2c4), - onPressed: startLiveCare, - child: Text("Start", style: TextStyle(fontSize: 18.0)), - ), - ), - ) : Container(), - ], - ), - ); + child: currentSelectedLiveCareType == "immediate" + ? getLiveCareImmediateClinicList() + : getLiveCareScheduleClinicList()); } void startLiveCare() { @@ -388,10 +330,298 @@ class _clinic_listState extends State { text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } + getLiveCareScheduleClinicsList() { + isDataLoaded = false; + LiveCareService service = new LiveCareService(); + service.getLiveCareScheduledClinics(context).then((res) { + print(res['ClinicsHaveScheduleList'].length); + if (res['MessageStatus'] == 1) { + setState(() { + liveCareScheduleClinicsListResponse = + LiveCareScheduleClinicsListResponse.fromJson(res); + print(liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList.length); + selectedClinicID = liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList[0].serviceID; + selectedClinicName = liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList[0].clinicDesc; + isDataLoaded = true; + }); + } else { + isDataLoaded = true; + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + + openLiveCareSelectionDialog() { + Navigator.of(context) + .push(new MaterialPageRoute( + builder: (BuildContext context) { + return LiveCareTypeSelect(); + }, + fullscreenDialog: true)) + .then((value) { + if (value == null) { + Navigator.pop(context); + } else { + print(value); + if (value == "immediate") { + setState(() { + currentSelectedLiveCareType = "immediate"; + }); + getLiveCareClinicsList(); + } + if (value == "schedule") { + setState(() { + currentSelectedLiveCareType = "schedule"; + }); + getLiveCareScheduleClinicsList(); + } + } + }); + } + + Widget getLiveCareScheduleClinicList() { + return Column( + children: [ + isDataLoaded + ? Container( + height: MediaQuery.of(context).size.height * 0.7, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ +// Container( +// margin: EdgeInsets.all(15.0), +// child: Text("Online Clinics: ", +// style: TextStyle( +// fontSize: 20.0, fontWeight: FontWeight.bold)), +// ), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + updateSelectedScheduleIndex( + liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList[index]); + }, + child: ScheduleClinicCard( + isSelected: selectedClinicID == + liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList[index] + .serviceID + ? true + : false, + clinicsHaveScheduleList: + liveCareScheduleClinicsListResponse + .clinicsHaveScheduleList[index], + languageID: languageID, + ), + ); + }, + ), + Container( + height: 10.0, + ), + ], + ), + ) + : Container(), + isDataLoaded + ? Align( + alignment: FractionalOffset.bottomCenter, + child: Container( + width: MediaQuery.of(context).size.width, + height: 50.0, + margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: new Color(0xFFbcc2c4), + onPressed: startScheduleLiveCare, + child: Text("Start", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ) + : Container(), + ], + ); + } + + Widget getLiveCareImmediateClinicList() { + return Column( + children: [ + isDataLoaded + ? Container( + height: MediaQuery.of(context).size.height * 0.7, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.all(15.0), + child: Text("Online Clinics: ", + style: TextStyle( + fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: liveCareClinicsListResponse + .patientERGetClinicsList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () { + updateSelectedIndex(liveCareClinicsListResponse + .patientERGetClinicsList[index]); + }, + child: ClinicCard( + isSelected: selectedClinicID == + liveCareClinicsListResponse + .patientERGetClinicsList[index] + .serviceID + ? true + : false, + patientERGetClinicsList: liveCareClinicsListResponse + .patientERGetClinicsList[index], + languageID: languageID, + ), + ); + }, + ), + Container( + height: 10.0, + ), + ], + ), + ) + : Container(), + isDataLoaded + ? Align( + alignment: FractionalOffset.bottomCenter, + child: Container( + width: MediaQuery.of(context).size.width, + height: 50.0, + margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: new Color(0xFFbcc2c4), + onPressed: startLiveCare, + child: Text("Start", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ) + : Container(), + ], + ); + } + + void startScheduleLiveCare() { + List doctorsList = []; + LiveCareService service = new LiveCareService(); + List _patientDoctorAppointmentListHospital = + List(); + service + .getLiveCareScheduledDoctorList(context, selectedClinicID) + .then((res) { + print(res['DoctorByClinicIDList']); + print(res['DoctorByClinicIDList'].length); + if (res['MessageStatus'] == 1) { + setState(() { + if (res['DoctorByClinicIDList'].length != 0) { + res['DoctorByClinicIDList'].forEach((v) { + doctorsList.add(new DoctorList.fromJson(v)); + }); + + doctorsList.forEach((element) { + List doctorByHospital = + _patientDoctorAppointmentListHospital + .where( + (elementClinic) => + elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[ + _patientDoctorAppointmentListHospital + .indexOf(doctorByHospital[0])] + .patientDoctorAppointmentList + .add(element); + } else { + _patientDoctorAppointmentListHospital.add( + PatientDoctorAppointmentList( + filterName: element.projectName, + distanceInKMs: + element.projectDistanceInKiloMeters.toString(), + patientDoctorAppointment: element)); + } + }); + } else {} + }); + this.sharedPref.setBool(IS_LIVECARE_APPOINTMENT, true); + navigateToSearchResults( + context, doctorsList, _patientDoctorAppointmentListHospital); + } else {} + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + + Future navigateToSearchResults( + context, + List docList, + List + patientDoctorAppointmentListHospital) async { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SearchResults( + doctorsList: docList, + isLiveCareAppointment: true, + patientDoctorAppointmentListHospital: + patientDoctorAppointmentListHospital))); + } + updateSelectedIndex(PatientERGetClinicsList patientERGetClinicsList) { setState(() { selectedClinicID = patientERGetClinicsList.serviceID; selectedClinicName = patientERGetClinicsList.serviceName; }); } + + updateSelectedScheduleIndex(ClinicsHaveScheduleList patientERGetClinicsList) { + setState(() { + selectedClinicID = patientERGetClinicsList.serviceID; + selectedClinicName = patientERGetClinicsList.clinicDesc; + }); + } } diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index c992e8e9..8d5b62f6 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -205,6 +205,42 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future getDoctorScheduledFreeSlots( + int docID, int clinicID, int projectID, int serviceID, BuildContext context) async { + Map request; + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "DoctorID": docID, + "IsBookingForLiveCare": 1, + "ClinicID": clinicID, + "ProjectID": projectID, + "OriginalClinicID": clinicID, + "ServiceID": serviceID, + "days": 50, + "isReschadual": false, + "VersionID": req.VersionID, + "Channel": 3, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "generalid": "Cs2020@2016\$2958", + "PatientOutSA": 0, + "SessionID": null, + "isDentalAllowedBackend": false, + "DeviceTypeID": 1 + }; + + dynamic localRes; + + await baseAppClient.post(GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, BuildContext context) async { Map request; @@ -258,6 +294,60 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future insertLiveCareScheduleAppointment(int docID, int clinicID, int projectID, int serviceID, + String selectedTime, String selectedDate, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "IsForLiveCare": true, + "ProjectID": projectID, + "ClinicID": clinicID, + "DoctorID": docID, + "ServiceID": serviceID, + "StartTime": selectedTime, + "SelectedTime": selectedTime, + "EndTime": selectedTime, + "InitialSlotDuration": 0, + "StrAppointmentDate": selectedDate, + "IsVirtual": false, + "DeviceType": Platform.isIOS ? 'iOS' : 'Android', + "BookedBy": 102, + "VisitType": 1, + "VisitFor": 1, + "VersionID": req.VersionID, + "Channel": req.Channel, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "TokenID": "@dm!n", + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + + dynamic localRes; + + await baseAppClient.post(INSERT_LIVECARE_SCHEDULE_APPOINTMENT, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getPatientShare( String appoID, int clinicID, int projectID, BuildContext context) async { Map request; @@ -302,6 +392,51 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future getLiveCareAppointmentPatientShare( + String appoID, int clinicID, int projectID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + + request = { + "ProjectID": projectID, + "ClinicID": clinicID, + "AppointmentNo": appoID, + "IsActiveAppointment": true, + "IsForLiveCare": true, + "VersionID": req.VersionID, + "Channel": req.Channel, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "TokenID": "@dm!n", + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + + dynamic localRes; + + await baseAppClient.post(GET_PATIENT_SHARE_LIVECARE, + onSuccess: (response, statusCode) async { + localRes = response['OnlineCheckInAppointments'][0]; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getPatientAppointmentHistory( bool isActiveAppointment, BuildContext context) async { Map request; diff --git a/lib/services/livecare_services/livecare_provider.dart b/lib/services/livecare_services/livecare_provider.dart index f76e0336..65cf6daf 100644 --- a/lib/services/livecare_services/livecare_provider.dart +++ b/lib/services/livecare_services/livecare_provider.dart @@ -53,6 +53,81 @@ class LiveCareService extends BaseService { return Future.value(localRes); } + Future getLiveCareScheduledClinics(BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": 0, + "TokenID": "", + "DeviceTypeID": req.DeviceTypeID, + "SessionID": "YckwoXhUmWBsnHKEKig", + "Age": authUser.age != null ? authUser.age : 0, + "PatientID": authUser.patientID != null ? authUser.patientID : 0, + "Gender": authUser.gender != null ? authUser.gender : 0 + }; + + dynamic localRes; + + await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINICS, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getLiveCareScheduledDoctorList(BuildContext context, int serviceID) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": 0, + "TokenID": "", + "DeviceTypeID": req.DeviceTypeID, + "ServiceID": serviceID, + "SessionID": "YckwoXhUmWBsnHKEKig", + "Age": authUser.age != null ? authUser.age : 0, + "PatientID": authUser.patientID != null ? authUser.patientID : 0, + "Gender": authUser.gender != null ? authUser.gender : 0 + }; + + dynamic localRes; + + await baseAppClient.post(GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getLivecareHistory(BuildContext context) async { Map request; diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index ba89fc2c..272d983f 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -95,6 +95,8 @@ class TranslationBase { String get confirm => localizedValues['confirm'][locale.languageCode]; + String get confirmLiveCare => localizedValues['confirmLiveCare'][locale.languageCode]; + String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; From 7fdc0da9dc08997edd45e1fb12f6c8524f5f0dc2 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 30 Sep 2020 15:33:14 +0300 Subject: [PATCH 3/7] livecare scheduling implemented --- lib/config/config.dart | 22 +- lib/config/localized_values.dart | 2 + .../AppoimentAllHistoryResultList.dart | 141 +++--- .../InsertAppointmentRequest.dart | 1 - .../Appointments/PatientShareResposne.dart | 102 ++-- lib/models/LiveCare/insertVIDARequest.dart | 92 ++++ lib/models/Request.dart | 1 + lib/pages/BookAppointment/BookConfirm.dart | 5 + lib/pages/BookAppointment/BookSuccess.dart | 40 +- .../widgets/AppointmentActions.dart | 36 +- .../widgets/AppointmentCardView.dart | 2 +- lib/pages/ToDoList/ToDo.dart | 464 ++++++++++-------- lib/pages/ToDoList/widgets/upcomingCard.dart | 30 +- lib/pages/landing/home_page.dart | 122 ++++- lib/pages/livecare/livecare_type_select.dart | 13 +- .../appointment_services/GetDoctorsList.dart | 72 ++- lib/uitl/translations_delegate_base.dart | 5 + 17 files changed, 775 insertions(+), 375 deletions(-) create mode 100644 lib/models/LiveCare/insertVIDARequest.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 90c37129..5cad4efd 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -5,7 +5,7 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; const MAX_SMALL_SCREEN = 660; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; @@ -121,6 +121,9 @@ const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = const CONFIRM_APPOINTMENT = "Services/MobileNotifications.svc/REST/ConfirmAppointment"; +const INSERT_VIDA_REQUEST = + "Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart"; + //URL to cancel appointment const CANCEL_APPOINTMENT = "Services/Doctors.svc/REST/CancelAppointment"; @@ -150,6 +153,22 @@ const SEND_CALL_REQUEST = 'Services/Doctors.svc/REST/InsertCallInfo'; const GET_LIVECARE_CLINICS = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinics'; + +const GET_LIVECARE_SCHEDULE_CLINICS = + 'Services/Doctors.svc/REST/PatientER_GetClinicsHaveSchedule'; + +const GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST = + 'Services/Doctors.svc/REST/PatientER_GetDoctorByClinicID'; + +const GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS = + 'Services/Doctors.svc/REST/PatientER_GetDoctorFreeSlots'; + +const INSERT_LIVECARE_SCHEDULE_APPOINTMENT = + 'Services/Doctors.svc/REST/InsertSpecificAppoitmentForSchedule'; + +const GET_PATIENT_SHARE_LIVECARE = + "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; + const GET_LIVECARE_CLINIC_TIMING = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; @@ -232,6 +251,7 @@ class AppGlobal { request.TokenID = "@dm!n"; request.isDentalAllowedBackend = false; request.DeviceTypeID = Platform.isIOS ? 1 : 2; + request.DeviceType = Platform.isIOS ? "iOS" : "Android"; return request; } diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 6053dd4a..1472ffe2 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -48,6 +48,7 @@ const Map> localizedValues = { 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, 'confirmLiveCare': {'en': 'Confirm LiveCare', 'ar': 'تأكيد لايف كير'}, + 'waitingForDoctor': {'en': 'Waiting for doctor', 'ar': 'في انتظار الطبيب'}, 'appointment': {'en': 'Appointment', 'ar': 'الموعد'}, 'confirmLater': {'en': 'Confirm Later', 'ar': 'تأكيد لاحقا'}, 'todoList': {'en': 'Todo List', 'ar': 'مهامي'}, @@ -59,6 +60,7 @@ const Map> localizedValues = { 'viewQR': {'en': 'View QR Code', 'ar': 'عرض رمز الاستجابة السريعة'}, 'instruction': {'en': 'Instructions', 'ar': 'تعليمات'}, 'livecare': {'en': 'LiveCare', 'ar': 'لايف كير'}, + 'livecareAppo': {'en': 'LiveCare Appointment', 'ar': 'الموعد لايف كير'}, 'cancelAppoMsg': { 'en': 'Are you sure you want to cancel this appointment?', 'ar': 'هل أنت متأكد أنك تريد إلغاء هذا الموعد؟' diff --git a/lib/models/Appointments/AppoimentAllHistoryResultList.dart b/lib/models/Appointments/AppoimentAllHistoryResultList.dart index 9ba1fb8e..20eace25 100644 --- a/lib/models/Appointments/AppoimentAllHistoryResultList.dart +++ b/lib/models/Appointments/AppoimentAllHistoryResultList.dart @@ -64,73 +64,75 @@ class AppoitmentAllHistoryResultList { String qR; int remaniningHoursTocanPay; bool sMSButtonVisable; + int serviceID; AppoitmentAllHistoryResultList( {this.setupID, - this.projectID, - this.appointmentNo, - this.appointmentDate, - this.appointmentDateN, - this.appointmentType, - this.bookDate, - this.patientType, - this.patientID, - this.clinicID, - this.doctorID, - this.endDate, - this.startTime, - this.endTime, - this.status, - this.visitType, - this.visitFor, - this.patientStatusType, - this.companyID, - this.bookedBy, - this.bookedOn, - this.confirmedBy, - this.confirmedOn, - this.arrivalChangedBy, - this.arrivedOn, - this.editedBy, - this.editedOn, - this.doctorName, - this.doctorNameN, - this.statusDesc, - this.statusDescN, - this.vitalStatus, - this.vitalSignAppointmentNo, - this.episodeID, - this.actualDoctorRate, - this.clinicName, - this.complainExists, - this.doctorImageURL, - this.doctorNameObj, - this.doctorRate, - this.doctorSpeciality, - this.doctorTitle, - this.gender, - this.genderDescription, - this.iSAllowOnlineCheckedIN, - this.isActiveDoctor, - this.isActiveDoctorProfile, - this.isDoctorAllowVedioCall, - this.isExecludeDoctor, - this.isFollowup, - this.isLiveCareAppointment, - this.isMedicalReportRequested, - this.isOnlineCheckedIN, - this.latitude, - this.listHISGetContactLensPerscription, - this.listHISGetGlassPerscription, - this.longitude, - this.nextAction, - this.noOfPatientsRate, - this.originalClinicID, - this.originalProjectID, - this.projectName, - this.qR, - this.remaniningHoursTocanPay, - this.sMSButtonVisable}); + this.projectID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.appointmentType, + this.bookDate, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.endDate, + this.startTime, + this.endTime, + this.status, + this.visitType, + this.visitFor, + this.patientStatusType, + this.companyID, + this.bookedBy, + this.bookedOn, + this.confirmedBy, + this.confirmedOn, + this.arrivalChangedBy, + this.arrivedOn, + this.editedBy, + this.editedOn, + this.doctorName, + this.doctorNameN, + this.statusDesc, + this.statusDescN, + this.vitalStatus, + this.vitalSignAppointmentNo, + this.episodeID, + this.actualDoctorRate, + this.clinicName, + this.complainExists, + this.doctorImageURL, + this.doctorNameObj, + this.doctorRate, + this.doctorSpeciality, + this.doctorTitle, + this.gender, + this.genderDescription, + this.iSAllowOnlineCheckedIN, + this.isActiveDoctor, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.isFollowup, + this.isLiveCareAppointment, + this.isMedicalReportRequested, + this.isOnlineCheckedIN, + this.latitude, + this.listHISGetContactLensPerscription, + this.listHISGetGlassPerscription, + this.longitude, + this.nextAction, + this.noOfPatientsRate, + this.originalClinicID, + this.originalProjectID, + this.projectName, + this.qR, + this.remaniningHoursTocanPay, + this.sMSButtonVisable, + this.serviceID}); AppoitmentAllHistoryResultList.fromJson(Map json) { setupID = json['SetupID']; @@ -173,7 +175,9 @@ class AppoitmentAllHistoryResultList { doctorImageURL = json['DoctorImageURL']; doctorNameObj = json['DoctorNameObj']; doctorRate = json['DoctorRate']; - doctorSpeciality = json['DoctorSpeciality'] != null ?json['DoctorSpeciality'].cast() : ["null"]; + doctorSpeciality = json['DoctorSpeciality'] != null + ? json['DoctorSpeciality'].cast() + : ["null"]; doctorTitle = json['DoctorTitle']; gender = json['Gender']; genderDescription = json['GenderDescription']; @@ -188,7 +192,7 @@ class AppoitmentAllHistoryResultList { isOnlineCheckedIN = json['IsOnlineCheckedIN']; latitude = json['Latitude']; listHISGetContactLensPerscription = - json['List_HIS_GetContactLensPerscription']; + json['List_HIS_GetContactLensPerscription']; listHISGetGlassPerscription = json['List_HIS_GetGlassPerscription']; longitude = json['Longitude']; nextAction = json['NextAction']; @@ -199,6 +203,7 @@ class AppoitmentAllHistoryResultList { qR = json['QR']; remaniningHoursTocanPay = json['RemaniningHoursTocanPay']; sMSButtonVisable = json['SMSButtonVisable']; + serviceID = json['ServiceID']; } Map toJson() { @@ -269,6 +274,7 @@ class AppoitmentAllHistoryResultList { data['QR'] = this.qR; data['RemaniningHoursTocanPay'] = this.remaniningHoursTocanPay; data['SMSButtonVisable'] = this.sMSButtonVisable; + data['ServiceID'] = this.serviceID; return data; } } @@ -278,7 +284,8 @@ class PatientAppointmentList { List patientDoctorAppointmentList = List(); PatientAppointmentList( - {this.filterName, AppoitmentAllHistoryResultList patientDoctorAppointment}) { + {this.filterName, + AppoitmentAllHistoryResultList patientDoctorAppointment}) { patientDoctorAppointmentList.add(patientDoctorAppointment); } } diff --git a/lib/models/Appointments/InsertAppointmentRequest.dart b/lib/models/Appointments/InsertAppointmentRequest.dart index badbb6a7..383e2eb5 100644 --- a/lib/models/Appointments/InsertAppointmentRequest.dart +++ b/lib/models/Appointments/InsertAppointmentRequest.dart @@ -13,7 +13,6 @@ class InsertAppointmentRequest extends Request { bool IsVirtual; List GeneralProcedureList; String DeviceToken; - String DeviceType; bool IsForLiveCare; String OriginalClinicID; String OriginalProjectID; diff --git a/lib/models/Appointments/PatientShareResposne.dart b/lib/models/Appointments/PatientShareResposne.dart index e3a596d6..2e22ed60 100644 --- a/lib/models/Appointments/PatientShareResposne.dart +++ b/lib/models/Appointments/PatientShareResposne.dart @@ -12,6 +12,7 @@ class PatientShareResponse { int companyShareWithTax; String doctorImageURL; String doctorNameObj; + int doctorID; List doctorSpeciality; dynamic errCode; int groupID; @@ -47,56 +48,59 @@ class PatientShareResponse { dynamic statusDesc; dynamic subPolicyNo; int userID; + int serviceID; PatientShareResponse( {this.advanceNumber, - this.appointmentDate, - this.appointmentNo, - this.cashPrice, - this.cashPriceTax, - this.cashPriceWithTax, - this.clinicID, - this.clinicName, - this.companyId, - this.companyName, - this.companyShareWithTax, - this.doctorImageURL, - this.doctorNameObj, - this.doctorSpeciality, - this.errCode, - this.groupID, - this.iSAllowOnlineCheckedIN, - this.insurancePolicyNo, - this.isExcludedForOnlineCheckin, - this.isFollowup, - this.isLiveCareAppointment, - this.isOnlineCheckedIN, - this.message, - this.nextAction, - this.patientCardID, - this.patientID, - this.patientShare, - this.patientShareWithTax, - this.patientStatusType, - this.patientTaxAmount, - this.patientType, - this.paymentAmount, - this.paymentDate, - this.paymentMethodName, - this.paymentReferenceNumber, - this.policyId, - this.policyName, - this.procedureName, - this.projectID, - this.projectName, - this.setupID, - this.sourceType, - this.startTime, - this.status, - this.statusCode, - this.statusDesc, - this.subPolicyNo, - this.userID}); + this.appointmentDate, + this.appointmentNo, + this.cashPrice, + this.cashPriceTax, + this.cashPriceWithTax, + this.clinicID, + this.clinicName, + this.companyId, + this.companyName, + this.companyShareWithTax, + this.doctorID, + this.doctorImageURL, + this.doctorNameObj, + this.doctorSpeciality, + this.errCode, + this.groupID, + this.iSAllowOnlineCheckedIN, + this.insurancePolicyNo, + this.isExcludedForOnlineCheckin, + this.isFollowup, + this.isLiveCareAppointment, + this.isOnlineCheckedIN, + this.message, + this.nextAction, + this.patientCardID, + this.patientID, + this.patientShare, + this.patientShareWithTax, + this.patientStatusType, + this.patientTaxAmount, + this.patientType, + this.paymentAmount, + this.paymentDate, + this.paymentMethodName, + this.paymentReferenceNumber, + this.policyId, + this.policyName, + this.procedureName, + this.projectID, + this.projectName, + this.setupID, + this.sourceType, + this.startTime, + this.status, + this.statusCode, + this.statusDesc, + this.subPolicyNo, + this.userID, + this.serviceID}); PatientShareResponse.fromJson(Map json) { advanceNumber = json['AdvanceNumber']; @@ -110,6 +114,7 @@ class PatientShareResponse { companyId = json['CompanyId']; companyName = json['CompanyName']; companyShareWithTax = json['CompanyShareWithTax']; + doctorID = json['DoctorID']; doctorImageURL = json['DoctorImageURL']; doctorNameObj = json['DoctorNameObj']; doctorSpeciality = json['DoctorSpeciality'].cast(); @@ -147,6 +152,7 @@ class PatientShareResponse { statusDesc = json['StatusDesc']; subPolicyNo = json['SubPolicyNo']; userID = json['UserID']; + serviceID = json['ServiceID']; } Map toJson() { @@ -162,6 +168,7 @@ class PatientShareResponse { data['CompanyId'] = this.companyId; data['CompanyName'] = this.companyName; data['CompanyShareWithTax'] = this.companyShareWithTax; + data['DoctorID'] = this.doctorID; data['DoctorImageURL'] = this.doctorImageURL; data['DoctorNameObj'] = this.doctorNameObj; data['DoctorSpeciality'] = this.doctorSpeciality; @@ -199,6 +206,7 @@ class PatientShareResponse { data['StatusDesc'] = this.statusDesc; data['SubPolicyNo'] = this.subPolicyNo; data['UserID'] = this.userID; + data['ServiceID'] = this.serviceID; return data; } } diff --git a/lib/models/LiveCare/insertVIDARequest.dart b/lib/models/LiveCare/insertVIDARequest.dart new file mode 100644 index 00000000..938ca102 --- /dev/null +++ b/lib/models/LiveCare/insertVIDARequest.dart @@ -0,0 +1,92 @@ +class insertVIDARequest { + int patientID; + int acceptedBy; + int appointmentNo; + String deviceToken; + double latitude; + double longitude; + int serviceID; + int projectID; + int clinicID; + String deviceType; + String voipToken; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + insertVIDARequest( + {this.patientID, + this.acceptedBy, + this.appointmentNo, + this.deviceToken, + this.latitude, + this.longitude, + this.serviceID, + this.projectID, + this.clinicID, + this.deviceType, + this.voipToken, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + insertVIDARequest.fromJson(Map json) { + patientID = json['PatientID']; + acceptedBy = json['AcceptedBy']; + appointmentNo = json['AppointmentNo']; + deviceToken = json['DeviceToken']; + latitude = json['Latitude']; + longitude = json['Longitude']; + serviceID = json['ServiceID']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + deviceType = json['DeviceType']; + voipToken = json['VoipToken']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientID'] = this.patientID; + data['AcceptedBy'] = this.acceptedBy; + data['AppointmentNo'] = this.appointmentNo; + data['DeviceToken'] = this.deviceToken; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['ServiceID'] = this.serviceID; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['DeviceType'] = this.deviceType; + data['VoipToken'] = this.voipToken; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/models/Request.dart b/lib/models/Request.dart index 03aa7760..a4cef77b 100644 --- a/lib/models/Request.dart +++ b/lib/models/Request.dart @@ -5,6 +5,7 @@ class Request { var ProjectID; var LanguageID; var DeviceTypeID; + var DeviceType; var AppointmentNo; var IPAdress; var VersionID; diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 8647b2f0..b0110d2b 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -210,11 +210,13 @@ class _BookConfirmState extends State { "assets/images/new-design/icon_hospital.png"), ), Container( + width: MediaQuery.of(context).size.width * 0.7, margin: EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), child: Text( TranslationBase.of(context).clinic + ": " + widget.doctor.clinicName, + overflow: TextOverflow.clip, style: TextStyle( fontSize: 14.0, color: Colors.grey[700], @@ -340,6 +342,9 @@ class _BookConfirmState extends State { ), ), ), + SizedBox( + height: 120.0, + ), ], ), ), diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 2f7bde88..704618ac 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -287,10 +287,15 @@ class _BookSuccessState extends State { disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), onPressed: () { - AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + AppoitmentAllHistoryResultList appo = + new AppoitmentAllHistoryResultList(); appo.clinicID = widget.docObject.clinicID; appo.projectID = widget.docObject.projectID; - appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.appointmentNo = + widget.patientShareResponse.appointmentNo; + appo.serviceID = widget.patientShareResponse.serviceID; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; confirmAppointment(appo); }, child: Text( @@ -336,7 +341,33 @@ class _BookSuccessState extends State { DoctorsListService service = new DoctorsListService(); service .confirmAppointment( - appo.appointmentNo, appo.clinicID, appo.projectID, context) + appo.appointmentNo, appo.clinicID, appo.projectID, appo.isLiveCareAppointment, context) + .then((res) { + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + if (appo.isLiveCareAppointment) { + insertLiveCareVIDARequest(appo); + } else { + navigateToHome(context); + } + }); + } + + insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service + .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, + appo.serviceID, appo.doctorID, context) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); @@ -346,7 +377,8 @@ class _BookSuccessState extends State { } }).catchError((err) { print(err); - }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } Widget _getPayNowAppo() { diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index b0330282..18740ce7 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -352,19 +352,24 @@ class _AppointmentActionsState extends State { cancelAppointment() { ConfirmDialog.closeAlertDialog(context); DoctorsListService service = new DoctorsListService(); - service.cancelAppointment(widget.appo, context).then((res) { - print(res); - if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); - } - }).catchError((err) { - print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)).then((value) { - Navigator.of(context).pop(); - }); + service + .cancelAppointment(widget.appo, context) + .then((res) { + print(res); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + Navigator.of(context).pop(); + }); } openAppointmentRadiology() { @@ -469,8 +474,7 @@ class _AppointmentActionsState extends State { } }).catchError((err) { print(err); - AppToast.showErrorToast( - message: err); + AppToast.showErrorToast(message: err); }).showProgressBar( text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } @@ -541,7 +545,7 @@ class _AppointmentActionsState extends State { DoctorsListService service = new DoctorsListService(); service .confirmAppointment(widget.appo.appointmentNo, widget.appo.clinicID, - widget.appo.projectID, context) + widget.appo.projectID, widget.appo.isLiveCareAppointment, context) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); diff --git a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart index b64bd232..2e5c88b0 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart @@ -24,7 +24,7 @@ class _ApointmentCardState extends State { navigateToAppointmentDetails(context, widget.appo); }, child: Card( - margin: EdgeInsets.fromLTRB(20.0, 16.0, 20.0, 8.0), + margin: EdgeInsets.fromLTRB(10.0, 16.0, 10.0, 8.0), color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index f83a62d5..796794b2 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -16,6 +16,7 @@ import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:rating_bar/rating_bar.dart'; import 'package:smart_progress_bar/smart_progress_bar.dart'; @@ -37,8 +38,6 @@ class _ToDoState extends State { @override void initState() { -// authUser = authProvider.getAuthenticatedUser(); - print("initState!!!!!"); widget.patientShareResponse = new PatientShareResponse(); WidgetsBinding.instance .addPostFrameCallback((_) => getPatientAppointmentHistory()); @@ -50,205 +49,230 @@ class _ToDoState extends State { return AppScaffold( appBarTitle: TranslationBase.of(context).todoList, body: SingleChildScrollView( - child: Container( - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - padding: EdgeInsets.all(0.0), - itemCount: widget.appoList.length, - itemBuilder: (context, index) { - return Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Row( + child: Column( + children: [ + Container( + child: ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + padding: EdgeInsets.all(0.0), + itemCount: widget.appoList.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.all(10.0), + child: Card( + margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ - Image.asset( - "assets/images/new-design/time_icon.png", - width: 20.0, - height: 20.0), - Container( - margin: EdgeInsets.only(left: 10.0, right: 30.0), - child: Text( - getDate( - widget.appoList[index].appointmentDate), - style: TextStyle(fontSize: 12.0)), + Row( + children: [ + Image.asset( + "assets/images/new-design/time_icon.png", + width: 20.0, + height: 20.0), + Container( + margin: + EdgeInsets.only(left: 5.0, right: 25.0), + child: Text( + getDate(widget + .appoList[index].appointmentDate), + style: TextStyle(fontSize: 11.0)), + ), + widget.appoList[index].isLiveCareAppointment + ? SvgPicture.asset( + "assets/images/new-design/liveCare_logo_icon.svg", + width: 20.0, + height: 20.0) + : Image.asset( + "assets/images/new-design/hospital_address_icon.png", + width: 20.0, + height: 20.0), + Container( + margin: + EdgeInsets.only(left: 5.0, right: 5.0), + child: widget + .appoList[index].isLiveCareAppointment + ? Text( + TranslationBase.of(context) + .liveCareAppo, + style: TextStyle(fontSize: 12.0)) + : Text(widget.appoList[index].projectName != null ? widget.appoList[index].projectName : "-", + style: TextStyle(fontSize: 12.0)), + ), + ], ), - Image.asset( - "assets/images/new-design/hospital_address_icon.png", - width: 20.0, - height: 20.0), Container( - margin: EdgeInsets.only(left: 10.0, right: 10.0), - child: Text(widget.appoList[index].projectName, - style: TextStyle(fontSize: 12.0)), - ), - ], - ), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Divider( - color: Colors.grey[500], - ), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - height: - MediaQuery.of(context).size.height * 0.1, - margin: EdgeInsets.only(top: 5.0), - child: ClipRRect( - borderRadius: BorderRadius.circular(100.0), - child: Image.network( - widget.appoList[index].doctorImageURL, - fit: BoxFit.fill), - ), + margin: EdgeInsets.only(top: 5.0), + child: Divider( + color: Colors.grey[500], ), ), - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 20.0, left: 20.0, right: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.appoList[index].doctorTitle + - " " + - widget - .appoList[index].doctorNameObj, - style: TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: FontWeight.bold, - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only( - top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality(widget - .appoList[index] - .doctorSpeciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + height: MediaQuery.of(context).size.height * + 0.1, + margin: EdgeInsets.only(top: 5.0), + child: ClipRRect( + borderRadius: + BorderRadius.circular(100.0), + child: Image.network( + widget.appoList[index].doctorImageURL, + fit: BoxFit.fill), ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, + ), + ), + Expanded( + flex: 3, + child: Container( + margin: EdgeInsets.only( + top: 20.0, left: 20.0, right: 20.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - RatingBar.readOnly( - initialRating: widget - .appoList[index].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, + Text( + widget.appoList[index].doctorTitle + + " " + + widget.appoList[index] + .doctorNameObj, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold, + letterSpacing: 1.0)), + Container( + margin: EdgeInsets.only( + top: 3.0, bottom: 3.0), + child: Text( + getDoctorSpeciality(widget + .appoList[index] + .doctorSpeciality) + .trim(), + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + RatingBar.readOnly( + initialRating: widget + .appoList[index] + .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, + ), + ], ), ], ), - ], + ), ), - ), + Expanded( + flex: 1, + child: InkWell( + onTap: () => performNextAction( + widget.appoList[index]), + child: Container( + margin: EdgeInsets.only(top: 20.0), + child: Column( + children: [ + Image.asset( + getNextActionImage(widget + .appoList[index].nextAction), + width: 50.0, + height: 50.0), + Container( + margin: EdgeInsets.only(top: 5.0), + child: Text( + getNextActionText(widget + .appoList[index] + .nextAction), + textAlign: TextAlign.center, + style: + TextStyle(fontSize: 12.0)), + ) + ], + ), + ), + ), + ) + ], + ), + Divider( + color: Colors.grey[500], ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => - performNextAction(widget.appoList[index]), - child: Container( - margin: EdgeInsets.only(top: 20.0), - child: Column( - children: [ - Image.asset( - getNextActionImage(widget - .appoList[index].nextAction), - width: 50.0, - height: 50.0), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Text( - getNextActionText(widget - .appoList[index].nextAction), - textAlign: TextAlign.center, - style: TextStyle(fontSize: 12.0)), - ) - ], + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 2, + child: Container( + child: Text( + getNextActionDescription( + widget.appoList[index].nextAction), + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[700])), ), ), - ), - ) - ], - ), - Divider( - color: Colors.grey[500], - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 2, - child: Container( - child: Text( - getNextActionDescription( - widget.appoList[index].nextAction), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[700])), - ), + Expanded( + flex: 1, + child: GestureDetector( + onTap: () { + navigateToAppointmentDetails( + context, widget.appoList[index]); + }, + child: Container( + child: Text( + TranslationBase.of(context) + .upcomingDetails, + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 12.0, + color: Colors.red[600], + decoration: + TextDecoration.underline)), + ), + ), + ) + ], ), - Expanded( - flex: 1, - child: GestureDetector( - onTap: () { - navigateToAppointmentDetails( - context, widget.appoList[index]); - }, - child: Container( - child: Text( - TranslationBase.of(context) - .upcomingDetails, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 12.0, - color: Colors.red[600], - decoration: - TextDecoration.underline)), - ), - ), - ) ], ), - ], + ), ), - ), - ), - ); - }, - ), + ); + }, + ), + ), + SizedBox( + height: 120.0, + ), + ], ), ), ); @@ -287,6 +311,10 @@ class _ToDoState extends State { return "assets/images/new-design/confirm_button.png"; break; + case 60: + return "assets/images/new-design/waiting_for_doctor.png"; + break; + default: return ""; } @@ -306,6 +334,8 @@ class _ToDoState extends State { case 50: confirmAppointment(appo); break; + case 60: + break; } } @@ -338,6 +368,10 @@ class _ToDoState extends State { return TranslationBase.of(context).confirmLiveCare; break; + case 60: + return TranslationBase.of(context).waitingForDoctor; + break; + default: return ""; } @@ -372,6 +406,10 @@ class _ToDoState extends State { return TranslationBase.of(context).upcomingLivecare; break; + case 60: + return TranslationBase.of(context).waitingForDoctor; + break; + default: return ""; } @@ -428,7 +466,6 @@ class _ToDoState extends State { getPatientAppointmentHistory() { DoctorsListService service = new DoctorsListService(); service.getPatientAppointmentHistory(true, context).then((res) { - print(res['AppoimentAllHistoryResultList']); if (res['MessageStatus'] == 1) { setState(() { if (res['AppoimentAllHistoryResultList'].length != 0) { @@ -439,6 +476,10 @@ class _ToDoState extends State { }); } else {} }); + widget.appoList.forEach((element) { + print(element.isLiveCareAppointment); + print(element.nextAction); + }); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } @@ -666,18 +707,49 @@ class _ToDoState extends State { confirmAppointment(AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); service - .confirmAppointment( - appo.appointmentNo, appo.clinicID, appo.projectID, context) + .confirmAppointment(appo.appointmentNo, appo.clinicID, appo.projectID, + appo.isLiveCareAppointment, context) .then((res) { - if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - getPatientAppointmentHistory(); - } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); - } - }).catchError((err) { - print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + getPatientAppointmentHistory(); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + if (appo.isLiveCareAppointment) { + insertLiveCareVIDARequest(appo); + } else { + getPatientAppointmentHistory(); + } + }); + } + + insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + service + .insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, + appo.serviceID, appo.doctorID, context) + .then((res) { + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + getPatientAppointmentHistory(); + }); } } diff --git a/lib/pages/ToDoList/widgets/upcomingCard.dart b/lib/pages/ToDoList/widgets/upcomingCard.dart index 1b4a4cc3..c1d1b546 100644 --- a/lib/pages/ToDoList/widgets/upcomingCard.dart +++ b/lib/pages/ToDoList/widgets/upcomingCard.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:rating_bar/rating_bar.dart'; class TodoListCard extends StatefulWidget { @@ -12,7 +13,6 @@ class TodoListCard extends StatefulWidget { var languageID; final VoidCallback onListUpdated; - TodoListCard({@required this.appo, this.onListUpdated}); @override @@ -54,14 +54,22 @@ class _TodoListCardState extends State { child: Text(getDate(widget.appo.appointmentDate), style: TextStyle(fontSize: 12.0)), ), - Image.asset( - "assets/images/new-design/hospital_address_icon.png", - width: 20.0, - height: 20.0), + widget.appo.isLiveCareAppointment + ? SvgPicture.asset( + "assets/images/new-design/liveCare_logo_icon.svg", + width: 20.0, + height: 20.0) + : Image.asset( + "assets/images/new-design/hospital_address_icon.png", + width: 20.0, + height: 20.0), Container( margin: EdgeInsets.only(left: 10.0, right: 10.0), - child: Text(widget.appo.projectName, - style: TextStyle(fontSize: 12.0)), + child: widget.appo.isLiveCareAppointment + ? Text(TranslationBase.of(context).upcomingLivecare, + style: TextStyle(fontSize: 12.0)) + : Text(widget.appo.projectName, + style: TextStyle(fontSize: 12.0)), ), ], ), @@ -105,7 +113,10 @@ class _TodoListCardState extends State { letterSpacing: 1.0)), Container( margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text(getDoctorSpeciality(widget.appo.doctorSpeciality).trim(), + child: Text( + getDoctorSpeciality( + widget.appo.doctorSpeciality) + .trim(), style: TextStyle( fontSize: 12.0, color: Colors.grey[600], @@ -323,14 +334,13 @@ class _TodoListCardState extends State { } String getMinute(DateTime dateObj) { - if(dateObj.minute == 0) { + if (dateObj.minute == 0) { return dateObj.minute.toString() + "0"; } else { return dateObj.minute.toString(); } } - String getDoctorSpeciality(List docSpecial) { String docSpeciality = ""; docSpecial.forEach((v) { diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index 59c0a167..55a095ed 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -5,16 +5,16 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medic import 'package:diplomaticquarterapp/pages/ContactUs/hmg_service.dart'; import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; +import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.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:flutter_svg/flutter_svg.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; @@ -56,20 +56,112 @@ class _HomePageState extends State { child: Stack( children: [ Positioned( - top: 30, - left: 15, - right: 15, + top: 15, + left: 5, + right: 5, child: Container( width: MediaQuery.of(context).size.width * 0.8, child: Row( children: [ + Expanded( + child: Container( + height: 120, + padding: EdgeInsets.all(5), + margin: EdgeInsets.all(5), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("assets/images/new-design/covid_bg_transparent.png"), + fit: BoxFit.fill, + ), + color: + Colors.white.withOpacity(0.3), + borderRadius: BorderRadius.all( + Radius.circular(5))), + child: Container( + margin: EdgeInsets.only(top: 10.0), + child: Column( + children: [ + Text("COVID-19 TEST", + style: TextStyle( + color: Colors.white, + fontWeight: + FontWeight.bold, + fontSize: 18.0)), + Row( + children: [ + Container( + margin: EdgeInsets.only( + top: 15.0), + child: SvgPicture.asset( + 'assets/images/new-design/covid-19-car.svg', + width: 50.0, + height: 50.0), + ), + Container( + margin: EdgeInsets.only( + left: 10.0, top: 10.0), + child: Column( + children: [ + Text("Drive-Thru", + style: TextStyle( + color: Colors + .white, + fontWeight: + FontWeight + .bold, + fontSize: + 16.0)), + ButtonTheme( + shape: + RoundedRectangleBorder( + borderRadius: + BorderRadius + .circular( + 5.0), + ), + minWidth: MediaQuery.of( + context) + .size + .width * + 0.15, + height: 25.0, + child: RaisedButton( + color: Colors.red[800], + textColor: + Colors.white, + disabledTextColor: + Colors.white, + disabledColor: + new Color( + 0xFFbcc2c4), + onPressed: () { +// if (_isButtonDisabled == false) { +// _searchDoctor(context); +// } + }, + child: Text("BOOK NOW", + style: TextStyle( + fontSize: + 12.0)), + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + ), Expanded( child: InkWell( onTap: () => Navigator.push(context, FadePage(page: LiveCareHome())), child: Container( - height: 110, + height: 120, padding: EdgeInsets.all(15), margin: EdgeInsets.all(5), decoration: BoxDecoration( @@ -77,25 +169,13 @@ class _HomePageState extends State { .withOpacity(0.3), borderRadius: BorderRadius.all( Radius.circular(5))), - child: Image.asset( - 'assets/images/livecare_white_logo.png', + child: SvgPicture.asset( + projectViewModel.isArabic ? 'assets/images/new-design/livecare_arabic_logo.svg' : + 'assets/images/new-design/liveCare_white_logo.svg', ), ), ), ), - Expanded( - child: Container( - height: 110, - padding: EdgeInsets.all(15), - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - color: - Colors.white.withOpacity(0.3), - borderRadius: BorderRadius.all( - Radius.circular(5))), - // child: Image.asset('assets/images/livecare_white_logo.png',), - ), - ), ], ), ), diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index d8978d8e..64114304 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -74,7 +74,7 @@ class _LiveCareTypeSelectState extends State { SvgPicture.asset("assets/images/new-design/check_icon.svg", width: 25), Container( - width: MediaQuery.of(context).size.width * 0.75, + width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), child: Text( "No need to wait, you will get Medical consultation immediately via Video call.", @@ -91,7 +91,7 @@ class _LiveCareTypeSelectState extends State { SvgPicture.asset("assets/images/new-design/check_icon.svg", width: 25), Container( - width: MediaQuery.of(context).size.width * 0.75, + width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), child: Text("The doctor will see your medical file.", overflow: TextOverflow.clip, @@ -107,7 +107,7 @@ class _LiveCareTypeSelectState extends State { SvgPicture.asset("assets/images/new-design/check_icon.svg", width: 25), Container( - width: MediaQuery.of(context).size.width * 0.75, + width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), child: Text("Free Prescription delivery service.", overflow: TextOverflow.clip, @@ -140,7 +140,7 @@ class _LiveCareTypeSelectState extends State { width: 80), ), Container( - width: MediaQuery.of(context).size.width * 0.6, + width: MediaQuery.of(context).size.width * 0.56, margin: EdgeInsets.fromLTRB(30.0, 20.0, 0.0, 0.0), child: Column( children: [ @@ -182,7 +182,7 @@ class _LiveCareTypeSelectState extends State { width: 70), ), Container( - width: MediaQuery.of(context).size.width * 0.6, + width: MediaQuery.of(context).size.width * 0.58, margin: EdgeInsets.fromLTRB(30.0, 30.0, 0.0, 0.0), child: Column( children: [ @@ -208,6 +208,9 @@ class _LiveCareTypeSelectState extends State { ], )), ), + SizedBox( + height: 40.0, + ), ], ), ), diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 8d5b62f6..542ea3e2 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/LiveCare/insertVIDARequest.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; @@ -21,6 +22,8 @@ class DoctorsListService extends BaseService { double lat; double long; + String deviceToken; + String tokenID; Future getDoctorsList( int clinicID, int projectID, bool isNearest, BuildContext context, @@ -48,7 +51,7 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "Channel": req.Channel, "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, + "PatientOutSA": authUser.outSA, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": "YckwoXhUmWBsnHKEKig", @@ -106,7 +109,7 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "Channel": req.Channel, "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, + "PatientOutSA": authUser.outSA, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -146,7 +149,7 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "Channel": req.Channel, "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, + "PatientOutSA": authUser.outSA, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -188,7 +191,7 @@ class DoctorsListService extends BaseService { "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", - "PatientOutSA": 0, + "PatientOutSA": authUser.outSA, "SessionID": null, "isDentalAllowedBackend": false, "DeviceTypeID": 1 @@ -224,7 +227,7 @@ class DoctorsListService extends BaseService { "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", - "PatientOutSA": 0, + "PatientOutSA": authUser.outSA, "SessionID": null, "isDentalAllowedBackend": false, "DeviceTypeID": 1 @@ -513,7 +516,7 @@ class DoctorsListService extends BaseService { } Future confirmAppointment( - int appoNo, int clinicID, int projectID, BuildContext context) async { + int appoNo, int clinicID, int projectID, bool isLiveCare, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -527,6 +530,7 @@ class DoctorsListService extends BaseService { request = { "AppointmentNumber": appoNo, + "IsLiveCareAppointment": isLiveCare, "ClinicID": clinicID, "ProjectID": projectID, "ConfirmationBy": 102, @@ -556,6 +560,62 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + + Future insertVIDARequest( + int appoNo, int clinicID, int projectID, int serviceID, int docID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + deviceToken = await sharedPref.getString(PUSH_TOKEN); + + if (await this.sharedPref.getDouble(USER_LAT) != null && + await this.sharedPref.getDouble(USER_LONG) != null) { + lat = await this.sharedPref.getDouble(USER_LAT); + long = await this.sharedPref.getDouble(USER_LONG); + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + + request = { + "AppointmentNo": appoNo, + "ClinicID": clinicID, + "ProjectID": projectID, + "ServiceID": serviceID, + "AcceptedBy": docID, + "DeviceToken": deviceToken, + "Latitude": lat, + "Longitude": long, + "DeviceType": req.DeviceType, + "VersionID": req.VersionID, + "Channel": req.Channel, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + + dynamic localRes; + + await baseAppClient.post(INSERT_VIDA_REQUEST, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future cancelAppointment( AppoitmentAllHistoryResultList appo, BuildContext context) async { Map request; diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 272d983f..71927d28 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -97,6 +97,8 @@ class TranslationBase { String get confirmLiveCare => localizedValues['confirmLiveCare'][locale.languageCode]; + String get waitingForDoctor => localizedValues['waitingForDoctor'][locale.languageCode]; + String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; @@ -222,6 +224,9 @@ class TranslationBase { String get upcomingLivecare => localizedValues['upcoming-livecare'][locale.languageCode]; + String get liveCareAppo => + localizedValues['livecareAppo'][locale.languageCode]; + String get upcomingDetails => localizedValues['upcoming-details'][locale.languageCode]; From 929e289a6f1a3cdb6cb6612d6ed2a96abfc8c470 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 30 Sep 2020 18:08:53 +0300 Subject: [PATCH 4/7] started implementing Covid-19 DriveThru Test Module --- assets/images/new-design/calendar.png | Bin 0 -> 5627 bytes .../new-design/covid_bg_transparent.png | Bin 0 -> 11952 bytes .../new-design/hmg_full_logo_hd_white.png | Bin 0 -> 19553 bytes .../images/new-design/waiting_for_doctor.png | Bin 0 -> 2554 bytes lib/config/config.dart | 2 + .../DriveThroughTestingCenterModel.dart | 68 +++++ lib/pages/BookAppointment/BookSuccess.dart | 2 +- .../covid-drivethru-location.dart | 258 ++++++++++++++++++ lib/pages/landing/home_page.dart | 27 +- .../appointment_services/GetDoctorsList.dart | 1 - .../covid-drivethru/covid-drivethru.dart | 52 ++++ lib/widgets/others/arrow_back.dart | 6 +- 12 files changed, 402 insertions(+), 14 deletions(-) create mode 100644 assets/images/new-design/calendar.png create mode 100644 assets/images/new-design/covid_bg_transparent.png create mode 100644 assets/images/new-design/hmg_full_logo_hd_white.png create mode 100644 assets/images/new-design/waiting_for_doctor.png create mode 100644 lib/models/CovidDriveThru/DriveThroughTestingCenterModel.dart create mode 100644 lib/pages/Covid-DriveThru/covid-drivethru-location.dart create mode 100644 lib/services/covid-drivethru/covid-drivethru.dart diff --git a/assets/images/new-design/calendar.png b/assets/images/new-design/calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..ac72b030ab799a61619080779577a75455d0dafe GIT binary patch literal 5627 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 cn-lhpeU}bQS)VFx-1`PWNySpYd(6|IAL4q|B zTyAD|c6Rsd+}Hb1Rp->H`XByN4^?0NvD%tS1bEbV&z?OaP*IlG{Wo6xYY8}5|9Umc zh<_7|&s5}P^!>7rEKGdKlroY`^&R+d8{-v586zA~&*-lf2N0S2R$F-+R#QFwHNp2g zpCv<1XD-x#x~vRu^fekMBw*n1e8|vsEa%yMac&XRCNHmOXRBhM5VE^hrvF2D>-cIo zF@4vcQ?p37+_=V98DyxMqp$jR`x3Kw)~0w?m4%+|SkwW7TC}DL^;iY-dAr9^Jj)Rj zlAmsh=l>XZ7!+HoS{``%=FbxgbkBIbM~=h5Ky^+wccC~v%TSeoqgX(-oUVA56yZOn zoc)eeLM}UBg$W^DVMur4f#^p_vVPJ%P%WP;@!!Uv-32R=7tj7%jXyHAucK-~evc%$ zJ*{dCZT!Jr`elP^D}qdWKSlPyPkrPy3;!#da6SZ^N8P&*kPLVe@;k`9Hbc6D|Dsvf zDgNQXoTG_h>s~V2CV)l42sS*>(%q4j%?7tQ&;qLEWQ|B()XreU?YPZ7x*^`D--v~J5kyOs?#6JM@^15owev`#$r^5+;|#*g_mJ`0 z?;|AytcI^Hw(pbaYiC@&ioBZ_l%Jkdg{KC5=k9H z!)*$L<$aRJxNi;+$B^Na@rS>#X@CYxLIqsU)xb+y`{twtmR?+~{bC5QM~@?zbtOCk zP?{+$VD+U_KPvD#AsIt6gbG+iN_Bi7>9IjIl|@|%4sn2U)4)*rU4oH^I8j;~8J#DS(8-;3-*R5-$Dk~Kv;gFk zH(qgeDKy~xitxRGDOMfdL`qEG1^wXLN}Flk%?>b36fmav+}UQPOX? zAgVw#X!!06k0QUL_$vnmr_QH6K%U7g@38K z+e-L0OnYwyS9>5$`0LXe$>j_fOZIhDKrAPaR0*3}83(^0 zOw;}^Y1hew@v26VdfXcZ^1R;i+YDLY=jRt3jrtS__SCSFx|?DSvJTXFbZv;w(j_oz zr9vJvK?U%o|BjED#}jS+O|QLVUbx=~F;4v)94

yfg5XnJb*p@D*Z@fHI*0Y5N;P^-nM5? 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 json) { + rowID = json['RowID']; + iD = json['ID']; + projectID = json['ProjectID']; + setupID = json['SetupID']; + longitude = json['Longitude']; + latitude = json['Latitude']; + numberOfTracks = json['NumberOfTracks']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedON = json['EditedON']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; + } + + Map toJson() { + final Map data = new Map(); + data['RowID'] = this.rowID; + data['ID'] = this.iD; + data['ProjectID'] = this.projectID; + data['SetupID'] = this.setupID; + data['Longitude'] = this.longitude; + data['Latitude'] = this.latitude; + data['NumberOfTracks'] = this.numberOfTracks; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedON'] = this.editedON; + data['ProjectName'] = this.projectName; + data['ProjectNameN'] = this.projectNameN; + return data; + } +} diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 704618ac..34dbdc2f 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -782,7 +782,7 @@ class _BookSuccessState extends State { } Future navigateToHome(context) async { - Navigator.of(context).pushNamed(HOME); + Navigator.of(context).popAndPushNamed(HOME); } getAppoQR(context) { diff --git a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart new file mode 100644 index 00000000..6b1c5f2b --- /dev/null +++ b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart @@ -0,0 +1,258 @@ +import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:maps_launcher/maps_launcher.dart'; + +class CovidDrivethruLocation extends StatefulWidget { + @override + _CovidDrivethruLocationState createState() => _CovidDrivethruLocationState(); +} + +class _CovidDrivethruLocationState extends State { + String projectDropdownValue; + List projectsList = []; + bool isLocationSelected = false; + String projectLat = ""; + String projectLong = ""; + String projectName = ""; + + @override + void initState() { + WidgetsBinding.instance + .addPostFrameCallback((_) => getProjectsList(context)); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "COVID-19 TEST", + isShowAppBar: true, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), + child: Column( + children: [ + Container( + alignment: Alignment.centerLeft, + child: Text("Get The Result During 8 Hours", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 22.0, + color: Colors.black)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text( + "We are using the advance technology to test COVID-19, The sample for examination is taking between the nose and mouth (nasopharyngeal swab), the examination is done by ELITE In Genius of the company ELITECH GROUP MOLECULAR DIAGNOSTICS, Note that the device belongs to an Italian company and is manufactured in Japan with RC- PCR​", + style: TextStyle(fontSize: 16.0, color: Colors.black)), + ), + Container( + margin: EdgeInsets.only(top: 20.0), + alignment: Alignment.centerLeft, + child: Text("Select Location", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + letterSpacing: 0.8, + color: Colors.grey[700])), + ), + Container( + height: 60.0, + decoration: BoxDecoration( + color: Colors.white, + border: Border.all( + color: Colors.grey[400], + width: 1.0, + ), + borderRadius: BorderRadius.circular(10), + ), + padding: EdgeInsets.all(8.0), + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(top: 15.0), + child: DropdownButtonHideUnderline( + child: DropdownButton( + hint: new Text("Select Address"), + value: projectDropdownValue, + items: projectsList.map((item) { + return new DropdownMenuItem( + value: item.iD.toString(), + child: new Text(item.projectName), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + projectDropdownValue = newValue; + setProjectLocation(newValue); + }); + }, + ), + )), + isLocationSelected + ? Container( + margin: EdgeInsets.only(top: 15.0), + alignment: Alignment.centerLeft, + child: Text("Selected Location", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + letterSpacing: 0.8, + color: Colors.black)), + ) : Container(), + isLocationSelected + ? Container( + margin: EdgeInsets.only(top: 5.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey[400], width: 1.0), + ), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=" + + this.projectLat + + "," + + this.projectLong + + "&zoom=15&size=800x400&maptype=roadmap&markers=color:red%7C" + + this.projectLat + + "," + + this.projectLong + + "&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8"), + ) + : Container(), + ], + ), + ), + ), + bottomSheet: Container( + height: MediaQuery.of(context).size.height * 0.15, + width: double.infinity, + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.91, + height: 45.0, + child: RaisedButton( + color: new Color(0xFFc5272d), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.red[300], + onPressed: () { + getDirections(); + }, + child: + Text("GET DIRECTIONS", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: () { + back(); + }, + child: Text("BACK", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: () { + next(); + }, + child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } + + getDirections() { + if(isLocationSelected) { + MapsLauncher.launchCoordinates(double.parse(projectLat),double.parse(projectLong), this.projectName); + } else { + Utils.showErrorToast("Please select address from the dropdown menu to get directions"); + } + } + + next() { + + } + + back() { + Navigator.of(context).popAndPushNamed(HOME); + } + + setProjectLocation(newValue) { + print(newValue); + print(projectsList[(int.parse(newValue) - 1)].projectName); + setState(() { + this.projectLat = + projectsList[(int.parse(newValue) - 1)].latitude.toString(); + this.projectLong = + projectsList[(int.parse(newValue) - 1)].longitude.toString(); + this.projectName = projectsList[(int.parse(newValue) - 1)].projectName; + isLocationSelected = true; + }); + } + + getProjectsList(BuildContext context) { + CovidDriveThruService service = new CovidDriveThruService(); + service.getCovidProjectsList(context).then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + res['List_COVID19_ProjectDriveThroughTestingCenter'].forEach((v) { + projectsList.add(new DriveThroughTestingCenterModel.fromJson(v)); + }); + }); + } else {} + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } +} diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index 55a095ed..d427c2f1 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/hmg_service.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; @@ -71,7 +72,8 @@ class _HomePageState extends State { margin: EdgeInsets.all(5), decoration: BoxDecoration( image: DecorationImage( - image: AssetImage("assets/images/new-design/covid_bg_transparent.png"), + image: AssetImage( + "assets/images/new-design/covid_bg_transparent.png"), fit: BoxFit.fill, ), color: @@ -100,7 +102,8 @@ class _HomePageState extends State { ), Container( margin: EdgeInsets.only( - left: 10.0, top: 10.0), + left: 10.0, + top: 10.0), child: Column( children: [ Text("Drive-Thru", @@ -127,7 +130,8 @@ class _HomePageState extends State { 0.15, height: 25.0, child: RaisedButton( - color: Colors.red[800], + color: Colors + .red[800], textColor: Colors.white, disabledTextColor: @@ -136,11 +140,10 @@ class _HomePageState extends State { new Color( 0xFFbcc2c4), onPressed: () { -// if (_isButtonDisabled == false) { -// _searchDoctor(context); -// } + navigateToCovidDriveThru(); }, - child: Text("BOOK NOW", + child: Text( + "BOOK NOW", style: TextStyle( fontSize: 12.0)), @@ -170,8 +173,9 @@ class _HomePageState extends State { borderRadius: BorderRadius.all( Radius.circular(5))), child: SvgPicture.asset( - projectViewModel.isArabic ? 'assets/images/new-design/livecare_arabic_logo.svg' : - 'assets/images/new-design/liveCare_white_logo.svg', + projectViewModel.isArabic + ? 'assets/images/new-design/livecare_arabic_logo.svg' + : 'assets/images/new-design/liveCare_white_logo.svg', ), ), ), @@ -742,6 +746,11 @@ class _HomePageState extends State { ), ); } + + navigateToCovidDriveThru() { + Navigator.push(context, + MaterialPageRoute(builder: (context) => CovidDrivethruLocation())); + } } class DashboardItem extends StatelessWidget { diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 542ea3e2..24d81bdf 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -28,7 +28,6 @@ class DoctorsListService extends BaseService { Future getDoctorsList( int clinicID, int projectID, bool isNearest, BuildContext context, {doctorId}) async { - //Utils.showProgressDialog(context); Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { diff --git a/lib/services/covid-drivethru/covid-drivethru.dart b/lib/services/covid-drivethru/covid-drivethru.dart new file mode 100644 index 00000000..a9ebbecd --- /dev/null +++ b/lib/services/covid-drivethru/covid-drivethru.dart @@ -0,0 +1,52 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/Request.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:flutter/material.dart'; + +class CovidDriveThruService extends BaseService { + AppSharedPreferences sharedPref = AppSharedPreferences(); + AppGlobal appGlobal = new AppGlobal(); + + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + + Future getCovidProjectsList(BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "TokenID": "", + "DeviceTypeID": req.DeviceTypeID, + "SessionID": "YckwoXhUmWBsnHKEKig", + "PatientID": authUser.patientID != null ? authUser.patientID : 0, + "License": true + }; + + dynamic localRes; + + await baseAppClient.post(GET_COVID_DRIVETHRU_PROJECT_LIST, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } +} diff --git a/lib/widgets/others/arrow_back.dart b/lib/widgets/others/arrow_back.dart index 498554fd..619f4f41 100644 --- a/lib/widgets/others/arrow_back.dart +++ b/lib/widgets/others/arrow_back.dart @@ -18,9 +18,9 @@ class ArrowBack extends StatelessWidget { }, context), child: Icon( projectViewModel.isArabic - ? Icons.arrow_back_ios - : Icons.arrow_forward_ios, - color: Theme.of(context).primaryColor), + ? Icons.arrow_forward_ios + : Icons.arrow_back_ios, + color: Colors.white), ); } } From 41d50e23e3df837e9a17bbe58e01472325a9e7d7 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 6 Oct 2020 14:06:28 +0300 Subject: [PATCH 5/7] covid drivethru implemented --- .../new-design/covid-19-big-banner-bg.png | Bin 0 -> 10233 bytes ios/Runner/Runner.entitlements | 5 +- .../Appointments/PatientShareResposne.dart | 34 +- .../CovidPaymentInfoResponse.dart | 96 +++ .../health_converter/blood_cholesterol.dart | 2 +- .../health_converter/blood_sugar.dart | 2 +- .../health_converter/triglycerides.dart | 2 +- .../components/DocAvailableAppointments.dart | 4 +- .../Covid-DriveThru/Covid-TimeSlots.dart | 599 ++++++++++++++++++ .../covid-drivethru-location.dart | 77 ++- .../Covid-DriveThru/covid-payment-alert.dart | 288 +++++++++ .../covid-payment-details.dart | 257 ++++++++ lib/pages/ToDoList/ToDo.dart | 2 +- lib/pages/landing/home_page.dart | 6 +- lib/pages/landing/landing_page.dart | 3 - .../covid-drivethru/covid-drivethru.dart | 74 +++ 16 files changed, 1406 insertions(+), 45 deletions(-) create mode 100644 assets/images/new-design/covid-19-big-banner-bg.png create mode 100644 lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart create mode 100644 lib/pages/Covid-DriveThru/Covid-TimeSlots.dart create mode 100644 lib/pages/Covid-DriveThru/covid-payment-alert.dart create mode 100644 lib/pages/Covid-DriveThru/covid-payment-details.dart diff --git a/assets/images/new-design/covid-19-big-banner-bg.png b/assets/images/new-design/covid-19-big-banner-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..a66d681553e9014c80c6452df934b6900d599f32 GIT binary patch literal 10233 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 0c67376e..903def2a 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -1,5 +1,8 @@ - + + aps-environment + development + diff --git a/lib/models/Appointments/PatientShareResposne.dart b/lib/models/Appointments/PatientShareResposne.dart index 2e22ed60..40670990 100644 --- a/lib/models/Appointments/PatientShareResposne.dart +++ b/lib/models/Appointments/PatientShareResposne.dart @@ -1,19 +1,19 @@ class PatientShareResponse { int advanceNumber; - String appointmentDate; + dynamic appointmentDate; int appointmentNo; int cashPrice; int cashPriceTax; int cashPriceWithTax; int clinicID; - String clinicName; + dynamic clinicName; int companyId; - String companyName; + dynamic companyName; int companyShareWithTax; - String doctorImageURL; - String doctorNameObj; + dynamic doctorImageURL; + dynamic doctorNameObj; int doctorID; - List doctorSpeciality; + List doctorSpeciality; dynamic errCode; int groupID; bool iSAllowOnlineCheckedIN; @@ -22,7 +22,7 @@ class PatientShareResponse { int isFollowup; bool isLiveCareAppointment; bool isOnlineCheckedIN; - String message; + dynamic message; int nextAction; dynamic patientCardID; int patientID; @@ -30,19 +30,19 @@ class PatientShareResponse { dynamic patientShareWithTax; int patientStatusType; dynamic patientTaxAmount; - String patientType; + dynamic patientType; int paymentAmount; - String paymentDate; + dynamic paymentDate; dynamic paymentMethodName; dynamic paymentReferenceNumber; int policyId; - String policyName; - String procedureName; + dynamic policyName; + dynamic procedureName; int projectID; - String projectName; + dynamic projectName; dynamic setupID; int sourceType; - String startTime; + dynamic startTime; int status; int statusCode; dynamic statusDesc; @@ -102,7 +102,7 @@ class PatientShareResponse { this.userID, this.serviceID}); - PatientShareResponse.fromJson(Map json) { + PatientShareResponse.fromJson(Map json) { advanceNumber = json['AdvanceNumber']; appointmentDate = json['AppointmentDate']; appointmentNo = json['AppointmentNo']; @@ -117,7 +117,7 @@ class PatientShareResponse { doctorID = json['DoctorID']; doctorImageURL = json['DoctorImageURL']; doctorNameObj = json['DoctorNameObj']; - doctorSpeciality = json['DoctorSpeciality'].cast(); +// doctorSpeciality = json['DoctorSpeciality'].cast(); errCode = json['ErrCode']; groupID = json['GroupID']; iSAllowOnlineCheckedIN = json['ISAllowOnlineCheckedIN']; @@ -155,8 +155,8 @@ class PatientShareResponse { serviceID = json['ServiceID']; } - Map toJson() { - final Map data = new Map(); + Map toJson() { + final Map data = new Map(); data['AdvanceNumber'] = this.advanceNumber; data['AppointmentDate'] = this.appointmentDate; data['AppointmentNo'] = this.appointmentNo; diff --git a/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart b/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart new file mode 100644 index 00000000..a1290e4d --- /dev/null +++ b/lib/models/CovidDriveThru/CovidPaymentInfoResponse.dart @@ -0,0 +1,96 @@ +class CovidPaymentInfoResponse { + dynamic propertyChanged; + dynamic cashPriceField; + dynamic cashPriceTaxField; + dynamic cashPriceWithTaxField; + dynamic companyIdField; + String companyNameField; + dynamic companyShareWithTaxField; + dynamic errCodeField; + dynamic groupIDField; + dynamic insurancePolicyNoField; + String messageField; + dynamic patientCardIDField; + dynamic patientShareField; + dynamic patientShareWithTaxField; + dynamic patientTaxAmountField; + dynamic policyIdField; + dynamic policyNameField; + String procedureNameField; + dynamic setupIDField; + dynamic statusCodeField; + dynamic subPolicyNoField; + + CovidPaymentInfoResponse( + {this.propertyChanged, + this.cashPriceField, + this.cashPriceTaxField, + this.cashPriceWithTaxField, + this.companyIdField, + this.companyNameField, + this.companyShareWithTaxField, + this.errCodeField, + this.groupIDField, + this.insurancePolicyNoField, + this.messageField, + this.patientCardIDField, + this.patientShareField, + this.patientShareWithTaxField, + this.patientTaxAmountField, + this.policyIdField, + this.policyNameField, + this.procedureNameField, + this.setupIDField, + this.statusCodeField, + this.subPolicyNoField}); + + CovidPaymentInfoResponse.fromJson(Map json) { + propertyChanged = json['PropertyChanged']; + cashPriceField = json['cashPriceField']; + cashPriceTaxField = json['cashPriceTaxField']; + cashPriceWithTaxField = json['cashPriceWithTaxField']; + companyIdField = json['companyIdField']; + companyNameField = json['companyNameField']; + companyShareWithTaxField = json['companyShareWithTaxField']; + errCodeField = json['errCodeField']; + groupIDField = json['groupIDField']; + insurancePolicyNoField = json['insurancePolicyNoField']; + messageField = json['messageField']; + patientCardIDField = json['patientCardIDField']; + patientShareField = json['patientShareField']; + patientShareWithTaxField = json['patientShareWithTaxField']; + patientTaxAmountField = json['patientTaxAmountField']; + policyIdField = json['policyIdField']; + policyNameField = json['policyNameField']; + procedureNameField = json['procedureNameField']; + setupIDField = json['setupIDField']; + statusCodeField = json['statusCodeField']; + subPolicyNoField = json['subPolicyNoField']; + } + + Map toJson() { + final Map data = new Map(); + data['PropertyChanged'] = this.propertyChanged; + data['cashPriceField'] = this.cashPriceField; + data['cashPriceTaxField'] = this.cashPriceTaxField; + data['cashPriceWithTaxField'] = this.cashPriceWithTaxField; + data['companyIdField'] = this.companyIdField; + data['companyNameField'] = this.companyNameField; + data['companyShareWithTaxField'] = this.companyShareWithTaxField; + data['errCodeField'] = this.errCodeField; + data['groupIDField'] = this.groupIDField; + data['insurancePolicyNoField'] = this.insurancePolicyNoField; + data['messageField'] = this.messageField; + data['patientCardIDField'] = this.patientCardIDField; + data['patientShareField'] = this.patientShareField; + data['patientShareWithTaxField'] = this.patientShareWithTaxField; + data['patientTaxAmountField'] = this.patientTaxAmountField; + data['policyIdField'] = this.policyIdField; + data['policyNameField'] = this.policyNameField; + data['procedureNameField'] = this.procedureNameField; + data['setupIDField'] = this.setupIDField; + data['statusCodeField'] = this.statusCodeField; + data['subPolicyNoField'] = this.subPolicyNoField; + return data; + } +} diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart index 9a2f08df..58caee36 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart @@ -190,7 +190,7 @@ class _BloodCholesterolState extends State { child: TextFormField( controller: textController, inputFormatters: [ - FilteringTextInputFormatter.digitsOnly +// FilteringTextInputFormatter.digitsOnly ], keyboardType: TextInputType.number, decoration: InputDecoration( diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart index a90a5bbb..f5d66ccf 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart @@ -192,7 +192,7 @@ class _BloodSugarState extends State { child: TextFormField( controller: textController, inputFormatters: [ - FilteringTextInputFormatter.digitsOnly +// FilteringTextInputFormatter.digitsOnly ], keyboardType: TextInputType.number, decoration: InputDecoration( diff --git a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart index fdf8d191..a86fdb88 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart @@ -188,7 +188,7 @@ class _TriglyceridesState extends State { child: TextFormField( controller: textController, inputFormatters: [ - FilteringTextInputFormatter.digitsOnly +// FilteringTextInputFormatter.digitsOnly ], keyboardType: TextInputType.number, decoration: InputDecoration( diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index aca0884f..88116cd9 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -385,8 +385,8 @@ class _DocAvailableAppointmentsState extends State color: _calendarController.isSelected(date) ? Colors.green[400] : _calendarController.isToday(date) - ? Colors.brown[300] - : Colors.blue[400], + ? Colors.brown[300] + : Colors.blue[400], ), width: 40.0, height: 40.0, diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart new file mode 100644 index 00000000..060a8132 --- /dev/null +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -0,0 +1,599 @@ +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-alert.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; +import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class CovidTimeSlots extends StatefulWidget { + int projectID; + static bool areSlotsAvailable = false; + static DateTime selectedAppoDateTime; + static String selectedDate; + static String selectedTime; + + int selectedClinicID; + int selectedDoctorID; + + PatientShareResponse patientShareResponse; + + CovidTimeSlots({@required this.projectID}); + + @override + _CovidTimeSlotsState createState() => _CovidTimeSlotsState(); +} + +class _CovidTimeSlotsState extends State + with TickerProviderStateMixin { + Map _events; + AnimationController _animationController; + CalendarController _calendarController; + + AppSharedPreferences sharedPref = new AppSharedPreferences(); + + var selectedDate = ""; + dynamic selectedDateJSON; + dynamic jsonFreeSlots; + + List docFreeSlots = []; + List dayEvents = []; + + int selectedButtonIndex = 0; + + dynamic freeSlotsResponse; + + ScrollController _scrollController; + + @override + void initState() { + final _selectedDay = DateTime.now(); + + widget.patientShareResponse = new PatientShareResponse(); + + _scrollController = new ScrollController(); + + _events = { + _selectedDay: ['Event A0'] + }; + + WidgetsBinding.instance.addPostFrameCallback( + (_) => getCovidFreeSlots(context, widget.projectID)); + + _calendarController = CalendarController(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 50), + ); + + _animationController.forward(); + super.initState(); + } + + @override + void dispose() { + _animationController.dispose(); + _calendarController.dispose(); + super.dispose(); + } + + void _onDaySelected(DateTime day, List events) { + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + setState(() { + this.selectedDate = DateUtil.getMonthDayYearDateFormatted(day); + openTimeSlotsPickerForDate(day, docFreeSlots); + CovidTimeSlots.selectedDate = formatter.format(day); + print(CovidTimeSlots.selectedDate); + }); + } + + void _onVisibleDaysChanged( + DateTime first, DateTime last, CalendarFormat format) { + print('CALLBACK: _onVisibleDaysChanged'); + } + + void _onCalendarCreated( + DateTime first, DateTime last, CalendarFormat format) { + print('CALLBACK: _onCalendarCreated'); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "COVID-19 TEST", + isShowAppBar: true, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 150.0, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "assets/images/new-design/covid-19-big-banner-bg.png"), + fit: BoxFit.fill, + ), + color: Colors.white.withOpacity(0.3), + borderRadius: BorderRadius.all(Radius.circular(10))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: + EdgeInsets.only(left: 15.0, right: 15.0, top: 30.0), + child: SvgPicture.asset( + 'assets/images/new-design/covid-19-car.svg', + width: 90.0, + height: 90.0), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only( + left: 20.0, right: 20.0, top: 40.0), + child: Text("COVID-19 TEST", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 24.0)), + ), + Container( + margin: EdgeInsets.only( + left: 20.0, right: 20.0, top: 10.0), + child: Text("Drive-Thru", + style: TextStyle( + color: Colors.white, fontSize: 24.0)), + ), + ], + ), + ], + ), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white), + margin: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 5.0), + padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.65, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.all(10.0), + child: Text( + "Kindly select one of the available appointments from below: ", + style: + TextStyle(color: Colors.black, fontSize: 16.0)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.center, + child: Text(selectedDate, + style: TextStyle( + fontSize: 18.0, fontWeight: FontWeight.bold)), + ), + Container( + height: 50, + margin: EdgeInsets.all(20.0), + child: ListView.builder( + controller: _scrollController, + scrollDirection: Axis.horizontal, + itemCount: dayEvents.length, + itemBuilder: (context, index) { + return Container( + margin: EdgeInsets.only(right: 10.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + side: BorderSide( + color: Colors.blue[400], + //Color of the border + style: BorderStyle.solid, + //Style of the border + width: 1.5, //width of the border + ), + ), + minWidth: + MediaQuery.of(context).size.width * 0.2, + child: index == selectedButtonIndex + ? getSelectedButton(index) + : getNormalButton(index)), + ); + }, + ), + ), + _buildTableCalendarWithBuilders(), + ], + ), + ), + SizedBox( + height: 100.0, + ), + ], + ), + ), + ), + bottomSheet: Container( + margin: EdgeInsets.all(10.0), + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: () { + bookCovidTestAppointment(); + }, + child: Text("BOOK", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildTableCalendarWithBuilders() { + return TableCalendar( + locale: 'en_US', + calendarController: _calendarController, + events: _events, + initialCalendarFormat: CalendarFormat.month, + startDay: DateTime.now(), + formatAnimation: FormatAnimation.slide, + startingDayOfWeek: StartingDayOfWeek.sunday, + weekendDays: [DateTime.friday, DateTime.saturday], + availableGestures: AvailableGestures.horizontalSwipe, + availableCalendarFormats: const { + CalendarFormat.month: '', + CalendarFormat.week: '', + }, + calendarStyle: CalendarStyle( + outsideDaysVisible: false, + weekendStyle: TextStyle().copyWith(color: Colors.blue[800]), + holidayStyle: TextStyle().copyWith(color: Colors.blue[800]), + ), + daysOfWeekStyle: DaysOfWeekStyle( + weekendStyle: TextStyle().copyWith(color: Colors.blue[600]), + ), + headerStyle: HeaderStyle( + centerHeaderTitle: true, + formatButtonVisible: false, + ), + builders: CalendarBuilders( + selectedDayBuilder: (context, date, _) { + return FadeTransition( + opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController), + child: Container( + margin: const EdgeInsets.all(4.0), + padding: const EdgeInsets.only(top: 5.0, left: 6.0), + color: Colors.transparent, + width: 0, + height: 0, + child: Text( + '${date.day}', + style: TextStyle().copyWith(fontSize: 16.0), + ), + ), + ); + }, + todayDayBuilder: (context, date, _) { + return Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _calendarController.isSelected(date) + ? Colors.green[400] + : _calendarController.isToday(date) + ? Colors.brown[300] + : Colors.blue[400], + ), + width: 40.0, + height: 40.0, + child: Center( + child: Text( + '${date.day}', + style: TextStyle().copyWith( + color: Colors.white, + fontSize: 14.0, + ), + ), + ), + ); + }, + markersBuilder: (context, date, events, holidays) { + final children = []; + + if (events.isNotEmpty) { + children.add( + Positioned( + right: 4, + bottom: 4, + child: _buildEventsMarker(date, events), + ), + ); + } + + return children; + }, + ), + onDaySelected: (date, events) { + _onDaySelected(date, events); + _animationController.forward(from: 0.0); + }, + onVisibleDaysChanged: _onVisibleDaysChanged, + onCalendarCreated: _onCalendarCreated, + ); + } + + openTimeSlotsPickerForDate(DateTime dateStart, List freeSlots) { + dayEvents.clear(); + DateTime dateStartObj = new DateTime( + dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); + + freeSlots.forEach((v) { + if (v.start == dateStartObj) dayEvents.add(v); + }); + + setState(() { + if (dayEvents.length != 0) + CovidTimeSlots.areSlotsAvailable = true; + else + CovidTimeSlots.areSlotsAvailable = false; + + selectedButtonIndex = 0; + + CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime; + }); + } + + Future> _getJSONSlots() async { + Map _eventsParsed; + List slotsList = []; + DateTime date; + final DateFormat formatter = DateFormat('HH:mm'); + final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); + for (var i = 0; i < freeSlotsResponse.length; i++) { + date = + DateUtil.convertStringToDate(freeSlotsResponse[i]['FreeTimeSlots']); + slotsList.add(FreeSlot(date, ['slot'])); + docFreeSlots.add(TimeSlot( + isoTime: formatter.format(date), + start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), + end: date)); + } + _eventsParsed = + Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); + setState(() { + CovidTimeSlots.selectedDate = dateFormatter.format( + DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); + selectedDate = DateUtil.getMonthDayYearDateFormatted( + DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots'])); + selectedDateJSON = freeSlotsResponse[0]['FreeTimeSlots']; + }); + openTimeSlotsPickerForDate( + DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots); + _calendarController + .setFocusedDay(DateUtil.convertStringToDate(selectedDateJSON)); + return _eventsParsed; + } + + Widget _buildEventsMarker(DateTime date, List events) { + return Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _calendarController.isSelected(date) + ? Colors.green[400] + : _calendarController.isToday(date) + ? Colors.brown[300] + : Colors.blue[400], + ), + width: 40.0, + height: 40.0, + child: Center( + child: Text( + '${date.day}', + style: TextStyle().copyWith( + color: Colors.white, + fontSize: 14.0, + ), + ), + ), + ); + } + + Widget getNormalButton(int index) { + return RaisedButton( + color: Colors.white, + textColor: new Color(0xFF60686b), + onPressed: () { + setState(() { + selectedButtonIndex = index; + CovidTimeSlots.selectedTime = dayEvents[index].isoTime; + print(CovidTimeSlots.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime, + style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + ); + } + + Widget getSelectedButton(int index) { + return RaisedButton( + color: Colors.blue[400], + textColor: Colors.white, + onPressed: () { + setState(() { + selectedButtonIndex = index; + CovidTimeSlots.selectedTime = dayEvents[index].isoTime; + print(CovidTimeSlots.selectedTime); + }); + }, + child: Text(dayEvents[index].isoTime, + style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), + ); + } + + bookCovidTestAppointment() { +// Navigator.push(context, +// MaterialPageRoute(builder: (context) => CovidPaymentAlert())); + + DoctorList docObject = new DoctorList(); + docObject.doctorID = widget.selectedDoctorID; + docObject.clinicID = widget.selectedClinicID; + docObject.projectID = widget.projectID; + insertAppointmentCovidTest(context, docObject); + } + + insertAppointmentCovidTest(context, DoctorList docObject) { + DoctorsListService service = new DoctorsListService(); + AppoitmentAllHistoryResultList appo; + service + .insertAppointment( + docObject.doctorID, + docObject.clinicID, + docObject.projectID, + CovidTimeSlots.selectedTime, + CovidTimeSlots.selectedDate, + context) + .then((res) { + print(res); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast(message: "Appointment Booked Successfully"); + Future.delayed(new Duration(milliseconds: 1800), () { + getPatientShare(context, res['AppointmentNo'], docObject.clinicID, + docObject.projectID, docObject); + }); + } else { + appo = new AppoitmentAllHistoryResultList(); + appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; + appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; + appo.projectID = res['SameClinicApptList'][0]['ProjectID']; + appo.endTime = res['SameClinicApptList'][0]['EndTime']; + appo.startTime = res['SameClinicApptList'][0]['StartTime']; + appo.doctorID = res['SameClinicApptList'][0]['DoctorID']; + appo.isLiveCareAppointment = false; + appo.originalClinicID = 0; + appo.originalProjectID = 0; + appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate']; + + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () => {cancelAppointment(docObject, appo, context)}, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + AppToast.showErrorToast(message: err); + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, + BuildContext context) { + ConfirmDialog.closeAlertDialog(context); + DoctorsListService service = new DoctorsListService(); + service.cancelAppointment(appo, context).then((res) { + if (res['MessageStatus'] == 1) { + Future.delayed(new Duration(milliseconds: 1500), () { + insertAppointmentCovidTest(context, docObject); + }); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } + + getPatientShare(context, String appointmentNo, int clinicID, int projectID, + DoctorList docObject) { + DoctorsListService service = new DoctorsListService(); + service + .getPatientShare(appointmentNo, clinicID, projectID, context) + .then((res) { + print(res); + widget.patientShareResponse = new PatientShareResponse.fromJson(res); + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + navigateToPaymentAlert(); + }); + } + + navigateToPaymentAlert() { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CovidPaymentAlert( + patientShareResponse: widget.patientShareResponse))); + } + + getCovidFreeSlots(BuildContext context, int projectID) { + CovidDriveThruService service = new CovidDriveThruService(); + service.getCovidFreeSlots(context, projectID).then((res) { + print(res['COVID19_FreeTimeSlots']); + if (res['MessageStatus'] == 1) { + if (res['COVID19_FreeTimeSlots'].length != 0) { + freeSlotsResponse = res['COVID19_FreeTimeSlots']; + print(res['COVID19_FreeTimeSlots'].length); + _getJSONSlots().then((value) => { + setState(() => { + widget.selectedClinicID = + freeSlotsResponse[0]['ClinicID'], + widget.selectedDoctorID = + freeSlotsResponse[0]['DoctorID'], + _events.clear(), + _events = value + }) + }); + } else {} + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + }).showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + } +} diff --git a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart index 6b1c5f2b..0563c4bd 100644 --- a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart +++ b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart @@ -1,11 +1,13 @@ +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-details.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import 'package:maps_launcher/maps_launcher.dart'; +import 'package:smart_progress_bar/smart_progress_bar.dart'; class CovidDrivethruLocation extends StatefulWidget { @override @@ -19,6 +21,7 @@ class _CovidDrivethruLocationState extends State { String projectLat = ""; String projectLong = ""; String projectName = ""; + String projectID = ""; @override void initState() { @@ -94,15 +97,16 @@ class _CovidDrivethruLocationState extends State { )), isLocationSelected ? Container( - margin: EdgeInsets.only(top: 15.0), - alignment: Alignment.centerLeft, - child: Text("Selected Location", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18.0, - letterSpacing: 0.8, - color: Colors.black)), - ) : Container(), + margin: EdgeInsets.only(top: 15.0), + alignment: Alignment.centerLeft, + child: Text("Selected Location", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + letterSpacing: 0.8, + color: Colors.black)), + ) + : Container(), isLocationSelected ? Container( margin: EdgeInsets.only(top: 5.0), @@ -212,15 +216,22 @@ class _CovidDrivethruLocationState extends State { } getDirections() { - if(isLocationSelected) { - MapsLauncher.launchCoordinates(double.parse(projectLat),double.parse(projectLong), this.projectName); + if (isLocationSelected) { + MapsLauncher.launchCoordinates(double.parse(projectLat), + double.parse(projectLong), this.projectName); } else { - Utils.showErrorToast("Please select address from the dropdown menu to get directions"); + Utils.showErrorToast( + "Please select address from the dropdown menu to get directions"); } } next() { - + if (isLocationSelected) { + getPaymentInfo(context, projectID); + } else { + Utils.showErrorToast( + "Please select address from the dropdown menu to continue"); + } } back() { @@ -229,21 +240,57 @@ class _CovidDrivethruLocationState extends State { setProjectLocation(newValue) { print(newValue); - print(projectsList[(int.parse(newValue) - 1)].projectName); setState(() { this.projectLat = projectsList[(int.parse(newValue) - 1)].latitude.toString(); this.projectLong = projectsList[(int.parse(newValue) - 1)].longitude.toString(); this.projectName = projectsList[(int.parse(newValue) - 1)].projectName; + this.projectID = + projectsList[(int.parse(newValue) - 1)].projectID.toString(); isLocationSelected = true; }); } + getPaymentInfo(BuildContext context, String projectID) { + CovidDriveThruService service = new CovidDriveThruService(); + + CovidPaymentInfoResponse covidPaymentInfoResponse = + new CovidPaymentInfoResponse(); + + service + .getCovidPaymentInformation(context, int.parse(projectID)) + .then((res) { + if (res['MessageStatus'] == 1) { + setState(() { + covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson( + res['COVID19_PatientShare']); + print(covidPaymentInfoResponse.procedureNameField); + }); + } else {} + }) + .catchError((err) { + print(err); + }) + .showProgressBar( + text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) + .then((value) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CovidPaymentDetails( + covidPaymentInfoResponse: covidPaymentInfoResponse, + projectID: int.parse(projectID), + ))); + }); + } + getProjectsList(BuildContext context) { CovidDriveThruService service = new CovidDriveThruService(); service.getCovidProjectsList(context).then((res) { + print(res); if (res['MessageStatus'] == 1) { + print(res); setState(() { res['List_COVID19_ProjectDriveThroughTestingCenter'].forEach((v) { projectsList.add(new DriveThroughTestingCenterModel.fromJson(v)); diff --git a/lib/pages/Covid-DriveThru/covid-payment-alert.dart b/lib/pages/Covid-DriveThru/covid-payment-alert.dart new file mode 100644 index 00000000..ac5f45fc --- /dev/null +++ b/lib/pages/Covid-DriveThru/covid-payment-alert.dart @@ -0,0 +1,288 @@ +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class CovidPaymentAlert extends StatefulWidget { + PatientShareResponse patientShareResponse; + + CovidPaymentAlert({@required this.patientShareResponse}); + + @override + _CovidPaymentAlertState createState() => _CovidPaymentAlertState(); +} + +class _CovidPaymentAlertState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "COVID-19 TEST", + isShowAppBar: true, + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 200.0, + color: new Color(0xFFc5272d), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 50.0), + child: SvgPicture.asset( + 'assets/images/new-design/alert_icon.svg', + width: 80.0, + height: 80.0), + ), + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.only(left: 30.0, right: 20.0), + child: Text("Alert", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 24.0)), + ), + Container( + width: MediaQuery.of(context).size.width * 0.55, + margin: EdgeInsets.only( + left: 30.0, right: 20.0, top: 5.0), + child: Text( + "Pay With-in 15 mins to confirm the appointment", + overflow: TextOverflow.clip, + style: TextStyle( + color: Colors.white, fontSize: 20.0)), + ), + ], + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(left: 20.0, right: 20.0, top: 30.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + alignment: Alignment.center, + child: Text("Pay With-in 15 mins", + overflow: TextOverflow.clip, + style: TextStyle( + color: new Color(0xFFc5272d), + fontSize: 24.0, + fontWeight: FontWeight.bold)), + ), + Container( + alignment: Alignment.center, + margin: EdgeInsets.only(top: 15.0), + child: Text( + "Payment for Covid-19 Test should Be made with-in 15 mins otherwise The system will Cancel the Scheduled appointment automatically​.", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.grey[700], + fontSize: 18.0, + letterSpacing: 0.8)), + ), + Container( + margin: EdgeInsets.only( + top: 40.0, bottom: 10.0, left: 0.0, right: 20.0), + child: Text(TranslationBase.of(context).appoInfo, + style: TextStyle( + fontSize: 18.0, + color: Colors.grey[700], + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(left: 0.0, bottom: 20.0), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.grey[200], + boxShadow: [ + BoxShadow(color: Colors.grey, spreadRadius: 2), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only( + top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text("COVID-19 TEST", + style: TextStyle( + fontSize: 18.0, + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 20.0, right: 20.0), + child: Icon( + Icons.local_hospital, + size: 24, + color: Colors.grey[700], + )), + Container( + child: Text( + widget.patientShareResponse.projectName != + null + ? widget.patientShareResponse.projectName + : "NULL", + style: TextStyle( + fontSize: 18.0, color: Colors.grey[700])), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 20.0, right: 20.0), + child: Icon( + Icons.date_range, + size: 24, + color: Colors.grey[700], + )), + Container( + child: Text( + widget.patientShareResponse.appointmentDate != + null + ? getDate(widget.patientShareResponse + .appointmentDate) + .split(" ")[0] + : "NULL", + style: TextStyle( + fontSize: 18.0, color: Colors.grey[700])), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 20.0, right: 20.0), + child: Icon( + Icons.access_time, + size: 24, + color: Colors.grey[700], + )), + Container( + child: Text( + widget.patientShareResponse.appointmentDate != + null + ? getDate(widget.patientShareResponse + .appointmentDate) + .split(" ")[1] + : "NULL", + style: TextStyle( + fontSize: 18.0, color: Colors.grey[700])), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 20.0, right: 20.0), + child: SvgPicture.asset( + "assets/images/new-design/track_icon.svg", + width: 20.0, + height: 20.0)), + Container( + child: Text( + widget.patientShareResponse.doctorNameObj != + null + ? widget + .patientShareResponse.doctorNameObj + : "NULL", + style: TextStyle( + fontSize: 18.0, color: Colors.grey[700])), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + bottomSheet: Container( + margin: EdgeInsets.all(10.0), + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: () { +// bookCovidTestAppointment(); + }, + child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + ], + ), + ), + ); + } + + String getDate(String appoDate) { + var appoDateFormatted = ""; + + var dateObj = DateUtil.convertStringToDate(appoDate); + + setState(() { + appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString() + + " " + + dateObj.hour.toString() + + ":" + + dateObj.minute.toString() + + ":00"; + }); + return appoDateFormatted; + } +} diff --git a/lib/pages/Covid-DriveThru/covid-payment-details.dart b/lib/pages/Covid-DriveThru/covid-payment-details.dart new file mode 100644 index 00000000..1254997d --- /dev/null +++ b/lib/pages/Covid-DriveThru/covid-payment-details.dart @@ -0,0 +1,257 @@ +import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/Covid-TimeSlots.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/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class CovidPaymentDetails extends StatefulWidget { + CovidPaymentInfoResponse covidPaymentInfoResponse; + int projectID; + + CovidPaymentDetails( + {@required this.covidPaymentInfoResponse, @required this.projectID}); + + @override + _CovidPaymentDetailsState createState() => _CovidPaymentDetailsState(); +} + +class _CovidPaymentDetailsState extends State { + bool isAgree = false; + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "COVID-19 TEST", + isShowAppBar: true, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 150.0, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "assets/images/new-design/covid-19-big-banner-bg.png"), + fit: BoxFit.fill, + ), + color: Colors.white.withOpacity(0.3), + borderRadius: BorderRadius.all(Radius.circular(10))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: + EdgeInsets.only(left: 15.0, right: 15.0, top: 30.0), + child: SvgPicture.asset( + 'assets/images/new-design/covid-19-car.svg', + width: 90.0, + height: 90.0), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only( + left: 20.0, right: 20.0, top: 40.0), + child: Text("COVID-19 TEST", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 24.0)), + ), + Container( + margin: EdgeInsets.only( + left: 20.0, right: 20.0, top: 10.0), + child: Text("Drive-Thru", + style: TextStyle( + color: Colors.white, fontSize: 24.0)), + ), + ], + ), + ], + ), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white), + margin: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 5.0), + padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), + child: Column( + children: [ + Container( + alignment: Alignment.center, + margin: + EdgeInsets.only(left: 0.0, right: 20.0, top: 30.0), + child: Text("Test Fees", + style: TextStyle( + color: Colors.black, + fontSize: 22.0, + fontWeight: FontWeight.bold)), + ), + Table( + children: [ + TableRow(children: [ + TableCell( + child: _getNormalText(TranslationBase.of(context) + .patientShareToDo)), + TableCell( + child: _getNormalText(widget + .covidPaymentInfoResponse.patientShareField + .toString())), + ]), + TableRow(children: [ + TableCell( + child: _getNormalText( + TranslationBase.of(context).patientTaxToDo)), + TableCell( + child: _getNormalText(widget + .covidPaymentInfoResponse + .patientTaxAmountField + .toString())), + ]), + TableRow(children: [ + TableCell( + child: _getNormalText(TranslationBase.of(context) + .patientShareTotalToDo)), + TableCell( + child: _getNormalText(widget + .covidPaymentInfoResponse + .patientShareWithTaxField + .toString())), + ]), + ], + ), + ], + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Checkbox( + value: isAgree, + onChanged: (value) { + setState(() { + isAgree = !isAgree; + }); + }, + activeColor: Colors.blue, + ), + Texts(TranslationBase.of(context) + .iAgreeToTheTermsAndConditions), + ], + ), + ), + Divider( + color: Colors.grey, + ), + Container( + alignment: Alignment.center, + margin: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 5.0), + child: Text("You can pay by following options: ", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + fontFamily: "Open-Sans")), + ), + Container( + alignment: Alignment.center, + margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 5.0), + child: Image.asset( + "assets/images/new-design/payment_options_invoice_confirmation.png", + width: 300), + ), + ], + ), + ), + ), + bottomSheet: Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 20.0), + child: Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: () { + cancel(); + }, + child: Text("CANCEL", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + margin: EdgeInsets.fromLTRB(10.0, 0.0, 5.0, 0.0), + child: ButtonTheme( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + minWidth: MediaQuery.of(context).size.width * 0.7, + height: 45.0, + child: RaisedButton( + color: new Color(0xFF60686b), + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: Colors.grey[500], + onPressed: isAgree ? next : null, + child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + ), + ), + ), + ), + ], + ), + ), + ); + } + + void next() { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CovidTimeSlots( + projectID: widget.projectID, + ))); + } + + cancel() { + Navigator.pop(context); + } + + _getNormalText(text) { + return Container( + margin: EdgeInsets.only(top: 20.0, right: 10.0), + child: Text(text, + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 15, + fontFamily: 'Open-Sans', + letterSpacing: 0.5, + color: Colors.grey[700])), + ); + } +} diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 796794b2..7c20b53d 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -107,7 +107,7 @@ class _ToDoState extends State { .liveCareAppo, style: TextStyle(fontSize: 12.0)) : Text(widget.appoList[index].projectName != null ? widget.appoList[index].projectName : "-", - style: TextStyle(fontSize: 12.0)), + style: TextStyle(fontSize: 11.0)), ), ], ), diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index d427c2f1..79671682 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -94,11 +94,11 @@ class _HomePageState extends State { children: [ Container( margin: EdgeInsets.only( - top: 15.0), + top: 15.0, left: 3.5, right: 3.5), child: SvgPicture.asset( 'assets/images/new-design/covid-19-car.svg', - width: 50.0, - height: 50.0), + width: 45.0, + height: 45.0), ), Container( margin: EdgeInsets.only( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index a545f8a7..0c6a2144 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -29,9 +29,6 @@ import 'package:rxdart/rxdart.dart'; import 'home_page.dart'; - - - class LandingPage extends StatefulWidget { static bool isOpenCallPage = false; diff --git a/lib/services/covid-drivethru/covid-drivethru.dart b/lib/services/covid-drivethru/covid-drivethru.dart index a9ebbecd..2681783b 100644 --- a/lib/services/covid-drivethru/covid-drivethru.dart +++ b/lib/services/covid-drivethru/covid-drivethru.dart @@ -49,4 +49,78 @@ class CovidDriveThruService extends BaseService { }, body: request); return Future.value(localRes); } + + Future getCovidPaymentInformation(BuildContext context, int projectID) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "ProjectID": projectID, + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "TokenID": "", + "DeviceTypeID": req.DeviceTypeID, + "SessionID": "YckwoXhUmWBsnHKEKig", + "PatientID": authUser.patientID != null ? authUser.patientID : 0, + "License": true + }; + + dynamic localRes; + + await baseAppClient.post(GET_COVID_DRIVETHRU_PAYMENT_INFO, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future getCovidFreeSlots(BuildContext context, int projectID) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + + var languageID = await sharedPref.getString(APP_LANGUAGE); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "ProjectID": projectID, + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "TokenID": "", + "DeviceTypeID": req.DeviceTypeID, + "SessionID": "YckwoXhUmWBsnHKEKig", + "PatientID": authUser.patientID != null ? authUser.patientID : 0, + "License": true + }; + + dynamic localRes; + + await baseAppClient.post(GET_COVID_DRIVETHRU_FREE_SLOTS, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } } From a8ee7db62b038f5895cace43ac58edc84410a2ec Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 11 Oct 2020 13:20:22 +0300 Subject: [PATCH 6/7] fixes # Conflicts: # lib/config/config.dart --- lib/config/config.dart | 9 ++++++++- .../AlHabibMedicalService/​ health_calculators.dart | 4 ++-- lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 96804aeb..0f92db66 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -258,6 +258,14 @@ const GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER = 'Services/Patients.svc/REST/AP_ const SEND_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/SendActivationCodeForAdvancePayment'; const CHECK_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/CheckActivationCodeForAdvancePayment'; + +const GET_COVID_DRIVETHRU_PROJECT_LIST = 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; + +const GET_COVID_DRIVETHRU_PAYMENT_INFO = 'Services/Doctors.svc/REST/COVID19_GetPatientPaymentInormation'; + +const GET_COVID_DRIVETHRU_FREE_SLOTS = 'Services/Doctors.svc/REST/COVID19_GetFreeSlots'; + + ///My Trackers const GET_DIABETIC_RESULT_AVERAGE='Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; const GET_DIABTEC_RESULT='Services/Patients.svc/REST/Patient_GetDiabtecResults'; @@ -304,7 +312,6 @@ const GET_ALL_CITIES = 'services/Lists.svc/rest/GetAllCities'; const CREATE_E_REFERRAL = "Services/Patients.svc/REST/CreateEReferral"; const GET_E_REFERRALS = "Services/Patients.svc/REST/GetEReferrals"; -const GET_COVID_DRIVETHRU_PROJECT_LIST = 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; const TIMER_MIN = 10; diff --git a/lib/pages/AlHabibMedicalService/​ health_calculators.dart b/lib/pages/AlHabibMedicalService/​ health_calculators.dart index 56fb0428..97141716 100644 --- a/lib/pages/AlHabibMedicalService/​ health_calculators.dart +++ b/lib/pages/AlHabibMedicalService/​ health_calculators.dart @@ -1,5 +1,3 @@ -import 'file:///C:/Users/admin/AndroidStudioProjects/diplomatic-quarter/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart'; -import 'file:///C:/Users/admin/AndroidStudioProjects/diplomatic-quarter/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; @@ -8,7 +6,9 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'health_calculator/bmi_calculator/bmi_calculator.dart'; import 'health_calculator/bmr_calculator/bmr_calculator.dart'; +import 'health_calculator/calorie_calculator/calorie_calculator.dart'; import 'health_calculator/ideal_body/ideal_body.dart'; class HealthCalculators extends StatefulWidget { diff --git a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart index 2113d2b5..8e9fe806 100644 --- a/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart +++ b/lib/pages/ContactUs/LiveChat/hospitalsLivechat_page.dart @@ -140,7 +140,6 @@ class _HospitalsLiveChatPageState extends State { icon: Icon( Icons .arrow_forward_ios, - .arrow_forward, color: tappedIndex == index ? Colors.white From a31796322bf8363ff14339da69487445289d9bc9 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 13 Oct 2020 11:28:14 +0300 Subject: [PATCH 7/7] fix icons issue --- .../health_calculator/delivery_due/delivery_due.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart index 1e8cb50c..c9993b95 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart @@ -96,7 +96,7 @@ class _DeliveryDueState extends State { children: [ Row( children: [ - Icon(Icons.date_range_rounded), + Icon(Icons.date_range), Texts('Date'), ], ),