DigitalConsumer.FixMyGlass/src/layouts/vin-lookup/vin-lookup.vue
2022-05-02 16:30:56 -04:00

300 lines
11 KiB
Vue

<template>
<Form
@submit="onSubmit"
@invalid-submit="onInvalidSubmit"
ref="theForm"
v-slot="{ meta }"
>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall px-5">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="false" />
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<div class="row my-2">
<div class="col">
<textboxQuestion cmsWidgetName="VinNumber" v-model="vin" inputId="vin" isRequired disableAutoFill validationRules="vin-required|vin-format" :isDisabled=isVinFieldReadOnly />
</div>
</div>
<div class="row my-2">
<div class="col">
<vinInformation />
</div>
</div>
<div class="row my-2">
<div class="col">
<textboxQuestion cmsWidgetName="ServiceZIP" v-model="zip" inputId="zip" mask="#####" isRequired disableAutoFill validationRules="zip-required" />
</div>
</div>
<div class="row my-2">
<div class="col">
<textboxQuestion cmsWidgetName="EmailAddress" v-model="email" inputId="email" isRequired disableAutoFill validationRules="email-address-required|email-address-format" />
</div>
</div>
<alert
class="my-3"
:manualHeadline="MatchedDifferentVehicleAlertHeader"
:manualCopy="MatchedDifferentVehicleAlertBody"
v-model="customAlertData"
v-if="matchedDifferentVehicle"
alertClass="alert-danger"
/>
<alert
class="my-3"
v-model="customAlertData"
v-if="noMatchAlert"
alertClass="alert-warning"
cmsWidgetName="NoMatchAlertWidget"
/>
<alert
class="my-3"
:manualHeadline="NoServiceZipHeader"
:manualCopy="NoServiceZipBody"
v-model="customAlertData"
v-if="noServiceZip"
alertClass="alert-warning"
/>
<alert
class="my-3"
v-model="customAlertData"
v-if="foundWindshieldAlert"
alertClass="alert-warning"
cmsWidgetName="FoundWindshieldAlert"
/>
<alert
class="my-3"
v-model="customAlertData"
v-if="vinNotFound"
alertClass="alert-warning"
cmsWidgetName="VinNotFound"
/>
<alert
class="my-3"
v-model="customAlertData"
v-if="perfectMatchNewVinAlert"
alertClass="alert-warning"
cmsWidgetName="PerfectMatchNewVinAlert"
/>
<funnelFooter
cmsWidgetName="FunnelFooterWidget"
ref="funnelFooter"
:isDisabled="!meta.valid"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction"
/>
</div>
</Form>
</template>
<script>
// Components
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import alert from "@/ux-components/alert/alert";
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
import vinInformation from "@/layouts/vin-lookup/vin-information/vin-information";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import { errorMessages } from "@/constants/error-messages";
import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper";
import { required, regex } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
// DEFINE VALIDATION RULES
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule("email-address-format", regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+).([a-zA-Z]{2,})$/, errorMessages.EMAIL_ADDRESS_FORMAT));
defineRule("vin-required", required(errorMessages.VIN_REQUIRED));
defineRule("vin-format", regex(/^[A-HJ-NPR-Z0-9]{17}$/, errorMessages.VIN_FORMAT));
export default {
name: "vin-lookup",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
});
},
props: {
validationRules: String,
},
data() {
return {
matchedDifferentVehicle: false,
noMatchAlert: false,
noServiceZip: false,
vinFound: false,
vinFoundReadOnly: false,
foundWindshieldAlert: false,
vinNotFound: false,
perfectMatchNewVinAlert: false,
vin: this.getVinFromStore(),
zip: this.getZipFromStore(),
email: this.getEmailFromStore(),
customAlertData: {},
isCarIdDifferent: false,
previouslyEnteredCarId: '',
invalidZip: '',
};
},
computed: {
MatchedDifferentVehicleAlertHeader(){
let text = this.getCmsContent("MatchedDifferentVehicle",
"HeadlineText").replaceAll("{custom:damage}", getDamageString());
return text;
},
MatchedDifferentVehicleAlertBody(){
let text = this.getCmsContent("MatchedDifferentVehicle",
"BodyText").replaceAll("{custom:damage}", getDamageString()).replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year).replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make).replaceAll("{custom:vinlookupModel}",
this.customAlertData?.vehicleInfo?.model);
return text;
},
NoServiceZipHeader(){
let text = this.getCmsContent("NoServiceZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", this.invalidZip);
return text;
},
NoServiceZipBody(){
return this.getCmsContent("NoServiceZipWidget", "BodyText");
},
PerfectMatchNewVinAlertHeader() {
return this.getCmsContent("PerfectMatchNewVinAlert", "HeadlineText");
},
PerfectMatchNewVinAlertBody() {
return this.getCmsContent("PerfectMatchNewVinAlert", "BodyText").replaceAll("{custom:damage}",
getDamageString())
},
isVinFieldReadOnly(){
return this.$store.getters.payment.insuranceCoverage.isVerified;
},
},
methods: {
arePagePrerequisitesValid() {
return store.getters.vehicle.carId !== null;
},
resetDependentState() {
store.commit(storeMutations.UPDATE_REGISTRATION_ADDRESS, null);
store.commit(storeMutations.UPDATE_REGISTRATION_CITY, null);
store.commit(storeMutations.UPDATE_REGISTRATION_FIRST_NAME, null);
store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, null);
store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
},
getEmailFromStore(){
return store.getters.order.customer.emailAddress
},
getVinFromStore(){
return store.getters.vehicle.vin
},
getZipFromStore(){
return store.getters.vehicle.registration.zipCode
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
async forwardButtonAction() {
this.pushEventToGA(this.$route.query[this.queryStrings.FMG_PAGE], this.GaActions.SUBMITTED, this.GaLabels.VINLOOKUP , true);
const zipValidation = await this.validateZip(this.zip);
if (!zipValidation.data.isServiceable) {
this.customAlertData.zip = this.zip;
this.$refs.funnelFooter.removeLoader();
this.noServiceZip = true;
this.invalidZip = this.zip;
return;
}
const vehicleLookup = await this.lookupVehicle(this.vin).catch(() => {
this.vinNotFound = true;
this.$refs.funnelFooter.removeLoader();
this.noServiceZip = false;
return;
});
this.isCarIdDifferent = vehicleLookup.data.carId !== store.getters.vehicle.carId;
if (this.isCarIdDifferent && (vehicleLookup.data.carId !== this.previouslyEnteredCarId)) {
this.previouslyEnteredCarId = vehicleLookup.data.carId;
this.noServiceZip = false;
this.customAlertData.vehicleInfo = vehicleLookup.data;
this.$refs.funnelFooter.updateButtonText(`Continue with ${vehicleLookup.data.year} ${vehicleLookup.data.make} ${vehicleLookup.data.model}`);
this.isVinValid = true;
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleLookup.data.carId);
this.$refs.funnelFooter.removeLoader();
this.matchedDifferentVehicle = true;
return;
}
this.updateStore(vehicleLookup.data);
this.navigateForward();
},
navigateForward(){
if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){
this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {});
return;
} else {
navigateAfterSaveToHeritageFunnel(this.$route);
return;
}
},
validateZip(zip) {
return baseMixin.methods.dispatchStoreAction(
storeActions.VALIDATE_ZIP,
{ zip }
);
},
lookupVehicle(vin) {
return baseMixin.methods.dispatchStoreAction(
storeActions.LOOKUP_VEHICLE_BY_VIN,
{ vin }
);
},
updateStore(carInfo) {
if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){
store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
}
store.commit(storeMutations.UPDATE_VEHICLE_VIN, this.vin);
store.commit(storeMutations.UPDATE_YEAR, carInfo.year);
store.commit(storeMutations.UPDATE_MAKE, carInfo.make);
store.commit(storeMutations.UPDATE_MODEL, carInfo.model);
store.commit(storeMutations.UPDATE_STYLE, carInfo.style);
store.commit(storeMutations.UPDATE_CAR_ID, carInfo.carId);
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, carInfo.category);
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl);
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber);
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageVifNumber);
store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.zip);
store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email);
},
},
components: {
Form,
funnelHeader,
vehicleBanner,
funnelSubHeader,
textboxQuestion,
alert,
funnelFooter,
vinInformation,
},
};
</script>