import timeSlotQuestion from "@/layouts/schedule/time-slot-question/time-slot-question.vue";
+import textBlock from "@/digital-components/text-block/text-block";
+import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
// Supporting files
import loader from "@/ux-components/loader/loader";
@@ -166,7 +179,12 @@ import {
MONTHS_OF_YEAR,
DAYS_OF_WEEK,
} from "@/digital-components/date-picker/mixins/constants";
-import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
+import {
+ AppointmentTypeStrings,
+ RouteCodeFlags,
+ PREMIUM_FEE_PART_TYPE,
+ cmsWidgetFieldMappings,
+} from "@/constants/schedule-constants";
import {
selectableDaysOptions,
requiredParameter,
@@ -178,6 +196,7 @@ import {
import { useField, ErrorMessage } from "vee-validate";
import { deepClone } from "@/helpers/object-helper";
import { v4 as uuidv4 } from "uuid";
+import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
export default {
name: "datePicker",
@@ -190,6 +209,7 @@ export default {
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
selectableDatesInshop: [], // NOTE: this and the mobile version below use monthNum (1-based), NOT monthIndex (0-based)
selectableDatesMobile: [],
+ durationTextBlockCopyForInshopOrDropoff: null,
};
},
props: {
@@ -224,7 +244,7 @@ export default {
pricingByDayUpcharge: Number,
isPricingByDayExperiment: Boolean,
timeSlotsForSelectedDate: Object,
- appointmentTypeForTimeSlotQuestion: String,
+ appointmentType: String,
premiumAppointmentFee: Object,
estimatedServiceMinutesMinimum: Number,
estimatedServiceMinutesMaximum: Number,
@@ -289,6 +309,54 @@ export default {
this.$emit("update:modelValue", newSelectedDate);
},
},
+ dropOffDurationText() {
+ return this.getCmsContent("DropOffTimeSlotModal", cmsWidgetFieldMappings.DURATION);
+ },
+ sameDayDropoffDurationText() {
+ return this.getCmsContent(
+ "SameDayDropOffTimeSlotModal",
+ cmsWidgetFieldMappings.DURATION
+ );
+ },
+ overnightDropoffDurationText() {
+ return this.getCmsContent(
+ "OvernightDropOffTimeSlotModal",
+ cmsWidgetFieldMappings.DURATION
+ );
+ },
+ inshopDurationText() {
+ const inshopDurationTextWithoutTime = this.getCmsContent(
+ "TimeSlotModalQuestion",
+ cmsWidgetFieldMappings.DURATION
+ );
+
+ const inshopDurationTime = getDisplayTextForDurationLength(
+ this.estimatedServiceMinutesMinimum,
+ this.estimatedServiceMinutesMaximum
+ );
+
+ return `${inshopDurationTextWithoutTime} ${inshopDurationTime}`;
+ },
+ durationTextBlockCopy() {
+ if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
+ return null;
+ } else if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
+ return this.inshopDurationText;
+ } else if (
+ this.appointmentType === AppointmentTypeStrings.IN_SHOP_OR_DROP_OFF ||
+ this.appointmentType === AppointmentTypeStrings.DROP_OFF
+ ) {
+ return this.durationTextBlockCopyForInshopOrDropoff ?? this.inshopDurationText;
+ }
+ return null;
+ },
+ isSameDay() {
+ if (!this.timeSlotsForSelectedDate) {
+ return false;
+ }
+ const todaysDate = new Date().toISOString().split("T")[0];
+ return this.selectedDate === todaysDate;
+ },
},
methods: {
initializeComponent(initialData) {
@@ -877,6 +945,18 @@ export default {
handleWaitListRequested(value) {
this.$emit("waitListRequested", value);
},
+ getDurationTextBlockCopyForInshopOrDropoff(selectedRouteCode) {
+ if (selectedRouteCode?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
+ return this.overnightDropoffDurationText;
+ } else if (selectedRouteCode?.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
+ if (this.isSameDay) {
+ return this.sameDayDropoffDurationText;
+ } else {
+ return this.dropOffDurationText;
+ }
+ }
+ return this.inshopDurationText;
+ },
},
watch: {
modelValue(newValue) {
@@ -891,13 +971,18 @@ export default {
}
},
selectedTimeSlotInfo(newValue) {
- this.$emit("TimeSlotSelected", newValue); // NEEDED ON SCHEDULE - to update footer button text and to save to Store correctly
+ const routeCode = newValue?.timeSlot?.routeCode;
+ this.durationTextBlockCopyForInshopOrDropoff =
+ this.getDurationTextBlockCopyForInshopOrDropoff(routeCode);
+ this.$emit("TimeSlotSelected", newValue); // needed to update footer button text on Schedule page and to save to Store correctly
},
},
components: {
loader,
ErrorMessage,
timeSlotQuestion,
+ textBlock,
+ funnelSubHeader,
},
};
@@ -913,6 +998,10 @@ export default {
display: flex;
flex-direction: column;
+ .date-picker-header {
+ margin-bottom: 1.5rem;
+ }
+
fieldset {
flex-grow: 1;
position: relative;
diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue
index bede93c4e..28adbe65c 100644
--- a/src/layouts/schedule/schedule.vue
+++ b/src/layouts/schedule/schedule.vue
@@ -129,7 +129,6 @@
-
-
.time-slots-question {
- border-top: 1px solid $gray-500;
margin-top: 1.5rem;
.time-slot-header {