WIP update markup for ancillary pages found by Katie.
This commit is contained in:
parent
3ab6d5d4ef
commit
4bcffb29b9
13 changed files with 1094 additions and 805 deletions
|
|
@ -4,69 +4,67 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition position-relative">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="select-car">
|
||||
<div class="container-fluid pb-2">
|
||||
<div class="row px-3">
|
||||
<div class="col">
|
||||
<div class="select-car-form rounded">
|
||||
<vehicleBanner
|
||||
ref="vehicleBanner"
|
||||
class="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader
|
||||
ref="siteSubHeader"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
class="mb-5" />
|
||||
<alert
|
||||
v-if="displayVinNotFoundAlert"
|
||||
ref="alertVinNotFound"
|
||||
class="mb-4 mt-4"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedDifferentVehicleAlert"
|
||||
ref="alertMatchedDifferentVehicle"
|
||||
class="mb-4 mt-4"
|
||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||
class="mb-4 mt-4"
|
||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||
ref="alertVinLookupsByHomeAddressNotAllowed"
|
||||
class="mt-4"
|
||||
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<customerQuestions
|
||||
ref="customerQuestions"
|
||||
v-model="customerQuestions" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<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
|
||||
ref="vehicleBanner"
|
||||
class="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader
|
||||
ref="siteSubHeader"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
class="mb-5" />
|
||||
<alert
|
||||
v-if="displayVinNotFoundAlert"
|
||||
ref="alertVinNotFound"
|
||||
class="mb-4 mt-4"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedDifferentVehicleAlert"
|
||||
ref="alertMatchedDifferentVehicle"
|
||||
class="mb-4 mt-4"
|
||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||
class="mb-4 mt-4"
|
||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||
:manualHeadline="
|
||||
AlertMatchedTwoIdenticalYMMVehicleHeader
|
||||
"
|
||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||
ref="alertVinLookupsByHomeAddressNotAllowed"
|
||||
class="mt-4"
|
||||
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<customerQuestions
|
||||
ref="customerQuestions"
|
||||
v-model="customerQuestions" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -89,7 +87,10 @@ import { Form } from 'vee-validate';
|
|||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import routerParams from '@/router/router-constants/router-params';
|
||||
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
||||
import {
|
||||
getDamageString,
|
||||
isGlassAvailableForCarId,
|
||||
} from '@/helpers/damage-helper';
|
||||
|
||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||
import { useMainStore } from '@/store/index.js';
|
||||
|
|
@ -104,7 +105,7 @@ export default {
|
|||
customerQuestions,
|
||||
alert,
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
Form,
|
||||
},
|
||||
mixins: [baseFormMixin, vinPagesMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -115,8 +116,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -137,7 +138,7 @@ export default {
|
|||
isCarIdDifferent: false,
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
customAlertData: {},
|
||||
forwardButtonCarStyle: ''
|
||||
forwardButtonCarStyle: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -151,10 +152,14 @@ export default {
|
|||
const vinYmmFound =
|
||||
// eslint-disable-next-line max-len
|
||||
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||
const vinYmmExpected =
|
||||
`${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model}`;
|
||||
const vinYmmExpected = `${useMainStore().order.vehicle.year} ${
|
||||
useMainStore().order.vehicle.make
|
||||
} ${useMainStore().order.vehicle.model}`;
|
||||
|
||||
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
||||
return this.getCmsContent(
|
||||
'AlertMatchedDifferentVehicleWidget',
|
||||
'BodyText'
|
||||
)
|
||||
.replaceAll('{custom:damage}', getDamageString())
|
||||
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
||||
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
||||
|
|
@ -171,9 +176,16 @@ export default {
|
|||
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
|
||||
const vinYmmsExpected =
|
||||
// eslint-disable-next-line max-len
|
||||
`${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model} ${useMainStore().order.vehicle.style}`;
|
||||
`${useMainStore().order.vehicle.year} ${
|
||||
useMainStore().order.vehicle.make
|
||||
} ${useMainStore().order.vehicle.model} ${
|
||||
useMainStore().order.vehicle.style
|
||||
}`;
|
||||
|
||||
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
||||
return this.getCmsContent(
|
||||
'AlertMatchedTwoIdenticalYMMVehicleWidget',
|
||||
'BodyText'
|
||||
)
|
||||
.replaceAll('{custom:damage}', getDamageString())
|
||||
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
||||
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
||||
|
|
@ -182,21 +194,24 @@ export default {
|
|||
const vinYmmFound =
|
||||
// eslint-disable-next-line max-len
|
||||
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||
const vinYmmExpected =
|
||||
`${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model}`;
|
||||
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
|
||||
}
|
||||
const vinYmmExpected = `${useMainStore().order.vehicle.year} ${
|
||||
useMainStore().order.vehicle.make
|
||||
} ${useMainStore().order.vehicle.model}`;
|
||||
return vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase();
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
customerQuestions: {
|
||||
handler() {
|
||||
// if they modify one of the lookup fields (address, city, state, zipCode, or lastName),
|
||||
// then modify the button text back to "Get my personalized quote"
|
||||
this.$refs.siteFooter.updateButtonText(this.getCmsContent('siteFooterWidget', 'ForwardButtonText'));
|
||||
// if they modify one of the lookup fields (address, city, state, zipCode, or lastName),
|
||||
// then modify the button text back to "Get my personalized quote"
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent('siteFooterWidget', 'ForwardButtonText')
|
||||
);
|
||||
this.resetWarningsAndErrors();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.attachCustomEvents();
|
||||
|
|
@ -224,23 +239,24 @@ export default {
|
|||
|
||||
const vinLookupResponse = useMainStore().lookupVinByAddress({
|
||||
licenseLastName: this.customerQuestions.lastName,
|
||||
licenseStreetAddress: this.customerQuestions.addressQuestions.streetAddress,
|
||||
licenseStreetAddress:
|
||||
this.customerQuestions.addressQuestions.streetAddress,
|
||||
licenseZip: this.customerQuestions.addressQuestions.zipCode,
|
||||
licenseState: this.customerQuestions.addressQuestions.state
|
||||
licenseState: this.customerQuestions.addressQuestions.state,
|
||||
});
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'vinLookupResponse',
|
||||
promise: vinLookupResponse
|
||||
}
|
||||
promise: vinLookupResponse,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
// If VIN Lookup by address is forbidden by State Restrictions then show an alert
|
||||
if (!resultMap.vinLookupResponse.isStatePermissible) {
|
||||
// State Restrictions forbid lookup by address
|
||||
// State Restrictions forbid lookup by address
|
||||
this.displayVinLookupByHomeAddressNotAllowedAlert = true;
|
||||
this.$refs.siteFooter.disableForwardButton();
|
||||
return this.$refs.siteFooter.removeLoader();
|
||||
|
|
@ -250,12 +266,16 @@ export default {
|
|||
|
||||
// Handle cases for different amounts of VINS found for the address.
|
||||
if (carsFound.length === 1) {
|
||||
// Single VIN found
|
||||
// Single VIN found
|
||||
const carFound = carsFound[0].vehicle;
|
||||
|
||||
this.isCarIdDifferent = carFound.carId !== useMainStore().order.vehicle.carId;
|
||||
if (this.isCarIdDifferent && carFound.carId !== this.previouslyEnteredCarId) {
|
||||
// Display Alert
|
||||
this.isCarIdDifferent =
|
||||
carFound.carId !== useMainStore().order.vehicle.carId;
|
||||
if (
|
||||
this.isCarIdDifferent &&
|
||||
carFound.carId !== this.previouslyEnteredCarId
|
||||
) {
|
||||
// Display Alert
|
||||
this.previouslyEnteredCarId = carFound.carId;
|
||||
this.customAlertData.vehicleInfo = carFound;
|
||||
if (this.isTwoIdenticalYMMVehicleFound) {
|
||||
|
|
@ -265,28 +285,39 @@ export default {
|
|||
this.displayMatchedDifferentVehicleAlert = true;
|
||||
}
|
||||
|
||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(carFound.carId);
|
||||
this.isSelectedGlassAvailableForVehicle =
|
||||
await isGlassAvailableForCarId(carFound.carId);
|
||||
|
||||
// Update button "Continue with..."
|
||||
this.$refs.siteFooter
|
||||
// eslint-disable-next-line max-len
|
||||
.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`);
|
||||
.updateButtonText(
|
||||
`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`
|
||||
);
|
||||
return this.$refs.siteFooter.removeLoader();
|
||||
}
|
||||
|
||||
// update data
|
||||
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
|
||||
vehicleInfoToCommit = Object.assign(carFound, {
|
||||
vin: carsFound[0].vin,
|
||||
});
|
||||
} else if (carsFound.length > 1) {
|
||||
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
|
||||
const matchingCars = carsFound.filter((vin) => vin.vehicle.carId === useMainStore().order.vehicle.carId);
|
||||
const matchingCars = carsFound.filter(
|
||||
(vin) =>
|
||||
vin.vehicle.carId === useMainStore().order.vehicle.carId
|
||||
);
|
||||
|
||||
if (matchingCars.length === 1) {
|
||||
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {
|
||||
vin: matchingCars[0].vin
|
||||
});
|
||||
vehicleInfoToCommit = Object.assign(
|
||||
matchingCars[0].vehicle,
|
||||
{
|
||||
vin: matchingCars[0].vin,
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// No VINS found.
|
||||
// No VINS found.
|
||||
this.displayVinNotFoundAlert = true;
|
||||
this.$refs.siteFooter.disableForwardButton();
|
||||
return this.$refs.siteFooter.removeLoader();
|
||||
|
|
@ -295,19 +326,23 @@ export default {
|
|||
// Save vehicle, customer, service and registration information
|
||||
await useMainStore().saveRegistrationAddressLookup(
|
||||
{
|
||||
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||
isSelectedGlassAvailableForVehicle:
|
||||
this.isSelectedGlassAvailableForVehicle,
|
||||
vehicleInfo:
|
||||
Object.keys(vehicleInfoToCommit).length === 0
|
||||
? null
|
||||
: vehicleInfoToCommit,
|
||||
Object.keys(vehicleInfoToCommit).length === 0
|
||||
? null
|
||||
: vehicleInfoToCommit,
|
||||
registrationInfo: {
|
||||
firstName: this.customerQuestions.firstName,
|
||||
lastName: this.customerQuestions.lastName,
|
||||
address: this.customerQuestions.addressQuestions.streetAddress,
|
||||
address:
|
||||
this.customerQuestions.addressQuestions
|
||||
.streetAddress,
|
||||
city: this.customerQuestions.addressQuestions.city,
|
||||
state: this.customerQuestions.addressQuestions.state,
|
||||
zipCode: this.customerQuestions.addressQuestions.zipCode
|
||||
}
|
||||
zipCode:
|
||||
this.customerQuestions.addressQuestions.zipCode,
|
||||
},
|
||||
},
|
||||
false
|
||||
);
|
||||
|
|
@ -315,15 +350,18 @@ export default {
|
|||
return this.navigateForward(carsFound);
|
||||
},
|
||||
async navigateForward(carsFound) {
|
||||
// Match vehicles found to vehicles in state.
|
||||
const matchingCars = carsFound.filter((car) => car.vehicle.carId === useMainStore().order.vehicle.carId);
|
||||
// Match vehicles found to vehicles in state.
|
||||
const matchingCars = carsFound.filter(
|
||||
(car) =>
|
||||
car.vehicle.carId === useMainStore().order.vehicle.carId
|
||||
);
|
||||
|
||||
// If a different vehicle is found than the one entered and the selected glass
|
||||
// is not available for that vehicle then navigate back to "vehicle-damage"
|
||||
// display vehicle changed alert on that page.
|
||||
if (
|
||||
this.isCarIdDifferent
|
||||
&& !this.isSelectedGlassAvailableForVehicle
|
||||
this.isCarIdDifferent &&
|
||||
!this.isSelectedGlassAvailableForVehicle
|
||||
) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
|
|
@ -335,7 +373,8 @@ export default {
|
|||
await this.navigateForwardWithSingleCarMatch();
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
||||
this.navigationScenarios
|
||||
.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
||||
this.$route,
|
||||
{},
|
||||
{},
|
||||
|
|
@ -348,7 +387,7 @@ export default {
|
|||
this.displayMatchedDifferentVehicleAlert = false;
|
||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||
this.$refs.siteFooter.enableForwardAction();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,66 +1,84 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="fade-on-route-transition sub-container overflow-scroll px-5">
|
||||
<vehicleBanner
|
||||
class="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<alert
|
||||
id="multiple-vehicles-alert"
|
||||
ref="alertFoundMultipleVehicles"
|
||||
cmsWidgetName="FoundMultipleVehicles"
|
||||
class="my-5"
|
||||
alertClass="alert-warning"
|
||||
:manualHeadline="AlertFoundMultipleVehiclesHeader"
|
||||
manualCopy=""
|
||||
:isDismissible="false" />
|
||||
<addressVehiclesQuestion
|
||||
ref="addressVehiclesQuestion"
|
||||
v-model="selectedVehicleVin"
|
||||
cmsWidgetName="VehicleConfirmationQuestion"
|
||||
:vehicles="VehiclesForQuestions"
|
||||
:vehicleSelected="VehicleSelected"
|
||||
validationRules="vehicle-required"
|
||||
:isCarIdDifferent="isCarIdDifferent"
|
||||
:displayMatchedDifferentVehicleAlert="displayMatchedDifferentVehicleAlert"
|
||||
:displayMatchedTwoIdenticalYMMVehicleAlert="displayMatchedTwoIdenticalYMMVehicleAlert" />
|
||||
<div
|
||||
v-if="splitAlertProvideVinBodyForLink.length"
|
||||
class="alert-provide-vin my-3">
|
||||
<span
|
||||
v-for="copy in splitAlertProvideVinBodyForLink"
|
||||
:key="copy">
|
||||
<span
|
||||
v-if="doesCopyContainRouterLink(copy)"
|
||||
class="text-body">
|
||||
<router-link
|
||||
:to="{
|
||||
query: { issPage: `${getRouterLinkRouteFromCopy(copy)}` },
|
||||
name: 'root',
|
||||
}">{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link>
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="m-0 text-body"
|
||||
v-html="copy"></span>
|
||||
</span>
|
||||
</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@backClicked="navigateBack"
|
||||
@forwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<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="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<alert
|
||||
id="multiple-vehicles-alert"
|
||||
ref="alertFoundMultipleVehicles"
|
||||
cmsWidgetName="FoundMultipleVehicles"
|
||||
class="my-5"
|
||||
alertClass="alert-warning"
|
||||
:manualHeadline="AlertFoundMultipleVehiclesHeader"
|
||||
manualCopy=""
|
||||
:isDismissible="false" />
|
||||
<addressVehiclesQuestion
|
||||
ref="addressVehiclesQuestion"
|
||||
v-model="selectedVehicleVin"
|
||||
cmsWidgetName="VehicleConfirmationQuestion"
|
||||
:vehicles="VehiclesForQuestions"
|
||||
:vehicleSelected="VehicleSelected"
|
||||
validationRules="vehicle-required"
|
||||
:isCarIdDifferent="isCarIdDifferent"
|
||||
:displayMatchedDifferentVehicleAlert="
|
||||
displayMatchedDifferentVehicleAlert
|
||||
"
|
||||
:displayMatchedTwoIdenticalYMMVehicleAlert="
|
||||
displayMatchedTwoIdenticalYMMVehicleAlert
|
||||
" />
|
||||
<div
|
||||
v-if="splitAlertProvideVinBodyForLink.length"
|
||||
class="alert-provide-vin my-3">
|
||||
<span
|
||||
v-for="copy in splitAlertProvideVinBodyForLink"
|
||||
:key="copy">
|
||||
<span
|
||||
v-if="doesCopyContainRouterLink(copy)"
|
||||
class="text-body">
|
||||
<router-link
|
||||
:to="{
|
||||
query: {
|
||||
issPage: `${getRouterLinkRouteFromCopy(
|
||||
copy
|
||||
)}`,
|
||||
},
|
||||
name: 'root',
|
||||
}"
|
||||
>{{
|
||||
getRouterLinkDisplayTextFromCopy(copy)
|
||||
}}</router-link
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="m-0 text-body"
|
||||
v-html="copy"></span>
|
||||
</span>
|
||||
</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@backClicked="navigateBack"
|
||||
@forwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -77,7 +95,7 @@ import {
|
|||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
} from '@/helpers/cms-content-helper.js';
|
||||
import routerParams from '@/router/router-constants/router-params';
|
||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||
|
|
@ -104,7 +122,7 @@ export default {
|
|||
Form,
|
||||
vehicleBanner,
|
||||
alert,
|
||||
addressVehiclesQuestion
|
||||
addressVehiclesQuestion,
|
||||
},
|
||||
mixins: [baseFormMixin, vinPagesMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -114,8 +132,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -125,7 +143,7 @@ export default {
|
|||
});
|
||||
},
|
||||
props: {
|
||||
validationRules: String
|
||||
validationRules: String,
|
||||
},
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
|
|
@ -140,7 +158,7 @@ export default {
|
|||
displayMatchedDifferentVehicleAlert: false,
|
||||
displayMatchedTwoIdenticalYMMVehicleAlert: false,
|
||||
previouslyEnteredCarId: '',
|
||||
forwardButtonCarStyle: ''
|
||||
forwardButtonCarStyle: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -154,11 +172,9 @@ export default {
|
|||
).replaceAll('{custom:vehicleCount}', this.vehicleCount);
|
||||
},
|
||||
isTwoIdenticalYMMVehicleFound() {
|
||||
const vinYmmFound =
|
||||
`${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
||||
const vinYmmExpected =
|
||||
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
|
||||
const vinYmmFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
return vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase();
|
||||
},
|
||||
AlertProvideVinBody() {
|
||||
return this.getCmsContent('ProvideVinAlert', 'BodyText');
|
||||
|
|
@ -178,7 +194,7 @@ export default {
|
|||
vehicle: v.vehicle,
|
||||
Text: `${v.vehicle.year} ${v.vehicle.make} ${v.vehicle.model}`,
|
||||
Name: v.vin,
|
||||
SubText: `VIN ${vinStart}${vinEnd}`
|
||||
SubText: `VIN ${vinStart}${vinEnd}`,
|
||||
};
|
||||
});
|
||||
return mappedData;
|
||||
|
|
@ -187,11 +203,13 @@ export default {
|
|||
return useMainStore().pageData(issPageValues.ADDRESS_VEHICLES);
|
||||
},
|
||||
selectedVehicle() {
|
||||
return this.VehiclesForQuestions.find(({ vin }) => vin === this.selectedVehicleVin);
|
||||
return this.VehiclesForQuestions.find(
|
||||
({ vin }) => vin === this.selectedVehicleVin
|
||||
);
|
||||
},
|
||||
VehicleSelected() {
|
||||
return this.mainStore.order.vehicle;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
selectedVehicleVin: {
|
||||
|
|
@ -199,10 +217,15 @@ export default {
|
|||
this.resetWarningsAndErrors();
|
||||
// does this vehicle match the previously selected carId?
|
||||
this.isCarIdDifferent =
|
||||
this.selectedVehicle?.vehicle.carId !== useMainStore().vehicle.carId;
|
||||
if (this.isCarIdDifferent
|
||||
&& this.selectedVehicle?.vehicle.carId !== this.previouslyEnteredCarId) {
|
||||
this.previouslyEnteredCarId = this.selectedVehicle?.vehicle.carId;
|
||||
this.selectedVehicle?.vehicle.carId !==
|
||||
useMainStore().vehicle.carId;
|
||||
if (
|
||||
this.isCarIdDifferent &&
|
||||
this.selectedVehicle?.vehicle.carId !==
|
||||
this.previouslyEnteredCarId
|
||||
) {
|
||||
this.previouslyEnteredCarId =
|
||||
this.selectedVehicle?.vehicle.carId;
|
||||
if (this.isTwoIdenticalYMMVehicleFound) {
|
||||
const carStyle = this.selectedVehicle?.vehicle.style;
|
||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
||||
|
|
@ -210,15 +233,21 @@ export default {
|
|||
} else {
|
||||
this.displayMatchedDifferentVehicleAlert = true;
|
||||
}
|
||||
this.$refs.siteFooter
|
||||
.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} `
|
||||
+ `${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model} ${this.forwardButtonCarStyle}`);
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
`Continue with ${this.selectedVehicle.vehicle.year} ` +
|
||||
`${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model} ${this.forwardButtonCarStyle}`
|
||||
);
|
||||
} else {
|
||||
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent(
|
||||
'SiteFooterWidget',
|
||||
'ForwardButtonText'
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
doesCopyContainRouterLink,
|
||||
|
|
@ -240,14 +269,15 @@ export default {
|
|||
if (!vinLookup) {
|
||||
return;
|
||||
}
|
||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
|
||||
this.isSelectedGlassAvailableForVehicle =
|
||||
await isGlassAvailableForCarId(vinLookup.data.carId);
|
||||
await useMainStore().saveVin(
|
||||
{
|
||||
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
|
||||
vin: this.selectedVehicle.vin
|
||||
vin: this.selectedVehicle.vin,
|
||||
}),
|
||||
isSelectedGlassAvailableForVehicle:
|
||||
this.isSelectedGlassAvailableForVehicle
|
||||
this.isSelectedGlassAvailableForVehicle,
|
||||
},
|
||||
false
|
||||
);
|
||||
|
|
@ -257,7 +287,10 @@ export default {
|
|||
async navigateForward() {
|
||||
// If the vehicle selected on this page is different from the one originally entered and the selected glass is not available
|
||||
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
|
||||
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||
if (
|
||||
this.isCarIdDifferent &&
|
||||
!this.isSelectedGlassAvailableForVehicle
|
||||
) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
this.$route,
|
||||
|
|
@ -272,28 +305,28 @@ export default {
|
|||
this.displayMatchedDifferentVehicleAlert = false;
|
||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = false;
|
||||
this.forwardButtonCarStyle = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.alert-provide-vin {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.4;
|
||||
a {
|
||||
//Per Devyn. This can't be documented in Figma so there is a comment with the Prototype mocks on the Quote page in Figma
|
||||
text-underline-offset: 4px;
|
||||
line-height: inherit;
|
||||
}
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.4;
|
||||
a {
|
||||
//Per Devyn. This can't be documented in Figma so there is a comment with the Prototype mocks on the Quote page in Figma
|
||||
text-underline-offset: 4px;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
#multiple-vehicles-alert p {
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
}
|
||||
|
||||
.overflow-scroll {
|
||||
height: calc(100% - 180px);
|
||||
overflow-X: hidden !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<questionsPageLayout
|
||||
ref="questionsPageLayout"
|
||||
v-model="selectedAnswers"
|
||||
isRequired
|
||||
:isMetaValid="meta.valid"
|
||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||
:questionsData="questionsData"
|
||||
:validationRules="rules.optionRequired"
|
||||
:index="currentGlassIndex"
|
||||
@forwardButtonAction="forwardButtonAction"
|
||||
@backClick="navigateBackByVehicleQuestions" />
|
||||
</Form>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<questionsPageLayout
|
||||
ref="questionsPageLayout"
|
||||
v-model="selectedAnswers"
|
||||
isRequired
|
||||
:isMetaValid="meta.valid"
|
||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||
:questionsData="questionsData"
|
||||
:validationRules="rules.optionRequired"
|
||||
:index="currentGlassIndex"
|
||||
@forwardButtonAction="forwardButtonAction"
|
||||
@backClick="navigateBackByVehicleQuestions" />
|
||||
</Form>
|
||||
</template>
|
||||
<script>
|
||||
// Import Supporting Files
|
||||
|
|
@ -37,7 +37,7 @@ export default {
|
|||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form,
|
||||
questionsPageLayout
|
||||
questionsPageLayout,
|
||||
},
|
||||
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -47,8 +47,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -63,36 +63,49 @@ export default {
|
|||
selectedAnswers: {},
|
||||
currentGlassIndex: 0,
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
optionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
AlertFewMoreQuestionsHeader() {
|
||||
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'HeadlineText');
|
||||
return this.getCmsContent(
|
||||
'AdditionalPartsQuestionsAlert',
|
||||
'HeadlineText'
|
||||
);
|
||||
},
|
||||
AlertFewMoreQuestionsCopy() {
|
||||
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
|
||||
return this.getCmsContent(
|
||||
'AdditionalPartsQuestionsAlert',
|
||||
'BodyText'
|
||||
);
|
||||
},
|
||||
partsOrQuestionsData() {
|
||||
return useMainStore().pageData(issPageValues.CAPABILITY_QUESTIONS)
|
||||
.partsOrQuestions;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getInitialQuestionData();
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
const capabilityQuestionsFromPageData = useMainStore().pageData(issPageValues.CAPABILITY_QUESTIONS);
|
||||
const capabilityQuestionsFromPageData = useMainStore().pageData(
|
||||
issPageValues.CAPABILITY_QUESTIONS
|
||||
);
|
||||
return (
|
||||
capabilityQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName)
|
||||
&& capabilityQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.capabilityQuestions?.length > 0)
|
||||
capabilityQuestionsFromPageData?.partsOrQuestions?.some(
|
||||
(part) => part?.glassName
|
||||
) &&
|
||||
capabilityQuestionsFromPageData?.partsOrQuestions?.some(
|
||||
(part) => part?.capabilityQuestions?.length > 0
|
||||
)
|
||||
);
|
||||
},
|
||||
getInitialQuestionData() {
|
||||
// get any questions that were already answered
|
||||
const alreadyAnsweredQuestions = useMainStore().damage.capabilityQuestionAnswers;
|
||||
const alreadyAnsweredQuestions =
|
||||
useMainStore().damage.capabilityQuestionAnswers;
|
||||
this.questionsData = this.partsOrQuestionsData
|
||||
.filter((x) => x.capabilityQuestions)
|
||||
.map((glass, index) => {
|
||||
|
|
@ -111,7 +124,10 @@ export default {
|
|||
`selectedAnswers.${glass.answerKey}`,
|
||||
(newValue) => {
|
||||
if (newValue && Object.keys(newValue).length > 0) {
|
||||
this.handleAnswerUpdates(newValue, glass.answerKey);
|
||||
this.handleAnswerUpdates(
|
||||
newValue,
|
||||
glass.answerKey
|
||||
);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
|
|
@ -124,7 +140,9 @@ export default {
|
|||
// get answerResult2 of returned answer
|
||||
let selectedAnswerResult2;
|
||||
glass.questions.forEach((q) => {
|
||||
const idx = q.answers.findIndex((a) => a.answerResult === glass.answerData.answerResult);
|
||||
const idx = q.answers.findIndex(
|
||||
(a) => a.answerResult === glass.answerData.answerResult
|
||||
);
|
||||
if (idx !== -1) {
|
||||
selectedAnswerResult2 = q.answers[idx].answerResult2;
|
||||
}
|
||||
|
|
@ -136,7 +154,7 @@ export default {
|
|||
result1: glass.answerData.answerResult,
|
||||
result2: selectedAnswerResult2,
|
||||
answeredQuestions: glass.answerData.answeredQuestions,
|
||||
isSuppressedPart: glass.isSuppressedPart
|
||||
isSuppressedPart: glass.isSuppressedPart,
|
||||
};
|
||||
});
|
||||
// clear out answerData for future page loads; must occur prior to store save
|
||||
|
|
@ -144,22 +162,25 @@ export default {
|
|||
glass.answerData = {};
|
||||
});
|
||||
// save to store as order.damage.moldingQuestionArrays (array)
|
||||
await this.mainStore.saveCapabilityQuestionAnswers(questionAnswersArray);
|
||||
await this.mainStore.saveCapabilityQuestionAnswers(
|
||||
questionAnswersArray
|
||||
);
|
||||
// get parts from the capabilityQuestionAnswers
|
||||
const partsOrQuestions = this.partsOrQuestionsData;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const answer of questionAnswersArray) {
|
||||
partsOrQuestions.find((partOrQuestion) => (
|
||||
partOrQuestion.glassLocation === answer.glassLocation
|
||||
&& partOrQuestion.glassName === answer.glassName
|
||||
)).parts[0].childParts = [
|
||||
partsOrQuestions.find(
|
||||
(partOrQuestion) =>
|
||||
partOrQuestion.glassLocation === answer.glassLocation &&
|
||||
partOrQuestion.glassName === answer.glassName
|
||||
).parts[0].childParts = [
|
||||
{
|
||||
partNumber: answer.partNum
|
||||
}
|
||||
partNumber: answer.partNum,
|
||||
},
|
||||
];
|
||||
}
|
||||
this.navigateForward(partsOrQuestions, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -4,72 +4,70 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition position-relative">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="select-car">
|
||||
<div class="container-fluid pb-2">
|
||||
<div class="row px-3">
|
||||
<div class="col">
|
||||
<div class="select-car-form rounded">
|
||||
<vehicleBanner
|
||||
class="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<alert
|
||||
v-if="displayVinNotFoundAlert"
|
||||
ref="alertVinNotFound"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedDifferentVehicleAlert"
|
||||
ref="alertMatchedDifferentVehicle"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<textboxQuestion
|
||||
id="license-plate-question-wrapper"
|
||||
v-model="licensePlate"
|
||||
cmsWidgetName="LicensePlateNumberQuestionWidget"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
inputId="license-plate-question"
|
||||
validationRules="license-plate-required" />
|
||||
<dropdownQuestion
|
||||
ref="state"
|
||||
v-model="licenseState"
|
||||
cmsWidgetName="StateQuestionWidget"
|
||||
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
||||
:options="stateOptions"
|
||||
disableAutoFill
|
||||
validationRules="state-required"
|
||||
class="mt-4 mb-2" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
@backClicked="navigateBack"
|
||||
@forwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<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="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<alert
|
||||
v-if="displayVinNotFoundAlert"
|
||||
ref="alertVinNotFound"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedDifferentVehicleAlert"
|
||||
ref="alertMatchedDifferentVehicle"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||
class="mb-4"
|
||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||
:manualHeadline="
|
||||
AlertMatchedTwoIdenticalYMMVehicleHeader
|
||||
"
|
||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<textboxQuestion
|
||||
id="license-plate-question-wrapper"
|
||||
v-model="licensePlate"
|
||||
cmsWidgetName="LicensePlateNumberQuestionWidget"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
inputId="license-plate-question"
|
||||
validationRules="license-plate-required" />
|
||||
<dropdownQuestion
|
||||
ref="state"
|
||||
v-model="licenseState"
|
||||
cmsWidgetName="StateQuestionWidget"
|
||||
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
||||
:options="stateOptions"
|
||||
disableAutoFill
|
||||
validationRules="state-required"
|
||||
class="mt-4 mb-2" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
@backClicked="navigateBack"
|
||||
@forwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -83,7 +81,10 @@ import { useMainStore } from '@/store';
|
|||
import errorMessages from '@/constants/error-messages';
|
||||
import { required } from '@/helpers/validation-rules';
|
||||
import { defineRule, Form } from 'vee-validate';
|
||||
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper.js';
|
||||
import {
|
||||
getDamageString,
|
||||
isGlassAvailableForCarId,
|
||||
} from '@/helpers/damage-helper.js';
|
||||
import routerParams from '@/router/router-constants/router-params.js';
|
||||
import states from '@/constants/states';
|
||||
|
||||
|
|
@ -100,7 +101,10 @@ import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-qu
|
|||
import alert from '@/ux-components/alert/alert.vue';
|
||||
|
||||
// Define Validation Rules
|
||||
defineRule('license-plate-required', required(errorMessages.LICENSE_PLATE_REQUIRED));
|
||||
defineRule(
|
||||
'license-plate-required',
|
||||
required(errorMessages.LICENSE_PLATE_REQUIRED)
|
||||
);
|
||||
defineRule('state-required', required(errorMessages.STATE_REQUIRED));
|
||||
|
||||
export default {
|
||||
|
|
@ -114,7 +118,7 @@ export default {
|
|||
vehicleBanner,
|
||||
textboxQuestion,
|
||||
dropdownQuestion,
|
||||
alert
|
||||
alert,
|
||||
},
|
||||
mixins: [baseFormMixin, vinPagesMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -125,8 +129,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -149,7 +153,7 @@ export default {
|
|||
isCarIdDifferent: false,
|
||||
customAlertData: {},
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
forwardButtonCarStyle: ''
|
||||
forwardButtonCarStyle: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -163,10 +167,12 @@ export default {
|
|||
const vinYmmFound =
|
||||
// eslint-disable-next-line max-len
|
||||
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||
const vinYmmExpected =
|
||||
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
|
||||
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
||||
return this.getCmsContent(
|
||||
'AlertMatchedDifferentVehicleWidget',
|
||||
'BodyText'
|
||||
)
|
||||
.replaceAll('{custom:damage}', getDamageString())
|
||||
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
||||
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
||||
|
|
@ -185,7 +191,10 @@ export default {
|
|||
// eslint-disable-next-line max-len
|
||||
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`;
|
||||
|
||||
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
||||
return this.getCmsContent(
|
||||
'AlertMatchedTwoIdenticalYMMVehicleWidget',
|
||||
'BodyText'
|
||||
)
|
||||
.replaceAll('{custom:damage}', getDamageString())
|
||||
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
||||
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
||||
|
|
@ -194,23 +203,26 @@ export default {
|
|||
const vinYmmFound =
|
||||
// eslint-disable-next-line max-len
|
||||
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||
const vinYmmExpected =
|
||||
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
|
||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
return vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase();
|
||||
},
|
||||
stateOptions: {
|
||||
get() {
|
||||
return states;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
licensePlate() {
|
||||
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
||||
);
|
||||
},
|
||||
registrationZipCode() {
|
||||
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||
}
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.attachCustomEvents();
|
||||
|
|
@ -221,7 +233,8 @@ export default {
|
|||
return useMainStore().order.vehicle.carId !== null;
|
||||
},
|
||||
loadDefaultsFromStore() {
|
||||
this.customerQuestions = this.mainStore.customerData.addressQuestions.state;
|
||||
this.customerQuestions =
|
||||
this.mainStore.customerData.addressQuestions.state;
|
||||
},
|
||||
attachCustomEvents() {
|
||||
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
||||
|
|
@ -238,14 +251,17 @@ export default {
|
|||
this.resetWarningsAndErrors();
|
||||
|
||||
// Lookup VIN
|
||||
const vinLookupResponse = await useMainStore().lookupVinByPlate(this.licensePlate, this.licenseState);
|
||||
const vinLookupResponse = await useMainStore().lookupVinByPlate(
|
||||
this.licensePlate,
|
||||
this.licenseState
|
||||
);
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'vinLookupResponse',
|
||||
promise: vinLookupResponse
|
||||
}
|
||||
promise: vinLookupResponse,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -265,8 +281,8 @@ export default {
|
|||
vehicleFromLookup.carId !== useMainStore().order.vehicle.carId;
|
||||
// Handle changing car
|
||||
if (
|
||||
this.isCarIdDifferent
|
||||
&& vehicleFromLookup.carId !== this.previouslyEnteredCarId
|
||||
this.isCarIdDifferent &&
|
||||
vehicleFromLookup.carId !== this.previouslyEnteredCarId
|
||||
) {
|
||||
// Display Alert
|
||||
this.previouslyEnteredCarId = vehicleFromLookup.carId;
|
||||
|
|
@ -279,24 +295,30 @@ export default {
|
|||
this.displayMatchedDifferentVehicleAlert = true;
|
||||
}
|
||||
|
||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleFromLookup.carId);
|
||||
this.isSelectedGlassAvailableForVehicle =
|
||||
await isGlassAvailableForCarId(vehicleFromLookup.carId);
|
||||
|
||||
// Update button "Continue with..."
|
||||
this.$refs.siteFooter
|
||||
// eslint-disable-next-line max-len
|
||||
.updateButtonText(`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`);
|
||||
.updateButtonText(
|
||||
`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`
|
||||
);
|
||||
return this.$refs.siteFooter.removeLoader();
|
||||
}
|
||||
|
||||
// Save vehicle, license plate, and registration information
|
||||
await useMainStore().saveRegistrationLicensePlateLookup(
|
||||
{
|
||||
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
|
||||
isSelectedGlassAvailableForVehicle:
|
||||
this.isSelectedGlassAvailableForVehicle,
|
||||
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, {
|
||||
vin: vinLookupResponse.data.vin,
|
||||
}),
|
||||
registrationInfo: {
|
||||
licensePlate: this.licensePlate,
|
||||
state: this.licenseState
|
||||
}
|
||||
state: this.licenseState,
|
||||
},
|
||||
},
|
||||
false
|
||||
);
|
||||
|
|
@ -307,7 +329,10 @@ export default {
|
|||
// If a different vehicle is found than the one entered and the selected glass is
|
||||
// not available for that vehicle then navigate back to "vehicle-damage"
|
||||
// display vehicle changed alert on that page.
|
||||
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||
if (
|
||||
this.isCarIdDifferent &&
|
||||
!this.isSelectedGlassAvailableForVehicle
|
||||
) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
this.$route,
|
||||
|
|
@ -321,8 +346,8 @@ export default {
|
|||
resetWarningsAndErrors() {
|
||||
this.displayVinNotFoundAlert = false;
|
||||
this.displayMatchedDifferentVehicleAlert = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<questionsPageLayout
|
||||
id="molding-question-wrapper"
|
||||
ref="questionsPageLayout"
|
||||
v-model="selectedAnswers"
|
||||
isRequired
|
||||
:isMetaValid="meta.valid"
|
||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||
:questionsData="questionsData"
|
||||
:validationRules="rules.optionRequired"
|
||||
:index="currentGlassIndex"
|
||||
@forwardButtonAction="forwardButtonAction"
|
||||
@backClick="navigateBackByVehicleQuestions" />
|
||||
</Form>
|
||||
<Form
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<questionsPageLayout
|
||||
id="molding-question-wrapper"
|
||||
ref="questionsPageLayout"
|
||||
v-model="selectedAnswers"
|
||||
isRequired
|
||||
:isMetaValid="meta.valid"
|
||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||
:questionsData="questionsData"
|
||||
:validationRules="rules.optionRequired"
|
||||
:index="currentGlassIndex"
|
||||
@forwardButtonAction="forwardButtonAction"
|
||||
@backClick="navigateBackByVehicleQuestions" />
|
||||
</Form>
|
||||
</template>
|
||||
<script>
|
||||
// Import Supporting Files
|
||||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form,
|
||||
questionsPageLayout
|
||||
questionsPageLayout,
|
||||
},
|
||||
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -48,8 +48,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -64,8 +64,8 @@ export default {
|
|||
selectedAnswers: {},
|
||||
currentGlassIndex: 0,
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
optionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -76,23 +76,34 @@ export default {
|
|||
);
|
||||
},
|
||||
AlertFewMoreQuestionsCopy() {
|
||||
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
|
||||
return this.getCmsContent(
|
||||
'AdditionalPartsQuestionsAlert',
|
||||
'BodyText'
|
||||
);
|
||||
},
|
||||
partsOrQuestionsData() {
|
||||
return useMainStore().pageData(issPageValues.MOLDING_QUESTIONS)
|
||||
.partsOrQuestions;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getInitialQuestionData();
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
const moldingQuestionsFromPageData = useMainStore().pageData(issPageValues.MOLDING_QUESTIONS);
|
||||
const moldingQuestionsFromPageData = useMainStore().pageData(
|
||||
issPageValues.MOLDING_QUESTIONS
|
||||
);
|
||||
return (
|
||||
// has childPartQuestions array and has glassName not null
|
||||
moldingQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName)
|
||||
&& moldingQuestionsFromPageData.partsOrQuestions.some((glass) => glass.parts?.some((part) => part?.childPartQuestions?.length > 0))
|
||||
// has childPartQuestions array and has glassName not null
|
||||
moldingQuestionsFromPageData?.partsOrQuestions?.some(
|
||||
(part) => part?.glassName
|
||||
) &&
|
||||
moldingQuestionsFromPageData.partsOrQuestions.some((glass) =>
|
||||
glass.parts?.some(
|
||||
(part) => part?.childPartQuestions?.length > 0
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
getInitialQuestionData() {
|
||||
|
|
@ -134,41 +145,44 @@ export default {
|
|||
glassName: glass.glassName,
|
||||
partNum: glass.answerData.answerResult,
|
||||
answeredQuestions: glass.answerData.answeredQuestions,
|
||||
isSuppressedPart: glass.isSuppressedPart
|
||||
isSuppressedPart: glass.isSuppressedPart,
|
||||
}));
|
||||
// clear out answerData for future page loads; must occur prior to store save
|
||||
this.questionsData.forEach((glass) => {
|
||||
glass.answerData = {};
|
||||
});
|
||||
// save to store as order.damage.moldingQuestionArrays (array)
|
||||
await this.mainStore.saveMoldingQuestionAnswers(questionAnswersArray);
|
||||
await this.mainStore.saveMoldingQuestionAnswers(
|
||||
questionAnswersArray
|
||||
);
|
||||
|
||||
// get parts from the questionAnswers
|
||||
const partsOrQuestions = this.partsOrQuestionsData;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const answer of questionAnswersArray) {
|
||||
partsOrQuestions.find((partOrQuestion) => (
|
||||
partOrQuestion.glassLocation === answer.glassLocation
|
||||
&& partOrQuestion.glassName === answer.glassName
|
||||
)).parts[0].childParts = [
|
||||
partsOrQuestions.find(
|
||||
(partOrQuestion) =>
|
||||
partOrQuestion.glassLocation === answer.glassLocation &&
|
||||
partOrQuestion.glassName === answer.glassName
|
||||
).parts[0].childParts = [
|
||||
{
|
||||
partNumber: answer.partNum
|
||||
}
|
||||
partNumber: answer.partNum,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
this.navigateForward(partsOrQuestions, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#molding-question-wrapper p.text-body.small {
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
}
|
||||
|
||||
#molding-question-wrapper .form-test-error {
|
||||
margin-top: 0 !important; // Overrides extra margin-top on error message text
|
||||
margin-top: 0 !important; // Overrides extra margin-top on error message text
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
overnightDropOffWidgetName="AddToCalendar_OvernightDropOff"
|
||||
allDayDropOffWidgetName="AddToCalendar_AllDayDropOff"
|
||||
sameDayDropOffWidgetName="AddToCalendar_SameDayDropOff"
|
||||
:serviceLocationFullAddress="serviceLocationFullAddress"
|
||||
:serviceLocationFullAddress="
|
||||
serviceLocationFullAddress
|
||||
"
|
||||
:providerFullAddress="providerFullAddress"
|
||||
:appointmentType="appointmentType"
|
||||
:scheduleDate="appointmentDate"
|
||||
|
|
@ -40,12 +42,10 @@
|
|||
:scheduleEndTime="appointmentEndTime" />
|
||||
<div
|
||||
class="appointment-text text-center lh-base"
|
||||
v-html="appointmentWordingText">
|
||||
</div>
|
||||
v-html="appointmentWordingText"></div>
|
||||
<div
|
||||
class="appointment-text text-center lh-base mt-2"
|
||||
v-html="appointmentWordingText2">
|
||||
</div>
|
||||
v-html="appointmentWordingText2"></div>
|
||||
</div>
|
||||
<div
|
||||
class="email-confirmation-text"
|
||||
|
|
@ -70,15 +70,20 @@ import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
|||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import addToCalendar from '@/layouts/order-confirmation/add-to-calendar/add-to-calendar.vue';
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage, processIfStatements } from '@/helpers/cms-content-helper';
|
||||
import {
|
||||
fetchCmsContentForPage,
|
||||
processIfStatements,
|
||||
} from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store';
|
||||
import { get12HourTimeFormat,
|
||||
import {
|
||||
get12HourTimeFormat,
|
||||
get12HourTimeMobileFormat,
|
||||
convertDateStringToDate,
|
||||
getDisplayTextForDurationLength } from '@/helpers/date-helper.js';
|
||||
getDisplayTextForDurationLength,
|
||||
} from '@/helpers/date-helper.js';
|
||||
import { toTitleCase } from '@/helpers/text-helper.js';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
import applicationConfig from '@/constants/application-config';
|
||||
|
|
@ -91,7 +96,7 @@ export default {
|
|||
siteHeader,
|
||||
vehicleBanner,
|
||||
siteFooter,
|
||||
addToCalendar
|
||||
addToCalendar,
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -103,9 +108,10 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}];
|
||||
// use resultMap to populate layout content.
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
|
|
@ -124,9 +130,18 @@ export default {
|
|||
return this.mainStore.issConfig.successReturnURL;
|
||||
},
|
||||
confirmationEmailText() {
|
||||
return this.getCmsContent('EmailConfirmationWordingWidget', 'BodyText')
|
||||
?.replaceAll('{custom:CUSTOMER_PORTAL_URL}', applicationConfig.CUSTOMER_PORTAL_URL)
|
||||
?.replaceAll('{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}', this.submittedOrder.customerPortalLoginToken)
|
||||
return this.getCmsContent(
|
||||
'EmailConfirmationWordingWidget',
|
||||
'BodyText'
|
||||
)
|
||||
?.replaceAll(
|
||||
'{custom:CUSTOMER_PORTAL_URL}',
|
||||
applicationConfig.CUSTOMER_PORTAL_URL
|
||||
)
|
||||
?.replaceAll(
|
||||
'{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}',
|
||||
this.submittedOrder.customerPortalLoginToken
|
||||
)
|
||||
?.replaceAll('<', '<')
|
||||
?.replaceAll('>', '>');
|
||||
},
|
||||
|
|
@ -155,11 +170,13 @@ export default {
|
|||
return dateObject.toLocaleDateString('en-us', {
|
||||
weekday: 'long',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
day: 'numeric',
|
||||
});
|
||||
},
|
||||
appointmentTimeFormatted() {
|
||||
const formattedTime = this.formatAppointmentTime(this.appointmentType);
|
||||
const formattedTime = this.formatAppointmentTime(
|
||||
this.appointmentType
|
||||
);
|
||||
return formattedTime;
|
||||
},
|
||||
mobileWordingText() {
|
||||
|
|
@ -169,7 +186,10 @@ export default {
|
|||
return this.getCmsContent('MobileWordingWidget', 'BodyText2');
|
||||
},
|
||||
dropOffAndInShopWordingText() {
|
||||
return this.getCmsContent('DropOffAndInShopWordingWidget', 'BodyText');
|
||||
return this.getCmsContent(
|
||||
'DropOffAndInShopWordingWidget',
|
||||
'BodyText'
|
||||
);
|
||||
},
|
||||
dropOffAndInShopWordingText2() {
|
||||
return this.getBodyText2FromCms('DropOffAndInShopWordingWidget');
|
||||
|
|
@ -191,13 +211,24 @@ export default {
|
|||
},
|
||||
serviceLocationFullAddress() {
|
||||
// eslint-disable-next-line max-len
|
||||
return `${this.serviceLocationAddress}, ${this.serviceLocationAddress2 ? `${this.serviceLocationAddress2},` : ''}<br/> ${this.serviceLocationCity}, ${this.serviceLocationState} ${this.serviceLocationZipCode}`;
|
||||
return `${this.serviceLocationAddress}, ${
|
||||
this.serviceLocationAddress2
|
||||
? `${this.serviceLocationAddress2},`
|
||||
: ''
|
||||
}<br/> ${this.serviceLocationCity}, ${this.serviceLocationState} ${
|
||||
this.serviceLocationZipCode
|
||||
}`;
|
||||
},
|
||||
providerAddress() {
|
||||
return toTitleCase(this.submittedOrder.serviceLocation.provider.address.streetAddress);
|
||||
return toTitleCase(
|
||||
this.submittedOrder.serviceLocation.provider.address
|
||||
.streetAddress
|
||||
);
|
||||
},
|
||||
providerCity() {
|
||||
return toTitleCase(this.submittedOrder.serviceLocation.provider.address.city);
|
||||
return toTitleCase(
|
||||
this.submittedOrder.serviceLocation.provider.address.city
|
||||
);
|
||||
},
|
||||
providerState() {
|
||||
return this.submittedOrder.serviceLocation.provider.address.state;
|
||||
|
|
@ -207,7 +238,9 @@ export default {
|
|||
},
|
||||
providerFullAddress() {
|
||||
// eslint-disable-next-line max-len
|
||||
return this.submittedOrder.serviceLocation?.provider?.address ? `${this.providerAddress},<br/> ${this.providerCity}, ${this.providerState} ${this.providerZipCode}` : '';
|
||||
return this.submittedOrder.serviceLocation?.provider?.address
|
||||
? `${this.providerAddress},<br/> ${this.providerCity}, ${this.providerState} ${this.providerZipCode}`
|
||||
: '';
|
||||
},
|
||||
appointmentWordingText() {
|
||||
switch (this.appointmentType) {
|
||||
|
|
@ -248,14 +281,24 @@ export default {
|
|||
}
|
||||
},
|
||||
mobileAppointment() {
|
||||
return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
return (
|
||||
this.submittedOrder.serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE ||
|
||||
this.submittedOrder.serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP
|
||||
);
|
||||
},
|
||||
inShopAppointment() {
|
||||
return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.IN_SHOP;
|
||||
return (
|
||||
this.submittedOrder.serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.IN_SHOP
|
||||
);
|
||||
},
|
||||
dropOffAppointment() {
|
||||
return this.submittedOrder.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF;
|
||||
return (
|
||||
this.submittedOrder.serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.DROP_OFF
|
||||
);
|
||||
},
|
||||
inShopAppointmentDuration() {
|
||||
const inshopDurationTime = getDisplayTextForDurationLength(
|
||||
|
|
@ -263,11 +306,13 @@ export default {
|
|||
this.submittedOrder.schedule.jobMaxMinutes
|
||||
);
|
||||
return inshopDurationTime;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.carrierUrl) {
|
||||
this.$refs.siteFooter.updateButtonText(`Go back to ${this.carrierName}`);
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
`Go back to ${this.carrierName}`
|
||||
);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -280,57 +325,62 @@ export default {
|
|||
// Service Location
|
||||
const { serviceLocation } = useMainStore().order;
|
||||
const mobileReqs = !!(
|
||||
serviceLocation.address
|
||||
&& serviceLocation.city
|
||||
&& serviceLocation.state
|
||||
&& serviceLocation.zipCode
|
||||
serviceLocation.address &&
|
||||
serviceLocation.city &&
|
||||
serviceLocation.state &&
|
||||
serviceLocation.zipCode
|
||||
);
|
||||
|
||||
const providerLocation = serviceLocation.provider.address;
|
||||
const dropOffInShopReqs = !!(
|
||||
providerLocation.streetAddress
|
||||
&& providerLocation.city
|
||||
&& providerLocation.state
|
||||
&& providerLocation.zipCode
|
||||
providerLocation.streetAddress &&
|
||||
providerLocation.city &&
|
||||
providerLocation.state &&
|
||||
providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
const isMobile =
|
||||
serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE ||
|
||||
serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInShopReqs);
|
||||
|
||||
// Insurance
|
||||
const isInsuranceSet = useMainStore().order.payment.isInsurance !== null;
|
||||
const isInsuranceSet =
|
||||
useMainStore().order.payment.isInsurance !== null;
|
||||
|
||||
// Schedule
|
||||
const { schedule } = useMainStore().order;
|
||||
const scheduleReqs = !!(
|
||||
schedule.date
|
||||
&& schedule.startTime
|
||||
&& schedule.endTime
|
||||
&& schedule.jobMaxMinutes
|
||||
&& schedule.jobMinMinutes
|
||||
schedule.date &&
|
||||
schedule.startTime &&
|
||||
schedule.endTime &&
|
||||
schedule.jobMaxMinutes &&
|
||||
schedule.jobMinMinutes
|
||||
);
|
||||
|
||||
// Contact Info
|
||||
const { contactInfo } = useMainStore().order;
|
||||
const contactInfoReqs = !!(
|
||||
contactInfo.firstName
|
||||
&& contactInfo.lastName
|
||||
&& contactInfo.servicePhone
|
||||
&& contactInfo.emailAddress
|
||||
contactInfo.firstName &&
|
||||
contactInfo.lastName &&
|
||||
contactInfo.servicePhone &&
|
||||
contactInfo.emailAddress
|
||||
);
|
||||
|
||||
// Payment
|
||||
const paymentMethodReqs = useMainStore().order.payment.isPayInAdvance === false;
|
||||
const paymentMethodReqs =
|
||||
useMainStore().order.payment.isPayInAdvance === false;
|
||||
|
||||
return (
|
||||
serviceLocationReqs
|
||||
&& isInsuranceSet
|
||||
&& scheduleReqs
|
||||
&& contactInfoReqs
|
||||
&& paymentMethodReqs
|
||||
serviceLocationReqs &&
|
||||
isInsuranceSet &&
|
||||
scheduleReqs &&
|
||||
contactInfoReqs &&
|
||||
paymentMethodReqs
|
||||
);
|
||||
},
|
||||
forwardButtonAction() {
|
||||
|
|
@ -341,11 +391,15 @@ export default {
|
|||
case AppointmentTypeStrings.MOBILE:
|
||||
case AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP:
|
||||
// eslint-disable-next-line max-len
|
||||
return `Between ${get12HourTimeMobileFormat(this.appointmentStartTime)} - ${get12HourTimeMobileFormat(this.appointmentEndTime)}`;
|
||||
return `Between ${get12HourTimeMobileFormat(
|
||||
this.appointmentStartTime
|
||||
)} - ${get12HourTimeMobileFormat(this.appointmentEndTime)}`;
|
||||
case AppointmentTypeStrings.DROP_OFF:
|
||||
return 'Drop off before 9:30 AM';
|
||||
case AppointmentTypeStrings.IN_SHOP:
|
||||
return `at ${get12HourTimeFormat(this.appointmentStartTime)}`;
|
||||
return `at ${get12HourTimeFormat(
|
||||
this.appointmentStartTime
|
||||
)}`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
@ -353,7 +407,11 @@ export default {
|
|||
processIfStatements,
|
||||
getBodyText2FromCms(cmsWidgetName) {
|
||||
const body2Text = this.getCmsContent(cmsWidgetName, 'BodyText2');
|
||||
return this.processIfStatements(body2Text, 'custom', this.getCustomValueFromString);
|
||||
return this.processIfStatements(
|
||||
body2Text,
|
||||
'custom',
|
||||
this.getCustomValueFromString
|
||||
);
|
||||
},
|
||||
getCustomValueFromString(str) {
|
||||
switch (str) {
|
||||
|
|
@ -364,8 +422,8 @@ export default {
|
|||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export default {
|
|||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form,
|
||||
questionsPageLayout
|
||||
questionsPageLayout,
|
||||
},
|
||||
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -48,8 +48,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -65,8 +65,8 @@ export default {
|
|||
selectedAnswers: {},
|
||||
currentGlassIndex: 0,
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
optionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -78,11 +78,12 @@ export default {
|
|||
},
|
||||
pageData() {
|
||||
return useMainStore().pageData(issPageValues.PART_QUESTIONS);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// are there alreadyAnsweredQuestions?
|
||||
const alreadyAnsweredQuestions = useMainStore().damage.partQuestionAnswers;
|
||||
const alreadyAnsweredQuestions =
|
||||
useMainStore().damage.partQuestionAnswers;
|
||||
|
||||
this.questionsData = this.pageData.partsOrQuestions
|
||||
.filter((x) => x.partQuestions)
|
||||
|
|
@ -93,7 +94,11 @@ export default {
|
|||
// reset selectedAnswers for this glass
|
||||
this.selectedAnswers[glass.answerKey] = [];
|
||||
|
||||
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
|
||||
const updatedGlass = this.setupInitialData(
|
||||
glass,
|
||||
index,
|
||||
alreadyAnsweredQuestions
|
||||
);
|
||||
|
||||
// Set up watch for each set of glass questions
|
||||
this.$watch(
|
||||
|
|
@ -111,19 +116,23 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
const partQuestionsFromPageData = useMainStore().pageData(issPageValues.PART_QUESTIONS);
|
||||
const partQuestionsFromPageData = useMainStore().pageData(
|
||||
issPageValues.PART_QUESTIONS
|
||||
);
|
||||
return (
|
||||
partQuestionsFromPageData
|
||||
&& Object.keys(partQuestionsFromPageData.partsOrQuestions).length > 0
|
||||
partQuestionsFromPageData &&
|
||||
Object.keys(partQuestionsFromPageData.partsOrQuestions).length >
|
||||
0
|
||||
);
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
const questionAnswersArray = this.questionsData.map((glass) => ({
|
||||
glassLocation: glass.glassLocation,
|
||||
glassName: glass.glassName,
|
||||
result: (glass.answerData && glass.answerData.answerResult) || '',
|
||||
result:
|
||||
(glass.answerData && glass.answerData.answerResult) || '',
|
||||
answeredQuestions: glass.answerData?.answeredQuestions,
|
||||
isSuppressedPart: glass.isSuppressedPart
|
||||
isSuppressedPart: glass.isSuppressedPart,
|
||||
}));
|
||||
|
||||
// clear out answerData for future page loads; must occur prior to store save
|
||||
|
|
@ -143,7 +152,7 @@ export default {
|
|||
|
||||
// TODO KO delete for quote mvp
|
||||
this.navigateForward(glassPartsForStore, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -4,53 +4,61 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
<vehicleBanner
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader
|
||||
class="mb-5 mt-4 px-3"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
subHeaderClasses="mt-2" />
|
||||
<div class="main-content-container">
|
||||
<hr class="my-0" />
|
||||
<reviewDropdown ref="reviewDropdown" />
|
||||
<hr class="my-0" />
|
||||
<cartDropdown
|
||||
:showAsPaid="false"
|
||||
:readOnly="false"
|
||||
recyclingModalCmsWidgetName="RecycleModal"
|
||||
servicePackageTitleWidgetName="ServicePackageTitle"
|
||||
:availableVaps="availableVaps" />
|
||||
<hr class="mt-0 mb-5" />
|
||||
<alert
|
||||
v-if="displayPayInAdvanceAlert"
|
||||
name="payInAdvanceErrorAlert"
|
||||
class="my-4"
|
||||
cmsWidgetName="PayInAdvanceErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<paymentMethodQuestion
|
||||
v-if="!isPayInAdvanceDisabled"
|
||||
v-model="paymentMethodInternalModel"
|
||||
cmsWidgetName="PaymentMethodWidget"
|
||||
:validationRules="rules.optionRequired" />
|
||||
<alert
|
||||
v-if="isPayInAdvanceDisabled"
|
||||
:isDismissible="false"
|
||||
alertClass="alert-info"
|
||||
cmsWidgetName="NoPayInAdvanceDisclaimerWidget"
|
||||
:shouldScrollToOnMount="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
:isStackedVertically="true"
|
||||
@backClicked="navigateBack"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 px-0 px-md-2">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<vehicleBanner
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<siteSubHeader
|
||||
class="mb-5 mt-4 px-3"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
subHeaderClasses="mt-2" />
|
||||
<div class="main-content-container">
|
||||
<hr class="my-0" />
|
||||
<reviewDropdown ref="reviewDropdown" />
|
||||
<hr class="my-0" />
|
||||
<cartDropdown
|
||||
:showAsPaid="false"
|
||||
:readOnly="false"
|
||||
recyclingModalCmsWidgetName="RecycleModal"
|
||||
servicePackageTitleWidgetName="ServicePackageTitle"
|
||||
:availableVaps="availableVaps" />
|
||||
<hr class="mt-0 mb-5" />
|
||||
<alert
|
||||
v-if="displayPayInAdvanceAlert"
|
||||
name="payInAdvanceErrorAlert"
|
||||
class="my-4"
|
||||
cmsWidgetName="PayInAdvanceErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
<paymentMethodQuestion
|
||||
v-if="!isPayInAdvanceDisabled"
|
||||
v-model="paymentMethodInternalModel"
|
||||
cmsWidgetName="PaymentMethodWidget"
|
||||
:validationRules="rules.optionRequired" />
|
||||
<alert
|
||||
v-if="isPayInAdvanceDisabled"
|
||||
:isDismissible="false"
|
||||
alertClass="alert-info"
|
||||
cmsWidgetName="NoPayInAdvanceDisclaimerWidget"
|
||||
:shouldScrollToOnMount="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
:isStackedVertically="true"
|
||||
@backClicked="navigateBack"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
@ -91,7 +99,7 @@ export default {
|
|||
reviewDropdown,
|
||||
cartDropdown,
|
||||
paymentMethodQuestion,
|
||||
alert
|
||||
alert,
|
||||
},
|
||||
mixins: [baseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -104,20 +112,20 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'reviewDropdownData',
|
||||
promise: reviewDropdownPromise
|
||||
promise: reviewDropdownPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'wipers',
|
||||
promise: wipersPromise
|
||||
promise: wipersPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'rainDefense',
|
||||
promise: rainDefensePromise
|
||||
}
|
||||
promise: rainDefensePromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -127,7 +135,8 @@ export default {
|
|||
const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
|
||||
|
||||
let hasBailedOut = false;
|
||||
const pricedVaps = await useMainStore().getPriceOrderItems(unpricedVaps)
|
||||
const pricedVaps = await useMainStore()
|
||||
.getPriceOrderItems(unpricedVaps)
|
||||
.catch((err) => {
|
||||
useMainStore().setBailout(
|
||||
bailoutMessage.pricingResponseError(
|
||||
|
|
@ -143,7 +152,9 @@ export default {
|
|||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
|
||||
vm.$refs.reviewDropdown.initializeComponent(
|
||||
resultMap.reviewDropdownData
|
||||
);
|
||||
vm.setAvailableVaps(pricedVaps ?? []);
|
||||
});
|
||||
}
|
||||
|
|
@ -153,8 +164,8 @@ export default {
|
|||
availableVaps: [],
|
||||
paymentMethodInternalModel: this.getPaymentMethodFromStore(),
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
optionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -171,113 +182,128 @@ export default {
|
|||
}
|
||||
},
|
||||
displayPayInAdvanceAlert() {
|
||||
return (
|
||||
this.$route.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]
|
||||
);
|
||||
return this.$route.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT];
|
||||
},
|
||||
isPayInAdvanceDisabled() {
|
||||
const piaExperience = this.getSettingValue(experimentSettings.ISS_DISPLAY_PAY_IN_ADVANCE);
|
||||
const piaExperience = this.getSettingValue(
|
||||
experimentSettings.ISS_DISPLAY_PAY_IN_ADVANCE
|
||||
);
|
||||
const isEnabled = piaExperience === 'true';
|
||||
|
||||
return !isEnabled || this.isUnverified;
|
||||
},
|
||||
isUnverified() {
|
||||
return !useMainStore().isNoComp && !useMainStore().isITAC
|
||||
&& (useMainStore().order.currentDeductible == null || !useMainStore().isVerifiedCoverageStatus);
|
||||
return (
|
||||
!useMainStore().isNoComp &&
|
||||
!useMainStore().isITAC &&
|
||||
(useMainStore().order.currentDeductible == null ||
|
||||
!useMainStore().isVerifiedCoverageStatus)
|
||||
);
|
||||
},
|
||||
paymentMethod() {
|
||||
return this.paymentMethodInternalModel;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
customCallToActionButtonCopy(newValue) {
|
||||
this.updateFooterButtonText(newValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
// Vehicle
|
||||
const { vehicle } = useMainStore().order;
|
||||
const vehicleReqs = !!(vehicle.year && vehicle.make && vehicle.model && vehicle.style);
|
||||
const vehicleReqs = !!(
|
||||
vehicle.year &&
|
||||
vehicle.make &&
|
||||
vehicle.model &&
|
||||
vehicle.style
|
||||
);
|
||||
|
||||
// Damage
|
||||
const { isRepair, numberOfChips, glassToReplace } = useMainStore().order.damage;
|
||||
const { isRepair, numberOfChips, glassToReplace } =
|
||||
useMainStore().order.damage;
|
||||
const damageReqs = !!(
|
||||
(isRepair && numberOfChips)
|
||||
|| (!isRepair && glassToReplace?.length)
|
||||
(isRepair && numberOfChips) ||
|
||||
(!isRepair && glassToReplace?.length)
|
||||
);
|
||||
|
||||
// Service Package
|
||||
const { lineItems } = useMainStore().order;
|
||||
const packageReqs = !!(
|
||||
(isRepair || lineItems.glassParts)
|
||||
&& lineItems.supportingItems
|
||||
(isRepair || lineItems.glassParts) &&
|
||||
lineItems.supportingItems
|
||||
);
|
||||
|
||||
// Service Location
|
||||
const { serviceLocation } = useMainStore().order;
|
||||
const mobileReqs = !!(
|
||||
serviceLocation.address
|
||||
&& serviceLocation.city
|
||||
&& serviceLocation.state
|
||||
&& serviceLocation.zipCode
|
||||
serviceLocation.address &&
|
||||
serviceLocation.city &&
|
||||
serviceLocation.state &&
|
||||
serviceLocation.zipCode
|
||||
);
|
||||
|
||||
const providerLocation = serviceLocation.provider.address;
|
||||
const dropOffInshopReqs = !!(
|
||||
providerLocation.streetAddress
|
||||
&& providerLocation.city
|
||||
&& providerLocation.state
|
||||
&& providerLocation.zipCode
|
||||
providerLocation.streetAddress &&
|
||||
providerLocation.city &&
|
||||
providerLocation.state &&
|
||||
providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
const isMobile =
|
||||
serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE ||
|
||||
serviceLocation.appointmentType ===
|
||||
AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
||||
|
||||
// Schedule
|
||||
const { date, startTime, endTime, jobMaxMinutes, jobMinMinutes } = useMainStore().order.schedule;
|
||||
const { date, startTime, endTime, jobMaxMinutes, jobMinMinutes } =
|
||||
useMainStore().order.schedule;
|
||||
const scheduleReqs = !!(
|
||||
date
|
||||
&& startTime
|
||||
&& endTime
|
||||
&& jobMaxMinutes
|
||||
&& jobMinMinutes
|
||||
date &&
|
||||
startTime &&
|
||||
endTime &&
|
||||
jobMaxMinutes &&
|
||||
jobMinMinutes
|
||||
);
|
||||
|
||||
// Customer
|
||||
const { firstName, lastName, emailAddress } = useMainStore().order.customer;
|
||||
const customerReqs = !!(
|
||||
firstName
|
||||
&& lastName
|
||||
&& emailAddress
|
||||
);
|
||||
const { firstName, lastName, emailAddress } =
|
||||
useMainStore().order.customer;
|
||||
const customerReqs = !!(firstName && lastName && emailAddress);
|
||||
|
||||
// Contact Info
|
||||
const { contactInfo } = useMainStore().order;
|
||||
const contactInfoReqs = !!(
|
||||
contactInfo.firstName
|
||||
&& contactInfo.lastName
|
||||
&& contactInfo.servicePhone
|
||||
&& contactInfo.emailAddress
|
||||
contactInfo.firstName &&
|
||||
contactInfo.lastName &&
|
||||
contactInfo.servicePhone &&
|
||||
contactInfo.emailAddress
|
||||
);
|
||||
|
||||
return (
|
||||
vehicleReqs
|
||||
&& damageReqs
|
||||
&& packageReqs
|
||||
&& serviceLocationReqs
|
||||
&& scheduleReqs
|
||||
&& customerReqs
|
||||
&& contactInfoReqs
|
||||
vehicleReqs &&
|
||||
damageReqs &&
|
||||
packageReqs &&
|
||||
serviceLocationReqs &&
|
||||
scheduleReqs &&
|
||||
customerReqs &&
|
||||
contactInfoReqs
|
||||
);
|
||||
},
|
||||
getPaymentMethodFromStore() {
|
||||
const { payInAdvanceType } = useMainStore().order.payment;
|
||||
const isPayInAdvance = useMainStore().order.payment.isPayInAdvance && !!payInAdvanceType;
|
||||
const isPayInAdvance =
|
||||
useMainStore().order.payment.isPayInAdvance &&
|
||||
!!payInAdvanceType;
|
||||
|
||||
return isPayInAdvance ? payInAdvanceType : paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
return isPayInAdvance
|
||||
? payInAdvanceType
|
||||
: paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
},
|
||||
updateFooterButtonText(newValue) {
|
||||
this.$refs.siteFooter.updateButtonText(newValue);
|
||||
|
|
@ -299,8 +325,8 @@ export default {
|
|||
},
|
||||
setAvailableVaps(vaps) {
|
||||
this.availableVaps = vaps;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,16 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div
|
||||
class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition position-relative">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="container-fluid mt-0 px-5">
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 px-0 px-md-2">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<siteSubHeader
|
||||
ref="siteSubHeader"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
|
|
@ -79,7 +82,7 @@ export default {
|
|||
siteFooter,
|
||||
buttonQuestion,
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
Form,
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -89,9 +92,10 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}];
|
||||
// use resultMap to populate layout content.
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
|
|
@ -108,10 +112,12 @@ export default {
|
|||
questionAnswersArray: [],
|
||||
schoolPropertyAnswer: '',
|
||||
parkingLotAnswer: '',
|
||||
hasValidCarId: this.mainStore.vehicle.carId && this.mainStore.vehicle.carId !== '0',
|
||||
hasValidCarId:
|
||||
this.mainStore.vehicle.carId &&
|
||||
this.mainStore.vehicle.carId !== '0',
|
||||
rules: {
|
||||
selectionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
selectionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -128,57 +134,66 @@ export default {
|
|||
return this.getCmsContent('ParkingLotQuestion', 'Answers');
|
||||
},
|
||||
educatorEndorsement() {
|
||||
return useMainStore().order.policy.endorsements?.includes(endorsementOptions.EDUCATOR) ?? false;
|
||||
return (
|
||||
useMainStore().order.policy.endorsements?.includes(
|
||||
endorsementOptions.EDUCATOR
|
||||
) ?? false
|
||||
);
|
||||
},
|
||||
parkingGuardEndorsement() {
|
||||
return useMainStore().order.policy.endorsements?.includes(endorsementOptions.PARKING_GUARD) ?? false;
|
||||
}
|
||||
return (
|
||||
useMainStore().order.policy.endorsements?.includes(
|
||||
endorsementOptions.PARKING_GUARD
|
||||
) ?? false
|
||||
);
|
||||
},
|
||||
},
|
||||
methods:
|
||||
{
|
||||
async forwardButtonAction() {
|
||||
// TO DO: remove hard coding and update data format once service returns endorsement questions
|
||||
if (this.educatorEndorsement) {
|
||||
this.questionAnswersArray.push({
|
||||
questionNum: 1,
|
||||
endorsementName: endorsementOptions.EDUCATOR,
|
||||
questionText: this.schoolPropertyQuestionText,
|
||||
selectedAnswer: this.schoolPropertyAnswer
|
||||
});
|
||||
}
|
||||
if (this.parkingGuardEndorsement) {
|
||||
this.questionAnswersArray.push({
|
||||
questionNum: 2,
|
||||
endorsementName: endorsementOptions.PARKING_GUARD,
|
||||
questionText: this.parkingLotQuestionText,
|
||||
selectedAnswer: this.parkingLotAnswer
|
||||
});
|
||||
}
|
||||
|
||||
// save answers to store as order.policy.endorsementQuestionAnswers
|
||||
useMainStore().saveEndorsementQuestionAnswers(this.questionAnswersArray);
|
||||
|
||||
return this.navigateForward();
|
||||
},
|
||||
navigateForward() {
|
||||
if (!this.hasValidCarId) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
this.$route
|
||||
);
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
methods: {
|
||||
async forwardButtonAction() {
|
||||
// TO DO: remove hard coding and update data format once service returns endorsement questions
|
||||
if (this.educatorEndorsement) {
|
||||
this.questionAnswersArray.push({
|
||||
questionNum: 1,
|
||||
endorsementName: endorsementOptions.EDUCATOR,
|
||||
questionText: this.schoolPropertyQuestionText,
|
||||
selectedAnswer: this.schoolPropertyAnswer,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.parkingGuardEndorsement) {
|
||||
this.questionAnswersArray.push({
|
||||
questionNum: 2,
|
||||
endorsementName: endorsementOptions.PARKING_GUARD,
|
||||
questionText: this.parkingLotQuestionText,
|
||||
selectedAnswer: this.parkingLotAnswer,
|
||||
});
|
||||
}
|
||||
|
||||
// save answers to store as order.policy.endorsementQuestionAnswers
|
||||
useMainStore().saveEndorsementQuestionAnswers(
|
||||
this.questionAnswersArray
|
||||
);
|
||||
|
||||
return this.navigateForward();
|
||||
},
|
||||
navigateForward() {
|
||||
if (!this.hasValidCarId) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios
|
||||
.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
this.$route
|
||||
);
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
:deep .subheader-primary {
|
||||
margin-bottom: map-get($spacers, 2);
|
||||
}
|
||||
|
|
@ -211,5 +226,4 @@ export default {
|
|||
:deep div.question-text.d-flex {
|
||||
margin-top: map-get($spacers, 4);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -4,48 +4,48 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition position-relative">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="container-fluid pb-2 px-5">
|
||||
<div class="row mt-4 mb-3">
|
||||
<div class="col">
|
||||
<siteSubHeader
|
||||
id="sub-header"
|
||||
cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<addressQuestions
|
||||
id="address-questions-wrapper"
|
||||
ref="addressQuestions"
|
||||
v-model="customerQuestions.addressQuestions"
|
||||
includeStreetAddress2="true" />
|
||||
<textboxQuestion
|
||||
ref="policyHolderFirstName"
|
||||
v-model="customerQuestions.firstName"
|
||||
inputId="firstNameField"
|
||||
cmsWidgetName="PolicyholderFirstNameQuestion"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
:validationRules="rules.firstName" />
|
||||
<textboxQuestion
|
||||
ref="policyHolderLastName"
|
||||
v-model="customerQuestions.lastName"
|
||||
class="mt-4"
|
||||
inputId="lastNameField"
|
||||
cmsWidgetName="PolicyholderLastNameQuestion"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
:validationRules="rules.lastName" />
|
||||
</div>
|
||||
</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<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">
|
||||
<siteSubHeader
|
||||
id="sub-header"
|
||||
cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<addressQuestions
|
||||
id="address-questions-wrapper"
|
||||
ref="addressQuestions"
|
||||
v-model="customerQuestions.addressQuestions"
|
||||
includeStreetAddress2="true" />
|
||||
<textboxQuestion
|
||||
ref="policyHolderFirstName"
|
||||
v-model="customerQuestions.firstName"
|
||||
inputId="firstNameField"
|
||||
cmsWidgetName="PolicyholderFirstNameQuestion"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
:validationRules="rules.firstName" />
|
||||
<textboxQuestion
|
||||
ref="policyHolderLastName"
|
||||
v-model="customerQuestions.lastName"
|
||||
class="mt-4"
|
||||
inputId="lastNameField"
|
||||
cmsWidgetName="PolicyholderLastNameQuestion"
|
||||
isRequired
|
||||
disableAutoFill
|
||||
:validationRules="rules.lastName" />
|
||||
</div>
|
||||
</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
|
@ -74,7 +74,7 @@ export default {
|
|||
addressQuestions,
|
||||
siteFooter,
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
Form,
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -85,8 +85,8 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
// use resultMap to populate layout content.
|
||||
|
|
@ -106,8 +106,8 @@ export default {
|
|||
vehiclesFound: [],
|
||||
rules: {
|
||||
firstName: globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
|
||||
lastName: globalRules.POLICYHOLDER_LAST_NAME_REQUIRED
|
||||
}
|
||||
lastName: globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -116,10 +116,9 @@ export default {
|
|||
},
|
||||
vehiclesCount() {
|
||||
return this.vehiclesFound.length;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods:
|
||||
{
|
||||
methods: {
|
||||
async forwardButtonAction() {
|
||||
this.mainStore.updatePolicyHolderDetails(this.customerQuestions);
|
||||
return this.navigateForward();
|
||||
|
|
@ -144,19 +143,20 @@ export default {
|
|||
|
||||
getPolicyHolderDetailsFromStore() {
|
||||
return {
|
||||
addressQuestions:
|
||||
{
|
||||
streetAddress: this.mainStore.order.customer.address.streetAddress,
|
||||
streetAddress2: this.mainStore.order.customer.address.streetAddress2,
|
||||
addressQuestions: {
|
||||
streetAddress:
|
||||
this.mainStore.order.customer.address.streetAddress,
|
||||
streetAddress2:
|
||||
this.mainStore.order.customer.address.streetAddress2,
|
||||
city: this.mainStore.order.customer.address.city,
|
||||
state: this.mainStore.order.customer.address.state,
|
||||
zipCode: this.mainStore.order.customer.address.zipCode
|
||||
zipCode: this.mainStore.order.customer.address.zipCode,
|
||||
},
|
||||
firstName: this.mainStore.order.customer.firstName,
|
||||
lastName: this.mainStore.order.customer.lastName
|
||||
lastName: this.mainStore.order.customer.lastName,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -164,14 +164,14 @@ export default {
|
|||
#sub-header p {
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
color: #4D5151;
|
||||
color: #4d5151;
|
||||
}
|
||||
|
||||
#address-questions-wrapper {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
#address-questions-wrapper .alert.heading {
|
||||
#address-questions-wrapper .alert.heading {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,18 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalid-submit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition sub-container make-tall">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<siteSubHeader
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
justification="left"
|
||||
issContainingPage="service-packages" />
|
||||
<div class="mx-5">
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<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">
|
||||
<siteSubHeader
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
justification="left"
|
||||
issContainingPage="service-packages" />
|
||||
<servicePackageQuestion
|
||||
ref="servicePackage"
|
||||
cmsWidgetName="ServicePackage"
|
||||
|
|
@ -31,22 +35,18 @@
|
|||
@ForwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
<loadingModal ref="loadingModal" :textSlides="loadingText" />
|
||||
<contentGroupModal
|
||||
ref="RainDefenseModal"
|
||||
cmsWidgetName="RainDefenseModal" />
|
||||
<contentGroupModal
|
||||
ref="FrontWiperModal"
|
||||
cmsWidgetName="FrontWiperModal" />
|
||||
<contentGroupModal
|
||||
ref="RearWiperModal"
|
||||
cmsWidgetName="RearWiperModal" />
|
||||
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
|
||||
</div>
|
||||
<loadingModal
|
||||
ref="loadingModal"
|
||||
:textSlides="loadingText" />
|
||||
<contentGroupModal
|
||||
ref="RainDefenseModal"
|
||||
cmsWidgetName="RainDefenseModal" />
|
||||
<contentGroupModal
|
||||
ref="FrontWiperModal"
|
||||
cmsWidgetName="FrontWiperModal" />
|
||||
<contentGroupModal
|
||||
ref="RearWiperModal"
|
||||
cmsWidgetName="RearWiperModal" />
|
||||
<contentGroupModal
|
||||
ref="RecalModal"
|
||||
cmsWidgetName="RecalModal" />
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ export default {
|
|||
Form,
|
||||
servicePackageQuestion,
|
||||
loadingModal,
|
||||
contentGroupModal
|
||||
contentGroupModal,
|
||||
},
|
||||
mixins: [baseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -94,20 +94,20 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'wipers',
|
||||
promise: wipersPromise
|
||||
promise: wipersPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'rainDefense',
|
||||
promise: rainDefensePromise
|
||||
promise: rainDefensePromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'supportingItems',
|
||||
promise: supportingItemsPromise
|
||||
}
|
||||
promise: supportingItemsPromise,
|
||||
},
|
||||
];
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
||||
|
|
@ -118,11 +118,12 @@ export default {
|
|||
resultMap.rainDefense,
|
||||
...resultMap.supportingItems,
|
||||
...resultMap.wipers,
|
||||
...clonedGlassParts
|
||||
...clonedGlassParts,
|
||||
];
|
||||
|
||||
let hasBailedOut = false;
|
||||
const pricingResults = await store.getPriceOrderItems(availableLineItems)
|
||||
const pricingResults = await store
|
||||
.getPriceOrderItems(availableLineItems)
|
||||
.catch((err) => {
|
||||
useMainStore().setBailout(
|
||||
bailoutMessage.pricingResponseError(
|
||||
|
|
@ -155,17 +156,17 @@ export default {
|
|||
'Looking for dates',
|
||||
'Searching for times',
|
||||
'Nearly there',
|
||||
'Finishing up'
|
||||
'Finishing up',
|
||||
],
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
optionRequired: globalRules.OPTION_REQUIRED,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
PriceDisclaimerText() {
|
||||
return this.getCmsContent('PriceDisclaimerWidget', 'Text');
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openModalAction(modalName) {
|
||||
|
|
@ -173,11 +174,11 @@ export default {
|
|||
},
|
||||
arePagePrerequisitesValid() {
|
||||
return (
|
||||
store.order.serviceLocation.zipCode
|
||||
&& store.order.serviceLocation.zipCodeCtu
|
||||
&& (store.order.damage.isRepair
|
||||
|| (store.order.lineItems?.glassParts != null
|
||||
&& store.order.lineItems.glassParts.length > 0))
|
||||
store.order.serviceLocation.zipCode &&
|
||||
store.order.serviceLocation.zipCodeCtu &&
|
||||
(store.order.damage.isRepair ||
|
||||
(store.order.lineItems?.glassParts != null &&
|
||||
store.order.lineItems.glassParts.length > 0))
|
||||
);
|
||||
},
|
||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||
|
|
@ -187,10 +188,12 @@ export default {
|
|||
const parts = {
|
||||
glassParts: this.pricedGlassParts,
|
||||
supportingItems: this.supportingItems,
|
||||
vaps: this.selectedVaps
|
||||
vaps: this.selectedVaps,
|
||||
};
|
||||
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
||||
window.console.error('One or more items have no price assigned!');
|
||||
window.console.error(
|
||||
'One or more items have no price assigned!'
|
||||
);
|
||||
}
|
||||
if (this.pricedGlassParts.length > 0) {
|
||||
store.updateGlassParts(this.pricedGlassParts);
|
||||
|
|
@ -198,15 +201,18 @@ export default {
|
|||
store.updateSupportingItems(this.supportingItems);
|
||||
store.updateVaps(this.selectedVaps);
|
||||
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
}
|
||||
}
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.subheader-secondary {
|
||||
margin-top: .5rem;
|
||||
margin-top: 0.5rem;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +220,7 @@ export default {
|
|||
margin: 1.3rem 0 1.5rem 0;
|
||||
|
||||
a {
|
||||
color: #4D5151;
|
||||
color: #4d5151;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@
|
|||
v-slot="{ meta }"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<div class="page-container-grouped-styles">
|
||||
<div class="fade-on-route-transition position-relative">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="container-fluid px-5 pb-2 confirmation">
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 px-0 px-md-2">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<vehicleBanner
|
||||
ref="vehicleBanner"
|
||||
class="mb-4"
|
||||
|
|
@ -17,7 +21,9 @@
|
|||
:displayGenericVehicleImage="false" />
|
||||
<div class="text-center text-color--black pb-2 fs-5">
|
||||
<img :src="tpaConfirmationImage" />
|
||||
<span class="ms-2" v-html="tpaConfirmationHeaderText"></span>
|
||||
<span
|
||||
class="ms-2"
|
||||
v-html="tpaConfirmationHeaderText"></span>
|
||||
</div>
|
||||
<div class="text-center text-color--black mb-3 fw-bold">
|
||||
<span v-html="tpaConfirmationSubheaderText"></span>
|
||||
|
|
@ -36,8 +42,7 @@
|
|||
:customText="contactCarrierText"
|
||||
class="contact-carrier-text small"
|
||||
@click="setBailoutInfo()" />
|
||||
<div
|
||||
ref="confirmationOrderDetailsSection">
|
||||
<div ref="confirmationOrderDetailsSection">
|
||||
<textBlock
|
||||
ref="tpaConfirmationOrderDetailsTitle"
|
||||
:customText="orderDetailsTitle"
|
||||
|
|
@ -75,12 +80,19 @@ import textBlock from '@/digital-components/text-block/text-block.vue';
|
|||
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
|
||||
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage, processIfStatements } from '@/helpers/cms-content-helper';
|
||||
import {
|
||||
fetchCmsContentForPage,
|
||||
processIfStatements,
|
||||
} from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store';
|
||||
import { toTitleCase, toDisplayPhoneNumber, formatAmountInDollars } from '@/helpers/text-helper.js';
|
||||
import {
|
||||
toTitleCase,
|
||||
toDisplayPhoneNumber,
|
||||
formatAmountInDollars,
|
||||
} from '@/helpers/text-helper.js';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
|
||||
const VERIFYING_COVERAGE = 'Verifying coverage';
|
||||
|
|
@ -94,7 +106,7 @@ export default {
|
|||
textBlock,
|
||||
deductibleBox,
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
Form,
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -105,12 +117,12 @@ export default {
|
|||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
{
|
||||
resultKey: 'accountInfo',
|
||||
promise: accountInfoPromise
|
||||
}
|
||||
promise: accountInfoPromise,
|
||||
},
|
||||
];
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
|
@ -130,40 +142,67 @@ export default {
|
|||
return this.getCmsContent('TPAConfirmationContent', 'Image');
|
||||
},
|
||||
tpaConfirmationSubheaderText() {
|
||||
return this.getCmsContent('TPAConfirmationContent', 'SubheaderText')
|
||||
?.replaceAll('{custom:glassShop}', this.preferredShopName);
|
||||
return this.getCmsContent(
|
||||
'TPAConfirmationContent',
|
||||
'SubheaderText'
|
||||
)?.replaceAll('{custom:glassShop}', this.preferredShopName);
|
||||
},
|
||||
tpaConfirmationBodyOne() {
|
||||
return this.getCmsContent('TPAConfirmationContent', 'BodyText')
|
||||
?.replaceAll('{custom:phoneNumber}', this.preferredShopPhoneNumber)
|
||||
?.replaceAll(
|
||||
'{custom:phoneNumber}',
|
||||
this.preferredShopPhoneNumber
|
||||
)
|
||||
?.replaceAll('{custom:glassShop}', this.preferredShopName);
|
||||
},
|
||||
tpaConfirmationBodyTwo() {
|
||||
return this.getCmsContent('TPAConfirmationContent', 'BodyText2');
|
||||
},
|
||||
contactCarrierText() {
|
||||
const contactCarrierText = this.getCmsContent('ContactCarrierContent', 'Text')
|
||||
?.replaceAll('{custom:carrierPhoneNumber}', this.carrierPhoneNumber);
|
||||
return this.processIfStatements(contactCarrierText, 'custom', this.getCustomValueFromString);
|
||||
const contactCarrierText = this.getCmsContent(
|
||||
'ContactCarrierContent',
|
||||
'Text'
|
||||
)?.replaceAll(
|
||||
'{custom:carrierPhoneNumber}',
|
||||
this.carrierPhoneNumber
|
||||
);
|
||||
return this.processIfStatements(
|
||||
contactCarrierText,
|
||||
'custom',
|
||||
this.getCustomValueFromString
|
||||
);
|
||||
},
|
||||
orderDetailsTitle() {
|
||||
return this.getCmsContent('OrderDetailsContent', 'HeaderText');
|
||||
},
|
||||
orderDetailsBody() {
|
||||
const orderDetailsBodyText = this.getCmsContent('OrderDetailsContent', 'BodyText');
|
||||
return this.processIfStatements(orderDetailsBodyText, 'custom', this.getCustomValueFromString);
|
||||
const orderDetailsBodyText = this.getCmsContent(
|
||||
'OrderDetailsContent',
|
||||
'BodyText'
|
||||
);
|
||||
return this.processIfStatements(
|
||||
orderDetailsBodyText,
|
||||
'custom',
|
||||
this.getCustomValueFromString
|
||||
);
|
||||
},
|
||||
deductibleBoxValue() {
|
||||
return this.isVerified ? this.formatAmountInDollars(this.currentDeductible) : VERIFYING_COVERAGE;
|
||||
return this.isVerified
|
||||
? this.formatAmountInDollars(this.currentDeductible)
|
||||
: VERIFYING_COVERAGE;
|
||||
},
|
||||
currentDeductible() {
|
||||
return useMainStore().order.currentDeductible;
|
||||
},
|
||||
preferredShopName() {
|
||||
return toTitleCase(useMainStore().order.serviceLocation.provider.companyName);
|
||||
return toTitleCase(
|
||||
useMainStore().order.serviceLocation.provider.companyName
|
||||
);
|
||||
},
|
||||
preferredShopPhoneNumber() {
|
||||
return this.toDisplayPhoneNumber(useMainStore().order.serviceLocation.provider.phoneNumber);
|
||||
return this.toDisplayPhoneNumber(
|
||||
useMainStore().order.serviceLocation.provider.phoneNumber
|
||||
);
|
||||
},
|
||||
isVerified() {
|
||||
return useMainStore().order.payment.insuranceCoverage.isVerified;
|
||||
|
|
@ -175,44 +214,46 @@ export default {
|
|||
return this.mainStore.issConfig.successReturnURL;
|
||||
},
|
||||
carrierPhoneNumber() {
|
||||
return this.toDisplayPhoneNumber(useMainStore().order.carrierPhoneNumber);
|
||||
}
|
||||
return this.toDisplayPhoneNumber(
|
||||
useMainStore().order.carrierPhoneNumber
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.carrierUrl) {
|
||||
this.$refs.siteFooter.updateButtonText(`Go back to ${this.carrierName}`);
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
`Go back to ${this.carrierName}`
|
||||
);
|
||||
}
|
||||
},
|
||||
methods:
|
||||
{
|
||||
async forwardButtonAction() {
|
||||
this.$router.navigateToExternalUrl(this.carrierUrl);
|
||||
},
|
||||
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;
|
||||
case 'coverageVerified':
|
||||
return this.isVerified;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
setBailoutInfo() {
|
||||
this.mainStore.setBailout(bailoutMessage.RequestCallback);
|
||||
},
|
||||
toDisplayPhoneNumber,
|
||||
formatAmountInDollars,
|
||||
processIfStatements
|
||||
}
|
||||
methods: {
|
||||
async forwardButtonAction() {
|
||||
this.$router.navigateToExternalUrl(this.carrierUrl);
|
||||
},
|
||||
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;
|
||||
case 'coverageVerified':
|
||||
return this.isVerified;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
setBailoutInfo() {
|
||||
this.mainStore.setBailout(bailoutMessage.RequestCallback);
|
||||
},
|
||||
toDisplayPhoneNumber,
|
||||
formatAmountInDollars,
|
||||
processIfStatements,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.text-color--black {
|
||||
color: $black;
|
||||
}
|
||||
|
|
@ -233,5 +274,4 @@ export default {
|
|||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -5,12 +5,16 @@
|
|||
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">
|
||||
<div class="container-fluid fade-on-route-transition">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 px-0 px-md-2">
|
||||
<siteHeader
|
||||
ref="siteHeader"
|
||||
:cmsWidgetName="widget.siteHeader" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<vehicleBanner
|
||||
ref="vehicleBanner"
|
||||
:cmsWidgetName="widget.vehicleBanner"
|
||||
|
|
|
|||
Loading…
Reference in a new issue