Merge branch 'develop' into feature/kroell/INSR-9266
This commit is contained in:
commit
afeb5635f5
8 changed files with 105 additions and 8 deletions
|
|
@ -14,6 +14,7 @@ const GaEvents = Object.freeze({
|
||||||
|
|
||||||
const GaCategories = Object.freeze({
|
const GaCategories = Object.freeze({
|
||||||
API_RESPONSE: 'Api_Response',
|
API_RESPONSE: 'Api_Response',
|
||||||
|
BAILOUT: 'Bailout',
|
||||||
CONFIRMATION_CLICKED: "confirmation clicked",
|
CONFIRMATION_CLICKED: "confirmation clicked",
|
||||||
CONFIRMATION_CLICKED_INSHOP: "inshop confirmation clicked",
|
CONFIRMATION_CLICKED_INSHOP: "inshop confirmation clicked",
|
||||||
CONFIRMATION_CLICKED_MOBILE: "mobile confirmation clicked",
|
CONFIRMATION_CLICKED_MOBILE: "mobile confirmation clicked",
|
||||||
|
|
@ -57,4 +58,10 @@ const analyticsServicePackageMap = new Map([
|
||||||
[packageNames.TIER_THREE, 'essentialsplus']
|
[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 };
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
linkType="text"
|
linkType="text"
|
||||||
text="Remove"
|
text="Remove"
|
||||||
href="javascript:void(0)"
|
href="javascript:void(0)"
|
||||||
@clickEvent="removeVap(item.partType)">
|
@clickEvent="removeVap(item.partType, item?.name ?? '')">
|
||||||
<template #after-text>
|
<template #after-text>
|
||||||
<span class="sr-only">{{ item?.name ?? '' }}</span>
|
<span class="sr-only">{{ item?.name ?? '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -367,8 +367,15 @@ export default {
|
||||||
?.filter((vapsLineItem) => vapsLineItem.partType === partType) ?? [];
|
?.filter((vapsLineItem) => vapsLineItem.partType === partType) ?? [];
|
||||||
return this.getCartItem(label, lineItems, cartItemType.VAP, partType);
|
return this.getCartItem(label, lineItems, cartItemType.VAP, partType);
|
||||||
},
|
},
|
||||||
removeVap(partType) {
|
removeVap(partType, partName) {
|
||||||
const newVaps = useMainStore().lineItems.vaps?.filter((vap) => vap?.partType !== partType) ?? [];
|
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().updateVaps(newVaps);
|
||||||
useMainStore().updateServicePackage(null);
|
useMainStore().updateServicePackage(null);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
||||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
// Supporting files
|
// Supporting files
|
||||||
|
import analyticsMixIn from '@/mixins/analytics-mixin.js';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
|
import { GaCategories } from '@/constants/analytics';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
import settleAllPromises from '@/helpers/layout-helper';
|
import settleAllPromises from '@/helpers/layout-helper';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
|
|
@ -111,8 +113,17 @@ export default {
|
||||||
Form,
|
Form,
|
||||||
textBlock
|
textBlock
|
||||||
},
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin, analyticsMixIn],
|
||||||
async beforeRouteEnter(to, from, next) {
|
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
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import buttonQuestion from '@/digital-components/button-question/button-question
|
||||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||||
import paymentMethodListButton from './payment-method-list-button/payment-method-list-button.vue';
|
import paymentMethodListButton from './payment-method-list-button/payment-method-list-button.vue';
|
||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
|
import { analyticsPaymentTypeMap } from '@/constants/analytics';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'payment-method-question',
|
name: 'payment-method-question',
|
||||||
|
|
@ -43,6 +44,8 @@ export default {
|
||||||
return this.modelValue;
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
set(selectedMethod) {
|
set(selectedMethod) {
|
||||||
|
const paymentMethod = analyticsPaymentTypeMap.get(this.piaType) ?? 'UNKNOWN';
|
||||||
|
this.pushEventToGA('submit_order', 'payment_type_selected', paymentMethod, true);
|
||||||
this.$emit('update:modelValue', selectedMethod);
|
this.$emit('update:modelValue', selectedMethod);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,9 @@ import { getCartTotal } from '@/helpers/cart-helper';
|
||||||
import { formatAmountInDollars } from '@/helpers/text-helper';
|
import { formatAmountInDollars } from '@/helpers/text-helper';
|
||||||
import widgetFields from '@/constants/cms-widget-fields';
|
import widgetFields from '@/constants/cms-widget-fields';
|
||||||
import MaskaFormattedMasks from '@/constants/maska-masks';
|
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 {
|
export default {
|
||||||
name: 'payment-method',
|
name: 'payment-method',
|
||||||
|
|
@ -197,6 +200,9 @@ export default {
|
||||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.handleAnalyticsEventsOnMounted();
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
paymentMethod: null,
|
paymentMethod: null,
|
||||||
|
|
@ -411,6 +417,7 @@ export default {
|
||||||
this.$refs.siteFooter.updateButtonText(newValue);
|
this.$refs.siteFooter.updateButtonText(newValue);
|
||||||
},
|
},
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
|
this.handleAnalyticsEventsOnForwardButtonAction();
|
||||||
this.mainStore.savePaymentMethodChoice(this.paymentMethod);
|
this.mainStore.savePaymentMethodChoice(this.paymentMethod);
|
||||||
this.savePageDataToStore(issPageValues.PAYMENT_METHOD, { smsOptIn: this.smsOptIn });
|
this.savePageDataToStore(issPageValues.PAYMENT_METHOD, { smsOptIn: this.smsOptIn });
|
||||||
if (!this.hideSMSOptIn) {
|
if (!this.hideSMSOptIn) {
|
||||||
|
|
@ -460,6 +467,7 @@ export default {
|
||||||
handleEditClicked(section) {
|
handleEditClicked(section) {
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case 'location':
|
case 'location':
|
||||||
|
this.pushEventToGA('order_summary', 'change', 'location', true);
|
||||||
const scenario = this.mainStore.isMobileAppointment
|
const scenario = this.mainStore.isMobileAppointment
|
||||||
? this.navigationScenarios.EDIT_SERVICE_LOCATION_MOBILE
|
? this.navigationScenarios.EDIT_SERVICE_LOCATION_MOBILE
|
||||||
: this.navigationScenarios.EDIT_SERVICE_LOCATION_INSHOP;
|
: this.navigationScenarios.EDIT_SERVICE_LOCATION_INSHOP;
|
||||||
|
|
@ -469,6 +477,7 @@ export default {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'schedule':
|
case 'schedule':
|
||||||
|
this.pushEventToGA('order_summary', 'change', 'time', true);
|
||||||
this.$router.navigateWithSpinner(
|
this.$router.navigateWithSpinner(
|
||||||
this.navigationScenarios.EDIT_SCHEDULE,
|
this.navigationScenarios.EDIT_SCHEDULE,
|
||||||
this.$route
|
this.$route
|
||||||
|
|
@ -499,6 +508,58 @@ export default {
|
||||||
},
|
},
|
||||||
closeContactDetailsWithoutSaving() {
|
closeContactDetailsWithoutSaving() {
|
||||||
this.smsOptIn = 'No';
|
this.smsOptIn = 'No';
|
||||||
|
},
|
||||||
|
handleAnalyticsEventsOnMounted() {
|
||||||
|
const mobileOrInshop = this.mainStore.isMobileAppointment ? 'mobile' : 'in_shop';
|
||||||
|
const verifiedOrNotVerified = this.mainStore.isVerified ? 'verified' : 'not_verified';
|
||||||
|
const repairOrReplace = this.mainStore.damage.isRepair ? 'repair' : 'replace';
|
||||||
|
this.pushEventToGA('order_summary', 'safelite', `${mobileOrInshop}_${repairOrReplace}_${verifiedOrNotVerified}`, true);
|
||||||
|
|
||||||
|
if (containsRecalParts(this.mainStore.lineItems)) {
|
||||||
|
let coverageTypeForLabel = '';
|
||||||
|
if (this.mainStore.isITAC) {
|
||||||
|
coverageTypeForLabel = 'ITAC';
|
||||||
|
} else if (this.mainStore.isNoComp) {
|
||||||
|
coverageTypeForLabel = 'no_comp';
|
||||||
|
} else if (this.mainStore.isVerified) {
|
||||||
|
coverageTypeForLabel = 'verified';
|
||||||
|
} else {
|
||||||
|
coverageTypeForLabel = 'unverified';
|
||||||
|
}
|
||||||
|
const recalibrationType = this.mainStore.lineItems.glassParts?.find((part) => part.requiresRecalibration)?.recalibrationType;
|
||||||
|
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 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.insuranceCoverage?.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:
|
||||||
|
default:
|
||||||
|
action = 'Unverified';
|
||||||
|
label = 'Unverified';
|
||||||
|
break;
|
||||||
|
d
|
||||||
|
}
|
||||||
|
this.pushEventToGA('Submit Appointment', action, label, true, null, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,8 @@ export default {
|
||||||
},
|
},
|
||||||
textLinkEmit(copy) {
|
textLinkEmit(copy) {
|
||||||
this.$parent.$emit('link-event', {
|
this.$parent.$emit('link-event', {
|
||||||
args: getRouterLinkRouteFromCopy(copy)
|
route: getRouterLinkRouteFromCopy(copy),
|
||||||
|
packageName: this.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ import servicePackageQuestion from '@/layouts/service-packages/service-package-q
|
||||||
import issPageValues from '@/router/router-constants/issPage-values';
|
import issPageValues from '@/router/router-constants/issPage-values';
|
||||||
import bailoutMessage from '@/constants/bailoutMessage';
|
import bailoutMessage from '@/constants/bailoutMessage';
|
||||||
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||||
|
import { analyticsServicePackageMap, analyticsVapsModalMap } from '@/constants/analytics';
|
||||||
|
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
|
|
||||||
|
|
@ -205,8 +206,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModalAction(modalName) {
|
openModalAction(eventData) {
|
||||||
this.$refs[modalName.args].openModal();
|
this.$refs[eventData.route].openModal();
|
||||||
|
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() {
|
arePagePrerequisitesValid() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -238,6 +242,9 @@ export default {
|
||||||
store.updateVaps(this.selectedVaps);
|
store.updateVaps(this.selectedVaps);
|
||||||
store.updateServicePackage(this.selectedPackageTier);
|
store.updateServicePackage(this.selectedPackageTier);
|
||||||
|
|
||||||
|
const packageName = analyticsServicePackageMap.get(this.selectedPackageTier) ?? 'UNKNOWN_PACKAGE';
|
||||||
|
this.pushEventToGA('service_package', 'attached_a_package', packageName, true);
|
||||||
|
|
||||||
const scenario = store.isMobileAppointment
|
const scenario = store.isMobileAppointment
|
||||||
? this.navigationScenarios.CLICKED_FORWARD_MOBILE
|
? this.navigationScenarios.CLICKED_FORWARD_MOBILE
|
||||||
: this.navigationScenarios.CLICKED_FORWARD_INSHOP;
|
: this.navigationScenarios.CLICKED_FORWARD_INSHOP;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const routerTitles = Object.freeze({
|
||||||
|
|
||||||
[issPageValues.ADDRESS_LOOKUP]: `Address Lookup ${titleSuffix}`,
|
[issPageValues.ADDRESS_LOOKUP]: `Address Lookup ${titleSuffix}`,
|
||||||
[issPageValues.ADDRESS_VEHICLES]: `Address Vehicles ${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.CAPABILITY_QUESTIONS]: `Capability Questions ${titleSuffix}`,
|
||||||
[issPageValues.CONTACT_CONFIRMATION]: `Contact Confirmation ${titleSuffix}`,
|
[issPageValues.CONTACT_CONFIRMATION]: `Contact Confirmation ${titleSuffix}`,
|
||||||
[issPageValues.CONTACT_DETAILS]: `Contact Details ${titleSuffix}`,
|
[issPageValues.CONTACT_DETAILS]: `Contact Details ${titleSuffix}`,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue