diff --git a/src/constants/experiments.js b/src/constants/experiments.js
index 6a2796da9..f358fc89f 100644
--- a/src/constants/experiments.js
+++ b/src/constants/experiments.js
@@ -4,6 +4,7 @@ const experimentUniverses = {
MSR: "MSR",
IGQ_SkipQuote: "NextGen_IGQSkipToInsurance",
AFTERPAY_BREAKOUT_DISPLAY: "AfterpayBreakoutDisplay",
+ MOBILE_FIRST_APPOINTMENT: "MobileFirstAppointment",
};
const experimentSettings = {
@@ -28,6 +29,10 @@ const experimentSettings = {
DISPLAY_AFTERPAY_BREAKOUT_DISPLAY: "Display_AfterpayBreakoutDisplay",
AFTERPAY_EXTENDED_PAY_OPTION_THRESHOLD: "AfterPayExtendedPayOptionThreshold",
DYNAMO_LOGGING: "DynamoLogging",
+ SHOW_MOBILE_FIRST_APPT: "ShowMobileFirstAppt",
+ SHOW_PM_MOBILE_DAYS: "Show_PMmobileDays",
+ SHOW_NO_PM_MOBILE_DAYS: "Show_NoPMmobileDays",
+ SHOW_NO_MOBILE_AVAILABLE_DAYS: "Show_NoMobileAvailableDays",
};
const experimentTriggers = {
diff --git a/src/digital-components/modal/modal.vue b/src/digital-components/modal/modal.vue
index 9167c03b3..867e73c75 100644
--- a/src/digital-components/modal/modal.vue
+++ b/src/digital-components/modal/modal.vue
@@ -14,6 +14,7 @@
+
{
@@ -1172,6 +1182,8 @@ export default {
moreShopTimeSlots.mobileTimeSlotsData.days
);
+ this.showMobileFirstModal();
+
return moreShopTimeSlots;
},
@@ -1699,6 +1711,7 @@ export default {
}
this.appointmentType = AppointmentTypeStrings.MOBILE;
this.updateSelectedProvider();
+ this.showMobileFirstModal();
} else if (newAppointmentType) {
if (this.appointmentType != AppointmentTypeStrings.MOBILE) {
// Clear last shop selected if appointment type was changed in any manner other than from Mobile
@@ -1723,6 +1736,116 @@ export default {
setSelectedDateToFirstAvailable() {
this.selectedDate = this.getFirstAvailableDate();
},
+ showMobileFirstModal() {
+ if (this.appointmentType == AppointmentTypeStrings.MOBILE) {
+ const isShowMobileFirstAppt = experimentMixin.methods.hasSettingEqualTo(
+ experimentSettings.SHOW_MOBILE_FIRST_APPT,
+ "true"
+ );
+ const pmMobileDays = experimentMixin.methods.getSettingValue(
+ experimentSettings.SHOW_PM_MOBILE_DAYS
+ );
+ const noPMMobileDays = experimentMixin.methods.getSettingValue(
+ experimentSettings.SHOW_NO_PM_MOBILE_DAYS
+ );
+ const noMobileAvailableDays = experimentMixin.methods.getSettingValue(
+ experimentSettings.SHOW_NO_MOBILE_AVAILABLE_DAYS
+ );
+
+ let preSelectedMobileAppointment = null;
+ const todaysDate = getTodayDate();
+ let firstMobilePMAppt = this.getFirstAvailableMobileApptByTOD("PM");
+ if (!firstMobilePMAppt) {
+ return;
+ }
+ let firstMobilePMDate = firstMobilePMAppt ? firstMobilePMAppt.date : null;
+ let numberOfDaysToFirstMobilePMDate =
+ (new Date(firstMobilePMDate) - todaysDate) / (1000 * 60 * 60 * 24);
+
+ const shouldExposeMobileFirstAppointment = () => {
+ return (
+ firstMobilePMDate &&
+ numberOfDaysToFirstMobilePMDate <= noMobileAvailableDays
+ );
+ };
+
+ if (shouldExposeMobileFirstAppointment()) {
+ const mobileFirstExperiment = store.getters.applicationUser.experiments.find(
+ (e) => e.universeName === experimentUniverses.MOBILE_FIRST_APPOINTMENT
+ );
+ const hasExposedMobileFirst = mobileFirstExperiment?.isExposed;
+
+ if (!hasExposedMobileFirst && mobileFirstExperiment) {
+ baseMixin.methods.dispatchStoreActionWithLogging(
+ storeActions.LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE,
+ {
+ userId: getUserIdValue(),
+ deviceId: getDeviceIdValue(),
+ sessionKey: getSessionKeyValue(),
+ pageName: "schedule",
+ experiment: mobileFirstExperiment,
+ },
+ "schedule",
+ false
+ );
+
+ if (isShowMobileFirstAppt) {
+ if (
+ firstMobilePMDate &&
+ numberOfDaysToFirstMobilePMDate <= pmMobileDays
+ ) {
+ preSelectedMobileAppointment = firstMobilePMAppt;
+ } else if (
+ firstMobilePMDate &&
+ numberOfDaysToFirstMobilePMDate >= noPMMobileDays
+ ) {
+ let firstMobileAMAppt = this.getFirstAvailableMobileApptByTOD("AM");
+ preSelectedMobileAppointment = firstMobileAMAppt
+ ? firstMobileAMAppt
+ : null;
+ !preSelectedMobileAppointment &&
+ (preSelectedMobileAppointment = firstMobilePMAppt);
+ }
+
+ this.$refs.mobileFirstModal.setSelectedAppointment(
+ preSelectedMobileAppointment
+ );
+ this.$refs.mobileFirstModal.openModal();
+ }
+ }
+ }
+ }
+ },
+ getFirstAvailableMobileApptByTOD(timeOfDay) {
+ if (!this.selectableDatesMobile?.days?.length) {
+ return null;
+ } else {
+ for (const dateObj of this.selectableDatesMobile.days) {
+ let matchingTimeSlot = {
+ estimatedServiceMinutes: {
+ minimum: this.estimatedServiceMinutesMinimum,
+ maximum: this.estimatedServiceMinutesMaximum,
+ },
+ timeSlot: null,
+ date: null,
+ };
+ const isMatchingApptDay = dateObj.timeSlots.some(
+ (slot) =>
+ slot.id.includes(timeOfDay) &&
+ (matchingTimeSlot.timeSlot = slot) &&
+ (matchingTimeSlot.date = dateObj.date)
+ );
+ if (isMatchingApptDay && matchingTimeSlot) {
+ return matchingTimeSlot;
+ }
+ }
+ return null;
+ }
+ },
+ updateTimeSlotandNavigateForward(timeSlotObj) {
+ this.updateTimeSlot(timeSlotObj);
+ this.forwardButtonAction();
+ },
},
watch: {
appointmentTypeFromAppointmentTypeQuestion: {
@@ -1767,6 +1890,7 @@ export default {
locationAlerts,
textBlock,
timeSlotQuestion,
+ mobileFirstModal,
alert,
serviceZipModalQuestion,
diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss
index c0a69a112..0c275ad51 100644
--- a/src/styles/ux-variables.scss
+++ b/src/styles/ux-variables.scss
@@ -123,14 +123,15 @@ $body-color: $gray-600;
//Fonts
$font-family-sans-serif: UrbanistRegular, Arial, Helvetica, sans-serif;
-$font-family-monospace: UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
- monospace;
+$font-family-monospace:
+ UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
// stylelint-enable value-keyword-case
$font-family-base: $font-family-sans-serif;
$font-family-code: $font-family-monospace;
$font-size-base: 1rem; // Assumes the browser default, typically `16px`
$font-size-12: $font-size-base * 0.75; // 12px
+$font-size-14: $font-size-base * 0.875; // 14px
$font-size-20: $font-size-base * 1.25; // 20px
//Custom Font size (extra small)