DigitalConsumer.ISS/src/layouts/order-confirmation/order-confirmation.vue
2024-02-29 16:13:21 -05:00

259 lines
9.3 KiB
Vue

<template>
<Form
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
<div class="main-content-container">
<div class="text-center text-color--black pt-5 pb-5 fs-5">
<img :src="orderConfirmationImage" />
<span
class="ms-2"
v-html="orderConfirmationHeaderText"></span>
</div>
<div class="appointment-details">
<div>
<vehicleBanner
cmsWidgetName="VehicleBannerWidget"
:displayGenericVehicleImage="false">
</vehicleBanner>
</div>
<div class="appointment-date-time text-center">
<p>{{ appointmentDateFormatted }}</p>
<p>{{ appointmentTimeFormatted }}</p>
</div>
<div
class="appointment-text text-center text-color--black lh-base"
v-html="appointmentWordingText">
</div>
</div>
<siteFooter
v-if="carrierUrl"
ref="siteFooter"
cmsWidgetName="SiteFooterWidget"
:isStackedVertically="true"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="navigateBack" />
</div>
</div>
</div>
</Form>
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header.vue';
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
import { get12HourTimeFormat, get12HourTimeMobileFormat, convertDateStringToDate } from '@/helpers/date-helper.js';
import { toTitleCase } from '@/helpers/text-helper.js';
export default {
name: 'order-confirmation',
components: {
siteHeader,
vehicleBanner,
siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form
},
mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
}];
// use resultMap to populate layout content.
const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
});
},
setup() {
const mainStore = useMainStore();
return { mainStore };
},
computed: {
carrierName() {
return this.mainStore.issConfig.clientName;
},
carrierUrl() {
return this.mainStore.issConfig.successReturnURL;
},
orderConfirmationHeaderText() {
return this.getCmsContent('OrderConfirmationContent', 'HeaderText');
},
orderConfirmationImage() {
return this.getCmsContent('OrderConfirmationContent', 'Image');
},
appointmentType() {
return this.mainStore.order.serviceLocation.appointmentType.toUpperCase();
},
appointmentDate() {
return this.mainStore.order.schedule.date;
},
appointmentStartTime() {
return this.mainStore.order.schedule.startTime;
},
appointmentEndTime() {
return this.mainStore.order.schedule.endTime;
},
appointmentDateFormatted() {
// This conversion ensures we don't get get GMT induced date changes
const dateObject = convertDateStringToDate(this.appointmentDate);
// Ex: Tuesday, April 22
return dateObject.toLocaleDateString('en-us', {
weekday: 'long',
month: 'long',
day: 'numeric'
});
},
appointmentTimeFormatted() {
const formattedTime = this.formatAppointmentTime(this.appointmentType);
return formattedTime;
},
mobileWordingText() {
return this.getCmsContent('MobileWordingWidget', 'BodyText');
},
dropOffAndInShopWordingText() {
return this.getCmsContent('DropOffAndInShopWordingWidget', 'BodyText');
},
serviceLocationAddress() {
return this.mainStore.order.serviceLocation.address;
},
serviceLocationAddress2() {
return this.mainStore.order.serviceLocation.address2;
},
serviceLocationCity() {
return this.mainStore.order.serviceLocation.city;
},
serviceLocationState() {
return this.mainStore.order.serviceLocation.state;
},
serviceLocationZipCode() {
return this.mainStore.order.serviceLocation.zipCode;
},
serviceLocationFullAddress() {
// eslint-disable-next-line max-len
return `<br/>${this.serviceLocationAddress}, ${this.serviceLocationAddress2 ? `${this.serviceLocationAddress2},` : ''}<br/> ${this.serviceLocationCity}, ${this.serviceLocationState} ${this.serviceLocationZipCode}<br/>`;
},
providerAddress() {
return toTitleCase(this.mainStore.order.serviceLocation.provider.address.streetAddress);
},
providerCity() {
return toTitleCase(this.mainStore.order.serviceLocation.provider.address.city);
},
providerState() {
return this.mainStore.order.serviceLocation.provider.address.state;
},
providerZipCode() {
return this.mainStore.order.serviceLocation.provider.address.zipCode;
},
providerFullAddress() {
// eslint-disable-next-line max-len
return `<br/>${this.providerAddress},<br/> ${this.providerCity}, ${this.providerState} ${this.providerZipCode}<br/>`;
},
appointmentWordingText() {
return this.formatWordingText(this.appointmentType);
}
},
mounted() {
if (this.carrierUrl) {
this.$refs.siteFooter.updateButtonText(`Go back to ${this.carrierName}`);
}
},
methods: {
forwardButtonAction() {
this.$router.navigateToExternalUrl(this.carrierUrl);
},
formatAppointmentTime(appointmentType) {
switch (appointmentType) {
case 'MOBILE':
// eslint-disable-next-line max-len
return `Between ${get12HourTimeMobileFormat(this.appointmentStartTime)} - ${get12HourTimeMobileFormat(this.appointmentEndTime)}`;
case 'DROP OFF':
return 'Drop off before 9:30 AM';
case 'INSHOP':
return `at ${get12HourTimeFormat(this.appointmentStartTime)}`;
default:
return null;
}
},
formatWordingText(appointmentType) {
switch (appointmentType) {
case 'MOBILE':
return this.mobileWordingText?.replaceAll(
'{custom:address}',
this.serviceLocationFullAddress
);
case 'DROP OFF':
return this.dropOffAndInShopWordingText?.replaceAll(
'{custom:address}',
this.providerFullAddress
);
case 'INSHOP':
return this.dropOffAndInShopWordingText?.replaceAll(
'{custom:address}',
this.providerFullAddress
);
default:
return null;
}
}
}
};
</script>
<style lang="scss" scoped>
$page-side-padding: 1.5rem;
.page-container-grouped-styles {
overflow: auto;
.main-content-container {
padding: 0 1.5rem !important;
}
}
.text-color--black {
color: $black;
}
.appointment-details {
margin-bottom: 1.5rem;
padding: 1rem 1.5rem 1.5rem;
box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
border-radius: 5px;
}
.appointment-date-time P {
color: $black;
font-size: $h5-font-size;
line-height: map-get($spacers, 6);
margin-bottom: 0.5rem;
+ p {
font-size: map-get($spacers, 4);
line-height: 1.625rem;
font-weight: $font-weight-bold;
}
}
.appointment-text {
:deep(strong) {
font-weight: $font-weight-bold;
}
}
</style>