DigitalConsumer.ISS/src/layouts/tpa-submit/tpa-submit.vue
2026-01-22 09:13:46 -05:00

434 lines
15 KiB
Vue

<template>
<Form
ref="tpaSubmitFormRef"
v-slot="{ meta }"
class="tpa-submit"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="fade-on-route-transition">
<div class="justify-content-center">
<siteHeader
ref="siteHeader"
:cmsWidgetName="widget.siteHeader" />
</div>
<div class="iss-heritage-container-width">
<div class="tpa-submit-container iss-heritage-content-container-width">
<alert
ref="alertIncomplete"
alertClass="alert-warning"
:cmsWidgetName="widget.alertIncomplete"
/>
<textBlock
ref="subHeaderTitle"
:customText="subHeaderTitle"
class="tpa-submit-title"/>
<textBlock
id="tpaSubmitSubHeaderBodyOne"
ref="tpaSubmitSubHeaderBodyOne"
:customText="subHeaderBodyOne" />
<alert
v-if="recalibrationRequired"
ref="alertRecalWarning"
alertClass="alert-warning recal-alert"
:isCollapsible="true"
:cmsWidgetName="widget.alertRecalWarning"
@textLinkClicked="openRecalModal" />
<modal
ref="recalModal"
class="recal-modal"
:modalPosition="modalPositions.center"
:headerText="recalModalContent.headerText"
:footerButtonText="recalModalContent.footerButtonText"
@footerButtonEvent="closeRecalModal">
<div class="recal-modal-subheader">{{ recalModalContent.subHeaderText }}</div>
<img class="recal-modal-image" :src="recalModalContent.image" />
<div class="recal-modal-body" v-html="recalModalContent.bodyText"></div>
</modal>
<hr />
<div id="serviceSummarySection">
<div
v-for="(section, index) in sections"
:key="section.title">
<hr v-if="index !== 0" />
<reviewBlock
:id="'review-block-' + index"
:customHeaderText="section.title"
:lines="section.lines"
:editLinkText="section.editLinkText"
@clickEdit="() => section.onClickEdit()" />
</div>
</div>
<hr />
<div
id="submitOrderDetailsSection"
ref="submitOrderDetailsSection">
<textBlock
id="tpaSubmitOrderDetailsTitle"
ref="tpaSubmitOrderDetailsTitle"
:customText="orderDetailsTitle"
:marginTopSizeOverride="0"
class="fw-bold order-details-title" />
<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 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';
import alert from '@/ux-components/alert/alert.vue';
import modal from '@/digital-components/modal/modal.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 {
toTitleCase,
toDisplayPhoneNumber,
formatAddress,
formatAmountInDollars
} from '@/helpers/text-helper.js';
import { submitWorkOrder } from '@/helpers/order-helper.js';
import bailoutMessage from '@/constants/bailoutMessage';
import submitType from '@/constants/submit-type';
import { modalPositions } from '@/constants/component-variants';
const VERIFYING_COVERAGE = 'Verifying coverage';
export default {
name: 'tpa-submit',
components: {
siteHeader,
textBlock,
buttonMain,
reviewBlock,
deductibleBox,
siteFooter,
contactDetailsDrawer,
// eslint-disable-next-line vue/no-reserved-component-names
Form,
alert,
modal
},
mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) {
const cmsContent = await fetchCmsContentForPage(to.query.issPage);
next((vm) => {
vm.setCmsContent(cmsContent);
vm.setSections();
});
},
data() {
return {
sections: [],
widget: {
siteHeader: 'SiteHeaderWidget',
siteSubHeader: 'SiteSubHeaderWidget',
orderDetails: 'OrderDetailsContent',
footer: 'SiteFooterWidget',
alertIncomplete: 'AlertIncompleteWidget',
alertRecalWarning: 'AlertRecalWarningWidget',
editShopLinkText: 'EditShopLinkTextWidget',
contactDetails: 'ContactDetailsSectionWidget'
},
modalPositions
};
},
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);
},
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 this.mainStore.isVerified;
},
currentDeductible() {
return this.mainStore.order.currentDeductible;
},
deductibleBoxValue() {
return this.isVerified
? formatAmountInDollars(this.currentDeductible)
: VERIFYING_COVERAGE;
},
getPreferredShopTitle() {
return toTitleCase(this.mainStore.order.serviceLocation.provider.companyName ?? '');
},
getPreferredShopLines() {
const { phoneNumber, address } = this.mainStore.order.serviceLocation.provider;
const { streetAddress, city, state, zipCode } = address;
const displayAddress = formatAddress(
streetAddress,
null,
city,
state,
zipCode
);
const displayPhoneNumber = toDisplayPhoneNumber(phoneNumber);
return [
displayAddress,
displayPhoneNumber
];
},
getEditShopLinkText() {
return this.getCmsContent(
this.widget.editShopLinkText,
widgetFields.TEXT_BLOCK_WIDGET.TEXT
);
},
getContactInfoTitle() {
const cmsContent = this.getCmsContent(
this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT
);
return getStringWithCustomValues(cmsContent, this.customValueMap);
},
getContactInfoLines() {
const cmsContent = this.getCmsContent(
this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
);
return [
getStringWithCustomValues(cmsContent, this.customValueMap)
];
},
getEditContactInfoLinkText() {
return this.getCmsContent(
this.widget.contactDetails,
widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT
);
},
recalModalContent() {
const widgetName = 'RecalModal';
return {
headerText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT),
subHeaderText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT),
bodyText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT),
footerButtonText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT),
image: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.IMAGE)
}
},
recalibrationRequired() {
return this.mainStore.hasRecalibrationPart;
},
customValueMap() {
let contactPhone = toDisplayPhoneNumber(this.mainStore.contactInfo.servicePhone);
if (this.mainStore.contactInfo.extension) {
contactPhone += ` Ext. ${this.mainStore.contactInfo.extension}`;
}
return {
glassShop: this.getPreferredShopTitle,
contactPhone: contactPhone,
contactEmail: this.mainStore.contactInfo.emailAddress ?? ''
}
}
},
methods: {
setSections() {
this.sections = [
this.getSection(
this.getPreferredShopTitle,
this.getPreferredShopLines,
this.getEditShopLinkText,
() => this.navigate(this.navigationScenarios.EDIT_PREFERRED_SHOP),
),
// eslint-disable-next-line max-len
this.getSection(
this.getContactInfoTitle,
this.getContactInfoLines,
this.getEditContactInfoLinkText,
this.openContactDetailsModal
)
];
},
getSection(title, lines, editLinkText, onClick) {
return {
title: title,
lines,
editLinkText,
onClickEdit: onClick
};
},
async forwardButtonAction() {
try {
await submitWorkOrder({ submitType: submitType.TPA }).then(() => {
this.navigate(this.navigationScenarios.CLICKED_FORWARD);
}).catch((submitError) => {
this.mainStore.setBailout(bailoutMessage.saveSessionError(submitError.data));
this.navigate(
this.navigationScenarios.SAVE_SESSION_FAILED,
this.$route,
{ issPage: this.issPageValues.TPA_SUBMIT }
);
});
} catch (error) {
console.error(`error: response from submit work order:${error.message}`);
}
},
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();
},
openRecalModal() {
this.$refs.recalModal.openModal();
},
closeRecalModal() {
this.$refs.recalModal.closeModal();
}
}
};
</script>
<style lang="scss">
.iss-heritage-container-width {
.tpa-submit-container {
position: relative;
min-height: 1px;
padding-left: .9375rem;
padding-right: .9375rem;
}
}
.tpa-submit {
.alert-warning {
margin-top: 1.25rem;
margin-bottom: 0rem;
}
.tpa-submit-title {
font-size: 1.25rem;
color: $black;
font-weight: 400;
margin-top: 1.25rem;
margin-bottom: .625rem;
}
.recal-alert {
margin-bottom: 4rem;
}
b {
font-weight: $font-weight-bold;
color: $black;
}
hr {
margin: 1.875rem 0rem;
}
.fw-bold {
color: $black;
}
.order-details-title {
margin-bottom: .625rem;
}
.modal.recal-modal .modal-dialog {
.modal-header {
justify-content: start;
margin: 0rem;
padding: 1.25rem 1.25rem .625rem 1.25rem;
.modal-title {
font-weight: $font-weight-bolder;
font-size: .875rem;
line-height: 1.25rem;
text-align: start;
justify-content: start;
}
.btn-close {
display: none;
}
}
.modal-body {
padding: 0rem 1.25rem 1.25rem 1.25rem;
b {
font-weight: 600;
}
}
.recal-modal-subheader {
font-weight: $font-weight-bold;
color: $black;
}
.recal-modal-image {
margin: 1.25rem 0rem
}
}
}
</style>