Merge branch 'release/2026.01.15' into feature/CASH-2114

This commit is contained in:
Chris 2026-01-12 16:13:01 -05:00 committed by GitHub
commit 72f3a686b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 102 additions and 59 deletions

View file

@ -281,7 +281,7 @@ export default {
if (event.screenX === 0 && event.screenY === 0) { if (event.screenX === 0 && event.screenY === 0) {
return; return;
} }
this.$emit("date-selected", date); this.$emit("date-clicked", date);
}, },
getWeekStartDate(dateString) { getWeekStartDate(dateString) {
const date = convertDateStringToDate(dateString); const date = convertDateStringToDate(dateString);
@ -846,6 +846,12 @@ export default {
}, },
}, },
watch: { watch: {
isLoading(newValue) {
// if done loading dates, then set to first available date
if (newValue === false && this.firstAvailableSelectableDate) {
this.selectedDate = this.firstAvailableSelectableDate;
}
},
modelValue(newValue) { modelValue(newValue) {
this.resetField({ this.resetField({
value: newValue, value: newValue,

View file

@ -22,7 +22,6 @@
cmsWidgetName="ScheduleYourServiceWidget" cmsWidgetName="ScheduleYourServiceWidget"
id="schedule-your-service" /> id="schedule-your-service" />
<appointmentTypeQuestion <appointmentTypeQuestion
v-if="hasSelectableDatesLoaded"
v-model="appointmentTypeFromAppointmentTypeQuestion" v-model="appointmentTypeFromAppointmentTypeQuestion"
v-show="isAppointmentTypeDisplayed" v-show="isAppointmentTypeDisplayed"
:isServiceableMobile="isServiceableMobile" :isServiceableMobile="isServiceableMobile"
@ -134,6 +133,8 @@
:isOvernightDropoff="isOvernightDropoff" /> :isOvernightDropoff="isOvernightDropoff" />
</div> </div>
<datePicker <datePicker
:currentZip="zipCode"
:currentProviderNumber="selectedProvider?.providerNumber"
v-show="appointmentType" v-show="appointmentType"
customComponentId="dateQuestion" customComponentId="dateQuestion"
selectableDatesSetting="custom" selectableDatesSetting="custom"
@ -143,7 +144,7 @@
class="text-link-small" class="text-link-small"
:getMoreDatesCallback="getMoreScheduleData" :getMoreDatesCallback="getMoreScheduleData"
validationRules="date-required" validationRules="date-required"
@date-selected="handleDateSelected" @date-clicked="handleDateClicked"
:pricingByDayBasePrice="pricingByDayBasePrice" :pricingByDayBasePrice="pricingByDayBasePrice"
:pricingByDayUpcharge="pricingByDayUpcharge" :pricingByDayUpcharge="pricingByDayUpcharge"
:showPricingByDay="showPricingByDay" :showPricingByDay="showPricingByDay"
@ -639,12 +640,12 @@ export default {
showTimeSlotQuestion() { showTimeSlotQuestion() {
if ( if (
this.selectedDate && this.selectedDate &&
this.appointmentTypeFromAppointmentTypeQuestion && this.selectedDate.includes("mobile") &&
this.timeSlotsForSelectedDate !this.isMobileSelected
) { ) {
return true; this.setSelectedDateToFirstAvailable();
} }
return false; return this.selectedDate && this.appointmentTypeFromAppointmentTypeQuestion;
}, },
isMobileStaticRecalibrationApplicable() { isMobileStaticRecalibrationApplicable() {
return ( return (
@ -872,13 +873,6 @@ export default {
? this.$refs.mobileFirstModal?.getIsModalOpen() ? this.$refs.mobileFirstModal?.getIsModalOpen()
: false; : false;
}, },
hasSelectableDatesLoaded() {
if (this.isMobileSelected) {
return this.selectableDatesMobile?.days?.length > 0;
} else {
return this.selectableDatesInshop?.days?.length > 0;
}
},
}, },
methods: { methods: {
splitCopyOnCMSPlaceHolder, splitCopyOnCMSPlaceHolder,
@ -1140,6 +1134,29 @@ export default {
); );
} }
}, },
getTimeSlotInfo() {
// Get the current date
const currentDate = getTodayDate();
// Add 10 days to the current date
currentDate.setDate(currentDate.getDate() + 10);
// Format the date as yyyy-mm-dd
const year = currentDate.getFullYear();
const month = String(currentDate.getMonth() + 1).padStart(2, "0");
const day = String(currentDate.getDate()).padStart(2, "0");
const formattedDate = `${year}-${month}-${day}`;
return {
date: formattedDate,
endTime: "12:00",
jobMaxMinutes: "180",
jobMinMinutes: "120",
routeCode: "3357I-03357-M-I*20988*AM",
startTime: "08:00",
};
},
onShopSelected(shopQuestionPopUpData) { onShopSelected(shopQuestionPopUpData) {
this.resetWaitlist(); this.resetWaitlist();
this.preSelectedDate = null; this.preSelectedDate = null;
@ -1192,6 +1209,8 @@ export default {
async initializeDatePicker() { async initializeDatePicker() {
this.isShowMobileFirstAppt && this.showLoadingModal(); this.isShowMobileFirstAppt && this.showLoadingModal();
this.selectedDate = null;
const includeMobileTimeSlots = this.isServiceableMobile; const includeMobileTimeSlots = this.isServiceableMobile;
const includeInshopTimeSlots = this.isServiceableInshop || this.isServiceableDropoff; const includeInshopTimeSlots = this.isServiceableInshop || this.isServiceableDropoff;
const datePickerInitialData = await this.$refs.datePicker.loadInitialData({ const datePickerInitialData = await this.$refs.datePicker.loadInitialData({
@ -1582,40 +1601,28 @@ export default {
handleWaitListRequested(value) { handleWaitListRequested(value) {
this.waitListRequested = value; this.waitListRequested = value;
}, },
handleDateSelected(date) { handleDateClicked(date) {
const previousDate = this.selectedDate; // do something to mark this as upcharge day or not...
if (date.isPricingByDayUpchargeDay) {
// check if date actually changed this.includePricingByDayUpcharge = true;
if (previousDate !== date.dateString) { } else {
this.selectedTimeSlotInfo = this.getEmptyTimeSlot(); this.includePricingByDayUpcharge = false;
this.updateFooterButtonText(this.selectedTimeSlotInfo);
} }
// TODO: REMOVE AS PART OF CASH-1634
// // do something to mark this as upcharge day or not...
// if (date.isPricingByDayUpchargeDay) {
// this.includePricingByDayUpcharge = true;
// } else {
// this.includePricingByDayUpcharge = false;
// }
},
getEmptyTimeSlot() {
return {
timeSlot: {
date: null,
routeCode: null,
startTime: null,
endTime: null,
jobMaxMinutes: null,
jobMinMinutes: null,
},
isPremiumAppointment: null,
};
}, },
updateTimeSlot(timeSlotObj) { updateTimeSlot(timeSlotObj) {
if (!timeSlotObj?.routeCode) { if (!timeSlotObj?.routeCode) {
this.appointmentType = AppointmentTypeStrings.IN_SHOP_OR_DROP_OFF; this.appointmentType = AppointmentTypeStrings.IN_SHOP_OR_DROP_OFF;
this.selectedTimeSlotInfo = this.getEmptyTimeSlot(); this.selectedTimeSlotInfo = {
timeSlot: {
date: null,
routeCode: null,
startTime: null,
endTime: null,
jobMaxMinutes: null,
jobMinMinutes: null,
},
isPremiumAppointment: null,
};
return; return;
} }
const timeSlot = this.timeSlotsForSelectedDate?.timeSlots?.find( const timeSlot = this.timeSlotsForSelectedDate?.timeSlots?.find(
@ -1714,9 +1721,6 @@ export default {
}, },
handleAppointmentTypeChange(newAppointmentType) { handleAppointmentTypeChange(newAppointmentType) {
this.updateFooterButtonText(); this.updateFooterButtonText();
// if time appointment type changes, clear any selected time slot
this.selectedTimeSlotInfo = this.getEmptyTimeSlot();
if (newAppointmentType === AppointmentTypeStrings.MOBILE) { if (newAppointmentType === AppointmentTypeStrings.MOBILE) {
// Remember last shop selected if previous selection was inshop/dropoff // Remember last shop selected if previous selection was inshop/dropoff
if ( if (
@ -1725,6 +1729,17 @@ export default {
AppointmentTypeStrings.IN_SHOP_OR_DROP_OFF) && AppointmentTypeStrings.IN_SHOP_OR_DROP_OFF) &&
this.selectedProvider this.selectedProvider
) { ) {
this.selectedTimeSlotInfo = {
timeSlot: {
date: null,
routeCode: null,
startTime: null,
endTime: null,
jobMaxMinutes: null,
jobMinMinutes: null,
},
isPremiumAppointment: null,
};
this.lastSelectedInshopOrDropoffProvider = this.selectedProvider; this.lastSelectedInshopOrDropoffProvider = this.selectedProvider;
} }
this.appointmentType = AppointmentTypeStrings.MOBILE; this.appointmentType = AppointmentTypeStrings.MOBILE;
@ -1751,8 +1766,8 @@ export default {
} else { } else {
this.appointmentType = null; this.appointmentType = null;
} }
this.setSelectedDateToFirstAvailable(); // v-if on appointmentTypeQuestion ensures dates have been loaded by now this.setSelectedDateToFirstAvailable();
this.setDisplayWaitList(); // v-if on appointmentTypeQuestion ensures dates have been loaded by now this.setDisplayWaitList();
}, },
setSelectedDateToFirstAvailable() { setSelectedDateToFirstAvailable() {
this.selectedDate = this.getFirstAvailableDate(); this.selectedDate = this.getFirstAvailableDate();
@ -1884,9 +1899,35 @@ export default {
watch: { watch: {
appointmentTypeFromAppointmentTypeQuestion: { appointmentTypeFromAppointmentTypeQuestion: {
handler(newValue, oldValue) { handler(newValue, oldValue) {
this.handleAppointmentTypeChange(newValue); // v-if on appointmentTypeQuestion ensures dates have been loaded by now this.handleAppointmentTypeChange(newValue);
}, },
}, },
selectedDate(newValue, oldValue) {
// Clear time slot selection if date selected changes
const selectedDate = this.getSelectedDateFromStore();
if (oldValue && this.appointmentType === AppointmentTypeStrings.MOBILE) {
oldValue = `${oldValue}-mobile`;
}
const hasValueChanged = newValue !== oldValue;
const isDateDifferent = (newValue || oldValue) !== selectedDate;
if (hasValueChanged && isDateDifferent && !this.selectedMobileFirstAppointment) {
this.selectedTimeSlotInfo = {
timeSlot: {
date: null,
routeCode: null,
startTime: null,
endTime: null,
jobMaxMinutes: null,
jobMinMinutes: null,
},
isPremiumAppointment: null,
};
}
},
selectedTimeSlotInfo(newValue) {
this.updateFooterButtonText(newValue);
},
}, },
components: { components: {
funnelHeader, funnelHeader,
@ -1899,6 +1940,7 @@ export default {
textBlock, textBlock,
timeSlotQuestion, timeSlotQuestion,
mobileFirstModal, mobileFirstModal,
alert, alert,
serviceZipModalQuestion, serviceZipModalQuestion,
appointmentTypeQuestion, appointmentTypeQuestion,

View file

@ -1,7 +1,6 @@
<template> <template>
<div class="time-slots-question"> <div class="time-slots-question">
<buttonQuestion <buttonQuestion
ref="chooseDropOffOrInshop"
v-if="isDropOffAppointmentAvailable" v-if="isDropOffAppointmentAvailable"
v-model="selectedAnswerForDropOffOrInshop" v-model="selectedAnswerForDropOffOrInshop"
@update:modelValue="dropOffSelectionChanged" @update:modelValue="dropOffSelectionChanged"
@ -24,9 +23,8 @@
</div> </div>
</buttonQuestion> </buttonQuestion>
<buttonQuestion <buttonQuestion
ref="chooseTimeSlot" ref="buttonQuestion"
v-if="displayTimeSlotQuestion" v-if="shouldDisplayTimeSlotQuestion"
v-model="selectedAnswerForTimeSlots"
@update:modelValue="timeSlotSelectionChanged" @update:modelValue="timeSlotSelectionChanged"
buttonTypeString="timeSlotModalListButton" buttonTypeString="timeSlotModalListButton"
:buttonTypeObject="timeSlotModalListButton" :buttonTypeObject="timeSlotModalListButton"
@ -36,12 +34,10 @@
isInshopOrDropOffAppointment ? 'is-inshop-or-drop-off-appointment' : '', isInshopOrDropOffAppointment ? 'is-inshop-or-drop-off-appointment' : '',
]" ]"
:answers="availableTimeSlots" :answers="availableTimeSlots"
:lazyLoad="{ :lazyLoad="{ isLazyLoad: !isMobileAppointment, amountToLoad: 10 }"
isLazyLoad: !isMobileAppointment && !selectedAnswerForTimeSlots,
amountToLoad: 10,
}"
groupName="chooseTimeSlot" groupName="chooseTimeSlot"
textPosition="text-center" textPosition="text-center"
v-model="selectedAnswerForTimeSlots"
questionText="Available times:" questionText="Available times:"
isRequired isRequired
validationRules="time-slot-required" /> validationRules="time-slot-required" />
@ -393,7 +389,7 @@ export default {
this.answersForDropOffQuestion[0].value !== PICK_A_TIME_BUTTON_VALUE this.answersForDropOffQuestion[0].value !== PICK_A_TIME_BUTTON_VALUE
); );
}, },
displayTimeSlotQuestion() { shouldDisplayTimeSlotQuestion() {
return ( return (
this.selectedAnswerForDropOffOrInshop == PICK_A_TIME_BUTTON_VALUE || this.selectedAnswerForDropOffOrInshop == PICK_A_TIME_BUTTON_VALUE ||
!this.isDropOffAppointmentAvailable !this.isDropOffAppointmentAvailable

View file

@ -80,7 +80,6 @@ export default {
}, },
set: function (newValue) { set: function (newValue) {
this.$emit("update:modelValue", newValue); this.$emit("update:modelValue", newValue);
this.$emit("handle-appointment-type-change", newValue);
}, },
}, },
isMobileOnly() { isMobileOnly() {