DigitalConsumer.FixMyGlass/src/layouts/scheduling/waitlist-question/waitlist-question.vue
2026-07-15 08:49:44 -04:00

146 lines
4.4 KiB
Vue

<template>
<template v-if="shouldDisplay">
<div
class="waitlist-question bg-light rounded"
v-bind="$attrs"
@click="handleContainerClick">
<textBlock
cmsWidgetName="WaitListLabelWidget"
typeStyle="medium"
fontWeight="600"
class="waitlist-label"
marginTopSizeOverride="0" />
<div ref="checkboxWrapper">
<checkboxQuestion
class="mt-3"
cmsWidgetName="WaitListQuestionWidget"
v-model="localValue" />
</div>
</div>
<div v-if="localValue" class="rounded waitlist-success">
<img :src="waitListSuccessImage" class="success-image" alt="" />
<span v-html="waitListSuccessText" class="success-text"></span>
</div>
</template>
</template>
<script>
import textBlock from "@/digital-components/text-block/text-block";
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
import experimentMixin from "@/mixins/experiment-mixin";
import { experimentSettings } from "@/constants/experiments";
import {
calcDaysBetweenDates,
convertDateToDateString,
} from "@/layouts/schedule/helpers/schedule-helper.js";
export default {
name: "waitlistQuestion",
mixins: [experimentMixin],
emits: ["update:modelValue"],
props: {
modelValue: {
type: Boolean,
default: false,
},
availableDates: {
type: Array,
default: () => [],
},
},
computed: {
localValue: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
waitListSuccessImage() {
return this.getCmsContent("WaitListSuccessWidget", "Image");
},
waitListSuccessText() {
return this.getCmsContent("WaitListSuccessWidget", "BodyText");
},
waitlistThresholdDays() {
return this.hasSetting(experimentSettings.WAITLIST_THRESHOLD_DAYS)
? parseInt(this.getSettingValue(experimentSettings.WAITLIST_THRESHOLD_DAYS), 10)
: 0;
},
daysUntilEarliestAvailableDate() {
const earliestDateString = this.availableDates?.[0];
if (!earliestDateString) return null;
const todayString = convertDateToDateString(new Date());
return calcDaysBetweenDates(todayString, earliestDateString);
},
shouldDisplay() {
return (
this.hasSettingEqualTo(experimentSettings.DISPLAY_WAITLIST, "true") &&
this.daysUntilEarliestAvailableDate !== null &&
this.waitlistThresholdDays < this.daysUntilEarliestAvailableDate
);
},
},
methods: {
handleContainerClick(event) {
// The checkbox's own label/input already toggles localValue natively,
// so ignore clicks that originate inside it to avoid double-toggling.
// Checking against our own wrapper element (rather than an internal
// class name owned by checkboxQuestion) keeps this decoupled from
// that component's markup.
if (this.$refs.checkboxWrapper?.contains(event.target)) return;
this.localValue = !this.localValue;
},
},
components: {
textBlock,
checkboxQuestion,
},
};
</script>
<style lang="scss" scoped>
.waitlist-question {
box-shadow: 0 1px 5px 0 #00000033;
padding: 16px;
.waitlist-label {
font-family: UrbanistSemibold;
}
:deep(.ui-checkbox) {
padding-left: 0px;
input {
border-radius: 4px;
box-shadow: 0 1px 5px 0 #00000033;
}
}
:deep(.form-check-input) {
margin-left: 0px;
}
}
.waitlist-success {
margin: 1rem 0 0;
background-color: #ecf5e9;
display: flex;
align-items: flex-start;
border: 1px solid #0c7e47;
border-radius: 5px;
font-size: 1.125rem;
padding: 0.75rem 1rem;
.success-text {
margin-left: 0.5rem;
:deep(p) {
margin-bottom: 0;
}
}
.success-image {
margin-top: 4.5px;
width: 1rem;
height: 1rem;
color: #0c7e47;
}
}
</style>