DigitalConsumer.ISS/src/layouts/vehicle-damage/vehicle-damage.vue
Bill Richardson bc6b31c790 PR updates
2024-10-01 15:25:21 -04:00

530 lines
21 KiB
Vue

<template>
<Form
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div
class="container-fluid fade-on-route-transition replace-options-question">
<div class="row justify-content-center">
<div class="col-md-6 px-0 px-md-2">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<vehicleBanner
class="mb-4"
cmsWidgetName="VehicleBannerWidget"
:displayGenericVehicleImage="false" />
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
<alert
v-if="shouldDisplayVehicleChangeAlert"
ref="vehicleChangeAlert"
class="mt-5 mb-0"
cmsWidgetName="VehicleChangeAlert"
alertClass="alert-warning"
:isDismissible="false" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6">
<damageLocationQuestion
ref="damageLocation"
v-model="selectedDamageLocations"
cmsWidgetName="DamageLocationQuestion"
groupName="DamageLocationQuestion" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<windshieldOptions
ref="windshieldOptions"
v-model="selectedWindshieldOptions"
:hasRepairReplaceConflict="hasRepairReplaceConflict"
:hasSplitSingleConflict="hasSplitSingleConflict"
:selectedDamageLocations="selectedDamageLocations" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<alert
v-if="hasRepairReplaceConflict"
class="my-5"
cmsWidgetName="HasReplacementConflict"
alertClass="alert-danger"
:isDismissible="false" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<sideDoorOptions
v-show="!hasRepairReplaceConflict"
ref="sideDoorOptions"
v-model="sideDoorOptionsData"
cmsWidgetName="SideDoorSideQuestion"
groupName="SideDoorSideQuestion"
:selectedDamageLocations="selectedDamageLocations" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<replaceOptionsQuestion
ref="backGlassOptions"
v-model="selectedRearReplaceOptions"
cmsWidgetName="RearReplaceOptionsQuestion"
:isAvailable="
isRearWindowDamageLocation &&
!hasRepairReplaceConflict
"
groupName="BackGlassReplaceOptionsQuestion"
validationRules="replace-options-required" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<site-footer
ref="siteFooter"
class="mt-5"
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@backClicked="navigateBack"
@forwardClicked="forwardButtonAction" />
</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 vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import sideDoorOptions from '@/layouts/vehicle-damage/side-door-options/side-door-options.vue';
import damageLocationQuestion from '@/layouts/vehicle-damage/damage-location-question/damage-location-question.vue';
import windshieldOptions from '@/layouts/vehicle-damage/windshield-options/windshield-options.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import alert from '@/ux-components/alert/alert.vue';
// Supporting files
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { Form, defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';
import damageLocationsCms from '@/constants/damage-locations-cms.js';
import damageLocationsSelected from '@/constants/damage-locations-selected.js';
import { useMainStore } from '@/store';
import bailoutMessage from '@/constants/bailoutMessage';
// DEFINE VALIDATION RULES
defineRule(
'replace-options-required',
required(errorMessages.REPLACE_OPTIONS_REQUIRED)
);
export default {
name: 'vehicle-damage',
components: {
siteHeader,
siteFooter,
vehicleBanner,
siteSubHeader,
sideDoorOptions,
damageLocationQuestion,
windshieldOptions,
replaceOptionsQuestion,
// eslint-disable-next-line vue/no-reserved-component-names
Form,
alert
},
mixins: [BaseFormMixin, vehicleQuestionsMixin],
async beforeRouteEnter(to, from, next) {
const store = useMainStore();
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const damageOptionsPromise = store.getDamageOptions(store.order.vehicle.carId);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
},
{
resultKey: 'damageOptions',
promise: damageOptionsPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.$refs.damageLocation.initializeComponent(resultMap.damageOptions);
vm.$refs.sideDoorOptions.initializeComponent(
resultMap.damageOptions.driverSideOptions
.availableReplacementOptions,
resultMap.damageOptions.passengerSideOptions
.availableReplacementOptions
);
vm.$refs.windshieldOptions.initializeComponent(resultMap.damageOptions.windshieldOptions
.availableReplacementOptions);
vm.$refs.backGlassOptions.initializeComponent(resultMap.damageOptions.backGlassOptions
.availableReplacementOptions);
});
},
setup() {
const mainStore = useMainStore();
return { mainStore };
},
data() {
return {
selectedDamageLocations: this.getDamageLocationsFromStore(),
sideDoorOptionsData: {
selectedDoorSides: this.getDoorSidesFromStore(),
selectedDriverSideReplaceOptions:
this.getDriverSideReplaceOptionsFromStore(),
selectedPassengerSideReplaceOptions:
this.getPassengerSideReplaceOptionsFromStore()
},
selectedWindshieldOptions: this.getWindshieldOptionsFromStore(),
selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore(),
hasBailedOut: false
};
},
computed: {
isWindshieldDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) =>
selectedDamages.toUpperCase()
=== damageLocationsCms.WINDSHIELD);
},
isSideDoorDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) =>
selectedDamages.toUpperCase()
=== damageLocationsCms.SIDEDOOR);
},
isRearWindowDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) =>
selectedDamages.toUpperCase()
=== damageLocationsCms.REARWINDOW);
},
isWindshieldRepair() {
return (
this.isWindshieldDamageLocation
&& this.selectedWindshieldOptions.selectedWindshieldDamageType
=== damageLocationsSelected.REPAIR
);
},
isDriverSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some((selectedDriverSide) =>
selectedDriverSide.toUpperCase()
=== damageLocationsCms.DRIVERSIDE);
},
isPassengerSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some((selectedPassengerSide) =>
selectedPassengerSide.toUpperCase()
=== damageLocationsCms.PASSENGERSIDE);
},
hasRepairReplaceConflict() {
return (
this.isWindshieldDamageLocation
&& this.selectedDamageLocations.length > 1
&& this.isWindshieldRepair
);
},
hasSplitSingleConflict() {
if (
!this.selectedDamageLocations?.includes('Windshield')
|| this.selectedWindshieldOptions.selectedWindshieldDamageType
=== damageLocationsSelected.REPAIR
|| !this.selectedWindshieldOptions.selectedWindshieldReplaceOptions
) return false;
return (
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some((selectedSingleWindshield) =>
selectedSingleWindshield.toUpperCase()
=== damageLocationsSelected.SINGLE.toUpperCase())
&& (this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some((selectedDriverWindshield) =>
selectedDriverWindshield.toUpperCase()
=== damageLocationsSelected.DRIVER.toUpperCase())
|| this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some((selectedPassengerWindshield) =>
selectedPassengerWindshield.toUpperCase()
=== damageLocationsSelected.PASSENGER.toUpperCase()))
);
},
shouldDisplayVehicleChangeAlert() {
return this.$router?.options?.history?.state[this.routerParams.DISPLAY_VEHICLE_CHANGE_ALERT] ?? false;
}
},
methods: {
arePagePrerequisitesValid() {
if (useMainStore().order.vehicle.carId) {
return true;
}
return false;
},
getDamageLocationsFromStore() {
const glassSelections = [];
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.WINDSHIELD)
|| this.mainStore.order.damage.isRepair
) {
glassSelections.push(damageLocationsSelected.WINDSHIELD);
}
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.DRIVER
|| glass.glassLocation
=== damageLocationsSelected.PASSENGER)
) {
glassSelections.push(damageLocationsSelected.SIDEDOOR);
}
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation === damageLocationsSelected.REAR)
) {
glassSelections.push(damageLocationsSelected.REARWINDOW);
}
return glassSelections;
},
getWindshieldOptionsFromStore() {
const windShieldOptions = {
selectedWindshieldDamageType: '',
selectedWindshieldChipCount: null,
selectedWindshieldReplaceOptions: []
};
if (this.mainStore.order.damage.isRepair === undefined) return windshieldOptions;
if (this.mainStore.order.damage.isRepair) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPAIR;
windShieldOptions.selectedWindshieldChipCount =
this.mainStore.order.damage.numberOfChips;
} else {
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.WINDSHIELD
&& glass.glassName === damageLocationsSelected.SINGLE)
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.SINGLE);
}
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.WINDSHIELD
&& glass.glassName === damageLocationsSelected.DRIVER)
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.DRIVER);
}
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.WINDSHIELD
&& glass.glassName
=== damageLocationsSelected.PASSENGER)
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.PASSENGER);
}
}
return windShieldOptions;
},
getDoorSidesFromStore() {
const doorSides = [];
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation === damageLocationsSelected.DRIVER)
) {
doorSides.push(damageLocationsSelected.DRIVERSIDE);
}
if (
this.mainStore.order.damage.glassToReplace?.some((glass) =>
glass.glassLocation
=== damageLocationsSelected.PASSENGER)
) {
doorSides.push(damageLocationsSelected.PASSENGERSIDE);
}
return doorSides;
},
getDriverSideReplaceOptionsFromStore() {
const driverSideReplaceOptions = [];
this.mainStore.order.damage.glassToReplace?.forEach((glass) => {
if (glass.glassLocation === damageLocationsSelected.DRIVER) {
driverSideReplaceOptions.push(glass.glassName);
}
});
return driverSideReplaceOptions;
},
getPassengerSideReplaceOptionsFromStore() {
const passengerSideReplaceOptions = [];
this.mainStore.order.damage.glassToReplace?.forEach((glass) => {
if (glass.glassLocation === damageLocationsSelected.PASSENGER) {
passengerSideReplaceOptions.push(glass.glassName);
}
});
return passengerSideReplaceOptions;
},
getRearReplaceOptionsFromStore() {
const rearReplaceOptions =
this.mainStore.order.damage.glassToReplace?.filter((glass) =>
glass.glassLocation === damageLocationsSelected.REAR)[0]?.glassName;
return rearReplaceOptions;
},
async forwardButtonAction() {
this.mainStore.saveVehicleDamage(
this.isWindshieldRepair,
this.selectedGlassToReplace(),
this.selectedWindshieldOptions.selectedWindshieldChipCount
);
if (this.isWindshieldRepair) {
const results = await Promise.allSettled([useMainStore().getSupportingItems(), useMainStore().getRecalParts()]);
const supportingItems = results[0];
useMainStore().updateSupportingItems(supportingItems.data);
}
if (this.mainStore.damage.isRepair) {
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_REPAIR,
this.$route
);
} else if (this.mainStore.order.vehicle.vin) {
// If vin already exists, navigate directly to vin-lookup
const partsOrQuestionsResponse = await this.getPartsOrQuestions();
if (partsOrQuestionsResponse.error) {
this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data));
window.console.error('Error on retrieving PartsOrQuestions');
this.$refs.siteFooter.removeLoader();
this.hasBailedOut = true;
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
this.$route
);
}
// Comes from vehicleQuestionsMixin.navigateForward()
if (!this.hasBailedOut) {
await this.navigateForward(
partsOrQuestionsResponse.data.partsOrQuestions,
this
);
}
} else {
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
this.$route
);
}
return null;
},
selectedGlassToReplace() {
const selectedGlassToReplace = [];
if (this.isWindshieldDamageLocation && !this.isWindshieldRepair) {
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.forEach((wsItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.WINDSHIELD,
glassName: wsItem
});
});
}
if (this.isDriverSideReplace) {
this.sideDoorOptionsData.selectedDriverSideReplaceOptions.forEach((driverItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.DRIVER,
glassName: driverItem
});
});
}
if (this.isPassengerSideReplace) {
this.sideDoorOptionsData.selectedPassengerSideReplaceOptions.forEach((passengerItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.PASSENGER,
glassName: passengerItem
});
});
}
if (this.isRearWindowDamageLocation) {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.REAR,
glassName: this.selectedRearReplaceOptions
});
}
return selectedGlassToReplace;
}
}
};
</script>
<style lang="scss">
.replace-options-question {
.row {
margin-top: 0;
.col-12 {
margin: 0 0 .5rem 0;
&:last-child {
margin-bottom: 0;
}
}
}
.question-text {
margin: 0;
span {
padding: 1rem 0;
text-align: center;
}
}
.two-list-card-width {
width: 100%;
flex: 0 auto;
}
}
.button-question,
.windshield-damage-type-question,
.damage-location-question {
.col {
margin-top: 0;
}
}
</style>