308 lines
12 KiB
Vue
308 lines
12 KiB
Vue
<template>
|
|
<Form
|
|
ref="theForm"
|
|
v-slot="{ meta }"
|
|
@submit="onSubmit"
|
|
@invalidSubmit="onInvalidSubmit">
|
|
<div class="fade-on-route-transition policy-vehicles">
|
|
<div class="justify-content-center">
|
|
<siteHeader
|
|
class="header"
|
|
cmsWidgetName="SiteHeaderWidget" />
|
|
</div>
|
|
<div class="iss-heritage-container-width">
|
|
<div class="policy-vehicles-container iss-heritage-content-container-width">
|
|
<div class="select-car-form rounded text-center">
|
|
<siteSubHeader
|
|
cmsWidgetName="SiteSubHeaderWidget"
|
|
class="mt-4" />
|
|
<policyVehiclesQuestion
|
|
v-model="selectedVehicleVin"
|
|
cmsWidgetName="PolicyVehiclesQuestion"
|
|
:vehicles="VehiclesForQuestions"
|
|
:validationRules="rules.optionRequired"
|
|
class="mb-2" />
|
|
<buttonMain
|
|
:variant="buttonVariants.primary"
|
|
buttonText="Add another vehicle"
|
|
class="w-100"
|
|
@clickEvent="addAnotherVehicle" />
|
|
<siteFooter
|
|
ref="siteFooter"
|
|
cmsWidgetName="SiteFooterWidget"
|
|
:isForwardActionDisabled="!meta.valid"
|
|
@ForwardClicked="forwardButtonAction"
|
|
@backClicked="backButtonAction" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Form>
|
|
</template>
|
|
<script>
|
|
// Components
|
|
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
|
import policyVehiclesQuestion from '@/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question.vue';
|
|
// Supporting files
|
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper.js';
|
|
import { Form } from 'vee-validate';
|
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
|
import vehicleSelectionOptions from '@/constants/vehicle-selection-options.js';
|
|
import endorsementOptions from '@/constants/endorsement-options.js';
|
|
import globalRules from '@/constants/global-rules.js';
|
|
import { useMainStore } from '@/store/index.js';
|
|
import {
|
|
deductibleForSelectedVehicle,
|
|
endorsementsForSelectedVehicle,
|
|
endorsementCodesForSelectedVehicle,
|
|
noCoverageForSelectedVehicle,
|
|
repairWaivedForSelectedVehicle
|
|
} from '@/helpers/policy-vehicle-helper';
|
|
import coverageType from '@/constants/coverage-type';
|
|
import coverageStatuses from '@/constants/coverage-statuses';
|
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
|
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
|
import { buttonVariants } from '@/constants/component-variants';
|
|
import bailoutMessage from '@/constants/bailoutMessage';
|
|
|
|
export default {
|
|
name: 'policy-vehicles',
|
|
components: {
|
|
buttonMain,
|
|
siteSubHeader,
|
|
siteHeader,
|
|
siteFooter,
|
|
policyVehiclesQuestion,
|
|
Form
|
|
},
|
|
mixins: [BaseFormMixin],
|
|
async beforeRouteEnter(to, from, next) {
|
|
const cmsContentPromise = await fetchCmsContentForPage(to.query.issPage);
|
|
next((vm) => {
|
|
vm.setCmsContent(cmsContentPromise);
|
|
});
|
|
},
|
|
setup() {
|
|
const mainStore = useMainStore();
|
|
return { mainStore };
|
|
},
|
|
data() {
|
|
const policyVehicles = useMainStore().order.policy.vehicles;
|
|
return {
|
|
policyVehicles,
|
|
selectedVehicleVin: '',
|
|
policyVinFound: true,
|
|
rules: {
|
|
optionRequired: globalRules.OPTION_REQUIRED
|
|
},
|
|
buttonVariants
|
|
};
|
|
},
|
|
computed: {
|
|
VehiclesForQuestions() {
|
|
// Map API result data, to address-vehicles data structure
|
|
const vehicles = this.policyVehicles;
|
|
const mappedData =
|
|
vehicles?.map((v) => {
|
|
const maskSymbol = '*';
|
|
const vinStart = maskSymbol.repeat(v.vin.length - 6);
|
|
const vinEnd = v.vin.substring(v.vin.length - 6);
|
|
return {
|
|
vin: v.vin,
|
|
vehicle: v,
|
|
Text: `${v.vehicleYear} ${v.vehicleMake} ${v.vehicleModel}`,
|
|
Name: v.vin,
|
|
SubText: `VIN: ${vinStart}${vinEnd}`
|
|
};
|
|
}) ?? [];
|
|
return mappedData;
|
|
},
|
|
selectedPolicyVehicle() {
|
|
if (this.selectedVehicleVin !== vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
|
return this.policyVehicles.find((p) => p.vin === this.selectedVehicleVin);
|
|
}
|
|
return null;
|
|
},
|
|
noCoverageForSelectedVehicle() {
|
|
return noCoverageForSelectedVehicle(this.selectedPolicyVehicle);
|
|
},
|
|
deductibleForSelectedVehicle() {
|
|
return deductibleForSelectedVehicle(this.selectedPolicyVehicle);
|
|
},
|
|
endorsementsForSelectedVehicle() {
|
|
return endorsementsForSelectedVehicle(this.selectedPolicyVehicle);
|
|
},
|
|
endorsementCodesForSelectedVehicle() {
|
|
return endorsementCodesForSelectedVehicle(this.selectedPolicyVehicle);
|
|
},
|
|
repairWaivedForSelectedVehicle() {
|
|
return repairWaivedForSelectedVehicle(this.selectedPolicyVehicle);
|
|
}
|
|
},
|
|
watch: {
|
|
async selectedVehicleVin(value) {
|
|
if (value === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
|
// clear previously selected vehicle and image
|
|
this.mainStore.resetVehicleState();
|
|
return;
|
|
}
|
|
|
|
// get vehicle details from selected VIN
|
|
try {
|
|
const vehicle = await this.lookupVehicleByVin(value);
|
|
if (vehicle) {
|
|
// save selected vehicle to the store
|
|
useMainStore().updateVehicle({
|
|
...vehicle.data,
|
|
policyVehicleId: this.selectedPolicyVehicle?.id,
|
|
vin: value
|
|
});
|
|
}
|
|
} catch (e) {
|
|
this.mainStore.resetVehicleState();
|
|
}
|
|
}
|
|
},
|
|
beforeMount() {
|
|
if (this.mainStore.order.vehicle.vin) {
|
|
this.selectedVehicleVin = this.mainStore.order.vehicle.vin;
|
|
} else if (this.policyVehicles?.length === 1) {
|
|
this.selectedVehicleVin = this.policyVehicles[0]?.vin;
|
|
}
|
|
},
|
|
methods: {
|
|
backButtonAction() {
|
|
useMainStore().issConfig.disabledFields.policyNumber = true;
|
|
this.$router.navigate(
|
|
this.navigationScenarios.CLICKED_BACK,
|
|
this.$route
|
|
);
|
|
},
|
|
async forwardButtonAction() {
|
|
if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
|
useMainStore().updateCoverageType(coverageType.NONE);
|
|
useMainStore().updateCoverageStatus(coverageStatuses.NO_COVERAGE);
|
|
this.navigateForward();
|
|
return;
|
|
}
|
|
|
|
const vehicle = this.policyVehicles.find((pv) => pv.vin === this.selectedVehicleVin);
|
|
try {
|
|
const vehicleLookupResponse = await this.lookupVehicleByVin(this.selectedVehicleVin);
|
|
|
|
if (!vehicleLookupResponse?.data.canSafeliteService) {
|
|
this.mainStore.setBailout(
|
|
bailoutMessage.HeavyTruckVehicle(vehicleLookupResponse?.data?.carId)
|
|
);
|
|
}
|
|
useMainStore().updateVehicle({
|
|
...vehicleLookupResponse.data,
|
|
policyVehicleId: vehicle.id,
|
|
vin: this.selectedVehicleVin
|
|
});
|
|
|
|
useMainStore().updateVehicleCoverage({
|
|
noCoverage: this.noCoverageForSelectedVehicle,
|
|
deductible: this.deductibleForSelectedVehicle,
|
|
repairWaived: this.repairWaivedForSelectedVehicle,
|
|
endorsements: this.endorsementsForSelectedVehicle,
|
|
cvrgEndorsementCode: this.endorsementCodesForSelectedVehicle
|
|
});
|
|
|
|
this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true);
|
|
|
|
this.navigateForward();
|
|
} catch (e) {
|
|
if (e.isAxiosError && e.status === 404) {
|
|
this.mainStore.resetVehicleState();
|
|
useMainStore().updateVehicle({
|
|
policyVehicleId: vehicle.id,
|
|
carId: '0',
|
|
category: '',
|
|
year: vehicle.vehicleYear || '',
|
|
make: vehicle.vehicleMake || '',
|
|
model: vehicle.vehicleModel || '',
|
|
style: vehicle.vehicleStyle || '',
|
|
vin: vehicle.vin
|
|
});
|
|
this.policyVinFound = false;
|
|
|
|
this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true);
|
|
|
|
this.navigateForward();
|
|
return;
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
},
|
|
navigateForward() {
|
|
if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
|
this.$router.navigate(
|
|
this.navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
|
|
this.$route,
|
|
{},
|
|
{}
|
|
);
|
|
} else if (this.mainStore.isBailout) {
|
|
this.$router.navigate(
|
|
this.navigationScenarios.BAILOUT,
|
|
this.$route
|
|
);
|
|
} else if (this.endorsementsForSelectedVehicle?.length > 0
|
|
&& (this.endorsementsForSelectedVehicle?.includes(endorsementOptions.PARKING_GUARD)
|
|
|| this.endorsementsForSelectedVehicle?.includes(endorsementOptions.EDUCATOR))
|
|
) {
|
|
this.$router.navigate(
|
|
this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS,
|
|
this.$route
|
|
);
|
|
} else if (!this.policyVinFound) {
|
|
this.$router.navigate(
|
|
this.navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
|
this.$route,
|
|
{},
|
|
{}
|
|
);
|
|
} else {
|
|
this.$router.navigate(
|
|
this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
|
|
this.$route,
|
|
{},
|
|
{}
|
|
);
|
|
}
|
|
},
|
|
async lookupVehicleByVin(vin) {
|
|
return useMainStore().lookupVehicleByVin(vin);
|
|
},
|
|
async addAnotherVehicle() {
|
|
this.selectedVehicleVin = vehicleSelectionOptions.VEHICLE_NOT_LISTED;
|
|
await this.forwardButtonAction();
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.iss-heritage-container-width {
|
|
.policy-vehicles-container {
|
|
position: relative;
|
|
min-height: 1px;
|
|
padding-left: .9375rem;
|
|
padding-right: .9375rem;
|
|
|
|
:deep(.subheader-secondary p) {
|
|
text-align: left;
|
|
}
|
|
|
|
:deep(span.small) {
|
|
font-size: 1rem;
|
|
}
|
|
|
|
:deep(.form-test-error) {
|
|
text-align: left;
|
|
}
|
|
}
|
|
}
|
|
</style>
|