diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 0d173db19..3f1979f83 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -5,7 +5,9 @@ const applicationConfig = { ANALYTICS_SESSION_TIMEOUT_MINUTES: 30, SAVED_SESSION_TIMEOUT_DAYS: 45, COOKIE_PATH: "/", - CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT // "Localhost", "Dev", "QA", and "Prod" + CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod" + APPLICATION_NAME: "SafeliteDotCom", + SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass" }; export { applicationConfig }; \ No newline at end of file diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index e7f856f40..3b3bc8bde 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -90,6 +90,10 @@ const endpoints = { GetExperimentsByUser: { url: "/analytics/api/v1/analytics/get-experiments", method: "GET", + }, + RunExperimentsForTrigger: { + url: "/experiments/api/v1/experiments/run", + method: "POST" } }; diff --git a/src/constants/experiments.js b/src/constants/experiments.js index cd2325a24..fdfa7acac 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -5,6 +5,11 @@ const experimentUniverses = { const experimentSettings = { GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index' } + +const experimentTriggers = { + SITE_ENTRY: "SiteEntry", + PAGE_ENTRY: "PageEntry" +}; -export { experimentUniverses, experimentSettings}; +export { experimentUniverses, experimentSettings, experimentTriggers }; \ No newline at end of file diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 87331daea..6d0fb1f6b 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -30,6 +30,7 @@ const storeActions = { LOG_CUSTOM_EVENT: "logCustomEvent", INITIALIZE_SESSION: "initializeSession", GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser", + RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger", CLEAR_VIN: "clearVin", // DEPENDENCY MUTATIONS diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 80697cc46..28dbb17bf 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -58,6 +58,10 @@ const storeMutations = { UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation", UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise", UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited", + + // EXPERIMENT MUTATIONS + UPDATE_EXPERIMENTS: "updateExperiments", + UPDATE_TRIGGERED_SITE_ENTRY: "updateTriggeredSiteEntry" }; export { storeMutations }; diff --git a/src/router/index.js b/src/router/index.js index b09f734a2..02ec313b8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -18,6 +18,8 @@ import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; import analyticsMixin from "@/mixins/analytics-mixin"; +import { experimentTriggers } from "../constants/experiments"; +import { applicationConfig } from "../constants/application-config"; const routes = [ { @@ -35,6 +37,14 @@ const routes = [ return next(false); } + if (!store.getters.applicationUser.triggeredSiteEntry) { + await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, { + userId: getDeviceIdValue(), + triggerEvent: experimentTriggers.SITE_ENTRY, + triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE + }); + } + // If the saved session has timed out, clear the session, execute 404 logic. if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); diff --git a/src/store/index.js b/src/store/index.js index bac95e3cf..0e766f3c3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,8 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/se import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "../constants/store-actions"; +import { applicationConfig } from "../constants/application-config"; +import { experimentTriggers } from "../constants/experiments"; // Export State const getDefaultState = () => { @@ -69,6 +71,8 @@ const getDefaultState = () => { saveQuoteId: null, crmCustomerId: null, lastPageVisited: null, + experiments: {}, + triggeredSiteEntry: false }, } }; @@ -313,6 +317,12 @@ export const mutations = { state.order.customer.emailAddress = orderInformation.customer.emailAddress; }, + updateExperiments(state, experiments) { + state.applicationUser.experiments = experiments; + }, + updateTriggeredSiteEntry(state, wasSiteEntryTriggered) { + state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered; + } } // Export Getters @@ -333,6 +343,30 @@ export const getters = { applicationUser: (state) => state.applicationUser, order: (state) => state.order, payment: (state) => state.order.payment, + experimentOrder: (state) => { + return { + vehicleYear: state.order.vehicle.year, + vehicleMake: state.order.vehicle.make, + vehicleModel: state.order.vehicle.model, + vehicleStyle: state.order.vehicle.style, + isRepair: state.order.damage.isRepair, + numberOfChips: state.order.damage.numberOfChips, + carId: state.order.vehicle.carId, + serviceCity: state.order.serviceLocation.city, + serviceState: state.order.serviceLocation.state, + serviceZipCode: state.order.serviceLocation.zipCode, + parentAccountNumber: state.order.accountNumber, + isCoverageVerified: state.order.payment.insuranceCoverage.isVerified, + orderPartNumbers: [...Object.values(state.order.lineItems.glassParts), ...Object.values(state.order.lineItems.otherParts)], + orderPartTypes: [...Object.keys(state.order.lineItems.glassParts), ...Object.keys(state.order.lineItems.otherParts)], + hasRecalibrationPart: Object.values(state.order.lineItems.glassParts).filter(x => x.requiresRecalibration)?.length > 0, + selectedMultiGlass: state.order.damage.glassToReplace.length > 1, + selectedWindshieldGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.WINDSHIELD), + selectedBackGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.BACK), + selectedDriverSideGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.DRIVER), + selectedPassengerSideGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.PASSENGER) + } + } } // Export Actions @@ -510,7 +544,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, action: action, event: event, shouldUseSessionId: shouldUseSessionId @@ -529,7 +563,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, category: category, action: action, label: label, @@ -546,7 +580,7 @@ export const actions = { }, initializeSession(context, { userId, sessionId, userAgent, referrer }) { var payload = { - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, userId: userId, deviceId: userId, sessionId: sessionId, @@ -579,6 +613,26 @@ export const actions = { }); }, + runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { + if (triggerValue == experimentTriggers.SITE_ENTRY) { + context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true); + } + + var payload = { + applicationName: applicationConfig.APPLICATION_NAME, + userId: userId, + triggerEvent: triggerEvent, + triggerValue: triggerValue, + experimentOrder: context.getters.experimentOrder + }; + + return globalMethods.callHttpClient({ + method: endpoints.RunExperimentsForTrigger.method, + endpoint: endpoints.RunExperimentsForTrigger.url, + payload: payload, + }); + }, + getEvoxImage(context, { relativeUrl }) { return globalMethods.callHttpClient({ method: endpoints.GetPageData.method,