DigitalConsumer.ISS/src/layouts/tpa-submit/tpa-submit.vue

313 lines
13 KiB
Vue

<template>
<Form
ref="tpaSubmitFormRef"
v-slot="{ meta }"
class="tpa-submit"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader
ref="siteHeader"
:cmsWidgetName="widget.siteHeader" />
<div class="px-5">
<vehicleBanner
ref="vehicleBanner"
:cmsWidgetName="widget.vehicleBanner"
:displayGenericVehicleImage="false"
class="mt-5" /> <!-- TODO fix styling -->
<textBlock
ref="subHeaderTitle"
:customText="subHeaderTitle"
justifyText="center"
:marginTopSizeOverride="4"
class="text-color--black fs-5 tpa-submit__title--line-height" />
<textBlock
id="tpaSubmitSubHeaderBodyOne"
ref="tpaSubmitSubHeaderBodyOne"
:customText="subHeaderBodyOne"
class="small text-color--darker-gray" />
<textBlock
id="tpaSubmitSubHeaderBodyTwo"
ref="tpaSubmitSubHeaderBodyTwo"
:customText="subHeaderBodyTwo"
class="mb-4 small text-color--darker-gray" />
<buttonMain
ref="buttonMainOne"
isPrimary
:buttonText="forwardButtonText"
loaderColor="white"
class="w-100 mb-5"
@clickEvent="forwardButtonAction" />
<hr class="mb-0" />
<div id="serviceSummarySection">
<textBlock
id="tpaSubmitServiceSummaryTitle"
ref="tpaSubmitServiceSummaryTitle"
:customText="serviceSummaryText"
:marginTopSizeOverride="4"
class="fw-bold fs-1 lh-lg text-color--black" />
<div class="px-4 my-3">
<div
v-for="(section, index) in sections"
:key="section.title">
<hr
v-if="index !== 0"
class="my-3" />
<reviewBlock
:id="'review-block-' + index"
:customHeaderText="section.title"
:lines="section.lines"
@clickEdit="() => section.onClickEdit()" />
</div>
</div>
</div>
<hr class="mb-0" />
<div
id="submitOrderDetailsSection"
ref="submitOrderDetailsSection">
<textBlock
id="tpaSubmitOrderDetailsTitle"
ref="tpaSubmitOrderDetailsTitle"
:customText="orderDetailsTitle"
:marginTopSizeOverride="4"
class="fw-bold text-color--black" />
<textBlock
id="tpaSubmitOrderDetailsBody"
ref="tpaSubmitOrderDetailsBody"
:customText="orderDetailsBody"
:marginTopSizeOverride="4"
class="mb-4 px-4 small text-color--darker-gray" />
<deductibleBox
ref="deductibleBox"
:value="deductibleBoxValue" />
</div>
<siteFooter
ref="siteFooter"
class="mt-5"
:cmsWidgetName="widget.footer"
:isForwardActionDisabled="!meta.valid"
@backClicked="navigateBack"
@forwardClicked="forwardButtonAction" />
</div>
</div>
<contactDetailsDrawer
ref="contactDetailsDrawer"
@updateContactDetails="setSections" />
</div>
</Form>
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header.vue';
import buttonMain from '@/ux-components/button-main/button-main.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import reviewBlock from '@/layouts/tpa-submit/review-block/review-block.vue';
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
import { fetchCmsContentForPage, processIfStatements, getStringWithCustomValues } from '@/helpers/cms-content-helper.js';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import widgetFields from '@/constants/cms-widget-fields.js';
import { useMainStore } from '@/store';
import { toTitleCase, toDisplayPhoneNumber, formatAddress, formatAmountInDollars } from '@/helpers/text-helper.js';
import { getDamageDisplayContent, getLocationAnswer } from '@/helpers/damage-review-content-generator.js';
import damageLocationsSelected from '@/constants/damage-locations-selected.js';
const VERIFYING_COVERAGE = 'Verifying coverage';
export default {
name: 'tpa-submit',
components: {
siteHeader,
vehicleBanner,
textBlock,
buttonMain,
reviewBlock,
deductibleBox,
siteFooter,
contactDetailsDrawer,
// eslint-disable-next-line vue/no-reserved-component-names
Form
},
mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) {
const cmsContent = await fetchCmsContentForPage(to.query.issPage);
next((vm) => {
vm.setCmsContent(cmsContent);
vm.setSections();
});
},
data() {
const { companyName } = useMainStore().order.serviceLocation.provider;
return {
sections: [],
widget: {
siteHeader: 'SiteHeaderWidget',
siteSubHeader: 'SiteSubHeaderWidget',
serviceSummary: 'ServiceSummaryContent',
vehicleBanner: 'VehicleBannerWidget',
subheader: {
vehicle: 'VehicleSubTitle',
damage: 'DamageSubTitle',
shop: 'PreferredShopSubTitle',
contactInfo: 'ContactDetailsSubTitle'
},
damageLocations: 'DamageLocationsWidget',
orderDetails: 'OrderDetailsContent',
footer: 'SiteFooterWidget'
},
companyName,
customValueMap: {
glassShop: companyName
}
};
},
computed: {
subHeaderTitle() {
return this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
},
subHeaderBodyOne() {
return this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
},
subHeaderBodyTwo() {
const cmsContent = this.getCmsContent(this.widget.siteSubHeader, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
return getStringWithCustomValues(cmsContent, this.customValueMap);
},
serviceSummaryText() {
return this.getCmsContent(this.widget.serviceSummary, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
},
orderDetailsTitle() {
return this.getCmsContent(this.widget.orderDetails, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
},
orderDetailsBody() {
const orderDetailsBodyText = this.getCmsContent(this.widget.orderDetails, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
return processIfStatements(orderDetailsBodyText, 'custom', this.getCustomValueFromString);
},
forwardButtonText() {
return this.getCmsContent(this.widget.footer, widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT);
},
isVerified() {
return useMainStore().order.payment.insuranceCoverage.isVerified;
},
currentDeductible() {
return useMainStore().order.currentDeductible;
},
deductibleBoxValue() {
return this.isVerified ? formatAmountInDollars(this.currentDeductible) : VERIFYING_COVERAGE;
},
getVehicleLines() {
const { year, make, model } = useMainStore().order.vehicle;
const line = [year, make, model]
.filter((v) => v != null && v !== '')
.join(' ');
return [line];
},
locationAnswers() {
return this.getInputQuestionWidgetAnswersNullSafe(this.widget.damageLocations);
},
driverSideDamageAnswers() {
const answerContent = getLocationAnswer(damageLocationsSelected.DRIVER, this.locationAnswers);
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
},
passengerSideDamageAnswers() {
const answerContent = getLocationAnswer(damageLocationsSelected.PASSENGER, this.locationAnswers);
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
},
getDamageLines() {
const { glassToReplace, isRepair } = useMainStore().order.damage;
return getDamageDisplayContent(
this.locationAnswers,
this.driverSideDamageAnswers,
this.passengerSideDamageAnswers,
glassToReplace,
isRepair
);
},
getPreferredShopLines() {
const { phoneNumber, address } = useMainStore().order.serviceLocation.provider;
const { streetAddress, city, state, zipCode } = address;
const displayAddress = formatAddress(streetAddress, null, city, state, zipCode);
const displayPhoneNumber = toDisplayPhoneNumber(phoneNumber);
return [toTitleCase(this.companyName ?? ''), displayAddress, displayPhoneNumber];
},
getContactInfoLines() {
const { firstName, lastName, emailAddress, phoneNumber } = useMainStore().contactInfo;
return [
`${firstName} ${lastName}`,
emailAddress ?? '',
toDisplayPhoneNumber(phoneNumber)
];
}
},
methods:
{
setSections() {
const vehicleScenario = useMainStore().isPolicyVehicle
? this.navigationScenarios.EDIT_POLICY_VEHICLE
: this.navigationScenarios.EDIT_VEHICLE;
this.sections = [
this.getSection(this.widget.subheader.vehicle, this.getVehicleLines, () => this.navigate(vehicleScenario)),
// eslint-disable-next-line max-len
this.getSection(this.widget.subheader.damage, this.getDamageLines, () => this.navigate(this.navigationScenarios.EDIT_DAMAGE)),
// eslint-disable-next-line max-len
this.getSection(this.widget.subheader.shop, this.getPreferredShopLines, () => this.navigate(this.navigationScenarios.EDIT_PREFERRED_SHOP)),
// eslint-disable-next-line max-len
this.getSection(this.widget.subheader.contactInfo, this.getContactInfoLines, this.openContactDetailsModal)
];
},
getSection(widgetName, lines, onClick) {
return {
title: this.getCmsContent(widgetName, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
lines,
onClickEdit: onClick
};
},
forwardButtonAction() {
this.navigate(this.navigationScenarios.CLICKED_FORWARD);
},
navigate(scenario) {
this.$router.navigate(scenario, this.$route);
},
getCustomValueFromString(str) {
switch (str) {
case 'deductibleAboveZero':
return this.isVerified && this.currentDeductible !== 0;
case 'zeroDeductible':
return this.isVerified && this.currentDeductible === 0;
case 'verifyingCoverage':
return !this.isVerified;
default:
return null;
}
},
openContactDetailsModal() {
this.$refs.contactDetailsDrawer.openModal();
}
}
};
</script>
<style lang="scss" scoped>
.tpa-submit__title--line-height {
line-height: map-get($spacers, 6);
}
.text-color--darker-gray {
color: $darker-gray
}
.text-color--black {
color: $black;
}
hr {
opacity: 1;
color: $gray-350
}
</style>