From 935e21c9934b646bdd34c51305d7161678bba14f Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 8 Apr 2026 14:55:48 -0400 Subject: [PATCH 1/3] schedule page analytics --- src/layouts/schedule-page/schedule-page.vue | 30 +++++++++++++++++ .../service-location/service-location.vue | 1 - src/mixins/analytics-mixin.js | 32 +++++++++++++++---- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index 904329f3..61d38ad4 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -514,6 +514,8 @@ export default { jobMinMinutes: emittedValue.estimatedServiceMinutesMin.toString(), }; + this.selectedAppointmentType = AppointmentTypeStrings.MOBILE; + this.pushServiceTypeEvent(); this.mainStore.saveSchedule(timeSlotToUse); showIssLoadingModal(true); this.$router.navigate( @@ -813,6 +815,7 @@ export default { if (this.selectedAppointmentType === AppointmentTypeStrings.MOBILE || this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) { + this.pushMobileFirstDateEvent(initialData); this.mobileDatesData = initialData; if (this.selectedProvider?.providerNumber) { @@ -833,9 +836,11 @@ export default { daysFromStart: endDateObject.daysFromStart || null })); + this.pushInshopFirstDateEvent(inShopData); this.inShopDatesData = inShopData; } } else { + this.pushInshopFirstDateEvent(initialData); this.inShopDatesData = initialData; this.mobileDatesData = []; } @@ -940,6 +945,30 @@ export default { }); } }, + pushInshopFirstDateEvent(inshopData) { + let dateDiffString = ''; + if (inshopData?.initialShopTimeSlotsResponse?.days?.length > 0) { + const todayDateString = convertDateToDateString(new Date()); + dateDiffString = calcDaysBetweenDates(todayDateString, inshopData.initialShopTimeSlotsResponse.days[0].date).toString(); + } + this.pushEventToGA('appointment', 'availability_inshop', `days_out_${dateDiffString}`, true, null, null); + }, + pushMobileFirstDateEvent(mobileData) { + let dateDiffString = ''; + if (mobileData?.initialShopTimeSlotsResponse?.days?.length > 0) { + const todayDateString = convertDateToDateString(new Date()); + dateDiffString = calcDaysBetweenDates(todayDateString, mobileData.initialShopTimeSlotsResponse.days[0].date).toString(); + } + this.pushEventToGA('appointment', 'availability_mobile', `days_out_${dateDiffString}`, true, null, null); + }, + pushServiceTypeEvent() { + if (this.selectedAppointmentType) { + const gaScheduleType = { + ['service_type']: this.selectedAppointmentType.toLowerCase() + }; + this.pushGenericObjectToGA(gaScheduleType, 'service_type', true); + } + }, async refreshDatePicker() { this.resetLocalFlags(); this.isDatePickerRefreshing = true; @@ -977,6 +1006,7 @@ export default { } await this.$refs.serviceLocation.forwardButtonAction(appointmentTypeToUse); + this.pushServiceTypeEvent(); this.mainStore.saveSchedule(this.selectedTimeSlotInfo.timeSlot); this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD, diff --git a/src/layouts/schedule-page/service-location/service-location.vue b/src/layouts/schedule-page/service-location/service-location.vue index f9787d16..9b23059e 100644 --- a/src/layouts/schedule-page/service-location/service-location.vue +++ b/src/layouts/schedule-page/service-location/service-location.vue @@ -571,7 +571,6 @@ export default { await mobileFeePromise.then((result) => { this.mobileFeePart = result ?? null; }); - } } } diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index cfe48753..f7bcac5a 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -27,6 +27,10 @@ import coverageType from '@/constants/coverage-type'; import issPageValues from '@/router/router-constants/issPage-values'; import { useMainStore } from '@/store'; +function keyExistsInDataLayer(keyName) { + return window.dataLayer.some(obj => Object.prototype.hasOwnProperty.call(obj, keyName)); +} + function pushToDataLayerIfDefined(data) { if (window.dataLayer !== undefined) { window.dataLayer.push(data); @@ -91,7 +95,6 @@ export default { store.logCustomEvent(payload); }, - pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null, value = undefined) { const currentPageName = this.getPageNameByQueryString(); const labelToLog = getValueToLog(label, valueToLogType); @@ -111,6 +114,13 @@ export default { this.logCustomEvent(category, action, labelToLog, value); } }, + pushGenericObjectToGA(object, keyName = null, skipExistsCheck = false) { + if (keyName && keyExistsInDataLayer(keyName) && !skipExistsCheck) { + console.log(`Key ${keyName} already exists in dataLayer. Skipping push.`); + } else { + pushToDataLayerIfDefined(object); + } + }, pushPageViewToGA() { const currentPageName = this.getPageNameByQueryString(); @@ -126,9 +136,17 @@ export default { }, pushValueToGA() { - pushToDataLayerIfDefined({ - siteType: useMainStore().issConfig.siteType - }); + const gaSiteType = { + ['siteType']: useMainStore().issConfig.siteType + }; + this.pushGenericObjectToGA(gaSiteType, 'siteType'); + + const gaServiceType = { + ['service_type']: useMainStore().order?.serviceLocation?.appointmentType?.toLowerCase() + }; + if (gaServiceType && gaServiceType['service_type']) { + this.pushGenericObjectToGA(gaServiceType, 'service_type'); + } }, pushExperimentsToDataLayer() { @@ -229,13 +247,13 @@ export default { const applicationUser = store.applicationUser; // NOTE: ISS does not support early bird times. - const isEarlyBird = false; /*order?.lineItems?.supportingItems?.find( + const isEarlyBird = false; /* order?.lineItems?.supportingItems?.find( (lineItem) => lineItem.partType == partTypeStrings.EARLY_BIRD ); */ // NOTE: No promo codes on ISS at the moment. - const promoCodes = ""; /*Array.isArray(order?.lineItems?.promos) + const promoCodes = ""; /* Array.isArray(order?.lineItems?.promos) ? order?.lineItems?.promos .map((item) => item.promoCode) .filter((code) => code) @@ -280,7 +298,7 @@ export default { } } */ - var parentAccountNumber = (order?.parentAccountNumber ?? ( issConfig.parentAccountNumber ?? 0)).toString(); + var parentAccountNumber = (order?.parentAccountNumber ?? (issConfig.parentAccountNumber ?? 0)).toString(); var sessionData = {}; sessionData.currentPage = currentPageName; From ed179010a73977babc197f6abbcdf555917e9ced Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 8 Apr 2026 15:01:18 -0400 Subject: [PATCH 2/3] test update --- src/layouts/schedule-page/schedule-page.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/layouts/schedule-page/schedule-page.spec.js b/src/layouts/schedule-page/schedule-page.spec.js index fefde032..411f7e4f 100644 --- a/src/layouts/schedule-page/schedule-page.spec.js +++ b/src/layouts/schedule-page/schedule-page.spec.js @@ -38,7 +38,8 @@ const mockMixin = { days: [] } }; - }) + }), + pushGenericObjectToGA: jest.fn() } }; From 4b1039f06a384640379e031d2b6bc1d95af5edcc Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 9 Apr 2026 13:51:46 -0400 Subject: [PATCH 3/3] remove dupecheck --- src/layouts/schedule-page/schedule-page.vue | 2 +- src/mixins/analytics-mixin.js | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index 61d38ad4..b40ad1d1 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -966,7 +966,7 @@ export default { const gaScheduleType = { ['service_type']: this.selectedAppointmentType.toLowerCase() }; - this.pushGenericObjectToGA(gaScheduleType, 'service_type', true); + this.pushGenericObjectToGA(gaScheduleType); } }, async refreshDatePicker() { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index f7bcac5a..b619b6b4 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -27,10 +27,6 @@ import coverageType from '@/constants/coverage-type'; import issPageValues from '@/router/router-constants/issPage-values'; import { useMainStore } from '@/store'; -function keyExistsInDataLayer(keyName) { - return window.dataLayer.some(obj => Object.prototype.hasOwnProperty.call(obj, keyName)); -} - function pushToDataLayerIfDefined(data) { if (window.dataLayer !== undefined) { window.dataLayer.push(data); @@ -114,12 +110,8 @@ export default { this.logCustomEvent(category, action, labelToLog, value); } }, - pushGenericObjectToGA(object, keyName = null, skipExistsCheck = false) { - if (keyName && keyExistsInDataLayer(keyName) && !skipExistsCheck) { - console.log(`Key ${keyName} already exists in dataLayer. Skipping push.`); - } else { - pushToDataLayerIfDefined(object); - } + pushGenericObjectToGA(object) { + pushToDataLayerIfDefined(object); }, pushPageViewToGA() { @@ -139,13 +131,13 @@ export default { const gaSiteType = { ['siteType']: useMainStore().issConfig.siteType }; - this.pushGenericObjectToGA(gaSiteType, 'siteType'); + this.pushGenericObjectToGA(gaSiteType); const gaServiceType = { ['service_type']: useMainStore().order?.serviceLocation?.appointmentType?.toLowerCase() }; if (gaServiceType && gaServiceType['service_type']) { - this.pushGenericObjectToGA(gaServiceType, 'service_type'); + this.pushGenericObjectToGA(gaServiceType); } },