diff --git a/src/constants/analytics.js b/src/constants/analytics.js
index c0171209..8cf147e8 100644
--- a/src/constants/analytics.js
+++ b/src/constants/analytics.js
@@ -11,22 +11,29 @@ const GaEvents = Object.freeze({
const GaCategories = Object.freeze({
API_RESPONSE: 'Api_Response',
+ CONFIRMATION_CLICKED: "confirmation clicked",
+ CONFIRMATION_CLICKED_INSHOP: "inshop confirmation clicked",
+ CONFIRMATION_CLICKED_MOBILE: "mobile confirmation clicked",
EVOX: 'Evox'
});
const GaActions = Object.freeze({
- RESULT: 'Result',
CLICKED: 'Clicked',
+ NO: "no",
+ RESULT: 'Result',
+ SUBMITTED: 'Submitted',
VIF: 'vif',
- SUBMITTED: 'Submitted'
+ YES: "yes",
});
const GaLabels = Object.freeze({
- SUCCESS: 'Success',
+ ADDRESS_LOOKUP: 'Address_Look_up',
ERROR: 'Error',
LICENSE_PLATE_LOOKUP: 'License_Plate_Look_Up',
+ NO: "no",
+ SUCCESS: 'Success',
VIN_LOOKUP: 'Vin_Look_Up',
- ADDRESS_LOOKUP: 'Address_Look_up'
+ YES: "yes",
});
const ValueToLogTypes = Object.freeze({
diff --git a/src/constants/experiments.js b/src/constants/experiments.js
index 9e959331..c336503b 100644
--- a/src/constants/experiments.js
+++ b/src/constants/experiments.js
@@ -2,6 +2,7 @@ const experimentUniverses = Object.freeze({
ISS_FUNNEL: 'ISSFunnel',
ISS_FEATURETOGGLE_AREFEES_HIDDEN: 'NextGenISS_FeatureToggle_AreFeesHidden',
ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN: 'NextGenISS_FeatureToggle_AreFeesOverridden',
+ ISS_MOBILE_FIRST_APPOINTMENTS: 'ISS_Mobile_First_Appointments',
ADYEN_PAYMENT_TEST: 'NextGenAdyenPaymentTest'
});
@@ -12,6 +13,9 @@ const experimentSettings = Object.freeze({
ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'OverrideMobileFee',
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee',
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee',
+ ISS_MOBILE_FIRST_MAX_MOBILE_DAYS: 'MaxMobileDays',
+ ISS_MOBILE_FIRST_MAX_PM_MOBILE_DAYS: 'MaxPmMobileDays',
+ ISS_MOBILE_FIRST_SHOW_FIRST_MOBILE_APPOINTMENT: 'ShowMobileFirstAppointment',
ISS_ENABLE_ADYEN_V1: 'ISS_Enable_Adyen_V1'
});
diff --git a/src/helpers/adyen-helper.js b/src/helpers/adyen-helper.js
index d1b5b571..70d2fe34 100644
--- a/src/helpers/adyen-helper.js
+++ b/src/helpers/adyen-helper.js
@@ -69,6 +69,7 @@ export function mapAdyenToIssPaymentMethod(adyenMethod) {
const paymentMethodMap = {
["scheme"]: paymentMethods.CREDIT_CARD,
["afterpaytouch_US"]: paymentMethods.AFTERPAY,
+ ["afterpaytouch"]: paymentMethods.AFTERPAY,
["paypal"]: paymentMethods.PAYPAL,
["applepay"]: paymentMethods.APPLEPAY,
};
diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js
index 72572256..13aced81 100644
--- a/src/helpers/service-location-helper.js
+++ b/src/helpers/service-location-helper.js
@@ -15,8 +15,23 @@ function processZipCodeResults(request) {
}));
}
-export async function getZipCodeData(zipCode) {
- return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode }));
+export async function getAvailabilityRating(
+ startDate,
+ endDate,
+ shopAppointmentType,
+ providerNumber
+) {
+ // For a given shop provider number and date range, get the appointment time slots available
+ const shopTimeSlots = await useMainStore().getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber);
+
+ const numberOfDaysToEvaluate = 2;
+ const isGoodAvailability =
+ shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length
+ >= numberOfDaysToEvaluate;
+
+ const shopStatus = isGoodAvailability ? 'high' : 'low';
+
+ return Promise.resolve(shopStatus);
}
export async function getMobileZipCodeData(zipCode) {
@@ -42,25 +57,6 @@ export async function getPricedMobileFeePart(serviceZipCode) {
return Promise.resolve(pricingResults[0]);
}
-export async function getAvailabilityRating(
- startDate,
- endDate,
- shopAppointmentType,
- providerNumber
-) {
- // For a given shop provider number and date range, get the appointment time slots available
- const shopTimeSlots = await useMainStore().getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber);
-
- const numberOfDaysToEvaluate = 2;
- const isGoodAvailability =
- shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length
- >= numberOfDaysToEvaluate;
-
- const shopStatus = isGoodAvailability ? 'high' : 'low';
-
- return Promise.resolve(shopStatus);
-}
-
export function getProviderData() {
const mainStore = useMainStore();
const storeServiceLocation = mainStore.order.serviceLocation;
@@ -73,6 +69,18 @@ export function getProviderData() {
return { storeServiceLocation, isMobileAppointment, storeSelectedProvider, serviceZipCode }
}
+export async function getZipCodeData(zipCode) {
+ return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode }));
+}
+
+export function mapTimeSlot(timeSlot, timeOfDay) {
+ return {
+ ...timeSlot,
+ isDropoff: timeSlot.id.endsWith('DROP OFF'),
+ timeOfDay
+ };
+}
+
export async function onProviderChanged() {
const { isMobileAppointment, storeSelectedProvider, serviceZipCode } = getProviderData();
if (!storeSelectedProvider) {
@@ -101,4 +109,4 @@ export async function onProviderChanged() {
}
await settleAllPromises(promiseResultMap);
-}
\ No newline at end of file
+}
diff --git a/src/iss-components/continue-modal/continue-modal.vue b/src/iss-components/continue-modal/continue-modal.vue
index def01d34..8bca85ce 100644
--- a/src/iss-components/continue-modal/continue-modal.vue
+++ b/src/iss-components/continue-modal/continue-modal.vue
@@ -68,6 +68,7 @@ export default {
},
methods: {
openModal() {
+ this.pushEventToGA("existing_claim", "pop_up_displayed", this.mainStore.accountNameForEvents, true);
this.$refs.continueModal.openModal();
},
setModalStatus(isOpened) {
@@ -77,9 +78,11 @@ export default {
this.$refs.continueModal.closeModal();
},
continueReferral() {
+ this.pushEventToGA("existing_claim", "finish_claim", this.mainStore.accountNameForEvents, true);
this.$emit('continue-previous-referral');
},
startNewReferral() {
+ this.pushEventToGA("existing_claim", "start_new_claim", this.mainStore.accountNameForEvents, true);
this.$emit('start-new-referral');
}
}
diff --git a/src/layouts/contact-details/contact-details.vue b/src/layouts/contact-details/contact-details.vue
index b73d3fc4..a5c0c646 100644
--- a/src/layouts/contact-details/contact-details.vue
+++ b/src/layouts/contact-details/contact-details.vue
@@ -230,11 +230,15 @@ export default {
},
watch: {
isSameAsPolicyAddress(newValue) {
+ this.pushEventToGA("mobile_location", "same_as_policy_address", newValue ? "checked" : "unchecked", true);
if (newValue) {
this.copyPolicyAddressToServiceLocation();
} else {
this.clearAddressFields();
}
+ },
+ isVehicleProtected(newValue) {
+ this.pushEventToGA("mobile_location", "is_vehicle_protected", newValue, true);
}
},
methods: {
diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue
index b4a68eb0..f0b1a150 100644
--- a/src/layouts/schedule-page/schedule-page.vue
+++ b/src/layouts/schedule-page/schedule-page.vue
@@ -60,6 +60,10 @@
+
+
+
\ No newline at end of file
diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue
index 92d8dd10..2b80ca23 100644
--- a/src/layouts/welcome-page/welcome-page.vue
+++ b/src/layouts/welcome-page/welcome-page.vue
@@ -68,6 +68,7 @@
:options="DamageCauseOptions"
disableAutoFill
:validationRules="rules.damageOption"
+ isRequired
placeHolderText="Select an option"
class="form-group" />
{
+ const formRoot = this.$el;
+ const requiredFieldCount = formRoot.querySelectorAll('[aria-required="true"]').length;
+ this.pushEventToGA("policy_info", "required_fields", requiredFieldCount.toString(), true);
+ });
+
+ this.mainStore.applicationUser.firstHit = false;
+ }
+
+ // TODO: Check if we're coming from SFA
+ // 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);
+ }
+ else {
+ this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", null);
+ }
+
+ this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, null);
+ },
computed: {
DamageCauseOptions() {
const damageCauseAnswers = this.getCmsContent(
@@ -460,6 +490,20 @@ export default {
this.answeredContinueModal = true;
this.$refs.continueModal.closeModal();
}
+ },
+ watch: {
+ 'welcomePageModel.policyZipCode': {
+ handler: async function (newZip) {
+ if (newZip.length === 5) {
+ this.pushEventToGA("policy_info", "policy_zip", newZip, true);
+ }
+ }
+ },
+ 'welcomePageModel.damageCause': function (newCause) {
+ if (newCause) {
+ this.pushEventToGA("policy_info", "cause_of_loss", newCause, true);
+ }
+ }
}
};
diff --git a/src/mixins/experiment-mixin.js b/src/mixins/experiment-mixin.js
index 5b1f7142..7f9a761e 100644
--- a/src/mixins/experiment-mixin.js
+++ b/src/mixins/experiment-mixin.js
@@ -8,6 +8,10 @@ export default {
hasSetting(settingName) {
return Object.hasOwn(useMainStore().experimentSettings, settingName);
},
+ getExperimentByName(experimentName) {
+ const experiment = useMainStore().applicationUser.experiments.find((e) => e.universeName === experimentName);
+ return experiment ? experiment : null;
+ },
getSettingValue(settingName) {
return this.hasSetting(settingName)
? useMainStore().experimentSettings[settingName]
diff --git a/src/store/index.js b/src/store/index.js
index 8a4f1b34..aa56015a 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -239,7 +239,8 @@ export const getDefaultState = () => ({
triggeredSiteEntry: false, // TODO not in save session
duplicateOrders: [],
hasSentSaveQuoteEmail: null,
- coverageLookupAttempts: 0
+ coverageLookupAttempts: 0,
+ firstHit: true
},
issConfig: {
clientName: 'Generic Insurance', // this is the default and will be overriden by the client's name
@@ -445,7 +446,8 @@ export const useMainStore = defineStore({
.map((x) => x.settings)
.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)
+ currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace),
+ accountNameForEvents: (state) => state.issConfig.clientName.replaceAll(" ", "").replaceAll("&", "amp")
},
actions:
{
@@ -2587,6 +2589,9 @@ export const useMainStore = defineStore({
}
);
},
+ logMobileFirstExperimentExposure() {
+ this.logExperimentIfExists(issPageValues.SCHEDULE_PAGE, experimentUniverses.ISS_MOBILE_FIRST_APPOINTMENTS);
+ },
logWelcomePageExperiments(issPage) {
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN);
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN);