From 99bdd25bd33761c5339f5ff4da01003eaf968836 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Thu, 17 Mar 2022 09:29:25 +0300 Subject: [PATCH] added more analytics logs --- .../xcshareddata/xcschemes/Runner.xcscheme | 10 +++ lib/analytics/flows/appointments.dart | 59 +++++++++++------ lib/analytics/flows/error_tracking.dart | 7 +- lib/analytics/flows/login_registration.dart | 17 +++-- lib/analytics/flows/todo_list.dart | 14 +--- lib/analytics/google-analytics.dart | 22 +++++-- lib/core/service/client/base_app_client.dart | 60 +++++++++++++++++ lib/models/Appointments/SearchInfoModel.dart | 6 ++ lib/pages/BookAppointment/BookSuccess.dart | 3 +- .../BookAppointment/DentalComplaints.dart | 7 +- lib/pages/BookAppointment/Search.dart | 4 ++ .../components/SearchByClinic.dart | 17 +++-- .../widgets/DentalComplaintCard.dart | 4 +- .../widgets/AppointmentActions.dart | 14 ++++ .../widgets/AppointmentCardView.dart | 2 + lib/pages/ToDoList/ToDo.dart | 2 + lib/pages/landing/home_page_2.dart | 1 + lib/pages/login/confirm-login.dart | 9 +-- lib/pages/login/register-info.dart | 2 +- lib/pages/login/register.dart | 65 +++++++++---------- lib/splashPage.dart | 6 ++ lib/uitl/app_shared_preferences.dart | 11 ++++ .../medical/time_line_new_widget.dart | 2 + .../medical/time_line_widget.dart | 2 + 24 files changed, 253 insertions(+), 93 deletions(-) diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a3..0ce7eafd 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,16 @@ ReferencedContainer = "container:Runner.xcodeproj"> + + + + + + parameters}) async { return MapEntry(key_, value_); }); - _analytics - .logEvent(name: name.trim().toLowerCase(), parameters: parameters) - .then((value) { - debugPrint('SUCCESS: Google analytics event "$name" sent with parameters $parameters'); - }).catchError((error) { - debugPrint('ERROR: Google analytics event "$name" sent failed'); - }); + try{ + _analytics + .logEvent(name: name.trim().toLowerCase(), parameters: parameters) + .then((value) { + debugPrint('SUCCESS: Google analytics event "$name" sent with parameters $parameters'); + }).catchError((error) { + debugPrint('ERROR: Google analytics event "$name" sent failed'); + }); + }catch(e){ + print(e); + } } } class GAnalytics { + static String TREATMENT_TYPE; + static String APPOINTMENT_DETAIL_FLOW_TYPE; + static String PAYMENT_TYPE; + setUser(AuthenticatedUser user){ if(user != null){ _analytics.setUserProperty(name: 'user_country', value: user.iSOCountryID); diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 2e237660..9cd90eb5 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io' show Platform; +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/medical/vital_sign_service.dart'; @@ -15,6 +16,7 @@ import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; @@ -34,6 +36,8 @@ AuthenticatedUserObject authenticatedUserObject = locator(); class BaseAppClient { + final _analytics = locator(); + post(String endPoint, {Map body, Function(dynamic response, int statusCode) onSuccess, @@ -143,6 +147,7 @@ class BaseAppClient { // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { var decoded = utf8.decode(response.bodyBytes); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -155,9 +160,11 @@ class BaseAppClient { } else { if (parsed['ErrorType'] == 4) { navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (parsed['ErrorType'] == 2) { await logout(); + logApiEndpointError(endPoint, "session logged out", statusCode); } if (isAllowAny) { onSuccess(parsed, statusCode); @@ -173,6 +180,7 @@ class BaseAppClient { // onSuccess(parsed, statusCode); // } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); // logout(); // } } @@ -185,11 +193,14 @@ class BaseAppClient { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { onFailure("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); } } else { onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } } } @@ -202,8 +213,10 @@ class BaseAppClient { } else { if (parsed['message'] != null) { onFailure(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -212,10 +225,12 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); onFailure(e.toString(), -1); + _analytics.errorTracking.log(endPoint, error: "api exception: $e"); } } @@ -317,6 +332,7 @@ class BaseAppClient { // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -325,6 +341,7 @@ class BaseAppClient { } else { if (parsed['ErrorType'] == 4) { navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } if (isAllowAny) { onSuccess(parsed, statusCode); @@ -340,6 +357,8 @@ class BaseAppClient { onSuccess(parsed, statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, 'session logged out', statusCode); logout(); } } @@ -352,11 +371,14 @@ class BaseAppClient { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { onFailure("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else { onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } else if (!parsed['IsAuthenticated']) { @@ -369,8 +391,10 @@ class BaseAppClient { } else { if (parsed['message'] != null) { onFailure(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -378,10 +402,12 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); onFailure(e.toString(), -1); + _analytics.errorTracking.log(endPoint, error: "api exception: $e"); } } @@ -421,6 +447,7 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -428,6 +455,7 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -470,11 +498,13 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode == 401) { onFailure(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); + logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode); Navigator.of(AppGlobal.context).pushNamed(HOME); } else { var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); // print(bodyUtf); onFailure(bodyUtf['error']['ErrorEndUserMsg'], statusCode); + logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode); } } else { // var parsed = json.decode(response.body.toString()); @@ -483,6 +513,7 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -512,11 +543,13 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { onSuccess(response.body.toString(), statusCode); } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -545,11 +578,13 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { onSuccess(response.body.toString(), statusCode); } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -571,11 +606,13 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { onSuccess(response.body.toString(), statusCode); } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -604,11 +641,13 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); + logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode); } else { onSuccess(response.body.toString(), statusCode); } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } @@ -750,6 +789,7 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { var parsed = json.decode(utf8.decode(response.bodyBytes)); onFailure(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); + logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode); } else { // var parsed = json.decode(response.body.toString()); var parsed = json.decode(utf8.decode(response.bodyBytes)); @@ -773,6 +813,7 @@ class BaseAppClient { onSuccess(parsed, statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); logout(); } } @@ -782,11 +823,14 @@ class BaseAppClient { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['ErrorSearchMsg'] == null) { onFailure("Server Error found with no available message", statusCode); + logApiEndpointError(endPoint, "Server Error found with no available message", statusCode); } else { onFailure(parsed['ErrorSearchMsg'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode); } } else { onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } else if (!parsed['IsAuthenticated']) { await logout(); @@ -798,8 +842,10 @@ class BaseAppClient { } else { if (parsed['message'] != null) { onFailure(parsed['message'] ?? parsed['message'], statusCode); + logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); + logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } } } @@ -807,10 +853,12 @@ class BaseAppClient { } } else { onFailure('Please Check The Internet Connection', -1); + _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); } } catch (e) { print(e); onFailure(e.toString(), -1); + logApiEndpointError(endPoint, e.toString(), -1); } } @@ -829,8 +877,20 @@ class BaseAppClient { } }, onFailure: (String error, int statusCode) { completer.complete(); + logApiFullUrlError(url, error, statusCode); }); await completer.future; return token; } + + + logApiFullUrlError(String fullUrl, error, code){ + final endpoint = Uri.parse(fullUrl).pathSegments.last; + logApiEndpointError(endpoint, error, code); + } + + logApiEndpointError(String endPoint, error, code){ + _analytics.errorTracking.log(endPoint, error: error); + } + } diff --git a/lib/models/Appointments/SearchInfoModel.dart b/lib/models/Appointments/SearchInfoModel.dart index f5500bca..c771695c 100644 --- a/lib/models/Appointments/SearchInfoModel.dart +++ b/lib/models/Appointments/SearchInfoModel.dart @@ -1,3 +1,6 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart'; + class SearchInfo { int ProjectID; int ClinicID; @@ -7,4 +10,7 @@ class SearchInfo { String currentLat; String currentLong; DateTime date; + + HospitalsModel hospital; + ListClinicCentralized clinic; } diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 3b0d3ecc..f0495cf5 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -566,7 +566,8 @@ class _BookSuccessState extends State { String txn_ref = res['Merchant_Reference']; String amount = res['Amount']; String payment_method = res['PaymentMethod']; - projectViewModel.analytics.appointment.payment_success(appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: 'SAR', txn_number: txn_ref); + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + projectViewModel.analytics.appointment.payment_success(appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); createAdvancePayment(res, appo); } else { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/pages/BookAppointment/DentalComplaints.dart b/lib/pages/BookAppointment/DentalComplaints.dart index f68d9503..15cae75a 100644 --- a/lib/pages/BookAppointment/DentalComplaints.dart +++ b/lib/pages/BookAppointment/DentalComplaints.dart @@ -1,4 +1,6 @@ +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/DentalChiefComplaintsModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/DentalProceduresModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; @@ -64,7 +66,10 @@ class _DentalComplaintsState extends State { child: DentalComplaintCard( listDentalChiefComplain: complaintsList[index], languageID: languageID, - ), + )..logAnalytics = (){ + final info = widget.searchInfo; + locator().appointment.book_appointment_chief_complaints(appointment_type: 'regular', hospital: info.hospital, clinic: info.clinic, treatment: complaintsList[index]); + }, ); }, separatorBuilder: (BuildContext context, int index) { diff --git a/lib/pages/BookAppointment/Search.dart b/lib/pages/BookAppointment/Search.dart index e10e3258..a56082c8 100644 --- a/lib/pages/BookAppointment/Search.dart +++ b/lib/pages/BookAppointment/Search.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/analytics/flows/appointments.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart'; @@ -33,6 +35,8 @@ class _SearchState extends State with TickerProviderStateMixin { Widget build(BuildContext context) { AppGlobal.context = context; ProjectViewModel projectViewModel = Provider.of(context); + GAnalytics.TREATMENT_TYPE = null; // reset treatment type on start new booking + return AppScaffold( isShowAppBar: false, isShowDecPage: false, diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 12553388..6aad6b69 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -52,6 +52,7 @@ class _SearchByClinicState extends State { bool isProjectLoaded = false; ListClinicCentralized selectedClinic; + HospitalsModel selectedHospital; AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); @@ -228,6 +229,7 @@ class _SearchByClinicState extends State { : InkWell( onTap: () { showClickListDialog(context, clinicsList, onSelection: (ListClinicCentralized clincs) { + selectedClinic = clincs; projectViewModel.analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription); Navigator.pop(context); setState(() { @@ -310,22 +312,23 @@ class _SearchByClinicState extends State { Container( height: 18, child: DropdownButtonHideUnderline( - child: DropdownButton( + child: DropdownButton( key: projectDropdownKey, hint: new Text(TranslationBase.of(context).selectHospital), - value: projectDropdownValue, + value: selectedHospital, iconSize: 0, isExpanded: true, style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black), items: projectsList.map((item) { - return new DropdownMenuItem( - value: item.mainProjectID.toString(), + return new DropdownMenuItem( + value: item, child: new Text(item.name), ); }).toList(), - onChanged: (newValue) { + onChanged: (newValue) async{ setState(() { - projectDropdownValue = newValue; + selectedHospital = newValue; + projectDropdownValue = newValue.mainProjectID.toString(); getDoctorsList(context); }); }, @@ -516,6 +519,8 @@ class _SearchByClinicState extends State { if (dropdownValue.split("-")[0] == "17") { searchInfo.ProjectID = int.parse(projectDropdownValue); searchInfo.ClinicID = int.parse(dropdownValue.split("-")[0]); + searchInfo.hospital = selectedHospital; + searchInfo.clinic = selectedClinic; searchInfo.date = DateTime.now(); navigateToDentalComplaints(context, searchInfo); diff --git a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart index d2adaafc..e65d25ca 100644 --- a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart +++ b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart @@ -12,6 +12,7 @@ import 'package:flutter/material.dart'; // ignore: must_be_immutable class DentalComplaintCard extends StatefulWidget { final ListDentalChiefComplain listDentalChiefComplain; + VoidCallback logAnalytics; var languageID; DentalComplaintCard({@required this.listDentalChiefComplain, this.languageID}); @@ -26,7 +27,8 @@ class _DentalComplaintCardState extends State { return Container( child: InkWell( onTap: () { - // locator().appointment.book_appointment_chief_complaints(appointment_type: 'regular', hospital: widget.listDentalChiefComplain.); + if(widget.logAnalytics != null) + widget.logAnalytics(); getChiefComplaintsList(); }, child: Container( diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index fcf1b6f0..125794f3 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -1,8 +1,10 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart'; import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart'; 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/appoDetailsButtons.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; @@ -94,15 +96,18 @@ class _AppointmentActionsState extends State { _handleButtonClicks(AppoDetailsButton, ToDoCountProviderModel model) { switch (AppoDetailsButton.caller) { case "openReschedule": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'reschedule appointment'); widget.tabController.animateTo((widget.tabController.index + 1) % 2); setState(() { widget.enableFooterButton(); }); break; case "navigateToProject": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'hospital location'); openMap(double.parse(widget.appo.latitude), double.parse(widget.appo.longitude)); break; case "addReminder": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'add reminder'); showReminderDialog( context, DateUtil.convertStringToDate(widget.appo.appointmentDate), @@ -117,32 +122,41 @@ class _AppointmentActionsState extends State { break; case "goToTodoList": // Navigator.of(context).pop(); + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'todo list'); navigateToToDoPage(context, model); break; case "askDoc": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'ask doctor'); askYourDoc(); break; case "radiology": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'radiology'); openAppointmentRadiology(); break; case "labResult": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'lab result'); openAppointmentLabResults(); break; case "prescriptions": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'prescriptions'); openPrescriptionReport(); break; case "Survey": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'survey'); rateAppointment(); break; case "Insurance": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'insurance'); navigateToInsuranceApprovals(widget.appo.appointmentNo); break; case "VitalSigns": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'vital sign'); navigateToVitalSigns(widget.appo.appointmentNo, widget.appo.projectID); break; case "insertComplaint": + locator().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint'); navigateToInsertComplaint(); break; } diff --git a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart index 31a7cb2d..ece790c0 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart'; @@ -237,6 +238,7 @@ class _ApointmentCardState extends State { } Future navigateToAppointmentDetails(context, appo) async { + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'my appointment'; Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo))) .then((value) { widget.onReloadAppointmentHistory(); diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 5b3c56bd..da90ffc3 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -628,6 +629,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { Future navigateToAppointmentDetails(context, AppoitmentAllHistoryResultList appo) async { projectViewModel.analytics.todoList.to_do_list_more_details(appo); + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'todo list'; Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo, parentIndex: appo.patientStatusType == 42 ? 1 : 0))).then((value) { getPatientAppointmentHistory(); }); diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart index 9f395cad..7374d273 100644 --- a/lib/pages/landing/home_page_2.dart +++ b/lib/pages/landing/home_page_2.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 09dee601..bde675ad 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -40,8 +40,8 @@ import 'package:provider/provider.dart'; class ConfirmLogin extends StatefulWidget { final Function changePageViewIndex; - - const ConfirmLogin({Key key, this.changePageViewIndex}) : super(key: key); + final fromRegistration; + const ConfirmLogin({Key key, this.changePageViewIndex, this.fromRegistration = false}) : super(key: key); @override _ConfirmLogin createState() => _ConfirmLogin(); @@ -579,6 +579,7 @@ class _ConfirmLogin extends State { else { // Navigator.of(context).pop(), + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result), GifLoaderDialogUtils.hideDialog(context), Future.delayed(Duration(seconds: 1), () { AppToast.showErrorToast(message: result); @@ -628,7 +629,7 @@ class _ConfirmLogin extends State { // Navigator.of(context).pop(), GifLoaderDialogUtils.hideDialog(context), Future.delayed(Duration(seconds: 1), () { - projectViewModel.analytics.errorTracking.log(error: "login_failed: $result"); + projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result); AppToast.showErrorToast(message: result); startSMSService(tempType); }), @@ -727,7 +728,7 @@ class _ConfirmLogin extends State { isMoreOption = true; }); } else { - projectViewModel.analytics.loginRegistration.login_verify_otp(method: _flag); + projectViewModel.analytics.loginRegistration.verify_otp_method(method: _flag, forRegistration: widget.fromRegistration); authenticateUser(_flag, isActive: _loginIndex); } }, diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart index 35ff6838..a38514a3 100644 --- a/lib/pages/login/register-info.dart +++ b/lib/pages/login/register-info.dart @@ -282,7 +282,7 @@ class _RegisterInfo extends State { child: Padding( 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'); + locator().loginRegistration.registration_cancel(step: page == 1 ? 'personal info' : 'other details'); }, textColor: Colors.white, color: Color(0xffD02127))), ), Expanded( diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index 74d7c48e..9e771f14 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -54,20 +54,17 @@ class _Register extends State { @override Widget build(BuildContext context) { return AppScaffold( + appBarTitle: TranslationBase.of(context).register, isShowAppBar: false, isShowDecPage: false, showNewAppBar: false, showNewAppBarTitle: true, - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column(children: [ + body: Column( + children: [ Expanded( child: ListView( - padding: EdgeInsets.zero, + padding: EdgeInsets.all(21), physics: BouncingScrollPhysics(), children: [ SizedBox(height: 10), @@ -150,32 +147,32 @@ class _Register extends State { ], ), ), - ]), - )), - bottomSheet: Container( - width: double.maxFinite, - // height: 80.0, - color: Colors.white, - margin: EdgeInsets.only(bottom: 50.0), - child: Row( - children: [ - Expanded( - child: Padding( - 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(); - locator().loginRegistration.registration_enter_details(); - }, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), - ), - ], - ))); + Container( + width: double.maxFinite, + // height: 80.0, + color: Colors.white, + // margin: EdgeInsets.only(bottom: 50.0), + child: Row( + children: [ + Expanded( + child: Padding( + 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, (){ + locator().loginRegistration.registration_enter_details(); + startRegistration(); + }, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))), + ), + ], + ),) + ], + ),); } Future _selectDate(BuildContext context) async { @@ -394,7 +391,7 @@ class _Register extends State { { result = CheckUserStatusResponse.fromJson(result), sharedPref.setObject(NHIC_DATA, result), - Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex))), + Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true))), } else { diff --git a/lib/splashPage.dart b/lib/splashPage.dart index e15cd330..a8a8d029 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; @@ -40,6 +41,11 @@ class _SplashScreenState extends State { }); }, ); + + + AppSharedPreferences().getAll().then((value){ + debugPrint(jsonEncode(value)); + }); } /// load the Privilege from service diff --git a/lib/uitl/app_shared_preferences.dart b/lib/uitl/app_shared_preferences.dart index ed8321eb..a69306dd 100644 --- a/lib/uitl/app_shared_preferences.dart +++ b/lib/uitl/app_shared_preferences.dart @@ -4,6 +4,17 @@ import 'package:shared_preferences/shared_preferences.dart'; class AppSharedPreferences { Future _prefs = SharedPreferences.getInstance(); + Map _allData; + + // To Test Saved Data + Future> getAll() async{ + final prefs = (await _prefs); + _allData = {}; + prefs.getKeys().forEach((key) { + _allData[key] = prefs.get(key); + }); + return _allData; + } /// Save String [key] the key for save value [value] the value we need to save it setString(String key, String value) async { diff --git a/lib/widgets/data_display/medical/time_line_new_widget.dart b/lib/widgets/data_display/medical/time_line_new_widget.dart index 4d38de2e..3df1bb48 100644 --- a/lib/widgets/data_display/medical/time_line_new_widget.dart +++ b/lib/widgets/data_display/medical/time_line_new_widget.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/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -343,6 +344,7 @@ class TimelineNewWidget extends StatelessWidget { mHeight(10), LargeAvatar( onTap: () { + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'timeline'; Navigator.push( context, FadePage( diff --git a/lib/widgets/data_display/medical/time_line_widget.dart b/lib/widgets/data_display/medical/time_line_widget.dart index b2d7ca56..11d2394f 100644 --- a/lib/widgets/data_display/medical/time_line_widget.dart +++ b/lib/widgets/data_display/medical/time_line_widget.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart'; @@ -51,6 +52,7 @@ class TimeLineWidget extends StatelessWidget { LargeAvatar( onTap: () { //AppointmentDetails + GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'timeline'; Navigator.push( context, FadePage(