DigitalConsumer.ISS/src/layouts/order-confirmation/order-confirmation.vue
Michaela Brydon 23de2db48e Almost clean
2024-08-12 15:00:19 -04:00

466 lines
17 KiB
Vue

<template>
<Form
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="container-fluid fade-on-route-transition">
<div class="row justify-content-center">
<div class="col-md-6 px-0 px-md-2">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<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 mt-4">
<p>{{ formatDate(schedule.date) }}</p>
<p class="mt-2">{{ appointmentTimeFormatted }}</p>
</div>
<addToCalendar
mobileWidgetName="AddToCalendar_Mobile"
inShopWidgetName="AddToCalendar_InShop"
dropOffWidgetName="AddToCalendar_DropOff"
overnightDropOffWidgetName="AddToCalendar_OvernightDropOff"
allDayDropOffWidgetName="AddToCalendar_AllDayDropOff"
sameDayDropOffWidgetName="AddToCalendar_SameDayDropOff"
:serviceLocationFullAddress="
serviceLocationFullAddress
"
:providerFullAddress="providerFullAddress"
:appointmentType="appointmentType"
:scheduleDate="schedule.date"
:scheduleStartTime="schedule.startTime"
:scheduleEndTime="schedule.endTime" />
<div
class="appointment-text text-center lh-base"
v-html="appointmentWordingText"></div>
<div
class="appointment-text text-center lh-base mt-2"
v-html="appointmentWordingText2"></div>
</div>
<hr class="mb-0" />
<div>
<cartDropdown
:showAsPaid="payment.isPayInAdvance"
:readOnly="true"
:isInitiallyExpanded="false"
:showDropdownHeader="true"
recyclingModalCmsWidgetName="RecycleModal"
servicePackageTitleWidgetName="ServicePackageTitle"
:submittedOrder="submittedOrder" />
</div>
<hr class="mt-0 mb-5" />
<div
class="email-confirmation-text"
v-html="confirmationEmailText" />
<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';
import addToCalendar from '@/layouts/order-confirmation/add-to-calendar/add-to-calendar.vue';
import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue';
// Supporting files
import {
fetchCmsContentForPage,
processIfStatements,
getStringWithCustomValues
} 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,
getDisplayTextForDurationLength
} from '@/helpers/date-helper.js';
import { toTitleCase } from '@/helpers/text-helper.js';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import applicationConfig from '@/constants/application-config';
import widgetFields from '@/constants/cms-widget-fields.js';
export default {
name: 'order-confirmation',
components: {
// eslint-disable-next-line vue/no-reserved-component-names
Form,
siteHeader,
vehicleBanner,
siteFooter,
addToCalendar,
cartDropdown
},
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();
const submittedOrder = mainStore.getSubmittedOrder();
return { mainStore, submittedOrder };
},
data() {
var {
vehicle,
serviceLocation,
schedule,
customer,
payment,
customerPortalLoginToken } = this.submittedOrder;
var { issConfig } = this.mainStore;
return {
vehicle,
customerEmail: customer.emailAddress,
payment,
schedule,
serviceLocation,
appointmentType: serviceLocation.appointmentType,
providerAddress: serviceLocation?.provider?.address,
customerPortalLoginToken,
carrierName: issConfig.clientName,
carrierUrl: issConfig.successReturnURL,
widgets: {
emailConfirmation: 'EmailConfirmationWordingWidget',
orderConfirmation: 'OrderConfirmationContent',
mobile: 'MobileWordingWidget',
dropOffAndInShop: 'DropOffAndInShopWordingWidget'
},
}
},
computed: {
customValueMap() {
return {
inShopAppointment: this.isInShopAppointment,
dropOffAppointment: this.isDropOffAppointment,
vehicleYear: this.vehicle.year,
vehicleMake: this.vehicle.make,
vehicleModel: this.vehicle.model,
address: this.appointmentAddress,
inShopDuration: this.inShopAppointmentDuration,
email: this.customerEmail,
CUSTOMER_PORTAL_URL: applicationConfig.CUSTOMER_PORTAL_URL,
CUSTOMER_PORTAL_LOGIN_TOKEN: this.customerPortalLoginToken
}
},
confirmationEmailText() {
var content = this.getCmsContentWithCustomValues(
this.widgets.emailConfirmation,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
return content
?.replaceAll('&lt;', '<')
?.replaceAll('&gt;', '>');
},
orderConfirmationHeaderText() {
return this.getCmsContent(
this.widgets.orderConfirmation,
widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
},
orderConfirmationImage() {
return this.getCmsContent(
this.widgets.orderConfirmation,
widgetFields.CONTENT_GROUP_WIDGET.IMAGE);
},
appointmentTimeFormatted() {
const { startTime, endTime } = this.schedule;
var appointmentTime = null;
if (this.isDropOffAppointment){
appointmentTime = 'Drop off before 9:30 AM';
}
if (this.isInShopAppointment){
const formattedStartTime = get12HourTimeFormat(startTime);
appointmentTime = `at ${formattedStartTime}`
}
if (this.isMobileAppointment) {
const mobileStartTime = get12HourTimeMobileFormat(startTime);
const mobileEndTime = get12HourTimeMobileFormat(endTime);
appointmentTime = `Between ${mobileStartTime} - ${mobileEndTime}`;
}
return appointmentTime;
},
mobileWordingText() {
return this.getCmsContentWithCustomValues(
this.widgets.mobile,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
},
mobileWordingText2() {
return this.getCmsContent(
this.widgets.mobile,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
},
dropOffAndInShopWordingText() {
return this.getCmsContentWithCustomValues(
this.widgets.dropOffAndInShop,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
},
dropOffAndInShopWordingText2() {
return this.getCmsContentWithCustomValues(
this.widgets.dropOffAndInShop,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
},
serviceLocationFullAddress() {
// var { address, address2, city, state, zipCode } = this.serviceLocation;
// console.log(JSON.stringify(this.serviceLocation));
// return `${address}, ${address2 ? `${address2},` : ''}<br/> ${city}, ${state} ${zipCode}`;
return `${this.serviceLocation.address}, ${
this.serviceLocation.address2
? `${this.serviceLocation.address2},`
: ''
}<br/> ${this.serviceLocation.city}, ${this.serviceLocation.state} ${
this.serviceLocation.zipCode
}`;
},
titleCaseProviderAddress() {
return toTitleCase(this.providerAddress?.streetAddress);
},
titleCaseProviderCity() {
return toTitleCase(this.providerAddress?.city);
},
appointmentAddress() {
if (this.isMobileAppointment){
return this.serviceLocationFullAddress;
}
if (this.isDropOffAppointment || this.isInShopAppointment){
return this.providerFullAddress;
}
return null
},
providerFullAddress() {
var { state, zipCode } = this.providerAddress;
return this.titleCaseProviderAddress
? `${this.titleCaseProviderAddress},<br/> ${this.titleCaseProviderCity}, ${state} ${zipCode}`
: '';
},
appointmentWordingText() {
var wording = null;
if (this.isMobileAppointment){
wording = this.mobileWordingText;
}
if (this.isInShopAppointment || this.isDropOffAppointment){
wording = this.dropOffAndInShopWordingText;
}
return wording;
},
appointmentWordingText2() {
var wording = null;
if (this.isMobileAppointment){
wording = this.mobileWordingText2;
}
if (this.isInShopAppointment || this.isDropOffAppointment){
wording = this.dropOffAndInShopWordingText2;
}
return wording;
},
isMobileAppointment() {
const mobileAppointmentTypes = [
AppointmentTypeStrings.MOBILE,
AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP
]
return mobileAppointmentTypes.includes(this.appointmentType);
},
isInShopAppointment() {
return this.appointmentType === AppointmentTypeStrings.IN_SHOP;
},
isDropOffAppointment() {
return this.appointmentType === AppointmentTypeStrings.DROP_OFF;
},
inShopAppointmentDuration() {
return getDisplayTextForDurationLength(
this.schedule.jobMinMinutes,
this.schedule.jobMaxMinutes
);
}
},
mounted() {
if (this.carrierUrl) {
this.$refs.siteFooter.updateButtonText(`Go back to ${this.carrierName}`);
}
},
methods: {
arePagePrerequisitesValid() {
const hasSubmittedOrder = useMainStore().hasSubmittedOrder();
if (hasSubmittedOrder) {
return true;
}
// Service Location
const { serviceLocation } = useMainStore().order;
const mobileReqs = !!(
serviceLocation.address
&& serviceLocation.city
&& serviceLocation.state
&& serviceLocation.zipCode
);
const providerLocation = serviceLocation.provider.address;
const dropOffInShopReqs = !!(
providerLocation.streetAddress
&& providerLocation.city
&& providerLocation.state
&& providerLocation.zipCode
);
const isMobile =
serviceLocation.appointmentType
=== AppointmentTypeStrings.MOBILE
|| serviceLocation.appointmentType
=== AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
const serviceLocationReqs =
(isMobile && mobileReqs) || (!isMobile && dropOffInShopReqs);
// Insurance
const isInsuranceSet =
useMainStore().order.payment.isInsurance !== null;
// Schedule
const { schedule } = useMainStore().order;
const scheduleReqs = !!(
schedule.date
&& schedule.startTime
&& schedule.endTime
&& schedule.jobMaxMinutes
&& schedule.jobMinMinutes
);
// Contact Info
const { contactInfo } = useMainStore().order;
const contactInfoReqs = !!(
contactInfo.firstName
&& contactInfo.lastName
&& contactInfo.servicePhone
&& contactInfo.emailAddress
);
// Payment
const paymentMethodReqs =
useMainStore().order.payment.isPayInAdvance === false;
return (
serviceLocationReqs
&& isInsuranceSet
&& scheduleReqs
&& contactInfoReqs
&& paymentMethodReqs
);
},
forwardButtonAction() {
this.$router.navigateToExternalUrl(this.carrierUrl);
},
getCmsContentWithCustomValues(widgetName, widgetField) {
const rawText = this.getCmsContent(widgetName, widgetField);
const processedIfStatements = processIfStatements(
rawText,
'custom',
(v) => { return this.customValueMap[v] }
)
return getStringWithCustomValues(processedIfStatements, this.customValueMap);
},
formatDate(date) {
// This conversion ensures we don't get get GMT induced date changes
const dateObject = convertDateStringToDate(date);
// Ex: Tuesday, April 22
return dateObject.toLocaleDateString('en-us', {
weekday: 'long',
month: 'long',
day: 'numeric'
});
}
}
};
</script>
<style lang="scss" scoped>
.page-container-grouped-styles {
overflow: auto;
}
.text-color--black {
color: $black;
}
.appointment-details {
margin-bottom: 1.5rem;
padding: 1rem 1.5rem 1.5rem;
box-shadow: 0 0.188rem 0.625rem rgb(0 0 0 / 0.2);
border-radius: 0.313rem;
}
.appointment-date-time P {
color: $black;
font-size: $h5-font-size;
line-height: map-get($spacers, 6);
margin-bottom: 0;
+ p {
font-size: map-get($spacers, 4);
line-height: 1.625rem;
font-weight: $font-weight-bold;
}
}
.appointment-text {
:deep(p) {
margin: 0;
}
:deep(strong) {
font-weight: $font-weight-bold;
color: $black;
}
}
.email-confirmation-text {
:deep(a) {
font-weight: $font-weight-bold;
text-decoration: underline;
}
:deep(strong) {
font-weight: $font-weight-bold;
color: $black;
}
}
</style>