425 lines
15 KiB
Vue
425 lines
15 KiB
Vue
<template>
|
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
|
|
<div class="page-container-grouped-styles position-relative">
|
|
<div>
|
|
<div class="container-fluid pb-2">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6">
|
|
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
|
|
</div>
|
|
</div>
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6 col-xl-4">
|
|
<div class="header-container">
|
|
<img :src="ScheduleConfirmationImage" />
|
|
<span v-html="ScheduleConfirmationText"></span>
|
|
</div>
|
|
<div class="main">
|
|
<div>
|
|
<vehicleBanner
|
|
cmsWidgetName="VehicleBannerWidget"
|
|
:displayVehicleImage="vehicleBannerImageUrl"
|
|
:displayGenericVehicleImage="false" />
|
|
</div>
|
|
<div class="scheduleText">
|
|
<p>{{ ScheduleDateFormatted }}</p>
|
|
<p>{{ ScheduleTimeFormatted }}</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="ScheduleDate"
|
|
:scheduleStartTime="ScheduleStartTime"
|
|
:scheduleEndTime="ScheduleEndTime" />
|
|
|
|
<div class="appoinmenttext" v-html="AppointmentWordingText"></div>
|
|
</div>
|
|
<hr />
|
|
<cart
|
|
v-if="ShowCart"
|
|
:damage="damageInfo"
|
|
:availableVaps="vaps"
|
|
:allowItemRemoval="false"
|
|
v-model="lineItems"
|
|
:showAsPaid="isPia"
|
|
servicePackageOptionsCmsName="ServicePackageTitle" />
|
|
<hr class="mb-5" />
|
|
<div class="emailtext" v-html="ConfirmationEmailText"></div>
|
|
<navbar
|
|
cmsWidgetName="FunnelFooterWidget"
|
|
ref="navbar"
|
|
isBackButtonHidden="true"
|
|
@ForwardClicked="forwardButtonAction"
|
|
:buttonSize="true" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Form>
|
|
</template>
|
|
<script>
|
|
// Components
|
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
|
import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar";
|
|
import cart from "@/fmg-components/cart/cart";
|
|
|
|
//Supporting files
|
|
import baseMixin from "@/mixins/base-mixin.js";
|
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
|
import store from "@/store";
|
|
import { storeActions } from "@/constants/store-actions";
|
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
import { applicationConfig } from "@/constants/application-config.js";
|
|
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
|
|
import { deepClone } from "@/helpers/object-helper";
|
|
import { Form } from "vee-validate";
|
|
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
|
|
|
|
export default {
|
|
name: "confirmation",
|
|
async beforeRouteEnter(to, from, next) {
|
|
await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER);
|
|
|
|
// Call APIs
|
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
|
|
const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.GET_WIPERS,
|
|
{
|
|
serviceZipCode: store.getters.submittedOrder.serviceLocation.zipCode,
|
|
carId: store.getters.submittedOrder.vehicle.carId,
|
|
},
|
|
"confirmation"
|
|
);
|
|
|
|
const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
|
storeActions.GET_RAIN_DEFENSE,
|
|
null,
|
|
"confirmation"
|
|
);
|
|
|
|
// Settle promises and get results
|
|
const promiseResultMap = [
|
|
{
|
|
resultKey: "cmsContent",
|
|
promise: cmsContentPromise,
|
|
},
|
|
{
|
|
resultKey: "wipers",
|
|
promise: wipersPromise,
|
|
},
|
|
{
|
|
resultKey: "rainDefense",
|
|
promise: rainDefensePromise,
|
|
},
|
|
];
|
|
|
|
const resultMap = await settleAllPromises(promiseResultMap);
|
|
const availableVaps = [resultMap.rainDefense, ...resultMap.wipers];
|
|
const lineItemsFromSubmittedOrder = deepClone(store.getters.submittedOrder.lineItems);
|
|
|
|
// Call the "next" function to complete the transition to this page.
|
|
next((vm) => {
|
|
vm.setCmsContent(resultMap.cmsContent);
|
|
vm.lineItems = lineItemsFromSubmittedOrder;
|
|
vm.vaps = availableVaps;
|
|
});
|
|
},
|
|
data() {
|
|
return {
|
|
lineItems: [],
|
|
vaps: [],
|
|
};
|
|
},
|
|
computed: {
|
|
ShowCart() {
|
|
if (this.isPia && store.getters.submittedOrder.settledTenderAmount == 0) {
|
|
// settleTenderAmount always shows 0 via localhost or dev.
|
|
// Temporarily set return true to see cart in localhost or dev environment
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
ScheduleConfirmationText() {
|
|
return this.getCmsContent("ScheduleConfirmationWidget", "BodyText");
|
|
},
|
|
ScheduleConfirmationImage() {
|
|
return this.getCmsContent("ScheduleConfirmationWidget", "Image");
|
|
},
|
|
CustomerPortalLoginToken() {
|
|
return store.getters.submittedOrder.customerPortalLoginToken;
|
|
},
|
|
ConfirmationEmailText() {
|
|
return this.getCmsContent("ConfirmationEmailWidget", "BodyText")
|
|
?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT)
|
|
?.replaceAll("{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}", this.CustomerPortalLoginToken)
|
|
?.replaceAll("<", "<")
|
|
?.replaceAll(">", ">");
|
|
},
|
|
ScheduleDate() {
|
|
return store.getters.submittedOrder.schedule.date;
|
|
},
|
|
AppointmentType() {
|
|
return store.getters.submittedOrder.serviceLocation.appointmentType;
|
|
},
|
|
ScheduleStartTime() {
|
|
return store.getters.submittedOrder.schedule.startTime;
|
|
},
|
|
ScheduleEndTime() {
|
|
return store.getters.submittedOrder.schedule.endTime;
|
|
},
|
|
InShopWordingText() {
|
|
return this.getCmsContent("InShopWordingWidget", "BodyText");
|
|
},
|
|
MobileWordingText() {
|
|
return this.getCmsContent("MobileWordingWidget", "BodyText");
|
|
},
|
|
DropOffWordingText() {
|
|
return this.getCmsContent("DropOffWordingWidget", "BodyText");
|
|
},
|
|
ServiceLocationAddress() {
|
|
return store.getters.submittedOrder.serviceLocation.address;
|
|
},
|
|
ServiceLocationAddress2() {
|
|
return store.getters.submittedOrder.serviceLocation.address2;
|
|
},
|
|
ServiceLocationCity() {
|
|
return store.getters.submittedOrder.serviceLocation.city;
|
|
},
|
|
ServiceLocationState() {
|
|
return store.getters.submittedOrder.serviceLocation.state;
|
|
},
|
|
ServiceLocationZipCode() {
|
|
return store.getters.submittedOrder.serviceLocation.zipCode;
|
|
},
|
|
ProviderAddress() {
|
|
return store.getters.submittedOrder.serviceLocation.provider.address.streetAddress;
|
|
},
|
|
ProviderCity() {
|
|
return store.getters.submittedOrder.serviceLocation.provider.address.city;
|
|
},
|
|
ProviderState() {
|
|
return store.getters.submittedOrder.serviceLocation.provider.address.state;
|
|
},
|
|
ProviderZipCode() {
|
|
return store.getters.submittedOrder.serviceLocation.provider.address.zipCode;
|
|
},
|
|
AppointmentWordingText() {
|
|
if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
|
|
return this.MobileWordingText?.replaceAll(
|
|
"{custom:ADDRESS}",
|
|
this.ServiceLocationFullAddress
|
|
);
|
|
} else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
|
|
return this.DropOffWordingText?.replaceAll(
|
|
"{custom:ADDRESS}",
|
|
this.ProviderFullAddress
|
|
);
|
|
} else {
|
|
return this.InShopWordingText?.replaceAll(
|
|
"{custom:ADDRESS}",
|
|
this.ProviderFullAddress
|
|
);
|
|
}
|
|
},
|
|
ServiceLocationFullAddress() {
|
|
return `${this.ServiceLocationAddress2 ? this.ServiceLocationAddress2 + "," : ""} ${
|
|
this.ServiceLocationAddress
|
|
},<br/> ${this.ServiceLocationCity}, ${this.ServiceLocationState} ${
|
|
this.ServiceLocationZipCode
|
|
}`;
|
|
},
|
|
ProviderFullAddress() {
|
|
return `${this.ProviderAddress},<br/> ${this.ProviderCity}, ${this.ProviderState} ${this.ProviderZipCode}`;
|
|
},
|
|
ScheduleDateFormatted() {
|
|
// This conversion ensures we don't get get GMT induced date changes
|
|
const dateObject = convertDateStringToDate(this.ScheduleDate);
|
|
// Ex: Tuesday, April 22
|
|
return dateObject.toLocaleDateString("en-us", {
|
|
weekday: "long",
|
|
month: "long",
|
|
day: "numeric",
|
|
});
|
|
},
|
|
ScheduleTimeFormatted() {
|
|
if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
|
|
return `Between ${get12HourTimeMobileFormat(
|
|
this.ScheduleStartTime
|
|
)} - ${get12HourTimeMobileFormat(this.ScheduleEndTime)}`;
|
|
} else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
|
|
return `Drop off before 9:30 AM`;
|
|
} else {
|
|
return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`;
|
|
}
|
|
},
|
|
vehicleBannerImageUrl() {
|
|
return store.getters.submittedOrder?.vehicle.imageUrl;
|
|
},
|
|
damageInfo() {
|
|
return store.getters.submittedOrder.damage;
|
|
},
|
|
isPia() {
|
|
return store.getters.submittedOrder?.payment.isPia;
|
|
},
|
|
},
|
|
methods: {
|
|
arePagePrerequisitesValid() {
|
|
if (store.getters.hasSubmittedOrder) {
|
|
return true;
|
|
}
|
|
|
|
// Service Location
|
|
const serviceLocation = store.getters.order.serviceLocation;
|
|
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;
|
|
|
|
const serviceLocationReqs =
|
|
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
|
|
|
// Schedule
|
|
const schedule = store.getters.order.schedule;
|
|
const scheduleReqs = !!(schedule.date && schedule.startTime && schedule.endTime);
|
|
|
|
// Customer
|
|
const customer = store.getters.order.customer;
|
|
const customerReqs = !!customer.emailAddress;
|
|
|
|
return serviceLocationReqs && scheduleReqs && customerReqs;
|
|
},
|
|
forwardButtonAction() {
|
|
window.location.assign(location.protocol + "//" + location.host);
|
|
},
|
|
},
|
|
components: {
|
|
funnelHeader,
|
|
Form,
|
|
navbar,
|
|
vehicleBanner,
|
|
addToCalendar,
|
|
cart,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.main {
|
|
margin-bottom: 1.5rem;
|
|
padding: 1rem 1.5rem 1.5rem;
|
|
box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
|
|
border-radius: 5px;
|
|
}
|
|
.scheduleText {
|
|
text-align: center;
|
|
}
|
|
|
|
.scheduleText P {
|
|
margin: 0;
|
|
font-weight: 400;
|
|
font-size: 1.25rem;
|
|
color: $black;
|
|
|
|
+ p {
|
|
font-size: 1rem;
|
|
margin-top: 0.5rem;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
.calendar-section[data-v-8004c52c] {
|
|
display: table;
|
|
position: relative;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.calendar-section .add-to-calendar {
|
|
padding: 1rem 0;
|
|
text-align: center;
|
|
}
|
|
|
|
.add-to-calendar button {
|
|
border: 0;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.appoinmenttext p {
|
|
margin: 0;
|
|
}
|
|
|
|
.calendar-section .add-to-calendar .add-to-calendar-span {
|
|
cursor: pointer;
|
|
}
|
|
.calendar-section .add-to-calendar .add-to-calendar-img {
|
|
display: inline;
|
|
width: 20px;
|
|
}
|
|
.add-to-calendar-text {
|
|
margin: 0 0 0 7px;
|
|
color: #1574a1;
|
|
vertical-align: middle;
|
|
font-weight: 500;
|
|
font-family: "Roboto";
|
|
text-decoration: underline;
|
|
}
|
|
.header-container {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 1rem 0 1.5rem 0;
|
|
|
|
p {
|
|
display: inline-block;
|
|
font-weight: 400;
|
|
font-size: 1.25rem;
|
|
color: $black;
|
|
margin: 0;
|
|
}
|
|
|
|
img {
|
|
margin-right: 0.5rem;
|
|
}
|
|
}
|
|
|
|
.appoinmenttext strong {
|
|
color: $black;
|
|
}
|
|
|
|
.emailtext {
|
|
padding: 0.5rem 0 0;
|
|
|
|
p {
|
|
font-size: 0.875rem;
|
|
margin: 0;
|
|
|
|
strong {
|
|
color: $black;
|
|
}
|
|
}
|
|
}
|
|
</style>
|