From fff491d0ada129416047fdbf56df32067155e54e Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 20 Apr 2026 10:59:21 -0400 Subject: [PATCH 01/10] Initial list of additional events. --- src/layouts/policy-vehicles/policy-vehicles.vue | 7 +++++++ src/layouts/schedule-page/schedule-page.vue | 7 ++----- src/layouts/welcome-page/welcome-page.vue | 5 ++++- src/mixins/analytics-mixin.js | 9 --------- src/router/index.js | 3 --- src/store/index.js | 2 +- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 019c0059..720a8e02 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -197,12 +197,16 @@ export default { policyVehicleId: vehicle.id, vin: this.selectedVehicleVin }); + useMainStore().updateVehicleCoverage({ noCoverage: this.noCoverageForSelectedVehicle, deductible: this.deductibleForSelectedVehicle, repairWaived: this.repairWaivedForSelectedVehicle, endorsements: this.endorsementsForSelectedVehicle }); + + this.pushEventToGA("policy_vehicle", "submitted", vehicle.vehicleMake + "_" + vehicle.vehicleModel + " " + vehicle.carId, true); + this.navigateForward(); } catch (e) { if (e.isAxiosError && e.status === 404) { @@ -218,6 +222,9 @@ export default { vin: vehicle.vin }); this.policyVinFound = false; + + this.pushEventToGA("policy_vehicle", "submitted", vehicle.vehicleMake + "_" + vehicle.vehicleModel + " " + vehicle.carId, true); + this.navigateForward(); return; } diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index b40ad1d1..c76aacce 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -961,12 +961,9 @@ export default { } this.pushEventToGA('appointment', 'availability_mobile', `days_out_${dateDiffString}`, true, null, null); }, - pushServiceTypeEvent() { + pushServiceTypeEvent() { if (this.selectedAppointmentType) { - const gaScheduleType = { - ['service_type']: this.selectedAppointmentType.toLowerCase() - }; - this.pushGenericObjectToGA(gaScheduleType); + this.pushEventToGA('appointment', 'service_type', this.selectedAppointmentType.toLowerCase(), true, null, null); } }, async refreshDatePicker() { diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 1bb70de7..b3450073 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -270,7 +270,7 @@ export default { this.mainStore.applicationUser.firstHit = false; } - // TODO: Check if we're coming from SFA + // TODO: Check if we're coming from SFA - site does not support SFA yet, add this back when it is enabled. // eslint-disable-next-line if (false) { this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", 0); @@ -358,6 +358,9 @@ export default { } promises.push(this.mainStore.getCoveragePolicyInfo()); await Promise.all(promises); + + this.pushEventToGA("policy_search", "policy_found", this.mainStore.isPolicyLookupSuccessful ? "Yes" : "No", true); + await saveSession({ shouldAwaitSaveSessionQueue: true, bailoutOnError: true }) this.navigateForward(); }, diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 81d63e41..9b30181b 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -128,15 +128,6 @@ export default { this.logPageView(analyticsPageEvents.ENTRY); }, - pushValueToGA() { - const gaServiceType = { - ['service_type']: useMainStore().order?.serviceLocation?.appointmentType?.toLowerCase() - }; - if (gaServiceType && gaServiceType['service_type']) { - this.pushGenericObjectToGA(gaServiceType); - } - }, - pushOrderToDataLayer() { // helper check for if an object is defined (but maybe falsey) const isDefined = (x) => x !== null && x !== undefined; diff --git a/src/router/index.js b/src/router/index.js index 4fd5306e..64771db5 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -190,9 +190,6 @@ router.afterEach(async (to, from) => { // Push experiments to Data Layer analyticsMixin.methods.pushExperimentsToDataLayer(); - // Push values to GA - analyticsMixin.methods.pushValueToGA(); - // Push current order status to Data Layer analyticsMixin.methods.pushOrderToDataLayer(); } diff --git a/src/store/index.js b/src/store/index.js index 680561af..19204b19 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -449,7 +449,7 @@ export const useMainStore = defineStore({ .reduce((r, c) => Object.assign(r, c), {}) ?? {}, originalDeductible: (state) => (state.order.damage.isRepair ? state.order.originalDeductible.repair : state.order.originalDeductible.replace), currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace), - accountNameForEvents: (state) => state.issConfig.clientName.replaceAll(" ", "").replaceAll("&", "amp") + accountNameForEvents: (state) => state.issConfig.clientName }, actions: { From 33c0526f1c862973d8a1824b4414d3055a2e7dd0 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 20 Apr 2026 11:34:43 -0400 Subject: [PATCH 02/10] Added zip validation event. --- src/layouts/welcome-page/welcome-page.vue | 9 +++++++++ src/store/index.js | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index b3450073..ba5f77ba 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -361,6 +361,15 @@ export default { this.pushEventToGA("policy_search", "policy_found", this.mainStore.isPolicyLookupSuccessful ? "Yes" : "No", true); + if ( this.mainStore.isPolicyLookupSuccessful) { + this.pushEventToGA("zip_validation", "success", "N/A", true); + } + else { + if ( this.mainStore.order.policy.policyLookupErrorCode === 2) { + this.pushEventToGA("zip_validation", "fail", "N/A", true); + } + } + await saveSession({ shouldAwaitSaveSessionQueue: true, bailoutOnError: true }) this.navigateForward(); }, diff --git a/src/store/index.js b/src/store/index.js index 19204b19..ecfda6f4 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -110,7 +110,8 @@ export const getDefaultState = () => ({ endorsements: [], endorsementQuestionAnswers: [], status: null, - policyData: null + policyData: null, + policyLookupErrorCode: 0 }, customer: { address: { @@ -595,10 +596,19 @@ export const useMainStore = defineStore({ // populate vehicles order.policy.vehicles = responsePolicy.vehicles ?? []; - } else { + + order.policy.policyLookupErrorCode = 0; + } else { + if ( response?.data?.isError) { + order.policy.policyLookupErrorCode = response.data.errorCode; + } this.updateCoverageType(coverageType.NONE); } } catch (e) { + if ( response?.data?.isError) { + order.policy.policyLookupErrorCode = response.data.errorCode; + } + this.updateCoverageType(coverageType.NONE); } }, @@ -2113,6 +2123,7 @@ export const useMainStore = defineStore({ this.order.policy.endorsements = []; this.order.policy.endorsementQuestionAnswers = []; this.order.policy.policyData = null; + this.order.policy.policyLookupErrorCode = 0; this.order.policy.deductible.repair = null; this.order.policy.deductible.replace = null; }, From 4ae51eeb24e0e24f4a6759beafe73fe54f860bfd Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 20 Apr 2026 12:04:44 -0400 Subject: [PATCH 03/10] Fixed vehicle info on event. --- src/layouts/policy-vehicles/policy-vehicles.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 720a8e02..49f8815a 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -205,7 +205,7 @@ export default { endorsements: this.endorsementsForSelectedVehicle }); - this.pushEventToGA("policy_vehicle", "submitted", vehicle.vehicleMake + "_" + vehicle.vehicleModel + " " + vehicle.carId, true); + this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true); this.navigateForward(); } catch (e) { From feb203dbc7acaec4722760e3802311c4a6dccd1b Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 20 Apr 2026 12:51:26 -0400 Subject: [PATCH 04/10] Made sure GA events from mounted method are logged to logapp as well as GA. --- src/layouts/order-confirmation/order-confirmation.vue | 2 +- src/layouts/welcome-page/welcome-page.vue | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index 1a3b6db9..d07f711d 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -665,7 +665,7 @@ export default { // TODO: Check if we're coming from SFA and add relevant events // eslint-disable-next-line if (false) { - this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'SFA', null); + this.pushEventToGA('_confirmation', 'referring_site', 'SFA', null); } else { this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'ClientSite', true); diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index ba5f77ba..6f72d2df 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -273,14 +273,14 @@ export default { // TODO: Check if we're coming from SFA - site does not support SFA yet, add this back when it is enabled. // eslint-disable-next-line if (false) { - this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", 0); - this.pushEventToGA("visitor_info_welcome", "referring_site", "SFA", null); + this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", true, null, '0'); + this.pushEventToGA("visitor_info_welcome", "referring_site", "SFA", true); } else { - this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", null); + this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", true); } - this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, null); + this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, true); }, computed: { DamageCauseOptions() { From 438b18aea9c5662c226bd1ba897f5c2b046d246b Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 10:12:54 -0400 Subject: [PATCH 05/10] Logic updates. --- src/store/index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 1954086a..f8237fae 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -602,15 +602,11 @@ export const useMainStore = defineStore({ order.policy.policyLookupErrorCode = 0; } else { if ( response?.data?.isError) { - order.policy.policyLookupErrorCode = response.data.errorCode; + order.policy.policyLookupErrorCode = response?.data?.errorCode; } this.updateCoverageType(coverageType.NONE); } } catch (e) { - if ( response?.data?.isError) { - order.policy.policyLookupErrorCode = response.data.errorCode; - } - this.updateCoverageType(coverageType.NONE); } }, From 8d0a61a53ce798da552a9bb3abfed5079c3f40d2 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 10:18:01 -0400 Subject: [PATCH 06/10] Changes for consistency. --- src/layouts/order-confirmation/order-confirmation.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index d07f711d..3f34efd4 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -665,7 +665,7 @@ export default { // TODO: Check if we're coming from SFA and add relevant events // eslint-disable-next-line if (false) { - this.pushEventToGA('_confirmation', 'referring_site', 'SFA', null); + this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'SFA', true); } else { this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'ClientSite', true); From 61d87f55fea8e207db0153c4d8be510e5d700a46 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 10:44:40 -0400 Subject: [PATCH 07/10] Error code resetting. --- src/store/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index f8237fae..b53885e0 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -562,6 +562,7 @@ export const useMainStore = defineStore({ console.log(`Coverage lookup attempt #${this.applicationUser.coverageAttempts}. Max attempts allowed: 10.`); try { + order.policy.policyLookupErrorCode = 0; const response = await globalMethods.callHttpClient({ method: endpoints.CoveragePolicyInfo.method, endpoint: endpoints.CoveragePolicyInfo.url, @@ -598,9 +599,7 @@ export const useMainStore = defineStore({ // populate vehicles order.policy.vehicles = responsePolicy.vehicles ?? []; - - order.policy.policyLookupErrorCode = 0; - } else { + } else { if ( response?.data?.isError) { order.policy.policyLookupErrorCode = response?.data?.errorCode; } From 0a040371eb49e588d6fd0599169df314e88e7c48 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 10:46:45 -0400 Subject: [PATCH 08/10] Vehicle field consistency. --- src/layouts/policy-vehicles/policy-vehicles.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index a8fe665a..b13f8b64 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -228,7 +228,7 @@ export default { }); this.policyVinFound = false; - this.pushEventToGA("policy_vehicle", "submitted", vehicle.vehicleMake + "_" + vehicle.vehicleModel + " " + vehicle.carId, true); + this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true); this.navigateForward(); return; From 828167813c2dc7cb3fd2717f23a60135b0eba2f4 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 15:24:49 -0400 Subject: [PATCH 09/10] Updates to some event pricing output and adding ShopSelection event. --- src/helpers/cart-helper.js | 14 ++++++++++++++ .../coverage-statement/coverage-statement.vue | 2 ++ .../provider-preference/provider-preference.vue | 4 ++++ src/mixins/analytics-mixin.js | 7 ++++--- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/helpers/cart-helper.js b/src/helpers/cart-helper.js index 405dea57..1920df3c 100644 --- a/src/helpers/cart-helper.js +++ b/src/helpers/cart-helper.js @@ -28,6 +28,20 @@ export function getServiceLineItems(order) { ]; } +/** + * Returns an array containing only the + * @param {object} order order object + * @returns {[]} array of service line items + */ +export function getAvailableLineItems(order) { + const { glassParts, supportingItems } = getLineItems(order); + const availableLineItems = [ + ...(glassParts ?? []), + ...(supportingItems ?? []) + ]; + return availableLineItems; +} + /** * Returns an array containing only the non-service line items (Vaps and Fees) * @param {object} order order object diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 54e341ff..b918ce71 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -145,6 +145,7 @@ import widgetFields from '@/constants/cms-widget-fields.js'; import { formatAmountInDollars, createUnorderedListFromStringOfParagraphs, createOrderedListFromStringOfParagraphs } from '@/helpers/text-helper.js'; import showIssLoadingModal from '@/helpers/loading-modal-helper'; import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems } from '@/helpers/cart-helper'; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; import oemEndorsementModal from '@/layouts/coverage-statement/oem-endorsement-modal/oem-endorsement-modal.vue'; @@ -494,6 +495,7 @@ export default { this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD); } else if (this.isITACQuoteVisible || this.isNoCompQuoteVisible) { this.mainStore.updateIsSafeliteProvider(true); + this.pushEventToGA('ShopSelection', 'Safelite', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE); } else { this.$router.navigateBailout(bailoutMessage.coverageStatementInvalidState()); diff --git a/src/layouts/provider-preference/provider-preference.vue b/src/layouts/provider-preference/provider-preference.vue index ff2fdf5c..27f88d72 100644 --- a/src/layouts/provider-preference/provider-preference.vue +++ b/src/layouts/provider-preference/provider-preference.vue @@ -67,6 +67,8 @@ import showIssLoadingModal from '@/helpers/loading-modal-helper'; import bailoutMessage from '@/constants/bailoutMessage'; import baseFormMixin from '@/mixins/base-form-mixin'; import PROVIDER_PREFERENCE_OPTIONS from '@/constants/provider-preference'; +import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems } from '@/helpers/cart-helper'; // Import Component import { Form } from 'vee-validate'; @@ -159,12 +161,14 @@ export default { this.mainStore.updateIsSafeliteProvider(true); const scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE; this.pushEventToGA('prefered_provider', 'Safelite', this.mainStore.accountNameForEvents, true); + this.pushEventToGA('ShopSelection', 'Safelite', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateForward(scenario); }, scheduleWithTPA() { this.mainStore.updateIsSafeliteProvider(false); const scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED; this.pushEventToGA('prefered_provider', 'TPA', this.mainStore.accountNameForEvents, true); + this.pushEventToGA('ShopSelection', 'Other', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateForward(scenario); }, findAnotherShopClicked() { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 9b30181b..6480a508 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -20,7 +20,8 @@ import { GaEvents, ValueToLogTypes } from '@/constants/analytics'; -import { getCartTotal, getSubtotal } from '@/helpers/cart-helper'; +import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems, getCartTotal, getSubtotal } from '@/helpers/cart-helper'; import { getRecalPartNumbers, isRecalOrder } from "@/helpers/recal-helper"; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; @@ -273,7 +274,7 @@ export default { payload.priceTotal = ""; // ITAC or NoComp (where cash price is shown) } else if (store.isVerified && (store.isITAC || store.isNoComp)) { - const subtotal = getSubtotal(order).toFixed(2); + const subtotal = getPriceOfLineItems(getAvailableLineItems(order)).toFixed(2); payload.priceSubTotal = parseFloat(subtotal); const total = getCartTotal(order).toFixed(2); payload.priceTotal = parseFloat(total); @@ -283,7 +284,7 @@ export default { } // Cash Quote or Cash Price Sub Total - payload.cashPriceSubTotal = getSubtotal(order).toString(); + payload.cashPriceSubTotal = getPriceOfLineItems(getAvailableLineItems(order)).toString(); // Recalibration payload.isRecalibrationOnOrder = isRecalOrder(order.lineItems); From 8b12758061e670c6382efe2438f42f6115c794f4 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 15:42:39 -0400 Subject: [PATCH 10/10] Refactoring some code out into a new method that was created. --- src/layouts/coverage-statement/coverage-statement.vue | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index b918ce71..b4bf1614 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -471,11 +471,7 @@ export default { this.isPageLoading = false; }, async getPricedParts() { - const { glassParts, supportingItems } = this.mainStore.order.lineItems; - const availableLineItems = [ - ...(glassParts ?? []), - ...(supportingItems ?? []) - ]; + const availableLineItems = getAvailableLineItems(this.mainStore.order); // We only call the ITAC pricing endpoint if we are not repair or we are NoComp if (!this.isRepair || this.mainStore.isNoComp) {