DigitalConsumer.ISS/src/layouts/service-packages/service-packages.vue

204 lines
7.1 KiB
Vue

<template>
<Form
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition sub-container make-tall">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
<siteSubHeader
cmsWidgetName="SiteSubHeaderWidget"
justification="left"
issContainingPage="service-packages" />
<div class="mx-5">
<servicePackageQuestion
ref="servicePackage"
cmsWidgetName="ServicePackage"
groupName="ServicePackageQuestion"
:availableLineItems="availableLineItems"
:validationRules="rules.optionRequired"
isRequired
@vapsItemsSelected="vapsItemsSelectedAction"
@link-event="openModalAction" />
<p
class="caption disclaimer"
v-html="PriceDisclaimerText"></p>
<siteFooter
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
</div>
</div>
</div>
<loadingModal
ref="loadingModal"
:textSlides="loadingText" />
<contentGroupModal
ref="RainDefenseModal"
cmsWidgetName="RainDefenseModal" />
<contentGroupModal
ref="FrontWiperModal"
cmsWidgetName="FrontWiperModal" />
<contentGroupModal
ref="RearWiperModal"
cmsWidgetName="RearWiperModal" />
<contentGroupModal
ref="RecalModal"
cmsWidgetName="RecalModal" />
</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';
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
},
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 supportingItemsPromise = await store.getSupportingItems();
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
},
{
resultKey: 'wipers',
promise: wipersPromise
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise
},
{
resultKey: 'supportingItems',
promise: supportingItemsPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
const clonedGlassParts = store.order.lineItems.glassParts
? JSON.parse(JSON.stringify(store.order.lineItems.glassParts))
: [];
const availableLineItems = [
resultMap.rainDefense,
...resultMap.supportingItems,
...resultMap.wipers,
...clonedGlassParts
];
const pricingResults = await store.getPriceOrderItems(availableLineItems);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.pricedGlassParts = clonedGlassParts;
vm.supportingItems = resultMap.supportingItems;
vm.availableLineItems = pricingResults;
});
},
data() {
return {
selectedVaps: [],
availableLineItems: [],
supportingItems: [],
pricedGlassParts: [],
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))
);
},
vapsItemsSelectedAction(vapsItemsSelected) {
this.selectedVaps = vapsItemsSelected;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
const parts = { glassParts: this.pricedGlassParts, supportingItems: this.supportingItems, vaps: this.selectedVaps };
if (!allGlassPartsAndItemsHavePrices(parts)) {
window.console.error('One or more items have no price assigned!');
}
if (this.pricedGlassParts.length > 0) {
store.saveGlassParts(this.pricedGlassParts);
}
store.saveSupportingItems(this.supportingItems);
store.saveVaps(this.selectedVaps);
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
}
}
};
</script>
<style lang="scss" scoped>
.subheader-secondary {
margin-top: .5rem;
padding: 0px;
}
.disclaimer {
margin: 1.3rem 0 1.5rem 0;
a {
color: #4D5151;
font-weight: 400;
}
}
</style>