Merge branch 'develop' into feature/kiener/INSR-7753

This commit is contained in:
Katie Kroell 2026-01-26 15:59:29 -05:00
commit eb92223842
14 changed files with 50 additions and 347 deletions

View file

@ -34,7 +34,7 @@ const errorMessages = Object.freeze({
VIN_FORMAT:
// eslint-disable-next-line max-len
'Invalid VIN. Please make sure that you entered the correct 17-digit, alpha-numeric number. VINs do not contain the letters I, O, or Q',
OPTION_REQUIRED: 'Please choose an option',
OPTION_REQUIRED: 'Please select an option',
VEHICLE_REQUIRED: 'Please select a vehicle',
POLICY_NUMBER_REQUIRED: 'Policy number is required.',
POLICY_NUMBER_FORMAT: 'Please enter an alpha-numeric string',

View file

@ -146,7 +146,7 @@ export default {
background-size: 0.625rem 1rem;
color: $gray-600;
border-radius: $border-radius;
min-height: 3rem;
min-height: 2.8125rem;
letter-spacing: inherit;
box-shadow: $box-shadow-input;
&:focus,

View file

@ -86,7 +86,7 @@ function defineGlobalPhoneNumberRules() {
function defineGlobalExtensionRules() {
defineRule(
globalRules.EXTENSION_FORMAT,
regex(/^[0-9]{5}$/, errorMessages.EXTENSION_FORMAT)
regex(/^[0-9]{1,5}$/, errorMessages.EXTENSION_FORMAT)
);
}

View file

@ -12,8 +12,7 @@
hasIcon
disableAutoFill
validationRules="street-address-required"
@keydown.enter.prevent
class="mb-4" />
@keydown.enter.prevent />
</div>
</div>
<transition
@ -29,24 +28,22 @@
v-model="addressModel.streetAddress2"
cmsWidgetName="StreetAddress2QuestionWidget"
aria-haspopup=""
inputId="streetAddress2Field"
class="mb-4" />
inputId="streetAddress2Field" />
</div>
</div>
<div
class="row"
aria-live="polite">
<div class="col">
<div class="col-lg-6">
<textboxQuestion
ref="city"
v-model="addressModel.city"
cmsWidgetName="CityQuestionWidget"
inputId="cbf28188fdf2436688fd735915f7ee56"
disableAutoFill
validationRules="city-required"
class="mb-4" />
validationRules="city-required" />
</div>
<div class="col">
<div class="col-lg-6">
<dropdownQuestion
ref="state"
v-model="addressModel.state"
@ -55,8 +52,7 @@
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
:options="stateOptions"
disableAutoFill
validationRules="state-required"
class="mb-4" />
validationRules="state-required" />
</div>
</div>
<div
@ -70,8 +66,7 @@
inputId="01a9a1c2de0b4c9da8e023c9ae3be498"
mask="#####"
disableAutoFill
validationRules="zip-code-required|zip-code-format"
class="mb-4" />
validationRules="zip-code-required|zip-code-format" />
</div>
</div>
</div>
@ -362,3 +357,12 @@ export default {
}
};
</script>
<style scoped lang="scss">
.textbox-question {
margin-bottom: 1.25rem;
}
.dropdown-question {
margin-bottom: 1.25rem;
}
</style>

View file

@ -24,8 +24,6 @@
"
:aria-disabled="disableForwardAction || isForwardActionDisabled"
:isDisabled="disableForwardAction || isForwardActionDisabled"
data-bs-target="#footerModal"
data-bs-dismiss="modal"
data-test-id="site-footer-main-button"
@clickEvent="buttonClick" />
</div>
@ -36,8 +34,6 @@
linkType="navigation"
:text="backLink"
href="javascript:void(0)"
data-bs-target="#footerModal"
data-bs-dismiss="modal"
data-test-id="site-footer-back-button"
@clickEvent="linkClick" />
</div>

View file

@ -1,50 +0,0 @@
import { mount, shallowMount } from '@vue/test-utils';
import menuModal from '@/iss-components/site-header/menu-modal/menu-modal.vue';
describe('menu-modal.vue', () => {
it('Should return text Footer Navigation', async () => {
// Act
const wrapper = shallowMount(menuModal);
// Assert
const footerModalLabel = wrapper.find('h5');
// Expect
expect(footerModalLabel.text()).toContain('Footer Navigation');
});
it('Should return footer text as Safelite Group', async () => {
// Act
const wrapper = shallowMount(menuModal);
// Assert
const modalFooter = wrapper.find('div.modal-footer');
// Expect
expect(modalFooter.text()).toContain('Safelite Group');
});
it('Should return Terms of use text link text', async () => {
// Act
const wrapper = shallowMount(menuModal);
// Expect
expect(wrapper.html()).toContain('Terms of service');
});
it('Should return "Your privacy choices" text link text', async () => {
// Act
const wrapper = mount(menuModal);
// Expect
expect(wrapper.html()).toContain('Your privacy choices');
});
it('Should return Warranty text link text', async () => {
// Act
const wrapper = shallowMount(menuModal);
// Expect
expect(wrapper.html()).toContain('Warranty');
});
});

View file

@ -1,232 +0,0 @@
<template>
<div class="menu-modal-container">
<button
class="menu-button"
type="button"
:class="[isActive ? 'active' : '']"
aria-label="Hamburger Menu (modal window)"
@click="toggleModal">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</button>
</div>
<div class="menu-modal-container">
<button
aria-hidden="true"
tabindex="-1"
class="menu-button"
type="button"
:class="[isActive ? 'active' : '']"
aria-label="Hamburger Menu (modal window)"
@click="toggleModal">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</button>
</div>
<!-- Modal -->
<div
id="footerModal"
class="modal menu-modal fade"
data-bs-backdrop="false"
tabindex="-1"
aria-labelledby="footerModalLabel"
aria-hidden="true"
v-on="{ 'show.bs.modal': show, 'hide.bs.modal': hide }">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header visually-hidden">
<h5 id="footerModalLabel" class="modal-title">
Footer Navigation
</h5>
</div>
<div class="modal-body d-flex flex-column">
<textLink
linkType="newWindowLink"
text="Terms of service"
href="//www.safelite.com/terms-of-use"
target="_blank" />
<textLink
linkType="newWindowLink"
text="Your privacy choices"
href="//www.safelite.com/privacy-center"
target="_blank">
<template #after-text>
<img
class="ccpa-icon"
src="~@/assets/img/icons/ccpa-icon.svg"
alt="Your privacy choices" />
</template>
</textLink>
<textLink
linkType="newWindowLink"
text="Warranty"
href="//www.safelite.com/national-lifetime-warranty"
target="_blank" />
<textLink
linkType="newWindowLink"
text="Notice at collection"
href="https://www.safelite.com/ccpa-privacy-policy"
target="_blank" />
</div>
<div class="modal-footer d-flex justify-content-start">
&copy; {{ new Date().getFullYear() }} Safelite Group
</div>
</div>
</div>
</div>
</template>
<script>
import textLink from '@/ux-components/text-link/text-link';
import { Modal } from 'bootstrap';
import baseMixin from '@/mixins/base-mixin.js';
export default {
name: 'menu-modal',
components: {
textLink,
},
data() {
return {
isActive: false,
};
},
methods: {
toggleModal() {
if (this.isActive) {
this.closeModal();
} else {
this.openModal();
}
},
openModal() {
Modal.getOrCreateInstance(
document.getElementById('footerModal')
).show();
},
closeModal() {
Modal.getInstance(document.getElementById('footerModal')).hide();
},
show() {
this.isActive = true;
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
},
hide() {
const self = this;
self.isActive = false;
},
},
};
</script>
<style lang="scss" scoped>
.menu-modal-container {
position: absolute;
padding: 1.47rem 0.5rem 1.47rem 1.47rem;
right: 0;
button {
border: none;
&.menu-button {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);
background-color: $white;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0; //Required to prevent 'squish' on iPhone
z-index: 1050;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
}
&.active .bar2 {
opacity: 0;
}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
}
}
}
}
.modal {
&.menu-modal {
left: auto;
height: calc(100% - 56px);
top: 56px;
border-top: 1px solid $gray-300;
overflow-x: visible;
overflow-y: visible;
.modal-body {
padding: 2rem;
.ccpa-icon {
width: 2.0625rem;
height: 1rem;
margin-left: 0.5rem;
}
}
.modal-fullscreen {
width: 100vw;
}
.modal-footer {
border-top: none;
padding: 2rem;
}
.menu-modal-container {
position: absolute;
padding: 1.47rem 0 1.47rem 1.47rem;
right: 0;
top: -5rem;
button {
border: none;
&.menu-button {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
box-shadow: none;
background-color: $white;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0; //Required to prevent 'squish' on iPhone
z-index: 1056;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
}
&.active .bar2 {
opacity: 0;
}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
}
}
}
}
//.modal-backdrop styles are in common-styles.scss
}
}
</style>

View file

@ -14,7 +14,7 @@
id="sub-header"
cmsWidgetName="SiteSubHeaderWidget"
class="mt-4" />
<div class="row mb-4">
<div class="row">
<div class="col">
<textboxQuestion
ref="policyHolderFirstName"
@ -36,8 +36,8 @@
:validationRules="rules.lastName" />
</div>
</div>
<div class="row mb-4">
<div class="col-md-8">
<div class="row">
<div class="col-lg-8">
<textboxQuestion
ref="phoneNumber"
v-model="customerQuestions.phoneNumber"
@ -48,13 +48,14 @@
:mask="phoneMask"
disableAutoFill />
</div>
<div class="col-md-4">
<div class="col-lg-4">
<textboxQuestion
ref="extension"
v-model="customerQuestions.extension"
inputId="extensionField"
cmsWidgetName="ExtensionQuestion"
:validationRules="rules.extension"
maxLength="5"
disableAutoFill />
</div>
</div>
@ -65,8 +66,7 @@
cmsWidgetName="EmailAddressQuestion"
:validationRules="rules.email"
isRequired
disableAutoFill
class="mb-4" />
disableAutoFill />
<addressQuestions
id="address-questions-wrapper"
ref="addressQuestions"
@ -228,4 +228,10 @@ export default {
#address-questions-wrapper .form-test-error {
line-height: 24px;
}
.textbox-question {
margin-bottom: 1.25rem;
}
.dropdown-question {
margin-bottom: 1.25rem;
}
</style>

View file

@ -322,6 +322,9 @@ export default {
}
}
}
.form-test-error {
text-align: left
}
}
.list-button-content {

View file

@ -49,6 +49,7 @@
inputId="extension"
:cmsWidgetName="widget.extensionQuestion"
disableAutoFill
maxLength="5"
:validationRules="rules.extension" />
</template>
</modal>

View file

@ -39,6 +39,7 @@
inputId="extensionField"
cmsWidgetName="ExtensionQuestion"
:validationRules="rules.extension"
maxLength="5"
disableAutoFill
class="form-group" />
<textboxQuestion

View file

@ -2293,7 +2293,8 @@ export const useMainStore = defineStore({
this.order.serviceLocation.zipCode = welcomePageModel?.policyZipCode;
this.updatePhoneNumbers({
home: welcomePageModel?.phoneNumber,
service: welcomePageModel?.phoneNumber
service: welcomePageModel?.phoneNumber,
extension: welcomePageModel?.extension
});
},
updatePolicyHolderDetails(customerQuestions) {
@ -2305,6 +2306,11 @@ export const useMainStore = defineStore({
this.order.customer.firstName = customerQuestions.firstName;
this.order.customer.lastName = customerQuestions.lastName;
this.order.customer.emailAddress = customerQuestions.email;
this.updatePhoneNumbers({
home: customerQuestions.phoneNumber,
service: customerQuestions.phoneNumber,
extension: customerQuestions.extension
});
this.order.serviceLocation.zipCode = customerQuestions.addressQuestions.zipCode;
},
updateIsSafeliteProvider(isSafelite) {

View file

@ -22,44 +22,6 @@ body {
flex-direction: column;
padding: 0 1.5rem;
}
// Set max-width on columns to prevent overly-wide
// components on extra wide screens.
.col-md-6 {
max-width: 472px;
@include media-breakpoint-up(xl) {
max-width: 708px;
}
.col {
max-width: 236px;
&.one-list-card-width {
max-width: 472px;
@include media-breakpoint-up(xl) {
max-width: 66.6666666%;
}
}
}
.shop-question {
.col {
max-width: 472px;
}
}
}
.col-xl-4 {
max-width: 472px;
.col {
max-width: 100%;
}
}
//END set max-width on columns
}
.pointer {
@ -156,6 +118,10 @@ body {
width: 46.25rem; // 740px
}
@include media-breakpoint-up(lg) {
width: 60rem; // 960px
}
@include media-breakpoint-up(xl) {
width: 63.75rem; // 1020px
}
@ -166,7 +132,7 @@ body {
width: 100%;
}
@include media-breakpoint-up(md) {
@include media-breakpoint-up(lg) {
width: 58.33333333%;
}
}

View file

@ -194,7 +194,9 @@ $spacers: (
//Bootstrap Grid Breakpoints - Use these breakpoints only
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1440px,
);