From 247237ba4825eabc7442ba09ad59c1c364abff1d Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 31 Mar 2026 13:09:10 -0400 Subject: [PATCH 1/3] updates for mobile first popup --- src/constants/experiments.js | 11 ++++++++++- src/helpers/service-location-helper.js | 15 +++++++++++++++ src/layouts/schedule-page/schedule-page.vue | 18 ++++++++++++++---- src/mixins/experiment-mixin.js | 10 ++++++++++ src/store/index.js | 3 +-- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/constants/experiments.js b/src/constants/experiments.js index c336503b..1c0edd15 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -19,9 +19,18 @@ const experimentSettings = Object.freeze({ ISS_ENABLE_ADYEN_V1: 'ISS_Enable_Adyen_V1' }); +const experimentTest = Object.freeze({ + ISS_MOBILE_FIRST_POPUP_V3: 'ISS_Mobile_First_Popup_V3' +}); + +const experimentVariation = Object.freeze({ + ISS_MOBILE_FIRST_CONTROL_V3: 'NoShowMobileFirstPopUp_V3_CONTROL', + ISS_MOBILE_FIRST_TEST_V3: 'YesShowMobileFirstPopUp_V3_TEST' +}); + const experimentTriggers = Object.freeze({ SITE_ENTRY: 'SiteEntry', PAGE_ENTRY: 'PageEntry' }); -export { experimentUniverses, experimentSettings, experimentTriggers }; +export { experimentUniverses, experimentSettings, experimentTest, experimentVariation, experimentTriggers }; diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 13aced81..12fc8589 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -73,6 +73,21 @@ export async function getZipCodeData(zipCode) { return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode })); } +export function isServicableMobileWithData(isGlassServiceableMobile, isRecalibrationServiceableMobile) { + const isBigTruck = useMainStore().order.serviceLocation.isBigTruck; + if (isBigTruck) { + return false; + } + + if (isRecalibrationServiceableMobile !== null) { + return ( + isGlassServiceableMobile + && isRecalibrationServiceableMobile + ); + } + return !!isGlassServiceableMobile; +} + export function mapTimeSlot(timeSlot, timeOfDay) { return { ...timeSlot, diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index f0b1a150..8fb784ed 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -77,7 +77,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import suggestTimeslotModal from '@/layouts/schedule-page/suggest-timeslot-modal/suggest-timeslot-modal.vue'; // Supporting files -import { experimentSettings, experimentUniverses } from '@/constants/experiments'; +import { experimentSettings, experimentTest, experimentVariation, experimentUniverses } from '@/constants/experiments'; import { AppointmentTypeStrings, GET_MOBILE_TIME_SLOTS, @@ -99,6 +99,7 @@ import { getPricedMobileFeePart, getMobileZipCodeData, getZipCodeData, + isServicableMobileWithData, mapTimeSlot } from '@/helpers/service-location-helper'; import { Form } from 'vee-validate'; @@ -337,7 +338,7 @@ export default { mobileProviderNumber: resultMap.providers?.mobileProviderNumber, serviceabilityDetails: resultMap.serviceabilityDetails, zipCode: initialServiceLocationObj.zipCode - } + }; vm.setCmsContent(resultMap.cmsContent); vm.$refs.serviceLocation.initializeComponent(serviceLocationData); @@ -492,12 +493,17 @@ export default { ); }, async checkMobileFirstExperience(mobileFirstObject = {}) { + const mobileFirstExperimentVariation = this.getExperimentVariationNameByTestName(experimentTest.ISS_MOBILE_FIRST_POPUP_V3); + const isMobileFirstTestVariation = mobileFirstExperimentVariation === experimentVariation.ISS_MOBILE_FIRST_TEST_V3; const showMobileFirst = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_SHOW_FIRST_MOBILE_APPOINTMENT); if (showMobileFirst) { const pmMobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_PM_MOBILE_DAYS); const mobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_MOBILE_DAYS); const hasSelectedDate = !!this.getSelectedDate(); - const isServicableMobile = mobileFirstObject.serviceabilityDetails?.isGlassServiceableMobile; + const isServicableMobile = isServicableMobileWithData( + mobileFirstObject.serviceabilityDetails?.isGlassServiceableMobile, + mobileFirstObject.serviceabilityDetails?.isRecalibrationServiceableMobile + ); if (!hasSelectedDate && isServicableMobile && mobileFirstObject.mobileProviderNumber && mobileFirstObject.zipCode) { const todayDateObject = new Date(); const todayDateString = convertDateToDateString(todayDateObject); @@ -624,7 +630,11 @@ export default { this.mainStore.logMobileFirstExperimentExposure(); } - this.$refs[SUGGEST_TIMESLOT_MODAL_REF_NAME].openModal(timeSlotForAutoSelectionMobile); + if (isMobileFirstTestVariation) { + this.$refs[SUGGEST_TIMESLOT_MODAL_REF_NAME].openModal(timeSlotForAutoSelectionMobile); + } else { + console.log('In Control group or experiment not found, skip showing popup'); + } } } } diff --git a/src/mixins/experiment-mixin.js b/src/mixins/experiment-mixin.js index 7f9a761e..6668722b 100644 --- a/src/mixins/experiment-mixin.js +++ b/src/mixins/experiment-mixin.js @@ -12,6 +12,16 @@ export default { const experiment = useMainStore().applicationUser.experiments.find((e) => e.universeName === experimentName); return experiment ? experiment : null; }, + getExperimentByTestName(testName) { + return useMainStore().applicationUser.experiments.find((experiment) => experiment.testName === testName); + }, + getExperimentVariationNameByTestName(testName) { + const experimentByTestName = this.getExperimentByTestName(testName); + if (!experimentByTestName) { + return null; + } + return experimentByTestName.variationName; + }, getSettingValue(settingName) { return this.hasSetting(settingName) ? useMainStore().experimentSettings[settingName] diff --git a/src/store/index.js b/src/store/index.js index 5b5b2f57..f3b21047 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2795,7 +2795,6 @@ export const useMainStore = defineStore({ ); }, - updateContactInfo(contactInfo) { this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName; this.order.customer.lastName = contactInfo?.lastName ?? this.order.customer.lastName; @@ -3087,7 +3086,7 @@ export const useMainStore = defineStore({ }); return response.data; }, - + hasSubmittedOrder() { return window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER) !== null; }, From b6402788334a23a251d5fe227fe94190ae041b5a Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 31 Mar 2026 13:31:36 -0400 Subject: [PATCH 2/3] copilot updates --- src/helpers/service-location-helper.js | 2 +- src/layouts/schedule-page/schedule-page.vue | 10 +++++----- src/mixins/experiment-mixin.js | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 12fc8589..2c074a3a 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -73,7 +73,7 @@ export async function getZipCodeData(zipCode) { return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode })); } -export function isServicableMobileWithData(isGlassServiceableMobile, isRecalibrationServiceableMobile) { +export function isServiceableMobileWithData(isGlassServiceableMobile, isRecalibrationServiceableMobile) { const isBigTruck = useMainStore().order.serviceLocation.isBigTruck; if (isBigTruck) { return false; diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index 8fb784ed..2e65643b 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -99,7 +99,7 @@ import { getPricedMobileFeePart, getMobileZipCodeData, getZipCodeData, - isServicableMobileWithData, + isServiceableMobileWithData, mapTimeSlot } from '@/helpers/service-location-helper'; import { Form } from 'vee-validate'; @@ -500,11 +500,11 @@ export default { const pmMobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_PM_MOBILE_DAYS); const mobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_MOBILE_DAYS); const hasSelectedDate = !!this.getSelectedDate(); - const isServicableMobile = isServicableMobileWithData( - mobileFirstObject.serviceabilityDetails?.isGlassServiceableMobile, - mobileFirstObject.serviceabilityDetails?.isRecalibrationServiceableMobile + const isServiceableMobile = isServiceableMobileWithData( + mobileFirstObject.serviceabilityDetails?.isGlassServiceableMobile ?? null, + mobileFirstObject.serviceabilityDetails?.isRecalibrationServiceableMobile ?? null ); - if (!hasSelectedDate && isServicableMobile && mobileFirstObject.mobileProviderNumber && mobileFirstObject.zipCode) { + if (!hasSelectedDate && isServiceableMobile && mobileFirstObject.mobileProviderNumber && mobileFirstObject.zipCode) { const todayDateObject = new Date(); const todayDateString = convertDateToDateString(todayDateObject); const calendarViewDirection = 'future'; diff --git a/src/mixins/experiment-mixin.js b/src/mixins/experiment-mixin.js index 6668722b..fab87d88 100644 --- a/src/mixins/experiment-mixin.js +++ b/src/mixins/experiment-mixin.js @@ -13,7 +13,8 @@ export default { return experiment ? experiment : null; }, getExperimentByTestName(testName) { - return useMainStore().applicationUser.experiments.find((experiment) => experiment.testName === testName); + const experiment = useMainStore().applicationUser.experiments.find((experiment) => experiment.testName === testName); + return experiment ? experiment : null; }, getExperimentVariationNameByTestName(testName) { const experimentByTestName = this.getExperimentByTestName(testName); From c6d4cf32caa1dea7a504956b98e1cb26ac339283 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 31 Mar 2026 14:13:43 -0400 Subject: [PATCH 3/3] readability null means car doesnt check recal --- src/helpers/service-location-helper.js | 2 +- src/layouts/schedule-page/service-location/service-location.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 2c074a3a..5da94148 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -79,7 +79,7 @@ export function isServiceableMobileWithData(isGlassServiceableMobile, isRecalibr return false; } - if (isRecalibrationServiceableMobile !== null) { + if (isRecalibrationServiceableMobile === true || isRecalibrationServiceableMobile === false) { return ( isGlassServiceableMobile && isRecalibrationServiceableMobile diff --git a/src/layouts/schedule-page/service-location/service-location.vue b/src/layouts/schedule-page/service-location/service-location.vue index 227c20bb..7476acd1 100644 --- a/src/layouts/schedule-page/service-location/service-location.vue +++ b/src/layouts/schedule-page/service-location/service-location.vue @@ -252,7 +252,7 @@ export default { return false; } - if (this.isRecalibrationServiceableMobile !== null) { + if (this.isRecalibrationServiceableMobile === true || this.isRecalibrationServiceableMobile === false) { return ( this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile