Merge pull request #1047 from Safelite/feature/INSR-7749

INSR-7749: Bailout Page and Contact Confirmation Page
This commit is contained in:
katiekroell 2026-02-05 14:04:35 -05:00 committed by GitHub
commit 751807da9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 77 additions and 40 deletions

View file

@ -65,7 +65,9 @@ const errorMessages = Object.freeze({
STYLE_REQUIRED: 'Vehicle style is required.',
MOBILE_LOCATION_REQUIRED: 'Please enter your service address',
DATE_REQUIRED: 'Please select a date',
TIME_REQUIRED: 'Please select an appointment time.'
TIME_REQUIRED: 'Please select an appointment time.',
PRIMARY_PHONE_REQUIRED: 'Primary phone number is required.',
BAILOUT_EMAIL_ADDRESS_REQUIRED: 'Email address is required.'
});
export default errorMessages;

View file

@ -26,7 +26,9 @@ const globalRules = Object.freeze({
EXTENSION_FORMAT: 'extension-format',
ZIP_CODE_REQUIRED: 'zip-code-required',
ZIP_CODE_SEARCH_FORMAT: 'zip-code-search-format',
OPTION_REQUIRED: 'option-required'
OPTION_REQUIRED: 'option-required',
PRIMARY_PHONE_REQUIRED: 'primary-phone-required',
BAILOUT_EMAIL_ADDRESS_REQUIRED: 'bailout-email-address-required'
});
export default globalRules;

View file

@ -10,7 +10,7 @@ function canBailoutNavigateBack() {
switch (code) {
case BailoutCode.VehicleNotFound:
case BailoutCode.DoNotSeeMyShop:
case BailoutCode.RequestCallback:
case BailoutCode.TPANotEnabled:
return true;

View file

@ -24,6 +24,7 @@ function defineGlobalNameRules() {
*/
function defineGlobalEmailRules() {
defineRule(globalRules.EMAIL_ADDRESS_REQUIRED, required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(globalRules.BAILOUT_EMAIL_ADDRESS_REQUIRED, required(errorMessages.BAILOUT_EMAIL_ADDRESS_REQUIRED));
defineRule(
globalRules.EMAIL_ADDRESS_FORMAT,
regex(
@ -71,6 +72,7 @@ function defineGlobalDateOfLossRules() {
*/
function defineGlobalPhoneNumberRules() {
defineRule(globalRules.PHONE_NUMBER_REQUIRED, required(errorMessages.PHONE_NUMBER_REQUIRED));
defineRule(globalRules.PRIMARY_PHONE_REQUIRED, required(errorMessages.PRIMARY_PHONE_REQUIRED));
defineRule(
globalRules.PHONE_NUMBER_FORMAT,
regex(

View file

@ -12,13 +12,14 @@ Object {
"phoneNumber": "6145550909",
},
"rules": Object {
"email": "email-required|email-address-format",
"firstName": "first-name-required",
"lastName": "last-name-required",
"phoneNumber": "phone-number-required|phone-number-format",
"email": "bailout-email-address-required|email-address-format",
"firstName": "policyholder-first-name-required",
"lastName": "policyholder-last-name-required",
"phoneNumber": "primary-phone-required|phone-number-format",
},
"widget": Object {
"defaultSiteHeader": "SiteSubHeaderWidget",
"disclaimerText": "DisclaimerWidget",
"noTpa": "ContentGroupNoTPAWidget",
"notSeeingPreferredShop": "ContentGroupNotSeeingPreferredShop",
},

View file

@ -156,6 +156,16 @@ describe('Bailout page', () => {
// Assert
expect(siteFooter.exists()).toBeTruthy();
});
test('disclaimer text block', () => {
// Arrange
const wrapper = shallowMount(bailoutPage, getMountOptions());
// Act
const disclaimerText = wrapper.findComponent({ ref: 'disclaimerText' });
// Assert
expect(disclaimerText.exists()).toBeTruthy();
});
});
describe('computed', () => {
describe('subHeaderCmsWidgetName', () => {

View file

@ -20,28 +20,34 @@
:subContentProperty="subContentProperty"
class="sub-header-content mt-2 mb-5"
justification="left" />
<textboxQuestion
ref="firstName"
v-model="bailoutPageModel.firstName"
class="mb-3"
inputId="firstNameField"
cmsWidgetName="FirstNameQuestion"
isRequired
disableAutoFill
:validationRules="rules.firstName" />
<textboxQuestion
ref="lastName"
v-model="bailoutPageModel.lastName"
class="mb-3"
inputId="lastNameField"
cmsWidgetName="LastNameQuestion"
isRequired
disableAutoFill
:validationRules="rules.lastName" />
<div class="row">
<div class="col">
<textboxQuestion
ref="firstName"
v-model="bailoutPageModel.firstName"
class="input"
inputId="firstNameField"
cmsWidgetName="FirstNameQuestion"
isRequired
disableAutoFill
:validationRules="rules.firstName" />
</div>
<div class="col">
<textboxQuestion
ref="lastName"
v-model="bailoutPageModel.lastName"
class="input"
inputId="lastNameField"
cmsWidgetName="LastNameQuestion"
isRequired
disableAutoFill
:validationRules="rules.lastName" />
</div>
</div>
<textboxQuestion
ref="phoneNumber"
v-model="bailoutPageModel.phoneNumber"
class="mb-3"
class="input"
inputId="phoneNumberField"
cmsWidgetName="PhoneNumberQuestion"
isRequired
@ -51,7 +57,7 @@
<textboxQuestion
ref="emailAddress"
v-model="bailoutPageModel.email"
class="mb-3"
class="input"
inputId="emailAddressField"
cmsWidgetName="EmailAddressQuestion"
isRequired
@ -65,6 +71,9 @@
:isBackButtonHidden="!canNavigateBack"
@backClicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
<textBlock
ref="disclaimerText"
cmsWidgetName="DisclaimerWidget" />
</div>
</div>
</div>
@ -77,6 +86,7 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
// Supporting files
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
@ -99,7 +109,8 @@ export default {
siteFooter,
textboxQuestion,
// eslint-disable-next-line vue/no-reserved-component-names
Form
Form,
textBlock
},
mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) {
@ -130,13 +141,14 @@ export default {
widget: {
defaultSiteHeader: 'SiteSubHeaderWidget',
noTpa: 'ContentGroupNoTPAWidget',
notSeeingPreferredShop: 'ContentGroupNotSeeingPreferredShop'
notSeeingPreferredShop: 'ContentGroupNotSeeingPreferredShop',
disclaimerText: 'DisclaimerWidget'
},
rules: {
firstName: globalRules.FIRST_NAME_REQUIRED,
lastName: globalRules.LAST_NAME_REQUIRED,
phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`,
email: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`
firstName: globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
lastName: globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
phoneNumber: `${globalRules.PRIMARY_PHONE_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`,
email: `${globalRules.BAILOUT_EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`
}
};
},
@ -221,9 +233,7 @@ export default {
};
</script>
<style lang="scss">
@import '@/styles/bailout-common.scss';
<style lang="scss" scoped>
.iss-heritage-container-width {
.bailout-page-container {
position: relative;
@ -232,4 +242,12 @@ export default {
padding-right: .9375rem;
}
}
.input {
margin-bottom: 20px;
}
.footer-content-container {
margin: 30px 0 30px 0;
}
</style>

View file

@ -24,6 +24,7 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import issPageValues from '@/router/router-constants/issPage-values.js';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
export default {
name: 'contact-confirmation',
@ -47,6 +48,7 @@ export default {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
});
showIssLoadingModal(false);
},
setup() {
const mainStore = useMainStore();

View file

@ -389,9 +389,9 @@ export default {
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.mainStore.setBailout(bailoutMessage.doNotSeeMyShop());
this.mainStore.setBailout(bailoutMessage.RequestCallback());
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.navigationScenarios.CLICKED_NEED_HELP,
this.$route
);
},

View file

@ -73,7 +73,7 @@ const navigationScenarios = Object.freeze({
PRICING_LOOKUP_ERROR: 'PRICING_LOOKUP_ERROR',
// TPA Search
CLICKED_DO_NOT_SEE_MY_SHOP_LINK: 'CLICKED_DO_NOT_SEE_MY_SHOP_LINK',
CLICKED_NEED_HELP: 'CLICKED_NEED_HELP',
CLICKED_FORWARD_WITH_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_SAFELITE_SHOP',
CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP',

View file

@ -744,7 +744,7 @@ const routingTable = () => [
destinationIssPageValue: issPageValues.TPA_SUBMIT
},
{
scenario: navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
scenario: navigationScenarios.CLICKED_NEED_HELP,
destinationIssPageValue: issPageValues.BAILOUT_PAGE
}
]