From ab4eb77ca55eb4f516d5940ea3df28e398737bb2 Mon Sep 17 00:00:00 2001 From: scottkiener-at-safelite Date: Fri, 17 Apr 2026 11:24:09 -0400 Subject: [PATCH 01/18] Remove heavy truck front-end logic Serviceability-Details handles this now --- src/helpers/service-location-helper.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 4755aa69..729400af 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -74,11 +74,6 @@ export async function getZipCodeData(zipCode) { } export function isServiceableMobileWithData(isGlassServiceableMobile, isRecalibrationServiceableMobile) { - const isBigTruck = useMainStore().order.serviceLocation.isBigTruck; - if (isBigTruck) { - return false; - } - if (isRecalibrationServiceableMobile === true || isRecalibrationServiceableMobile === false) { return ( isGlassServiceableMobile From fff491d0ada129416047fdbf56df32067155e54e Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Mon, 20 Apr 2026 10:59:21 -0400 Subject: [PATCH 02/18] 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 03/18] 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 04/18] 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 05/18] 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 06/18] 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 07/18] 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 08/18] 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 09/18] 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 6e96a4635c73895d4fffa230940c16827a358805 Mon Sep 17 00:00:00 2001 From: scottkiener-at-safelite Date: Tue, 21 Apr 2026 15:08:28 -0400 Subject: [PATCH 10/18] INSR-8540 | Allow heavy trucks to do mobile --- .../schedule-page/service-location/service-location.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/layouts/schedule-page/service-location/service-location.vue b/src/layouts/schedule-page/service-location/service-location.vue index 9b23059e..5dc908be 100644 --- a/src/layouts/schedule-page/service-location/service-location.vue +++ b/src/layouts/schedule-page/service-location/service-location.vue @@ -249,10 +249,6 @@ export default { return this.isGlassServiceableInshop; }, isServiceableMobile() { - if (this.isBigTruck) { - return false; - } - if (this.isRecalibrationServiceableMobile === true || this.isRecalibrationServiceableMobile === false) { return ( this.isGlassServiceableMobile From fa21cb1a7cd83d14278258a9260b140c32bd6030 Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Tue, 21 Apr 2026 15:08:31 -0400 Subject: [PATCH 11/18] INSR-8884: Some payment-method events --- src/constants/analytics.js | 8 +++++- .../cart-dropdown/cart-dropdown.vue | 11 ++++++-- src/layouts/payment-method/payment-method.vue | 25 +++++++++++++++++++ .../service-package-radio.vue | 3 ++- .../service-packages/service-packages.vue | 11 ++++++-- 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/constants/analytics.js b/src/constants/analytics.js index dc023b15..f81b19bc 100644 --- a/src/constants/analytics.js +++ b/src/constants/analytics.js @@ -57,4 +57,10 @@ const analyticsServicePackageMap = new Map([ [packageNames.TIER_THREE, 'essentialsplus'] ]); -export { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes, analyticsPaymentTypeMap, analyticsServicePackageMap }; +const analyticsVapsModalMap = new Map([ + ['FrontWiperModal', 'wiper'], + ['RearWiperModal', 'wiper'], + ['RainDefenseModal', 'raindefense'], +]); + +export { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes, analyticsPaymentTypeMap, analyticsServicePackageMap, analyticsVapsModalMap }; diff --git a/src/iss-components/cart-dropdown/cart-dropdown.vue b/src/iss-components/cart-dropdown/cart-dropdown.vue index a24586c7..3bbfacb4 100644 --- a/src/iss-components/cart-dropdown/cart-dropdown.vue +++ b/src/iss-components/cart-dropdown/cart-dropdown.vue @@ -42,7 +42,7 @@ linkType="text" text="Remove" href="javascript:void(0)" - @clickEvent="removeVap(item.partType)"> + @clickEvent="removeVap(item.partType, item?.name ?? '')"> @@ -367,8 +367,15 @@ export default { ?.filter((vapsLineItem) => vapsLineItem.partType === partType) ?? []; return this.getCartItem(label, lineItems, cartItemType.VAP, partType); }, - removeVap(partType) { + removeVap(partType, partName) { const newVaps = useMainStore().lineItems.vaps?.filter((vap) => vap?.partType !== partType) ?? []; + if (partType === partTypeStrings.FRONT_WIPER) { + this.pushEventToGA('Removed From Cart', 'Product - Front Wiper', 'Safelite advanced', true); + } else if (partType === partTypeStrings.REAR_WIPER) { + this.pushEventToGA('Removed From Cart', 'Product - Rear Wiper', 'Safelite advanced', true); + } else { + this.pushEventToGA('Removed From Cart', `Product - Other - ${partName}`, 'none', true); + } useMainStore().updateVaps(newVaps); useMainStore().updateServicePackage(null); }, diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 0c3d0c7d..af37a518 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -156,6 +156,7 @@ import { getCartTotal } from '@/helpers/cart-helper'; import { formatAmountInDollars } from '@/helpers/text-helper'; import widgetFields from '@/constants/cms-widget-fields'; import MaskaFormattedMasks from '@/constants/maska-masks'; +import { containsRecalParts } from '@/helpers/recal-helper'; export default { name: 'payment-method', @@ -197,6 +198,9 @@ export default { vm.updateFooterButtonText(vm.customCallToActionButtonCopy); }); }, + mounted() { + this.handleAnalyticsEvents(); + }, data() { return { paymentMethod: null, @@ -499,6 +503,27 @@ export default { }, closeContactDetailsWithoutSaving() { this.smsOptIn = 'No'; + }, + handleAnalyticsEvents() { + const mobileOrInshop = this.mainStore.isMobileAppointment ? 'mobile' : 'in_shop'; + const verifiedOrNotVerified = this.mainStore.isVerified ? 'verified' : 'not_verified'; + const repairOrReplace = this.mainStore.isRepair ? 'repair' : 'replace'; + this.pushEventToGA('order_summary', 'safelite', `${mobileOrInshop}_${repairOrReplace}_${verifiedOrNotVerified}`, true); + + if (containsRecalParts(this.mainStore.lineItems)) { + let coverageType = ''; + if (this.mainStore.isITAC) { + coverageType = 'ITAC'; + } else if (this.mainStore.isNoComp) { + coverageType = 'no_comp'; + } else if (this.mainStore.isVerified) { + coverageType = 'verified'; + } else { + coverageType = 'unverified'; + } + const recalibrationType = this.mainStore.lineItems.glassParts?.find((part) => part.requiresRecalibration)?.recalibrationType; + this.pushEventToGA(`recalibration_added_${coverageType}`, this.mainStore.vehicle.carId, `recal_type_${recalibrationType}`.replace(/ /g, '_').toLowerCase(), true); + } } } }; diff --git a/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue index 5951d611..ccfa4629 100644 --- a/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue +++ b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue @@ -115,7 +115,8 @@ export default { }, textLinkEmit(copy) { this.$parent.$emit('link-event', { - args: getRouterLinkRouteFromCopy(copy) + route: getRouterLinkRouteFromCopy(copy), + packageName: this.value }); } } diff --git a/src/layouts/service-packages/service-packages.vue b/src/layouts/service-packages/service-packages.vue index 6c95e13b..f495d7ae 100644 --- a/src/layouts/service-packages/service-packages.vue +++ b/src/layouts/service-packages/service-packages.vue @@ -80,6 +80,7 @@ import servicePackageQuestion from '@/layouts/service-packages/service-package-q import issPageValues from '@/router/router-constants/issPage-values'; import bailoutMessage from '@/constants/bailoutMessage'; import buttonMain from '@/ux-components/button-main/button-main.vue'; +import { analyticsServicePackageMap, analyticsVapsModalMap } from '@/constants/analytics'; const store = useMainStore(); @@ -204,8 +205,11 @@ export default { } }, methods: { - openModalAction(modalName) { - this.$refs[modalName.args].openModal(); + openModalAction(eventData) { + this.$refs[eventData.route].openModal(); + const packageName = analyticsServicePackageMap.get(eventData.packageName); + const modalName = analyticsVapsModalMap.get(eventData.route); + this.pushEventToGA('service_package', 'modal_displayed', `${packageName}_${modalName}_modal_displayed`, true); }, arePagePrerequisitesValid() { return ( @@ -235,6 +239,9 @@ export default { } store.updateVaps(this.selectedVaps); store.updateServicePackage(this.selectedPackageTier); + + const packageName = analyticsServicePackageMap.get(this.selectedPackageTier); + this.pushEventToGA('service_package', 'attached_a_package', packageName, true); const scenario = store.isMobileAppointment ? this.navigationScenarios.CLICKED_FORWARD_MOBILE From 828167813c2dc7cb3fd2717f23a60135b0eba2f4 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 21 Apr 2026 15:24:49 -0400 Subject: [PATCH 12/18] 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 13/18] 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) { From 9a7b452b9827f33fb46d5e13850e136de530688d Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Tue, 21 Apr 2026 16:53:34 -0400 Subject: [PATCH 14/18] INSR-8884: More payment-method events --- .../payment-method-question.vue | 2 + src/layouts/payment-method/payment-method.vue | 37 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/layouts/payment-method/payment-method-question/payment-method-question.vue b/src/layouts/payment-method/payment-method-question/payment-method-question.vue index 33d82adf..38919f7b 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-question.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-question.vue @@ -20,6 +20,7 @@ import buttonQuestion from '@/digital-components/button-question/button-question import widgetFields from '@/constants/cms-widget-fields.js'; import paymentMethodListButton from './payment-method-list-button/payment-method-list-button.vue'; import { markRaw } from 'vue'; +import { analyticsPaymentTypeMap } from '@/constants/analytics'; export default { name: 'payment-method-question', @@ -43,6 +44,7 @@ export default { return this.modelValue; }, set(selectedMethod) { + this.pushEventToGA('submit_order', 'payment_type_selected', analyticsPaymentTypeMap.get(selectedMethod), true); this.$emit('update:modelValue', selectedMethod); } }, diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index af37a518..b4599eb5 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -157,6 +157,7 @@ import { formatAmountInDollars } from '@/helpers/text-helper'; import widgetFields from '@/constants/cms-widget-fields'; import MaskaFormattedMasks from '@/constants/maska-masks'; import { containsRecalParts } from '@/helpers/recal-helper'; +import coverageType from '@/constants/coverage-type'; export default { name: 'payment-method', @@ -199,7 +200,7 @@ export default { }); }, mounted() { - this.handleAnalyticsEvents(); + this.handleAnalyticsEventsOnMounted(); }, data() { return { @@ -415,6 +416,7 @@ export default { this.$refs.siteFooter.updateButtonText(newValue); }, async forwardButtonAction() { + this.handleAnalyticsEventsOnForwardButtonAction(); this.mainStore.savePaymentMethodChoice(this.paymentMethod); this.savePageDataToStore(issPageValues.PAYMENT_METHOD, { smsOptIn: this.smsOptIn }); if (!this.hideSMSOptIn) { @@ -464,6 +466,7 @@ export default { handleEditClicked(section) { switch (section) { case 'location': + this.pushEventToGA('order_summary', 'change', 'location', true); const scenario = this.mainStore.isMobileAppointment ? this.navigationScenarios.EDIT_SERVICE_LOCATION_MOBILE : this.navigationScenarios.EDIT_SERVICE_LOCATION_INSHOP; @@ -473,6 +476,7 @@ export default { ); break; case 'schedule': + this.pushEventToGA('order_summary', 'change', 'time', true); this.$router.navigateWithSpinner( this.navigationScenarios.EDIT_SCHEDULE, this.$route @@ -504,7 +508,7 @@ export default { closeContactDetailsWithoutSaving() { this.smsOptIn = 'No'; }, - handleAnalyticsEvents() { + handleAnalyticsEventsOnMounted() { const mobileOrInshop = this.mainStore.isMobileAppointment ? 'mobile' : 'in_shop'; const verifiedOrNotVerified = this.mainStore.isVerified ? 'verified' : 'not_verified'; const repairOrReplace = this.mainStore.isRepair ? 'repair' : 'replace'; @@ -524,6 +528,35 @@ export default { const recalibrationType = this.mainStore.lineItems.glassParts?.find((part) => part.requiresRecalibration)?.recalibrationType; this.pushEventToGA(`recalibration_added_${coverageType}`, this.mainStore.vehicle.carId, `recal_type_${recalibrationType}`.replace(/ /g, '_').toLowerCase(), true); } + + const hasFrontWiper = this.mainStore.lineItems.vaps.some((part) => part.partType === partTypeStrings.FRONT_WIPER); + const hasRearWiper = this.mainStore.lineItems.vaps.some((part) => part.partType === partTypeStrings.REAR_WIPER); + const wiperEventLabel = `front_${hasFrontWiper ? 'advanced' : 'none'}_rear_${hasRearWiper ? 'advanced' : 'none'}`; + this.pushEventToGA('wipers', 'attached_to_order', wiperEventLabel, true); + }, + handleAnalyticsEventsOnForwardButtonAction() { + this.pushEventToGA('order_summary', 'edit', 'contact_details', true); + let action; + let label; + switch (this.mainStore.coverageType) { + case coverageType.Deductible: + action = 'Covered'; + label = this.mainStore.currentDeductible; + break; + case coverageType.ITAC: + action = 'ITAC'; + label = this.mainStore.currentDeductible + "_" + getCartTotal(this.mainStore.order); + break; + case coverageType.NO_COMP: + action = 'NOCOMP'; + label = 'Unverified'; + break; + case coverageType.NONE: + action = 'Unverified'; + label = 'Unverified'; + break; + } + this.pushEventToGA('Submit Appointment', action, label, true, null, 1); } } }; From 746b45e37248e848bc691be1e2afa102b3088e50 Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Tue, 21 Apr 2026 17:24:21 -0400 Subject: [PATCH 15/18] INSR-8884: Better null/undefined handling for analytics events --- .../payment-method-question.vue | 3 ++- src/layouts/payment-method/payment-method.vue | 21 ++++++++++--------- .../service-packages/service-packages.vue | 8 +++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/layouts/payment-method/payment-method-question/payment-method-question.vue b/src/layouts/payment-method/payment-method-question/payment-method-question.vue index 38919f7b..87980750 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-question.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-question.vue @@ -44,7 +44,8 @@ export default { return this.modelValue; }, set(selectedMethod) { - this.pushEventToGA('submit_order', 'payment_type_selected', analyticsPaymentTypeMap.get(selectedMethod), true); + const paymentMethod = analyticsPaymentTypeMap.get(this.piaType) ?? 'UNKNOWN'; + this.pushEventToGA('submit_order', 'payment_type_selected', paymentMethod, true); this.$emit('update:modelValue', selectedMethod); } }, diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index b4599eb5..70196840 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -158,6 +158,7 @@ import widgetFields from '@/constants/cms-widget-fields'; import MaskaFormattedMasks from '@/constants/maska-masks'; import { containsRecalParts } from '@/helpers/recal-helper'; import coverageType from '@/constants/coverage-type'; +import partTypeStrings from '@/constants/part-type-strings'; export default { name: 'payment-method', @@ -511,26 +512,26 @@ export default { handleAnalyticsEventsOnMounted() { const mobileOrInshop = this.mainStore.isMobileAppointment ? 'mobile' : 'in_shop'; const verifiedOrNotVerified = this.mainStore.isVerified ? 'verified' : 'not_verified'; - const repairOrReplace = this.mainStore.isRepair ? 'repair' : 'replace'; + const repairOrReplace = this.mainStore.damage.isRepair ? 'repair' : 'replace'; this.pushEventToGA('order_summary', 'safelite', `${mobileOrInshop}_${repairOrReplace}_${verifiedOrNotVerified}`, true); if (containsRecalParts(this.mainStore.lineItems)) { - let coverageType = ''; + let coverageTypeForLabel = ''; if (this.mainStore.isITAC) { - coverageType = 'ITAC'; + coverageTypeForLabel = 'ITAC'; } else if (this.mainStore.isNoComp) { - coverageType = 'no_comp'; + coverageTypeForLabel = 'no_comp'; } else if (this.mainStore.isVerified) { - coverageType = 'verified'; + coverageTypeForLabel = 'verified'; } else { - coverageType = 'unverified'; + coverageTypeForLabel = 'unverified'; } const recalibrationType = this.mainStore.lineItems.glassParts?.find((part) => part.requiresRecalibration)?.recalibrationType; - this.pushEventToGA(`recalibration_added_${coverageType}`, this.mainStore.vehicle.carId, `recal_type_${recalibrationType}`.replace(/ /g, '_').toLowerCase(), true); + this.pushEventToGA(`recalibration_added_${coverageTypeForLabel}`, this.mainStore.vehicle.carId, `recal_type_${recalibrationType}`.replace(/ /g, '_').toLowerCase(), true); } - const hasFrontWiper = this.mainStore.lineItems.vaps.some((part) => part.partType === partTypeStrings.FRONT_WIPER); - const hasRearWiper = this.mainStore.lineItems.vaps.some((part) => part.partType === partTypeStrings.REAR_WIPER); + const hasFrontWiper = this.mainStore.lineItems?.vaps?.some((part) => part.partType === partTypeStrings.FRONT_WIPER); + const hasRearWiper = this.mainStore.lineItems?.vaps?.some((part) => part.partType === partTypeStrings.REAR_WIPER); const wiperEventLabel = `front_${hasFrontWiper ? 'advanced' : 'none'}_rear_${hasRearWiper ? 'advanced' : 'none'}`; this.pushEventToGA('wipers', 'attached_to_order', wiperEventLabel, true); }, @@ -538,7 +539,7 @@ export default { this.pushEventToGA('order_summary', 'edit', 'contact_details', true); let action; let label; - switch (this.mainStore.coverageType) { + switch (this.mainStore.insuranceCoverage.coverageType) { case coverageType.Deductible: action = 'Covered'; label = this.mainStore.currentDeductible; diff --git a/src/layouts/service-packages/service-packages.vue b/src/layouts/service-packages/service-packages.vue index f495d7ae..12a05e8e 100644 --- a/src/layouts/service-packages/service-packages.vue +++ b/src/layouts/service-packages/service-packages.vue @@ -207,8 +207,8 @@ export default { methods: { openModalAction(eventData) { this.$refs[eventData.route].openModal(); - const packageName = analyticsServicePackageMap.get(eventData.packageName); - const modalName = analyticsVapsModalMap.get(eventData.route); + const packageName = analyticsServicePackageMap.get(eventData.packageName) ?? 'UNKNOWN_PACKAGE'; + const modalName = analyticsVapsModalMap.get(eventData.route) ?? 'UNKNOWN_MODAL'; this.pushEventToGA('service_package', 'modal_displayed', `${packageName}_${modalName}_modal_displayed`, true); }, arePagePrerequisitesValid() { @@ -239,8 +239,8 @@ export default { } store.updateVaps(this.selectedVaps); store.updateServicePackage(this.selectedPackageTier); - - const packageName = analyticsServicePackageMap.get(this.selectedPackageTier); + + const packageName = analyticsServicePackageMap.get(this.selectedPackageTier) ?? 'UNKNOWN_PACKAGE'; this.pushEventToGA('service_package', 'attached_a_package', packageName, true); const scenario = store.isMobileAppointment From 98117c328dbeb42a05f60001aade7929c9625102 Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Tue, 21 Apr 2026 17:32:05 -0400 Subject: [PATCH 16/18] INSR-8884: One more fixed undefined check --- src/layouts/payment-method/payment-method.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 70196840..210f6fd4 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -539,7 +539,7 @@ export default { this.pushEventToGA('order_summary', 'edit', 'contact_details', true); let action; let label; - switch (this.mainStore.insuranceCoverage.coverageType) { + switch (this.mainStore.insuranceCoverage?.coverageType) { case coverageType.Deductible: action = 'Covered'; label = this.mainStore.currentDeductible; @@ -553,9 +553,11 @@ export default { label = 'Unverified'; break; case coverageType.NONE: + default: action = 'Unverified'; label = 'Unverified'; break; + d } this.pushEventToGA('Submit Appointment', action, label, true, null, 1); } From e168a25787dba51bd9874813dfd5b405a4116012 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 21 Apr 2026 14:35:43 -0400 Subject: [PATCH 17/18] capture bailout dataLayer event Includes Reason and Page from --- src/constants/analytics.js | 1 + src/layouts/bailout-page/bailout-page.vue | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/constants/analytics.js b/src/constants/analytics.js index dc023b15..ef128f13 100644 --- a/src/constants/analytics.js +++ b/src/constants/analytics.js @@ -14,6 +14,7 @@ const GaEvents = Object.freeze({ const GaCategories = Object.freeze({ API_RESPONSE: 'Api_Response', + BAILOUT: 'Bailout', CONFIRMATION_CLICKED: "confirmation clicked", CONFIRMATION_CLICKED_INSHOP: "inshop confirmation clicked", CONFIRMATION_CLICKED_MOBILE: "mobile confirmation clicked", diff --git a/src/layouts/bailout-page/bailout-page.vue b/src/layouts/bailout-page/bailout-page.vue index 8617ce77..dbd250d4 100644 --- a/src/layouts/bailout-page/bailout-page.vue +++ b/src/layouts/bailout-page/bailout-page.vue @@ -88,8 +88,10 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue'; import textBlock from '@/digital-components/text-block/text-block.vue'; // Supporting files +import analyticsMixIn from '@/mixins/analytics-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; +import { GaCategories } from '@/constants/analytics'; import globalRules from '@/constants/global-rules'; import settleAllPromises from '@/helpers/layout-helper'; import { useMainStore } from '@/store'; @@ -111,8 +113,17 @@ export default { Form, textBlock }, - mixins: [BaseFormMixin], + mixins: [BaseFormMixin, analyticsMixIn], async beforeRouteEnter(to, from, next) { + const fromPage = from?.query?.issPage || 'external'; + // Only log bailout event if user is coming from a different page. + // This ensures that we cannot get stuck in a loop, if the bailout-page ever bails out. + if (fromPage !== issPageValues.BAILOUT_PAGE) { + const bailoutCode = useMainStore().pageData(issPageValues.BAILOUT_PAGE).bailoutCode; + const bailoutString = Object.keys(BailoutCode).find(key => BailoutCode[key] === bailoutCode); + analyticsMixIn.methods.pushEventToGA(GaCategories.BAILOUT, bailoutString, fromPage, true, null, null); + } + // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); // Settle promises and get results From 70f80affec34530f889d5bbee0c81522048e7201 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 21 Apr 2026 14:46:45 -0400 Subject: [PATCH 18/18] Update Title --- src/router/router-constants/router-titles.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/router-constants/router-titles.js b/src/router/router-constants/router-titles.js index e6b8d0a6..09697588 100644 --- a/src/router/router-constants/router-titles.js +++ b/src/router/router-constants/router-titles.js @@ -9,7 +9,7 @@ const routerTitles = Object.freeze({ [issPageValues.ADDRESS_LOOKUP]: `Address Lookup ${titleSuffix}`, [issPageValues.ADDRESS_VEHICLES]: `Address Vehicles ${titleSuffix}`, - [issPageValues.BAILOUT_PAGE]: `Bailout Page ${titleSuffix}`, + [issPageValues.BAILOUT_PAGE]: `Need Help ${titleSuffix}`, [issPageValues.CAPABILITY_QUESTIONS]: `Capability Questions ${titleSuffix}`, [issPageValues.CONTACT_CONFIRMATION]: `Contact Confirmation ${titleSuffix}`, [issPageValues.CONTACT_DETAILS]: `Contact Details ${titleSuffix}`,