DigitalConsumer.FixMyGlass/src/layouts/schedule/mobile-first-modal/mobile-first-modal.vue
2026-01-06 10:09:26 -05:00

242 lines
8.6 KiB
Vue

<template>
<div id="mobile-first-modal-container">
<modal
:ref="modalName"
:headerText="modalHeaderText"
suppressPageScroll
:onModalClosedCallback="onModalClosed"
:footerButtonText="modalFooterText"
:isFooterButtonPrimary="true"
@footer-button-event="confirmAppointment"
@isModalOpened="setIsModalOpen">
<p class="modal-body-inner" v-html="modalBodyText"></p>
<template v-slot:modal-header-slot>
<span>{{ modalSubHeaderText }}</span>
</template>
<template v-slot:modal-footer-slot>
<button
type="button"
class="btn btn-link"
id="see-more-options"
:disabled="isLoading"
@click="closeModal">
{{ buttonText }}
</button>
</template>
</modal>
</div>
</template>
<script>
// Supporting files
import store from "@/store";
import modal from "@/digital-components/modal/modal";
import { splitCopyOnCMSPlaceHolder } from "@/helpers/cms-content-helper";
import { get12HourTimeFormat } from "@/helpers/date-helper";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
const INLINE_SERVICETYPE_TOKEN = "custom:serviceType";
const INLINE_DAY_TOKEN = "custom:day";
const INLINE_DATE_TOKEN = "custom:date";
const INLINE_TIMESLOT_TOKEN = "custom:timeslot";
const INLINE_SERVICE_LENGTH_TOKEN = "custom:serviceLength";
export default {
name: "mobile-first-modal",
props: {
cmsWidgetName: String,
modalWidgetName: String,
},
data() {
return {
isModalOpen: false,
selectedAppointment: {
estimatedServiceMinutes: {
minimum: null,
maximum: null,
},
timeSlot: null,
date: null,
},
confirmedAppointment: false,
};
},
methods: {
splitCopyOnCMSPlaceHolder,
get12HourTimeFormat,
openModal() {
this.modal.openModal();
},
onModalClosed() {
this.pushEvent();
this.$emit("close-mobile-first-modal");
this.confirmedAppointment = false;
},
closeModal() {
this.modal.closeModal();
},
confirmAppointment() {
let selectedTimeSlot = {
timeSlot: this.selectedAppointment.timeSlot,
routeCode: this.selectedAppointment.timeSlot.id,
date: this.selectedAppointment.date,
};
this.confirmedAppointment = true;
this.$emit("confirm-appointment", selectedTimeSlot);
this.modal.closeModal();
},
setSelectedAppointment(appointment) {
this.selectedAppointment = appointment;
},
getIsModalOpen() {
return this.isModalOpen;
},
setIsModalOpen(isOpen) {
this.isModalOpen = isOpen;
},
pushEvent() {
let gaAction = this.confirmedAppointment ? this.GaActions.YES : this.GaActions.NO;
if (this.selectedAppointment && this.selectedAppointment.timeSlot) {
this.pushEventToGA(
this.GaCategories.CONFIRMATION_CLICKED,
gaAction,
this.selectedAppointment.timeSlot.startTime +
"-" +
this.selectedAppointment.timeSlot.endTime +
" " +
this.selectedAppointment.date,
true
);
}
},
},
computed: {
modalName() {
return this.modalWidgetName;
},
modal() {
return this.$refs[this.modalName];
},
modalSubHeaderText() {
return this.getCmsContent(this.modalWidgetName, "SubheaderText");
},
modalHeaderText() {
return this.getCmsContent(this.modalWidgetName, "HeaderText");
},
modalBodyText() {
var tokens = this.splitCopyOnCMSPlaceHolder(
this.getCmsContent(this.modalWidgetName, "BodyText")
);
tokens.forEach((token) => {
if (token.includes(INLINE_SERVICETYPE_TOKEN)) {
const serviceType = "<strong>" + this.getServiceType + "</strong>";
tokens.splice(tokens.indexOf(token), 1, serviceType);
} else if (token.includes(INLINE_DAY_TOKEN) && this.selectedAppointment.date) {
const day =
"<strong>" +
new Date(this.selectedAppointment.date).toLocaleDateString("en-US", {
weekday: "long",
timeZone: "UTC",
}) +
"</strong>";
tokens.splice(tokens.indexOf(token), 1, day);
} else if (token.includes(INLINE_DATE_TOKEN) && this.selectedAppointment.date) {
const date = new Date(this.selectedAppointment.date).toLocaleDateString(
"en-US",
{ timeZone: "UTC", weekday: "long", month: "long", day: "numeric" }
);
tokens.splice(tokens.indexOf(token), 1, date);
} else if (
token.includes(INLINE_TIMESLOT_TOKEN) &&
this.selectedAppointment.timeSlot
) {
const timeslot =
this.get12HourTimeFormat(this.selectedAppointment.timeSlot.startTime) +
" - " +
this.get12HourTimeFormat(this.selectedAppointment.timeSlot.endTime);
tokens.splice(tokens.indexOf(token), 1, timeslot);
} else if (
token.includes(INLINE_SERVICE_LENGTH_TOKEN) &&
this.selectedAppointment.estimatedServiceMinutes
) {
const inshopDurationTime = getDisplayTextForDurationLength(
this.selectedAppointment.estimatedServiceMinutes.minimum,
this.selectedAppointment.estimatedServiceMinutes.maximum
);
tokens.splice(tokens.indexOf(token), 1, inshopDurationTime);
}
});
return tokens.join("");
},
modalFooterText() {
return this.getCmsContent(this.modalWidgetName, "FooterText");
},
buttonText() {
return this.getCmsContent(this.modalWidgetName, "FooterText2");
},
getServiceType() {
return store.getters.order.damage.isRepair ? "repair" : "replace";
},
},
components: { modal },
};
</script>
<style lang="scss">
#mobile-first-modal-container {
.modal-component {
@include media-breakpoint-up(md) {
.modal-dialog {
left: 0;
align-content: center;
flex-wrap: wrap;
width: 22.063rem;
transform: translate(0, 0);
.modal-content {
border-radius: $border-radius-lg;
}
}
}
.modal-dialog {
.modal-content {
.modal-header {
flex-direction: column;
& > span {
color: $red;
font-size: $font-size-14;
font-weight: $font-weight-600;
text-transform: uppercase;
}
.modal-title {
font-size: $font-size-20;
font-weight: $font-weight-normal;
}
}
.modal-body {
padding: 0.5rem 1rem;
.modal-body-inner {
ul {
list-style: none;
padding: 1rem;
background-color: #f4f4f4;
font-size: $font-size-14;
}
}
}
.modal-footer {
flex-flow: wrap-reverse;
#see-more-options {
width: 100%;
text-decoration: none;
margin-top: 1.5rem;
font-weight: $font-weight-600;
}
}
}
}
}
}
</style>