258 lines
8.7 KiB
Vue
258 lines
8.7 KiB
Vue
<template>
|
|
<Form
|
|
ref="theForm"
|
|
v-slot="{ meta }"
|
|
@submit="onSubmit"
|
|
@invalidSubmit="onInvalidSubmit">
|
|
<div class="fade-on-route-transition service-packages">
|
|
<div class="justify-content-center">
|
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
|
</div>
|
|
<div class="iss-heritage-container-width">
|
|
<div class="service-packages-container">
|
|
<siteSubHeader
|
|
class="subheader mt-4"
|
|
justification="center"
|
|
cmsWidgetName="SiteSubHeaderWidget"
|
|
issContainingPage="service-packages" />
|
|
<servicePackageQuestion
|
|
ref="servicePackage"
|
|
cmsWidgetName="ServicePackage"
|
|
groupName="ServicePackageQuestion"
|
|
:availableLineItems="availableLineItems"
|
|
:validationRules="rules.optionRequired"
|
|
isRequired
|
|
@vapsItemsSelected="vapsItemsSelectedAction"
|
|
@link-event="openModalAction" />
|
|
<div class="d-flex justify-content-center mt-8 mb-4">
|
|
<buttonMain
|
|
ref="buttonMain"
|
|
class="continue-button"
|
|
variant="navigation"
|
|
:buttonText="'Continue'"
|
|
@clickEvent="forwardButtonAction" />
|
|
</div>
|
|
<siteFooter
|
|
cmsWidgetName="SiteFooterWidget"
|
|
:isForwardActionDisabled="!meta.valid"
|
|
:isForwardButtonHidden="true"
|
|
@backClicked="navigateBack" />
|
|
</div>
|
|
<p
|
|
class="caption disclaimer"
|
|
v-html="PriceDisclaimerText"></p>
|
|
</div>
|
|
<loadingModal
|
|
ref="loadingModal"
|
|
:textSlides="loadingText" />
|
|
<contentGroupModal
|
|
ref="RainDefenseModal"
|
|
cmsWidgetName="RainDefenseModal" />
|
|
<contentGroupModal
|
|
ref="FrontWiperModal"
|
|
cmsWidgetName="FrontWiperModal" />
|
|
<contentGroupModal
|
|
ref="RearWiperModal"
|
|
cmsWidgetName="RearWiperModal" />
|
|
<contentGroupModal
|
|
ref="RecalModal"
|
|
cssModalHeadlineClass="text-center"
|
|
cmsWidgetName="RecalModal" />
|
|
</div>
|
|
</Form>
|
|
</template>
|
|
|
|
<script>
|
|
// Components
|
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
|
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
|
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
|
import loadingModal from '@/iss-components/loading-modal/loading-modal.vue';
|
|
import settleAllPromises from '@/helpers/layout-helper';
|
|
import { useMainStore } from '@/store';
|
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
|
import { Form } from 'vee-validate';
|
|
import allGlassPartsAndItemsHavePrices from '@/layouts/service-packages/service-package-helper/service-package-helper';
|
|
import globalRules from '@/constants/global-rules';
|
|
import servicePackageQuestion from '@/layouts/service-packages/service-package-question/service-package-question.vue';
|
|
import issPageValues from '@/router/router-constants/issPage-values';
|
|
import bailoutMessage from '@/constants/bailoutMessage';
|
|
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
|
|
|
const store = useMainStore();
|
|
|
|
export default {
|
|
name: 'service-packages',
|
|
components: {
|
|
siteHeader,
|
|
siteFooter,
|
|
siteSubHeader,
|
|
// eslint-disable-next-line vue/no-reserved-component-names
|
|
Form,
|
|
servicePackageQuestion,
|
|
loadingModal,
|
|
contentGroupModal,
|
|
buttonMain
|
|
},
|
|
mixins: [baseFormMixin],
|
|
async beforeRouteEnter(to, from, next) {
|
|
// Call APIs
|
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
|
|
|
const wipersPromise = await store.getWipers();
|
|
const rainDefensePromise = await store.getRainDefense();
|
|
const promiseResultMap = [
|
|
{
|
|
resultKey: 'cmsContent',
|
|
promise: cmsContentPromise
|
|
},
|
|
{
|
|
resultKey: 'wipers',
|
|
promise: wipersPromise
|
|
},
|
|
{
|
|
resultKey: 'rainDefense',
|
|
promise: rainDefensePromise
|
|
}
|
|
];
|
|
const resultMap = await settleAllPromises(promiseResultMap);
|
|
|
|
const { feeItems } = store.order.lineItems;
|
|
|
|
const availableLineItems = [];
|
|
|
|
if (resultMap?.rainDefense) {
|
|
availableLineItems.push(resultMap.rainDefense);
|
|
}
|
|
|
|
if (resultMap?.wipers?.length > 0) {
|
|
availableLineItems.push(...resultMap.wipers);
|
|
}
|
|
|
|
if (feeItems?.length > 0) {
|
|
availableLineItems.push(...feeItems);
|
|
}
|
|
|
|
let hasBailedOut = false;
|
|
const pricedItems = await store.getCombinedQuote(availableLineItems)
|
|
.catch((err) => {
|
|
useMainStore().setBailout(bailoutMessage.pricingResponseError(
|
|
availableLineItems.map((li) => li.partNumber),
|
|
{ code: err.code, message: err.message, data: err.data }
|
|
));
|
|
hasBailedOut = true;
|
|
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
|
|
});
|
|
|
|
// Call the "next" function to complete the transition to this page.
|
|
if (!hasBailedOut) {
|
|
next((vm) => {
|
|
vm.setCmsContent(resultMap.cmsContent);
|
|
vm.setData(pricedItems);
|
|
});
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
selectedVaps: [],
|
|
availableLineItems: [],
|
|
loadingText: [
|
|
'Finding shops near you',
|
|
'Looking for dates',
|
|
'Searching for times',
|
|
'Nearly there',
|
|
'Finishing up'
|
|
],
|
|
rules: {
|
|
optionRequired: globalRules.OPTION_REQUIRED
|
|
}
|
|
};
|
|
},
|
|
computed: {
|
|
PriceDisclaimerText() {
|
|
return this.getCmsContent('PriceDisclaimerWidget', 'Text');
|
|
}
|
|
},
|
|
methods: {
|
|
openModalAction(modalName) {
|
|
this.$refs[modalName.args].openModal();
|
|
},
|
|
arePagePrerequisitesValid() {
|
|
return (
|
|
store.order.serviceLocation.zipCode
|
|
&& store.order.serviceLocation.zipCodeCtu
|
|
&& (store.order.damage.isRepair
|
|
|| (store.order.lineItems?.glassParts != null
|
|
&& store.order.lineItems.glassParts.length > 0))
|
|
);
|
|
},
|
|
setData(pricedVaps) {
|
|
this.availableLineItems = pricedVaps;
|
|
useMainStore().order.availableVaps = pricedVaps;
|
|
},
|
|
vapsItemsSelectedAction(vapsItemsSelected) {
|
|
this.selectedVaps = vapsItemsSelected;
|
|
},
|
|
forwardButtonAction() {
|
|
const parts = {
|
|
vaps: this.selectedVaps
|
|
};
|
|
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
|
window.console.error('One or more items have no price assigned!');
|
|
}
|
|
store.updateVaps(this.selectedVaps);
|
|
|
|
const scenario = store.isMobileAppointment
|
|
? this.navigationScenarios.CLICKED_FORWARD_MOBILE
|
|
: this.navigationScenarios.CLICKED_FORWARD_INSHOP;
|
|
|
|
this.$router.navigate(
|
|
scenario,
|
|
this.$route
|
|
);
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.iss-heritage-container-width {
|
|
.service-packages-container {
|
|
@media (min-width: 992px) {
|
|
width: 85%; // REVISIT
|
|
}
|
|
position: relative;
|
|
min-height: 1px;
|
|
padding-left: .9375rem;
|
|
padding-right: .9375rem;
|
|
display: block;
|
|
margin: 0 auto;
|
|
:deep(.subheader-primary) {
|
|
display: block;
|
|
}
|
|
:deep(.subheader-secondary) {
|
|
display: block;
|
|
text-align: center;
|
|
margin-top: 0.75rem;
|
|
padding: 0px;
|
|
}
|
|
}
|
|
}
|
|
.disclaimer {
|
|
margin: 0.5rem 0 1.5rem 0;
|
|
padding-left: 3rem;
|
|
:deep(.external-text) {
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
.service-packages {
|
|
:deep(strong) {
|
|
font-weight: 400;
|
|
}
|
|
}
|
|
|
|
.continue-button {
|
|
width: 60%
|
|
}
|
|
</style>
|