CASH-152: go back to just using one component for datePicker due to conflicts with 2

This commit is contained in:
Adam Caouette 2025-03-17 18:45:18 -04:00
parent b61e6e619a
commit 5bfbd71c93
3 changed files with 141 additions and 76 deletions

View file

@ -1,5 +1,5 @@
<template>
<div class="date-picker text-center" :class="calendarViewDirection">
<div class="date-picker text-center" :class="`${calendarViewDirection} ${isPricingByDayClass}`">
<fieldset id="date-picker-fieldset" ref="datePickerFieldset">
<legend class="sr-only">Select a day and time</legend>
<div
@ -72,7 +72,7 @@
:id="`${month.monthLabel}-${date.dateNum.toString()}`" />
<label :for="`${month.monthLabel}-${date.dateNum.toString()}`">
<span>{{ date.dateNum.toString() }}</span>
<span v-if="showPricingByDay && date.isSelectable">
<span v-if="isPricingByDayExperiment && showPricingByDay && date.isSelectable" class="price">
{{ date.priceString }}
</span>
</label>
@ -163,6 +163,7 @@ export default {
showPricingByDay: Boolean,
baseDayPrice: Number,
pricingByDayUpcharge: Number,
isPricingByDayExperiment: Boolean,
},
setup(props) {
const uuid = uuidv4();
@ -214,6 +215,9 @@ export default {
if (this.selectableDatesSetting === "custom") return "future";
return "past";
},
isPricingByDayClass() {
return this.isPricingByDayExperiment ? "pricing-by-day" : "";
},
selectedDate: {
get() {
return this.modelValue;
@ -795,7 +799,7 @@ export default {
.grid-item {
text-align: center;
margin: 0;
margin: 10px 3px;
font-size: 0.875rem;
line-height: 1.5;
@ -830,13 +834,12 @@ export default {
}
.month-year {
grid-area: 1 / 1 / 2 / 8;
grid-area: 1 / 1 / 2 / 5;
text-transform: uppercase;
font-weight: 300;
letter-spacing: 0.75px;
}
.legend {
display: none;
grid-area: 1 / 5 / 2 / 8;
.legend-circle {
border-radius: 50%;
@ -855,27 +858,43 @@ export default {
position: relative;
display: flex;
justify-content: center;
align-items: flex-start;
align-items: center;
outline: none;
width: 100%;
height: 1.5rem;
opacity: 1;
transition:
height ease 250ms,
opacity ease 250ms;
color: $gray-500;
background-color: $gray-100;
input[type="radio"] {
position: absolute; //override bootstrap
height: 0;
opacity: 0;
&:checked + label {
background: $blue-100;
border: 2px solid $blue;
border-radius: 4px;
&:focus-visible + label {
box-shadow: 0 0 0 2.5px $blue;
}
&:focus + label,
&:checked:focus + label {
box-shadow:
0 0 0 3px #fff,
0 0 0 5.5px #1574a1;
background-color: $blue;
color: $white;
&.current-day {
&:after {
background-color: $white;
}
.first-day {
color: $white;
}
}
}
&:checked + label {
color: $white;
background: $blue;
&:after {
background-color: $white;
}
@ -894,28 +913,17 @@ export default {
z-index: 1;
}
button {
width: 2.5rem;
font-size: 8px;
background: pink;
}
label {
position: relative;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 2.5rem;
height: 3rem;
width: 100%;
font-size: 0.75rem;
line-height: 1.2;
justify-content: flex-start;
padding: 0.25rem;
width: 2.5rem;
height: 2.5rem;
span {
margin-top: 0.25rem;
&.small {
font-size: 0.75rem;
color: $gray-550;
@ -947,17 +955,23 @@ export default {
}
&.selectable-day {
background-color: $white;
label {
color: $blue;
cursor: pointer;
span {
text-decoration: underline;
}
background-color: $blue-100;
border: 1px solid $blue;
min-width: 2.5rem;
width: 2.5rem;
border-radius: 50%;
}
}
&.unavailable-day {
label {
color: $gray-500;
background-color: $gray-100;
border: none;
pointer-events: none;
}
}
&.unavailable-day:not(&.sunday) {
label {
&::before {
@ -978,11 +992,12 @@ export default {
&:after {
content: "";
margin-top: 0.2rem;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
background-color: $black;
position: absolute;
top: 28px;
}
.first-day {
color: $blue;
@ -1073,7 +1088,82 @@ export default {
}
}
}
&.pricing-by-day { // pricing by day override styles
.calendar-grid-container .grid-item {
margin: 0;
}
.month-year {
grid-area: 1 / 1 / 2 / 8;
}
.legend {
display: none;
}
.radio-wrapper {
align-items: flex-start;
width: 100%;
height: 3rem;
color: $gray-500;
background-color: $gray-100;
input[type="radio"] {
&:focus-visible + label {
box-shadow: none;
}
&:focus + label,
&:checked:focus + label {
box-shadow: none;
background-color: $white;
color: $blue;
}
&:checked + label {
background: $blue-100;
border: 2px solid $blue;
border-radius: 4px;
color: $blue;
}
}
label {
flex-direction: column;
height: 3rem;
width: 100%;
font-size: 0.75rem;
line-height: 1.2;
justify-content: flex-start;
padding: 0.25rem;
span {
margin-top: 0.25rem;
}
}
&.selectable-day {
background-color: $white;
label {
background-color: $white;
border: none;
min-width: initial;
width: initial;
height: -webkit-fill-available;
border-radius: 0;
cursor: pointer;
span {
text-decoration: underline;
}
}
}
&.current-day {
label:after {
margin-top: 0.2rem;
position: relative;
top: 0;
}
}
}
}
}
.btn-link {
display: block;
position: relative;

View file

@ -662,7 +662,6 @@ function setupMocks({ customMountOptions }) {
wrapper.vm.setCmsContent = jest.fn();
wrapper.vm.$refs.datePicker.initializeComponent = jest.fn();
wrapper.vm.$refs.datePickerForPricingByDay.initializeComponent = jest.fn();
wrapper.vm.$refs.locationAlerts.initializeComponent = jest.fn();
wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
wrapper.vm.$refs.timeSlotModalQuestion.openModal = jest.fn();

View file

@ -19,20 +19,6 @@
</template>
<locationAlerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
<datePickerForPricingByDay
v-show="isPricingByDayExperiment"
customComponentId="dateQuestion"
selectableDatesSetting="custom"
ref="datePickerForPricingByDay"
v-model="selectedDate"
class="text-link-small"
:customSelectableDatesCallback="getAvailableDatesMethod"
validationRules="date-required"
:baseDayPrice="baseDayPrice"
:pricingByDayUpcharge="pricingByDayUpcharge"
:showPricingByDay="showPricingByDay"
@date-clicked="handleDateClicked" />
<datePicker
v-show="!isPricingByDayExperiment"
customComponentId="dateQuestion"
selectableDatesSetting="custom"
ref="datePicker"
@ -40,7 +26,11 @@
class="text-link-small"
:customSelectableDatesCallback="getAvailableDatesMethod"
validationRules="date-required"
@date-clicked="openInshopTimeSlotsModal" />
:baseDayPrice="baseDayPrice"
:pricingByDayUpcharge="pricingByDayUpcharge"
:showPricingByDay="showPricingByDay"
:isPricingByDayExperiment="isPricingByDayExperiment"
@date-clicked="handleDateClicked" />
<timeSlotModalQuestion
ref="timeSlotModalQuestion"
customComponentId="timeSlotModalQuestion"
@ -87,7 +77,6 @@ import navbar from "@/fmg-components/nav-bar/nav-bar";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import { Form, defineRule } from "vee-validate";
import datePicker from "@/digital-components/date-picker/date-picker";
import datePickerForPricingByDay from "@/experiment-components/date-picker-for-pricing-by-day";
import locationAlerts from "@/layouts/schedule/location-alerts/location-alerts";
import timeSlotModalQuestion from "./time-slot-modal-question/time-slot-modal-question";
@ -303,27 +292,16 @@ export default {
store.getters.order.serviceLocation.provider?.address?.zipCodeCtu
);
// While Pricing By Day Experiment is ongoing, there are two different datePickers, but only one will load
let datePickerInitialDataPromise;
if (isPricingByDayExperiment) {
datePickerInitialDataPromise = await datePickerForPricingByDay.methods.loadInitialData({
// setup config options for date-picker
selectableDatesSetting: "custom",
initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate,
baseDayPrice: baseDayPrice,
pricingByDayUpcharge: pricingByDayUpcharge,
});
} else {
datePickerInitialDataPromise = await datePicker.methods.loadInitialData({
// setup config options for date-picker
selectableDatesSetting: "custom",
initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate,
});
}
// While Pricing By Day Experiment is ongoing, using the updated datePicker
const datePickerInitialDataPromise = await datePickerForPricingByDay.methods.loadInitialData({
// setup config options for date-picker
selectableDatesSetting: "custom",
initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate,
baseDayPrice: baseDayPrice,
pricingByDayUpcharge: pricingByDayUpcharge,
});
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_MOBILE_PREMIUM_FEE,
@ -371,7 +349,6 @@ export default {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.$refs.datePicker.initializeComponent(resultMap.datePickerInitialData);
vm.$refs.datePickerForPricingByDay.initializeComponent(resultMap.datePickerInitialData);
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse;
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
@ -735,7 +712,6 @@ export default {
funnelSubHeader,
Form,
loadingModal,
datePicker,
datePickerForPricingByDay,
locationAlerts,
timeSlotModalQuestion,