From d974a7430c76e21b97a2810fdc27d4f18247996a Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Mon, 31 Jan 2022 15:00:18 +0300 Subject: [PATCH] Google Analytics as per e-Cense document --- lib/analytics/flows/advance_payments.dart | 82 +++++++ lib/analytics/flows/app_nav.dart | 13 + lib/analytics/flows/appointments.dart | 222 ++++++++++++++++++ lib/analytics/flows/error_tracking.dart | 8 + lib/analytics/flows/hamburger_menu.dart | 15 ++ lib/analytics/flows/hmg_services.dart | 13 + lib/analytics/flows/live_care.dart | 101 ++++++++ lib/analytics/flows/login_registration.dart | 103 ++++++++ lib/analytics/flows/offers_promotions.dart | 9 + lib/analytics/flows/todo_list.dart | 119 ++++++++++ lib/analytics/google-analytics.dart | 57 ++++- lib/core/viewModels/project_view_model.dart | 5 + lib/locator.dart | 7 + lib/models/Clinics/ClinicListResponse.dart | 2 +- lib/pages/BookAppointment/BookConfirm.dart | 12 + lib/pages/BookAppointment/BookSuccess.dart | 8 + lib/pages/BookAppointment/DoctorProfile.dart | 8 + lib/pages/BookAppointment/QRCode.dart | 5 + lib/pages/BookAppointment/Search.dart | 7 +- lib/pages/BookAppointment/SearchResults.dart | 12 +- .../BookAppointment/book_reminder_page.dart | 6 + .../components/DocAvailableAppointments.dart | 9 + .../components/SearchByClinic.dart | 2 + .../components/SearchByDoctor.dart | 5 + .../BookAppointment/widgets/DoctorView.dart | 4 +- .../widgets/reminder_dialog.dart | 9 + .../MyAppointments/AppointmentDetails.dart | 3 + lib/pages/MyAppointments/SchedulePage.dart | 2 + lib/pages/ToDoList/ToDo.dart | 8 + lib/pages/ToDoList/widgets/paymentDialog.dart | 2 + .../fragments/home_page_fragment2.dart | 1 + lib/pages/landing/landing_page.dart | 17 +- lib/pages/landing/widgets/services_view.dart | 24 ++ .../livecare/live_care_payment_page.dart | 1 + lib/pages/livecare/livecare_type_select.dart | 7 + lib/pages/livecare/widgets/clinic_card.dart | 11 +- lib/pages/livecare/widgets/clinic_list.dart | 10 + lib/pages/login/register-info.dart | 19 +- lib/pages/login/register.dart | 12 +- lib/pages/login/welcome.dart | 4 + .../medical/balance/advance_payment_page.dart | 10 + .../medical/balance/confirm_payment_page.dart | 8 + .../medical/balance/my_balance_page.dart | 7 + lib/pages/paymentService/payment_service.dart | 3 + lib/widgets/drawer/app_drawer_widget.dart | 26 +- lib/widgets/nfc/nfc_reader_sheet.dart | 7 +- 46 files changed, 997 insertions(+), 28 deletions(-) create mode 100644 lib/analytics/flows/advance_payments.dart create mode 100644 lib/analytics/flows/app_nav.dart create mode 100644 lib/analytics/flows/appointments.dart create mode 100644 lib/analytics/flows/error_tracking.dart create mode 100644 lib/analytics/flows/hamburger_menu.dart create mode 100644 lib/analytics/flows/hmg_services.dart create mode 100644 lib/analytics/flows/live_care.dart create mode 100644 lib/analytics/flows/login_registration.dart create mode 100644 lib/analytics/flows/offers_promotions.dart create mode 100644 lib/analytics/flows/todo_list.dart diff --git a/lib/analytics/flows/advance_payments.dart b/lib/analytics/flows/advance_payments.dart new file mode 100644 index 00000000..db52eb59 --- /dev/null +++ b/lib/analytics/flows/advance_payments.dart @@ -0,0 +1,82 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class AdvancePayments{ + + final GALogger logger; + AdvancePayments(this.logger); + + // R038 + payment_services({@required String service_type}){ + logger('payment_services', parameters: { + 'service_type' : service_type + }); + } + + // R039 + wallet_recharge({@required String service_type}){ + logger('wallet_recharge', parameters: { + 'service_type' : service_type + }); + } + + // R040 + wallet_payment_details(){ + logger('wallet_payment_details'); + } + + // R041 + payment_method({@required String method,type}){ + logger('payment_method', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R042 + payment_confirm({@required String method,type}){ + logger('payment_confirm', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R043 + payment_otp_confirmation({@required String method,type}){ + logger('payment_otp_confirmation', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R044 + payment_confirm_card_details({@required String method,type}){ + logger('payment_confirm_card_details', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R045 + payment_pay({@required String method,type}){ + logger('payment_pay', parameters: { + 'payment_method' : method, + 'payment_type' : type + }); + } + + // R046 + payment_success({@required String appointment_type, clinic, hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}){ + logger('payment_success', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type, + 'hospital_name' : hospital, + 'transaction_number' : txn_number, + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/app_nav.dart b/lib/analytics/flows/app_nav.dart new file mode 100644 index 00000000..12601fcd --- /dev/null +++ b/lib/analytics/flows/app_nav.dart @@ -0,0 +1,13 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; + +class AppNav{ + final name = 'app_nav'; + final GALogger logger; + AppNav(this.logger); + + logNavName(String value){ + logger(name, parameters: { + 'nav_name' : value + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/appointments.dart b/lib/analytics/flows/appointments.dart new file mode 100644 index 00000000..bd69769d --- /dev/null +++ b/lib/analytics/flows/appointments.dart @@ -0,0 +1,222 @@ +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../google-analytics.dart'; + +class Appointment{ + + final GALogger logger; + Appointment(this.logger); + + // R015 + book_appointment(){ + logger('book_appointment'); + } + + // R016.1, R017.2 + book_appointment_by_clinic(){ + logger('book_appointment_by_clinic'); + } + + // R016.2, R018.2 + book_appointment_by_doctor(){ + logger('book_appointment_by_doctor'); + } + + // R017.1 + book_appointment_doctor_search({@required String query}){ + // doctor_search_query : value + logger('book_appointment_doctor_search', parameters: { + 'doctor_search_query' : query + }); + } + + // R018.1 + book_appointment_select_clinic({@required String appointment_type, clinic}){ + // appointment_type: regular | livecare + // clinic_type : $clinic_type + logger('book_appointment_select_clinic', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : clinic + }); + } + + // R019.1 + book_appointment_livecare_accept(){ + logger('book_appointment_livecare_accept'); + } + + // R019.2 + book_appointment_livecare_decline(){ + logger('book_appointment_livecare_decline'); + } + + // R020 + book_appointment_chief_complaints({@required String appointment_type, clinic, hospital, treatment}){ + logger('book_appointment_chief_complaints', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : clinic, + 'hospital_name' : hospital, + 'treatment_type' : treatment, + }); + } + + // R021 + book_appointment_select_doctor({@required String appointment_type, @required DoctorList doctor}){ + // appointment_type, clinic_type, hospital_name, treatment_type, doctor_name, doctor_nationality, doctor_gender + logger('book_appointment_select_doctor', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + }); + } + + // R022 + book_appointment_schedule({@required String appointment_type, @required DoctorList doctor}){ + // appointment_type, clinic_type, hospital_name, treatment_type, doctor_name, doctor_nationality, doctor_gender + logger('book_appointment_schedule', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + }); + } + + // R023 + book_appointment_date_selection({@required String appointment_type, @required day, @required DoctorList doctor}){ + logger('book_appointment_date_selection', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + 'appointment_day' : day + }); + } + + // R024.1 + book_appointment_time_selection({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){ + final day = DateUtil.getWeekDay(dateTime.weekday); + final time = DateUtil.formatDateToTime(dateTime); + logger('book_appointment_time_selection', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + 'appointment_day' : day, + 'appointment_hour' : time + }); + } + + // R024.2 + book_appointment_review({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){ + final day = DateUtil.getWeekDay(dateTime.weekday); + final time = DateUtil.formatDateToTime(dateTime); + logger('book_appointment_review', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + 'appointment_day' : day, + 'appointment_hour' : time + }); + } + + // R025 + book_appointment_click_confirm({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){ + final day = DateUtil.getWeekDay(dateTime.weekday); + final time = DateUtil.formatDateToTime(dateTime); + logger('book_appointment_click_confirm', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + 'appointment_day' : day, + 'appointment_hour' : time + }); + } + + // R026 + book_appointment_confirmation_success({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){ + final day = DateUtil.getWeekDay(dateTime.weekday); + final time = DateUtil.formatDateToTime(dateTime); + logger('book_appointment_confirmation_success', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctor.clinicName, + 'hospital_name' : doctor.projectName, + 'treatment_type' : doctor.clinicName, + 'doctor_name' : doctor.name, + 'doctor_nationality' : doctor.nationalityName, + 'doctor_gender' : doctor.gender, + 'appointment_day' : day, + 'appointment_hour' : time + }); + } + + // R027 + appointment_reminder(bool value){ + logger('appointment_reminder', parameters: { + 'reminder' : value ? 'yes' : 'no' + }); + } + + // R028 + appointment_reminder_time({@required String reminde_before}){ + logger('appointment_reminder_time', parameters: { + 'reminder_before' : reminde_before + }); + } + + // R053 + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + pay_now_for_appointment({@required String appointment_type, @required DoctorList doctorDetail, bool payNow = true}){ + logger('pay_now_for_appointment', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type' : doctorDetail.clinicName, + 'hospital_name' : doctorDetail.projectName, + 'doctor_name' : doctorDetail.name, + 'payment_type' : 'appointment' + }); + } + + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_detail_action({@required AppoitmentAllHistoryResultList appointment, @required String action}){ + logger('appointment_detail_action', parameters: { + }); + } + + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_details_confirm({@required AppoitmentAllHistoryResultList appointment}){ + logger('appointment_details_confirm', parameters: { + }); + } + + // R053 + // Note : - Payment flow beyond this step are same as listed under ‘Advance Payment’ section of this document + appointment_details_cancel({@required AppoitmentAllHistoryResultList appointment}){ + logger('appointment_details_cancel', parameters: { + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/error_tracking.dart b/lib/analytics/flows/error_tracking.dart new file mode 100644 index 00000000..1ceb2ab9 --- /dev/null +++ b/lib/analytics/flows/error_tracking.dart @@ -0,0 +1,8 @@ +import '../google-analytics.dart'; + +class ErrorTracking{ + + final GALogger logger; + ErrorTracking(this.logger); + +} \ No newline at end of file diff --git a/lib/analytics/flows/hamburger_menu.dart b/lib/analytics/flows/hamburger_menu.dart new file mode 100644 index 00000000..404cdbcf --- /dev/null +++ b/lib/analytics/flows/hamburger_menu.dart @@ -0,0 +1,15 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; + +class HamburgerMenu{ + final hamburger_menu = 'hamburger_menu'; + + final GALogger logger; + HamburgerMenu(this.logger); + + logMenuItemClick(String value){ + logger(hamburger_menu, parameters: { + 'menu_item' : value + }); + } + +} \ No newline at end of file diff --git a/lib/analytics/flows/hmg_services.dart b/lib/analytics/flows/hmg_services.dart new file mode 100644 index 00000000..357f81ab --- /dev/null +++ b/lib/analytics/flows/hmg_services.dart @@ -0,0 +1,13 @@ +import '../google-analytics.dart'; + +class HMGServices{ + final hmg_services = 'hmg_services'; + + final GALogger logger; + HMGServices(this.logger); + logServiceName(String value){ + logger('hmg_services', parameters: { + 'services_name' : value + }); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/live_care.dart b/lib/analytics/flows/live_care.dart new file mode 100644 index 00000000..fd7d03d4 --- /dev/null +++ b/lib/analytics/flows/live_care.dart @@ -0,0 +1,101 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class LiveCare{ + + final GALogger logger; + LiveCare(this.logger); + + // R030.1 + livecare_immediate_consultation(){ + logger('livecare_immediate_consultation'); + } + + // R030.2 + livecare_schedule_video_call(){ + logger('livecare_schedule_video_call'); + } + + // R031.1 + livecare_clinic_schedule({@required String clinic}){ + logger('livecare_clinic_schedule', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R031.2 + livecare_immediate_consultation_clinic({@required String clinic}){ + logger('livecare_immediate_consultation_clinic', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R031.2 + livecare_schedule_video_call_clinic({@required String clinic}){ + logger('livecare_schedule_video_call_clinic', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R032 + livecare_immediate_consultation_TnC({@required String clinic}){ + logger('livecare_immediate_consultation_TnC', parameters: { + 'clinic_type_online' : clinic + }); + } + + // R033 + payment_method({@required String appointment_type, clinic, payment_method, payment_type}){ + logger('payment_method', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type + }); + } + + // R034 + payment_confirm({@required String appointment_type, clinic, payment_method, payment_type}){ + logger('payment_confirm', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type + }); + } + + // R035 + payment_pay({@required String appointment_type, clinic, hospital, payment_method, payment_type}){ + // logger('payment_pay', parameters: { + // 'appointment_type' : appointment_type, + // 'clinic_type_online' : clinic, + // 'payment_method' : payment_method, + // 'payment_type' : payment_type, + // 'hospital_name' : hospital + // }); + } + + // R036 + payment_success({@required String appointment_type, clinic, hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}){ + // appointment_type + // clinic_type_online + // payment_method + // payment_type + // hospital_name + // transaction_number + // transaction_amount + // transaction_currency + } + + // R037 + livecare_immediate_consultation_payment_failed({@required String appointment_type, clinic, hospital, payment_method, payment_type, error_code, error_message}){ + // appointment_type + // clinic_type_online + // payment_method + // payment_type + // hospital_name + // error_code + // error_message + } +} \ No newline at end of file diff --git a/lib/analytics/flows/login_registration.dart b/lib/analytics/flows/login_registration.dart new file mode 100644 index 00000000..cf123b62 --- /dev/null +++ b/lib/analytics/flows/login_registration.dart @@ -0,0 +1,103 @@ +import 'package:flutter/cupertino.dart'; + +import '../google-analytics.dart'; + +class LoginRegistration{ + + final GALogger logger; + LoginRegistration(this.logger); + // R004.1 + login_register_initiate(){ + logger('login_register_initiate'); + } + + // R005.1 + visited_alhabib_group(bool value){ + // selection_type: yes/no + logger('visited_alhabib_group', parameters: { + 'selection_type' : value ? 'yes' : 'no' + }); + } + + // R006.1, R007.1, R008.1, R009.1 + registration_cancel({@required String step}){ + // registration_step : enter details + // registration_step : personal info + // registration_step : patient info + // fourth (verification) + logger('registration_cancel', parameters: { + 'registration_step' : step + }); + } + + // R006.2 + registration_enter_details(){ + logger('registration_enter_details'); + } + + // R007.2 + registration_personal_info(){ + logger('registration_personal_info'); + } + + // R008.2 + registration_patient_info(){ + logger('registration_patient_info'); + } + + // R009.2 + registration_verification_option(){ + logger('registration_verification_option'); + } + + // R010 + registration_confirmation({@required String by}){ + // verification_method: by + logger('registration_confirmation', parameters: { + 'verification_method' : by + }); + } + + // R011.1 + login_start({@required String method}){ + logger('login_start', parameters: { + 'login_method' : method + }); + } + + // R011.2 + forget_file_number(){ + logger('forget_file_number'); + } + + // R011.3 + register_now({@required String method}){ + logger('register_now', parameters: { + 'login_method' : method + }); + } + + // R012.1, R014.1 + login_successful({@required String method}){ + logger('login_successful', parameters: { + 'login_method' : method + }); + } + + // R012.4 + login_unsuccessful({@required String method, error}){ + logger('login_unsuccessful', parameters: { + 'login_method' : method + }); + } + + // R013 + recover_file_number(){ + logger('recover_file_number'); + } + + // R014.2 + login_with_other_account(){ + logger('login_with_other_account'); + } +} \ No newline at end of file diff --git a/lib/analytics/flows/offers_promotions.dart b/lib/analytics/flows/offers_promotions.dart new file mode 100644 index 00000000..eea90b15 --- /dev/null +++ b/lib/analytics/flows/offers_promotions.dart @@ -0,0 +1,9 @@ +import '../google-analytics.dart'; + +class OfferAndPromotion{ + + final GALogger logger; + OfferAndPromotion(this.logger); + + final offers_and_promotion = 'offers_&_promotion'; +} \ No newline at end of file diff --git a/lib/analytics/flows/todo_list.dart b/lib/analytics/flows/todo_list.dart new file mode 100644 index 00000000..bfcde052 --- /dev/null +++ b/lib/analytics/flows/todo_list.dart @@ -0,0 +1,119 @@ +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; + +import '../google-analytics.dart'; + +class TodoList{ + + final GALogger logger; + TodoList(this.logger); + + // R047.1 + to_do_list_pay_now(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_pay_now', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R047.2 + to_do_list_more_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_more_details', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R048 + to_do_list_confirm_payment_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_confirm_payment_details', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R048 + to_do_list_cancel_payment_details(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_cancel_payment_details', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R049.1 // should be for appointment flow + // to_do_list_appointment_actions(AppoitmentAllHistoryResultList appointment, action){ + // logger('to_do_list_pay_now', parameters: { + // 'appointment_type' : appointment.appointmentType, + // 'clinic_type_online' : appointment.clinicName, + // 'hospital_name' : appointment.projectName, + // 'doctor_name' : appointment.doctorName, + // 'payment_type' : appointment.patientType, + // }); + // } + + // R049.2 + to_do_list_cancel_appointment(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_cancel_appointment', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R049.3 + to_do_list_confirm_appointment(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_confirm_appointment', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R050 + to_do_list_check_in(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_check_in', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R051 + to_do_list_nfc(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_nfc', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } + + // R052 + to_do_list_nfc_cancel(AppoitmentAllHistoryResultList appointment){ + logger('to_do_list_nfc_cancel', parameters: { + 'appointment_type' : appointment.appointmentType, + 'clinic_type_online' : appointment.clinicName, + 'hospital_name' : appointment.projectName, + 'doctor_name' : appointment.doctorName, + 'payment_type' : appointment.patientType, + }); + } +} \ No newline at end of file diff --git a/lib/analytics/google-analytics.dart b/lib/analytics/google-analytics.dart index 0ded8cc6..c88055a6 100644 --- a/lib/analytics/google-analytics.dart +++ b/lib/analytics/google-analytics.dart @@ -1,4 +1,13 @@ import 'package:diplomaticquarterapp/analytics/analytic-events.dart'; +import 'package:diplomaticquarterapp/analytics/flows/advance_payments.dart'; +import 'package:diplomaticquarterapp/analytics/flows/appointments.dart'; +import 'package:diplomaticquarterapp/analytics/flows/error_tracking.dart'; +import 'package:diplomaticquarterapp/analytics/flows/hamburger_menu.dart'; +import 'package:diplomaticquarterapp/analytics/flows/live_care.dart'; +import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart'; +import 'package:diplomaticquarterapp/analytics/flows/offers_promotions.dart'; +import 'package:diplomaticquarterapp/analytics/flows/todo_list.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; @@ -6,29 +15,61 @@ import 'package:firebase_analytics/observer.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -class Singleton { - const Singleton(); //Constant constructor +import 'flows/app_nav.dart'; +import 'flows/hmg_services.dart'; - void hello() { - print('Hello world'); + +typedef GALogger = Function(String name, {Map parameters}); + +var _analytics = FirebaseAnalytics(); +_logger(String name, {Map parameters}) async { + if (name != null && name.isNotEmpty) { + if(name.contains(' ')) + name = name.replaceAll(' ','_'); + + _analytics + .logEvent(name: name.trim(), parameters: parameters) + .then((value) { + debugPrint('SUCCESS: Google analytics event "$name" sent'); + }).catchError((error) { + debugPrint('ERROR: Google analytics event "$name" sent failed'); + }); } } -var analytics = FirebaseAnalytics(); class GAnalytics { - const GAnalytics(); - static GAnalytics shared = const GAnalytics(); + setUser(AuthenticatedUser user){ + if(user != null){ + _analytics.setUserProperty(name: 'user_country', value: user.iSOCountryID); + _analytics.setUserProperty(name: 'user_language', value: user.preferredLanguage); + _analytics.setUserProperty(name: 'userid', value: user.patientID.toString() ); + _analytics.setUserProperty(name: 'login_status', value: 'yes'); + } + } + NavObserver navObserver() => NavObserver(); + final hamburgerMenu = HamburgerMenu(_logger); + final bottomTabNavigation = AppNav(_logger); + final hmgServices = HMGServices(_logger); + final loginRegistration = LoginRegistration(_logger); + final appointment = Appointment(_logger); + final liveCare = LiveCare(_logger); + final todoList = TodoList(_logger); + final advancePayments = AdvancePayments(_logger); + final offerPackages = OfferAndPromotion(_logger); + final errorTracking = ErrorTracking(_logger); } + + // adb shell setprop debug.firebase.analytics.app com.ejada.hmg -> Android class NavObserver extends RouteObserver> { _sendScreenView(PageRoute route) async { log(String className) { var event = AnalyticEvents.get(className); if (event.active != null) { - analytics + _analytics .setCurrentScreen( screenName: event.flutterName(), screenClassOverride: className) .catchError( diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index ab2f931b..78ed83b4 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -1,9 +1,11 @@ import 'dart:async'; import 'package:connectivity/connectivity.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; @@ -11,6 +13,9 @@ import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; var isAppArabic = false; class ProjectViewModel extends BaseViewModel { + + GAnalytics get analytics => locator(); + // Platform Bridge PlatformBridge platformBridge() { return PlatformBridge.shared(); diff --git a/lib/locator.dart b/lib/locator.dart index c0a8bd51..df0561fd 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -24,6 +24,7 @@ import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:get_it/get_it.dart'; +import 'analytics/google-analytics.dart'; import 'core/service/AlHabibMedicalService/cmc_service.dart'; import 'core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'core/service/AlHabibMedicalService/e_referral_service.dart'; @@ -325,4 +326,10 @@ void setupLocator() { () => GeofencingServices()); // Geofencing Services locator.registerFactory(() => TermsConditionsViewModel()); locator.registerFactory(() => AnciallryOrdersViewModel()); + + + // Google/Firebase Analytics + // --------------------------- + locator.registerFactory(() => GAnalytics()); + } diff --git a/lib/models/Clinics/ClinicListResponse.dart b/lib/models/Clinics/ClinicListResponse.dart index 1aa4065e..6aadabc0 100644 --- a/lib/models/Clinics/ClinicListResponse.dart +++ b/lib/models/Clinics/ClinicListResponse.dart @@ -1,7 +1,7 @@ class ListClinicCentralized { int clinicID; String clinicDescription; - Null clinicDescriptionN; + String clinicDescriptionN; int age; int gender; bool isLiveCareClinicAndOnline; diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 63e711e5..793ac4bf 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; @@ -26,6 +27,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'book_reminder_page.dart'; +import 'components/DocAvailableAppointments.dart'; class BookConfirm extends StatefulWidget { DoctorList doctor; @@ -47,6 +49,7 @@ class BookConfirm extends StatefulWidget { } class _BookConfirmState extends State { + ProjectViewModel projectViewModel; ToDoCountProviderModel toDoProvider; AppSharedPreferences sharedPref = new AppSharedPreferences(); @@ -63,6 +66,7 @@ class _BookConfirmState extends State { @override Widget build(BuildContext context) { toDoProvider = Provider.of(context); + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: widget.doctor.doctorTitle + " " + widget.doctor.name, isShowDecPage: false, @@ -265,10 +269,14 @@ class _BookConfirmState extends State { } insertAppointment(context, DoctorList docObject) { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'regular', dateTime: timeSlot, doctor: widget.doctor); + GifLoaderDialogUtils.showMyDialog(context); AppoitmentAllHistoryResultList appo; widget.service.insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, widget.selectedTime, widget.selectedDate, context).then((res) { if (res['MessageStatus'] == 1) { + projectViewModel.analytics.appointment.book_appointment_confirmation_success(appointment_type: 'regular', dateTime: timeSlot, doctor: widget.doctor); AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); print(res['AppointmentNo']); @@ -307,10 +315,14 @@ class _BookConfirmState extends State { } insertLiveCareScheduledAppointment(context, DoctorList docObject) { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'livecare', dateTime: timeSlot, doctor: widget.doctor); + GifLoaderDialogUtils.showMyDialog(context); AppoitmentAllHistoryResultList appo; widget.service.insertLiveCareScheduleAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, docObject.serviceID, widget.selectedTime, widget.selectedDate, context).then((res) { if (res['MessageStatus'] == 1) { + projectViewModel.analytics.appointment.book_appointment_confirmation_success(appointment_type: 'livecare', dateTime: timeSlot, doctor: widget.doctor); AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); print(res['AppointmentNo']); diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 04086ee3..15906851 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; @@ -20,6 +21,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:provider/provider.dart'; import 'QRCode.dart'; @@ -43,8 +45,11 @@ class _BookSuccessState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUser authUser; + ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: widget.docObject.doctorTitle + " " + widget.docObject.name, isShowDecPage: false, @@ -182,6 +187,7 @@ class _BookSuccessState extends State { disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), onPressed: () { + projectViewModel.analytics.appointment.pay_now_for_appointment(appointment_type: 'regular', doctorDetail: widget.docObject, payNow: true); startPaymentProcess(); }, child: Text(TranslationBase.of(context).payNow.toUpperCase(), style: TextStyle(fontSize: 18.0)), @@ -203,6 +209,7 @@ class _BookSuccessState extends State { disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), onPressed: () { + projectViewModel.analytics.appointment.pay_now_for_appointment(appointment_type: 'regular', doctorDetail: widget.docObject, payNow: false); navigateToHome(context); }, child: Text(TranslationBase.of(context).payLater.toUpperCase(), style: TextStyle(fontSize: 18.0)), @@ -388,6 +395,7 @@ class _BookSuccessState extends State { } confirmAppointment(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service.confirmAppointment(appo.appointmentNo, appo.clinicID, appo.projectID, appo.isLiveCareAppointment, context).then((res) { diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index 87941ed5..033d360b 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; @@ -20,6 +21,7 @@ import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; import 'BookConfirm.dart'; @@ -59,8 +61,11 @@ class _DoctorProfileState extends State with TickerProviderStateM super.initState(); } + ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: widget.doctor.doctorTitle + " " + widget.doctor.name, isShowAppBar: true, @@ -122,6 +127,7 @@ class _DoctorProfileState extends State with TickerProviderStateM showConfirmMessageDialog: false, isNeedToShowButton: !widget.isLiveCareAppointment, onTap: () { + projectViewModel.analytics.appointment.book_appointment_schedule(appointment_type: 'regular', doctor: widget.doctor); Navigator.push( context, FadePage( @@ -490,6 +496,8 @@ class _DoctorProfileState extends State with TickerProviderStateM void goToBookConfirm() async { if (DocAvailableAppointments.areSlotsAvailable) { if (await sharedPref.getObject(USER_PROFILE) != null) { + final timeSlot = DocAvailableAppointments.selectedAppoDateTime; + projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot, doctor: widget.doctor); navigateToBookConfirm(context); } else { ConfirmDialog dialog = new ConfirmDialog( diff --git a/lib/pages/BookAppointment/QRCode.dart b/lib/pages/BookAppointment/QRCode.dart index 5bf0a9f0..2f8b0875 100644 --- a/lib/pages/BookAppointment/QRCode.dart +++ b/lib/pages/BookAppointment/QRCode.dart @@ -2,6 +2,8 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -88,10 +90,13 @@ class _QRCodeState extends State { child: Image.asset("assets/images/nfc/ic_nfc.png"), ), onTap: () { + locator().analytics.todoList.to_do_list_nfc(); showNfcReader(context, onNcfScan: (String nfcId) { Future.delayed(const Duration(milliseconds: 100), () { sendNfcCheckInRequest(nfcId); }); + }, onCancel: (){ + locator().analytics.todoList.to_do_list_nfc_cancel(); }); }, ), diff --git a/lib/pages/BookAppointment/Search.dart b/lib/pages/BookAppointment/Search.dart index d4942ccf..e10e3258 100644 --- a/lib/pages/BookAppointment/Search.dart +++ b/lib/pages/BookAppointment/Search.dart @@ -26,7 +26,6 @@ class _SearchState extends State with TickerProviderStateMixin { @override void initState() { _tabController = new TabController(length: 2, vsync: this, initialIndex: widget.type); - super.initState(); } @@ -64,6 +63,12 @@ class _SearchState extends State with TickerProviderStateMixin { letterSpacing: -0.48, ), tabs: [Text(TranslationBase.of(context).clinicName), Text(TranslationBase.of(context).doctorName)], + onTap: (idx){ + if(idx == 0) + projectViewModel.analytics.appointment.book_appointment_by_clinic(); + else + projectViewModel.analytics.appointment.book_appointment_by_doctor(); + }, ), Expanded( child: TabBarView( diff --git a/lib/pages/BookAppointment/SearchResults.dart b/lib/pages/BookAppointment/SearchResults.dart index 0a654e22..ba35a0f3 100644 --- a/lib/pages/BookAppointment/SearchResults.dart +++ b/lib/pages/BookAppointment/SearchResults.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; @@ -6,6 +7,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class SearchResults extends StatefulWidget { List doctorsList = []; @@ -21,9 +23,11 @@ class SearchResults extends StatefulWidget { class _SearchResultsState extends State { // var event = RobotProvider(); List tempList = []; + ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).bookAppo, isShowDecPage: false, @@ -50,9 +54,13 @@ class _SearchResultsState extends State { padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), itemBuilder: (context, _index) { //widget.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList[_index].speciality = null; + final doctor = widget.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList[_index]; return DoctorView( - doctor: widget.patientDoctorAppointmentListHospital[index].patientDoctorAppointmentList[_index], - isLiveCareAppointment: widget.isLiveCareAppointment, + doctor: doctor, + isLiveCareAppointment: widget.isLiveCareAppointment, + onTap: (){ + projectViewModel.analytics.appointment.book_appointment_select_doctor(appointment_type: 'regular', doctor: doctor); + } ); }, separatorBuilder: (context, index) => SizedBox(height: 14), diff --git a/lib/pages/BookAppointment/book_reminder_page.dart b/lib/pages/BookAppointment/book_reminder_page.dart index 39f1648f..ddf741f1 100644 --- a/lib/pages/BookAppointment/book_reminder_page.dart +++ b/lib/pages/BookAppointment/book_reminder_page.dart @@ -1,4 +1,5 @@ import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/header_model.dart'; @@ -14,6 +15,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; import 'BookSuccess.dart'; @@ -52,8 +54,10 @@ class _BookReminderPageState extends State { }); } + ProjectViewModel projectViewModel; @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); // print("selectedTime "+selectedTime??""); print("appointmentNo1 " + widget.patientShareResponse.appointmentNo.toString() ?? ""); return AppScaffold( @@ -173,6 +177,7 @@ class _BookReminderPageState extends State { disabledTextColor: Colors.white, disabledColor: new Color(0xFFEAEAEA), onPressed: () { + projectViewModel.analytics.appointment.appointment_reminder(false); navigateToBookSuccess(context); }, child: Text(TranslationBase.of(context).no, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48)), @@ -194,6 +199,7 @@ class _BookReminderPageState extends State { disabledTextColor: Colors.white, disabledColor: CustomColors.green, onPressed: () async { + projectViewModel.analytics.appointment.appointment_reminder(true); print(widget.patientShareResponse.appointmentNo); showReminderDialog( context, diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index 3a6d9185..d37ef5a9 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart'; @@ -12,6 +13,7 @@ import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; import '../../../uitl/date_uitl.dart'; @@ -112,8 +114,11 @@ class _DocAvailableAppointmentsState extends State wit }); } + ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return SingleChildScrollView( child: Container( child: Column( @@ -247,6 +252,10 @@ class _DocAvailableAppointmentsState extends State wit elevation: 0, textColor: new Color(0xFF60686b), onPressed: () { + final timeslot = dayEvents[index]; + DocAvailableAppointments.selectedAppoDateTime = timeslot.end; + projectViewModel.analytics.appointment.book_appointment_time_selection(appointment_type: 'regular', dateTime: timeslot.end, doctor: widget.doctor); + setState(() { selectedButtonIndex = index; DocAvailableAppointments.selectedTime = dayEvents[index].isoTime; diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 7fb724b8..bd1d8b91 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -229,6 +229,7 @@ class _SearchByClinicState extends State { : InkWell( onTap: () { showClickListDialog(context, clinicsList, onSelection: (ListClinicCentralized clincs) { + projectViewModel.analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); Navigator.pop(context); setState(() { print(clincs.clinicID.toString() + "-" + clincs.isLiveCareClinicAndOnline.toString() + "-" + clincs.liveCareClinicID.toString() + "-" + clincs.liveCareServiceID.toString()); @@ -506,6 +507,7 @@ class _SearchByClinicState extends State { } else { isProjectLoaded = false; } + }).catchError((err) { }).catchError((err) { print(err); }); diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index 6bfac9a7..836bae7d 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; @@ -6,6 +7,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../SearchResults.dart'; @@ -17,6 +19,7 @@ class SearchByDoctor extends StatefulWidget { class _SearchByDoctorState extends State { TextEditingController doctorNameController = new TextEditingController(); bool _isButtonDisabled; + ProjectViewModel projectViewModel; @override void initState() { @@ -26,6 +29,7 @@ class _SearchByDoctorState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return Column( children: [ Expanded( @@ -143,6 +147,7 @@ class _SearchByDoctorState extends State { } _searchDoctor(BuildContext context) { + projectViewModel.analytics.appointment.book_appointment_doctor_search(query: doctorNameController.text); getDoctorsList(context); } diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index 7ebc26ca..2d113545 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -29,9 +29,9 @@ class DoctorView extends StatelessWidget { Widget build(BuildContext context) { projectViewModel = Provider.of(context); return InkWell( - onTap: onTap ?? - () { + onTap: () { if (isShowFlag) getDoctorsProfile(context, doctor, isAppo: true); + (onTap ?? (){})(); // For log analytics of doctor click from book appointment }, child: Container( decoration: BoxDecoration( diff --git a/lib/pages/BookAppointment/widgets/reminder_dialog.dart b/lib/pages/BookAppointment/widgets/reminder_dialog.dart index 6fcab59a..eece4d9f 100644 --- a/lib/pages/BookAppointment/widgets/reminder_dialog.dart +++ b/lib/pages/BookAppointment/widgets/reminder_dialog.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -41,23 +43,30 @@ Future _showReminderDialog(BuildContext context, DateTime dateTime, String insetPadding: EdgeInsets.all(21), child: ReminderDialog( onClick: (int i) async { + String text = ""; if (i == 0) { // Before 30 mints dateTime = Jiffy(dateTime).subtract(minutes: 30).dateTime; + text = "30 minutes"; // dateTime.add(new Duration(minutes: -30)); } else if (i == 1) { // Before 1 hour // dateTime.add(new Duration(minutes: -60)); dateTime = Jiffy(dateTime).subtract(hours: 1).dateTime; + text = "1 hours"; } else if (i == 2) { // Before 1 hour and 30 mints // dateTime.add(new Duration(minutes: -90)); dateTime = Jiffy(dateTime).subtract(hours: 1, minutes: 30).dateTime; + text = "1 hours 30 minutes"; } else if (i == 3) { // Before 2 hours // dateTime.add(new Duration(minutes: -120)); dateTime = Jiffy(dateTime).subtract(hours: 2).dateTime; + text = "2 hours"; } + + locator().appointment.appointment_reminder_time(reminde_before: text); if (onMultiDateSuccess == null) { CalendarUtils calendarUtils = await CalendarUtils.getInstance(); calendarUtils diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 06710183..901e6c6c 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -551,6 +551,7 @@ class _AppointmentDetailsState extends State with SingleTick service.confirmAppointment(widget.appo.appointmentNo, widget.appo.clinicID, widget.appo.projectID, widget.appo.isLiveCareAppointment, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { + projectViewModel.analytics.appointment.appointment_details_confirm(appointment: widget.appo); AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); Navigator.of(context).pop(); } else { @@ -567,6 +568,8 @@ class _AppointmentDetailsState extends State with SingleTick GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.cancelAppointment(widget.appo, context).then((res) { + + projectViewModel.analytics.appointment.appointment_details_cancel(appointment: widget.appo); GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { getToDoCount(); diff --git a/lib/pages/MyAppointments/SchedulePage.dart b/lib/pages/MyAppointments/SchedulePage.dart index 92fbeedf..17cae84e 100644 --- a/lib/pages/MyAppointments/SchedulePage.dart +++ b/lib/pages/MyAppointments/SchedulePage.dart @@ -97,6 +97,8 @@ class _SchedulePageState extends State { itemCount: weeks[index].length, itemBuilder: (context, index2) => InkWell( onTap: () { + final weekDay = weeks[index][index2]['DayName']; + projectViewModel.analytics.appointment.book_appointment_date_selection(appointment_type: 'regular', day: weekDay, doctor: doctorList); openBookAppointment(weeks[index][index2]); }, child: Row( diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index b46e1958..f3a98df6 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -683,6 +683,7 @@ class _ToDoState extends State { } Future navigateToAppointmentDetails(context, AppoitmentAllHistoryResultList appo) async { + projectViewModel.analytics.todoList.to_do_list_more_details(appo); Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo, parentIndex: appo.patientStatusType == 42 ? 1 : 0))).then((value) { getPatientAppointmentHistory(); }); @@ -763,6 +764,7 @@ class _ToDoState extends State { DoctorsListService service = new DoctorsListService(); service.generateAppointmentQR(patientShareResponse, context).then((res) { GifLoaderDialogUtils.hideDialog(context); + projectViewModel.analytics.todoList.to_do_list_check_in(appo); navigateToQR(context, res['AppointmentQR'], patientShareResponse); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -783,6 +785,7 @@ class _ToDoState extends State { } openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) { + projectViewModel.analytics.todoList.to_do_list_pay_now(appo); showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), transitionBuilder: (context, a1, a2, widget) { @@ -804,7 +807,10 @@ class _ToDoState extends State { print(value); if (value != null) { + projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo); navigateToPaymentMethod(context, value, appo); + }else{ + projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); } }); } @@ -950,11 +956,13 @@ class _ToDoState extends State { } confirmAppointment(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.confirmAppointment(appo.appointmentNo, appo.clinicID, appo.projectID, appo.isLiveCareAppointment, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { + projectViewModel.analytics.todoList.to_do_list_confirm_appointment(); AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); if (appo.isLiveCareAppointment) { insertLiveCareVIDARequest(appo); diff --git a/lib/pages/ToDoList/widgets/paymentDialog.dart b/lib/pages/ToDoList/widgets/paymentDialog.dart index 3e22494e..b145e173 100644 --- a/lib/pages/ToDoList/widgets/paymentDialog.dart +++ b/lib/pages/ToDoList/widgets/paymentDialog.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 2b8aa394..2cf7345f 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -101,6 +101,7 @@ class _HomePageFragment2State extends State { child: SliderView( onLoginClick: () { widget.onLoginClick(); + projectViewModel.analytics.loginRegistration.login_register_initiate(); // navigateTo(context, CallHomePage()); }, ), diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 915c8e96..40ff61f9 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -135,6 +135,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/en/1.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/family-file/ar/1.png'), ); + + projectViewModel.analytics.bottomTabNavigation.logNavName('my family'); Navigator.push( context, MaterialPageRoute( @@ -154,6 +156,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { imagesInfo.add( ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/todo/ar/0.png')); + projectViewModel.analytics.bottomTabNavigation.logNavName('todo list'); Navigator.push( context, MaterialPageRoute( @@ -174,6 +177,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { if (tab == 5) { IS_VOICE_COMMAND_CLOSED = false; triggerRobot(); + projectViewModel.analytics.bottomTabNavigation.logNavName('help robot'); // pageController.jumpToPage(tab); } else { @@ -234,10 +238,10 @@ class _LandingPageState extends State with WidgetsBindingObserver { }); // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] //for now commented to reduce this call will enable it when needed - HMGNetworkConnectivity(context, () { - GifLoaderDialogUtils.showMyDialog(context); - PlatformBridge.shared().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); - }).checkAndConnectIfNoInternet(); + // HMGNetworkConnectivity(context, () { + // GifLoaderDialogUtils.showMyDialog(context); + // PlatformBridge.shared().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); + // }).checkAndConnectIfNoInternet(); requestPermissions().then((results) { locationUtils.getCurrentLocation(); @@ -463,6 +467,9 @@ class _LandingPageState extends State with WidgetsBindingObserver { PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, + onPageChanged: (idx){ + projectViewModel.analytics.bottomTabNavigation.logNavName(''); + }, children: [ HomePage2( goToMyProfile: () { @@ -472,6 +479,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { login(); }, onMedicalFileClick: () { + projectViewModel.analytics.bottomTabNavigation.logNavName('medical file'); changeCurrentTab(1); }, ), @@ -510,6 +518,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { ? FloatingButton( elevation: true, onTap: () { + projectViewModel.analytics.appointment.book_appointment(); changeCurrentTab(2); }, ) diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index b233c6a7..ef5ad06b 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -1,4 +1,5 @@ import 'package:auto_size_text/auto_size_text.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -52,26 +53,36 @@ class ServicesView extends StatelessWidget { return InkWell( onTap: () { if (index == 0) { + locator().hmgServices.logServiceName('live care service'); Navigator.push(context, FadePage(page: LiveCareHome())).then((value) { LiveCareHome.isLiveCareTypeSelected = false; }); } else if (index == 1) { + locator().hmgServices.logServiceName('covid-test drive-thru'); Navigator.push(context, FadePage(page: CovidDrivethruLocation())); } else if (index == 2) { + locator().hmgServices.logServiceName('online payments'); Navigator.push(context, FadePage(page: PaymentService())); } else if (index == 3) { + locator().hmgServices.logServiceName('home health care'); Navigator.push(context, FadePage(page: HomeHealthCarePage())); } else if (index == 4) { + locator().hmgServices.logServiceName('comprehensive medical checkup'); Navigator.push(context, FadePage(page: CMCPage())); } else if (index == 5) { + locator().hmgServices.logServiceName('emergency service'); Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); } else if (index == 6) { + locator().hmgServices.logServiceName('e-referral service'); Navigator.push(context, FadePage(page: EReferralPage())); } else if (index == 7) { + locator().hmgServices.logServiceName('water consumption'); Navigator.push(context, FadePage(page: H2OPage())); } else if (index == 8) { + locator().hmgServices.logServiceName('find us reach us'); Navigator.push(context, FadePage(page: ContactUsPage())); } else if (index == 9) { + locator().hmgServices.logServiceName('my medical details'); Navigator.push( context, FadePage( @@ -79,6 +90,7 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 10) { + locator().hmgServices.logServiceName('book appointment'); Navigator.push( context, FadePage( @@ -86,8 +98,10 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 11) { + locator().hmgServices.logServiceName('al habib pharmacy'); getPharmacyToken(context); } else if (index == 12) { + locator().hmgServices.logServiceName('update insurance'); Navigator.push( context, FadePage( @@ -95,6 +109,7 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 13) { + locator().hmgServices.logServiceName('my family files'); Navigator.push( context, FadePage( @@ -102,19 +117,23 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 14) { + locator().hmgServices.logServiceName('my child vaccines'); Navigator.push( context, FadePage(page: ChildInitialPage()), ); } else if (index == 15) { // Navigator.pop(context); + locator().hmgServices.logServiceName('todo list'); LandingPage.shared.switchToDoFromHMGServices(); } else if (index == 16) { + locator().hmgServices.logServiceName('blood donation'); Navigator.push( context, FadePage(page: BloodDonationPage()), ); } else if (index == 17) { + locator().hmgServices.logServiceName('health calculator'); Navigator.push( context, FadePage( @@ -122,6 +141,7 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 18) { + locator().hmgServices.logServiceName('heath converters'); Navigator.push( context, FadePage( @@ -129,11 +149,13 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 19) { + locator().hmgServices.logServiceName('smart watches'); Navigator.push( context, FadePage(page: SmartWatchInstructions()), ); } else if (index == 20) { + locator().hmgServices.logServiceName('car parcking service'); Navigator.push( context, FadePage( @@ -141,8 +163,10 @@ class ServicesView extends StatelessWidget { ), ); } else if (index == 21) { + locator().hmgServices.logServiceName('virtual tour'); launch("https://hmgwebservices.com/vt_mobile/html/index.html"); } else if (index == 22) { + locator().hmgServices.logServiceName('latest news'); Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => MyWebView( title: "HMG News", diff --git a/lib/pages/livecare/live_care_payment_page.dart b/lib/pages/livecare/live_care_payment_page.dart index 3980c5a7..54aeffbf 100644 --- a/lib/pages/livecare/live_care_payment_page.dart +++ b/lib/pages/livecare/live_care_payment_page.dart @@ -279,6 +279,7 @@ class _LiveCarePatmentPageState extends State { if (_selected == 0) { AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); } else { + projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); Navigator.pop(context, true); } }, diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index e07c5615..fb5f1e0f 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -1,10 +1,12 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.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'; +import 'package:provider/provider.dart'; class LiveCareTypeSelect extends StatefulWidget { @override @@ -15,6 +17,8 @@ class _LiveCareTypeSelectState extends State { var languageID; AppSharedPreferences sharedPref = AppSharedPreferences(); + ProjectViewModel projectViewModel; + @override void initState() { getLanguageID(); @@ -23,6 +27,7 @@ class _LiveCareTypeSelectState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: true, isShowAppBar: true, @@ -109,8 +114,10 @@ class _LiveCareTypeSelectState extends State { return InkWell( onTap: () { if (_loginIndex == 1) { + projectViewModel.analytics.liveCare.livecare_immediate_consultation(); Navigator.pop(context, "immediate"); } else { + projectViewModel.analytics.liveCare.livecare_schedule_video_call(); Navigator.pop(context, "schedule"); } }, diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index 0f534d98..99fa8610 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -1,4 +1,6 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsResponse.dart'; import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; @@ -21,7 +23,9 @@ class ClinicCard extends StatefulWidget { var languageID; int isOnline; - ClinicCard({this.isSelected, this.languageID, this.isOnline, @required this.patientERGetClinicsList}); + ClinicCard({this.isSelected, this.languageID, this.isOnline, @required this.patientERGetClinicsList}){ + + } @override _State createState() => _State(); @@ -126,7 +130,7 @@ class _State extends State { ), ), InkWell( - onTap: (){ getClinicTimings(widget.patientERGetClinicsList);}, + onTap: () => getClinicTimings(widget.patientERGetClinicsList), child: Container( padding: EdgeInsets.only(left: 8,right: 8,top: 4,bottom: 4), decoration: containerRadius(CustomColors.devider, 100), @@ -159,6 +163,9 @@ class _State extends State { } getClinicTimings(PatientERGetClinicsList patientERGetClinicsList) { + + locator().liveCare.livecare_clinic_schedule(clinic: patientERGetClinicsList.serviceName); + LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); service.getLivecareClinicTiming(patientERGetClinicsList.serviceID, context).then((res) { diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index 232f62de..49ef4c1c 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -32,6 +33,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; import '../live_care_payment_page.dart'; @@ -69,6 +71,8 @@ class _clinic_listState extends State { String liveCareClinicIDs; + ProjectViewModel projectViewModel; + @override void initState() { liveCareClinicsListResponse = new LiveCareClinicsListResponse(); @@ -95,12 +99,15 @@ class _clinic_listState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return Container( child: currentSelectedLiveCareType == "immediate" ? getLiveCareImmediateClinicList() : getLiveCareScheduleClinicList(), ); } void startLiveCare() { + projectViewModel.analytics.liveCare.livecare_immediate_consultation_clinic(clinic: selectedClinicName); + bool isError = false; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); @@ -277,6 +284,7 @@ class _clinic_listState extends State { }))).then((value) { print(value); if (value != null) { + projectViewModel.analytics.liveCare.payment_method(appointment_type: 'livecare', clinic: selectedClinicName, payment_method: value, payment_type: 'appointment'); openPayment(value, authUser, double.parse(getERAppointmentFeesList.total), appo); } }); @@ -588,6 +596,8 @@ class _clinic_listState extends State { } void startScheduleLiveCare() { + projectViewModel.analytics.liveCare.livecare_schedule_video_call_clinic(clinic: selectedClinicName); + List doctorsList = []; LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart index 341f6098..c275ec38 100644 --- a/lib/pages/login/register-info.dart +++ b/lib/pages/login/register-info.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; @@ -373,13 +374,25 @@ class _RegisterInfo extends State { children: [ Expanded( child: Padding( - padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () => {Navigator.of(context).pop()}, textColor: Colors.white, color: Color(0xffD02127))), + padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () { + Navigator.of(context).pop(); + locator().loginRegistration.registration_cancel(step: page == 1 ? 'personal info' : 'patient info'); + }, textColor: Colors.white, color: Color(0xffD02127))), ), Expanded( child: Padding( padding: EdgeInsets.all(10), - child: DefaultButton(page == 1 ? TranslationBase.of(context).next : TranslationBase.of(context).register, () => {nextPage()}, - textColor: Colors.white, color: isValid() == true && page == 2 || page == 1 ? Color(0xff359846) : Colors.grey)), + child: DefaultButton( + page == 1 ? TranslationBase.of(context).next : TranslationBase.of(context).register, + (){ + nextPage(); + page == 1 + ? locator().loginRegistration.registration_personal_info() + : locator().loginRegistration.registration_patient_info(); + + }, + textColor: Colors.white, color: isValid() == true && page == 2 || page == 1 ? Color(0xff359846) : Colors.grey) + ), ), ], ))); diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index ea8ef803..74d7c48e 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -1,5 +1,7 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/checkpatient_for_registration.dart'; @@ -159,12 +161,18 @@ class _Register extends State { children: [ Expanded( child: Padding( - padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () => {Navigator.of(context).pop()}, textColor: Colors.white, color: Color(0xffD02127))), + padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () { + Navigator.of(context).pop(); + locator().loginRegistration.registration_cancel(step: 'enter details'); + }, textColor: Colors.white, color: Color(0xffD02127))), ), Expanded( child: Padding( padding: EdgeInsets.all(10), - child: DefaultButton(TranslationBase.of(context).next, () => {startRegistration()}, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), + child: DefaultButton(TranslationBase.of(context).next, (){ + startRegistration(); + locator().loginRegistration.registration_enter_details(); + }, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), ), ], ))); diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 8688fec3..ea6d18cf 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; import 'package:diplomaticquarterapp/pages/login/register_new.dart'; @@ -79,6 +81,7 @@ class _WelcomeLogin extends State { child: DefaultButton( TranslationBase.of(context).no, () => { + locator().loginRegistration.visited_alhabib_group(false), Navigator.of(context).push(FadePage(page: RegisterNew())), }, color: CustomColors.accentColor, @@ -90,6 +93,7 @@ class _WelcomeLogin extends State { child: DefaultButton( TranslationBase.of(context).yes, () => { + locator().loginRegistration.visited_alhabib_group(true), Navigator.of(context).push(FadePage(page: LoginType())), }, color: CustomColors.green, diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index 2fdb93ce..5f397548 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; @@ -20,6 +21,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../../../core/model/my_balance/AdvanceModel.dart'; import 'confirm_payment_page.dart'; @@ -49,6 +51,8 @@ class _AdvancePaymentPageState extends State { List imagesInfo = List(); + ProjectViewModel projectViewModel; + @override void initState() { super.initState(); @@ -60,6 +64,7 @@ class _AdvancePaymentPageState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) { model.getHospitals(); @@ -309,6 +314,9 @@ class _AdvancePaymentPageState extends State { advanceModel.mobileNumber = mobileNum; advanceModel.patientName = patientName; GifLoaderDialogUtils.showMyDialog(context); + + + projectViewModel.analytics.advancePayments.wallet_payment_details(); model.getPatientInfoByPatientIDAndMobileNumber(advanceModel).then((value) { GifLoaderDialogUtils.hideDialog(context); if (model.state != ViewState.Error && model.state != ViewState.ErrorLocal) { @@ -324,6 +332,8 @@ class _AdvancePaymentPageState extends State { ), ).then( (value) { + projectViewModel.analytics.advancePayments.payment_method(method: value.toString().toLowerCase(), type: 'wallet'); + Navigator.push( context, FadePage( diff --git a/lib/pages/medical/balance/confirm_payment_page.dart b/lib/pages/medical/balance/confirm_payment_page.dart index 2d79219d..09bd4ade 100644 --- a/lib/pages/medical/balance/confirm_payment_page.dart +++ b/lib/pages/medical/balance/confirm_payment_page.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; @@ -22,6 +23,7 @@ import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; import 'new_text_Field.dart'; @@ -47,6 +49,7 @@ class _ConfirmPaymentPageState extends State { AppSharedPreferences sharedPref = AppSharedPreferences(); String transID = ""; + ProjectViewModel projectViewModel; void submit(MyBalanceViewModel model, code) { final activationCode = code; @@ -59,6 +62,8 @@ class _ConfirmPaymentPageState extends State { AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); appo.projectID = widget.patientInfoAndMobileNumber.projectID; + + projectViewModel.analytics.advancePayments.payment_otp_confirmation(method: widget.selectedPaymentMethod.toLowerCase(), type: 'wallet'); openPayment(widget.selectedPaymentMethod, widget.authenticatedUser, double.parse(widget.advanceModel.amount), null); }); @@ -80,6 +85,7 @@ class _ConfirmPaymentPageState extends State { ).displayDialog(context); } + projectViewModel = Provider.of(context); return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, @@ -196,6 +202,8 @@ class _ConfirmPaymentPageState extends State { child: DefaultButton( TranslationBase.of(context).confirm.toUpperCase(), () { + projectViewModel.analytics.advancePayments.payment_confirm(method: widget.selectedPaymentMethod.toLowerCase(), type: 'wallet'); + GifLoaderDialogUtils.showMyDialog(context); model .sendActivationCodeForAdvancePayment( diff --git a/lib/pages/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index e4ff9581..70b81b02 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_advance_balance_amount.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -11,14 +12,19 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:provider/provider.dart'; import 'advance_payment_page.dart'; class MyBalancePage extends StatelessWidget { List imagesInfo = List(); + ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + imagesInfo.add(ImagesInfo( imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/ar/0.png')); return BaseView( @@ -172,6 +178,7 @@ class MyBalancePage extends StatelessWidget { DefaultButton( TranslationBase.of(context).createAdvancedPayment, () { + projectViewModel.analytics.advancePayments.wallet_recharge(service_type: 'alhabib wallet'); Navigator.push(context, FadePage(page: AdvancePaymentPage())); }, ).insideContainer, diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index 13a97866..83dc69bc 100644 --- a/lib/pages/paymentService/payment_service.dart +++ b/lib/pages/paymentService/payment_service.dart @@ -59,6 +59,7 @@ class PaymentService extends StatelessWidget { medical.add( InkWell( onTap: () { + projectViewModel.analytics.advancePayments.payment_services(service_type: 'payment service'); Navigator.push(context, FadePage(page: AdvancePaymentPage())); }, child: MedicalProfileItem( @@ -75,6 +76,7 @@ class PaymentService extends StatelessWidget { medical.add( InkWell( onTap: () { + projectViewModel.analytics.advancePayments.payment_services(service_type: 'online check-in appointment'); navigateToToDoPage(context); }, child: MedicalProfileItem( @@ -91,6 +93,7 @@ class PaymentService extends StatelessWidget { medical.add( InkWell( onTap: () { + projectViewModel.analytics.advancePayments.payment_services(service_type: 'alhabib wallet'); Navigator.push(context, FadePage(page: MyBalancePage())); }, child: MedicalProfileItem( diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index b7e00d54..e8572670 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; @@ -165,8 +166,10 @@ class _AppDrawerState extends State { sharedPref.remove(CLINICS_LIST); if (projectProvider.isArabic) { projectProvider.changeLanguage('en'); + locator().hamburgerMenu.logMenuItemClick('change language to english'); } else { projectProvider.changeLanguage('ar'); + locator().hamburgerMenu.logMenuItemClick('change language to arabic'); } var themeNotifier = Provider.of(context, listen: false); themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins')); @@ -191,6 +194,8 @@ class _AppDrawerState extends State { Navigator.of(context).pushNamed( MY_FAMILIY, ); + + locator().hamburgerMenu.logMenuItemClick('my family'); }, ) : SizedBox(), @@ -317,8 +322,10 @@ class _AppDrawerState extends State { sharedPref.setBool(IS_ROBOT_INIT, null); if (projectProvider.isArabic) { projectProvider.changeLanguage('en'); + locator().hamburgerMenu.logMenuItemClick('change language to english'); } else { projectProvider.changeLanguage('ar'); + locator().hamburgerMenu.logMenuItemClick('change language to arabic'); } }, ), @@ -363,6 +370,7 @@ class _AppDrawerState extends State { //NotificationsPage // Navigator.of(context).pop(); if (!projectProvider.isLoginChild) Navigator.push(context, FadePage(page: NotificationsPage())); + locator().hamburgerMenu.logMenuItemClick('notifications'); }, ), if (projectProvider.havePrivilege(3)) @@ -373,11 +381,13 @@ class _AppDrawerState extends State { Navigator.of(context).pushNamed( SETTINGS, ); + locator().hamburgerMenu.logMenuItemClick('app settings'); }, ), InkWell( child: DrawerItem(TranslationBase.of(context).rateApp, Icons.star, bottomLine: false, letterSpacing: -0.84, fontSize: 14, projectProvider: projectProvider), onTap: () { + locator().hamburgerMenu.logMenuItemClick('rate our app'); openAppReviewDialog(); // if (Platform.isIOS) { // launch("https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); @@ -390,6 +400,7 @@ class _AppDrawerState extends State { child: DrawerItem(TranslationBase.of(context).logout, SvgPicture.asset("assets/images/new/logout.svg"), isImageIcon: true, bottomLine: false, letterSpacing: -0.84, fontSize: 14, projectProvider: projectProvider), onTap: () { + locator().hamburgerMenu.logMenuItemClick('logout'); logout(); }, ) @@ -420,7 +431,17 @@ class _AppDrawerState extends State { mHeight(12), InkWell( onTap: () { - Navigator.push(context, FadePage(page: CallPage())); + // Navigator.push(context, FadePage(page: CallPage())); + locator().hamburgerMenu.logMenuItemClick('cloud solution logo tap'); + String patientID = '2001273'; + GifLoaderDialogUtils.showMyDialog(context); + projectProvider + .platformBridge() + .connectHMGInternetWifi(patientID) + .then((value) => {GifLoaderDialogUtils.hideDialog(context)}) + .catchError((err) { + print(err.toString()); + }); }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -504,6 +525,8 @@ class _AppDrawerState extends State { login() async { var data = await sharedPref.getObject(IMEI_USER_DATA); sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); + + locator().loginRegistration.login_register_initiate(); if (data != null) { Navigator.of(context).pushNamed(CONFIRM_LOGIN); } else { @@ -544,6 +567,7 @@ class _AppDrawerState extends State { // GifLoaderDialogUtils.hideDialog(context); // Navigator.of(context).pop(); loginAfter(value, context, user is AuthenticatedUser); + locator().hamburgerMenu.logMenuItemClick('switch to my family account'); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); diff --git a/lib/widgets/nfc/nfc_reader_sheet.dart b/lib/widgets/nfc/nfc_reader_sheet.dart index 00be462a..43f1f05e 100644 --- a/lib/widgets/nfc/nfc_reader_sheet.dart +++ b/lib/widgets/nfc/nfc_reader_sheet.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; -void showNfcReader(BuildContext context, {Function onNcfScan}) { +void showNfcReader(BuildContext context, {Function onNcfScan, VoidCallback onCancel}) { showModalBottomSheet( context: context, enableDrag: false, @@ -13,14 +13,16 @@ void showNfcReader(BuildContext context, {Function onNcfScan}) { builder: (context) { return NfcLayout( onNcfScan: onNcfScan, + onCancel: onCancel, ); }); } class NfcLayout extends StatefulWidget { Function onNcfScan; + VoidCallback onCancel; - NfcLayout({this.onNcfScan}); + NfcLayout({this.onNcfScan, this.onCancel}); @override _NfcLayoutState createState() => _NfcLayoutState(); @@ -103,6 +105,7 @@ class _NfcLayoutState extends State { child: RaisedButton( onPressed: () { // _stream?.cancel(); + widget.onCancel(); Navigator.pop(context); }, elevation: 0,