WIP update markup for ancillary pages found by Katie.

This commit is contained in:
Bryan Mauger 2024-04-16 16:48:39 -04:00
parent 3ab6d5d4ef
commit 4bcffb29b9
13 changed files with 1094 additions and 805 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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('&lt;', '<')
?.replaceAll('&gt;', '>');
},
@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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>

View file

@ -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"