diff --git a/src/constants/progress-bar-mapper.js b/src/constants/progress-bar-mapper.js index e80fbb5c..efb6225d 100644 --- a/src/constants/progress-bar-mapper.js +++ b/src/constants/progress-bar-mapper.js @@ -53,10 +53,10 @@ export const pageProgressMapper = { 'schedule-page': { percent: 70 }, - 'contact-details': { - percent: 80 - }, 'service-packages': { + percent: 75 + }, + 'contact-details': { percent: 85 }, 'payment-method': { diff --git a/src/digital-components/button-question/button-question.vue b/src/digital-components/button-question/button-question.vue index 68ca6d57..ca731b44 100644 --- a/src/digital-components/button-question/button-question.vue +++ b/src/digital-components/button-question/button-question.vue @@ -79,7 +79,7 @@
diff --git a/src/digital-components/textarea-question/textarea-question.spec.js b/src/digital-components/textarea-question/textarea-question.spec.js index 27968aa1..c3d903a1 100644 --- a/src/digital-components/textarea-question/textarea-question.spec.js +++ b/src/digital-components/textarea-question/textarea-question.spec.js @@ -67,7 +67,7 @@ describe('textarea-question.vue', () => { }, mixins: [mockMixin] }); - const expected = `${maxLength}/${maxLength}`; + const expected = `${maxLength} characters allowed`; // Act // Assert diff --git a/src/digital-components/textarea-question/textarea-question.vue b/src/digital-components/textarea-question/textarea-question.vue index 60293dde..f6d94ebb 100644 --- a/src/digital-components/textarea-question/textarea-question.vue +++ b/src/digital-components/textarea-question/textarea-question.vue @@ -18,7 +18,7 @@ :id="inputId" :ref="inputId" v-model.trim="value" - class="form-control" + class="textarea-input" :name="inputId" :rows="[inputRows ?? 10]" :placeholder="placeholderText" @@ -32,8 +32,15 @@ @drop="trimOnPaste"> -

- {{ maxLength - characterCount }}/{{ maxLength }} characters remaining +

+ {{ maxLength }} characters allowed +

+

+ {{ maxLength - characterCount }} characters left

diff --git a/src/layouts/contact-details/contact-details.spec.js b/src/layouts/contact-details/contact-details.spec.js index 58d16b8e..5b5131a8 100644 --- a/src/layouts/contact-details/contact-details.spec.js +++ b/src/layouts/contact-details/contact-details.spec.js @@ -32,65 +32,175 @@ describe('contactDetails.vue', () => { // Assert expect(siteSubHeader.exists()).toBe(true); }); - test('Should render first name question subcomponent', () => { + test('Should render appointment information alert', () => { // Arrange const wrapper = shallowMount(contactDetails, getMountOptions()); // Act - const firstNameQuestion = wrapper.findComponent({ ref: 'firstNameQuestion' }); + const appointmentInformationAlert = wrapper.findComponent({ ref: 'appointmentInformationAlert' }); // Assert - expect(firstNameQuestion.exists()).toBe(true); + expect(appointmentInformationAlert.exists()).toBe(true); }); - test('Should render last name question subcomponent', () => { + test('Should render same as policy address question subcomponent if service zip is same as customer zip', async () => { // Arrange - const wrapper = shallowMount(contactDetails, getMountOptions()); - - // Act - const lastNameQuestion = wrapper.findComponent({ ref: 'lastNameQuestion' }); - - // Assert - expect(lastNameQuestion.exists()).toBe(true); - }); - test('Should render email question subcomponent', () => { - // Arrange - const wrapper = shallowMount(contactDetails, getMountOptions()); - - // Act - const emailQuestion = wrapper.findComponent({ ref: 'emailQuestion' }); - - // Assert - expect(emailQuestion.exists()).toBe(true); - }); - test('Should render phone number question subcomponent', () => { - // Arrange - const wrapper = shallowMount(contactDetails, getMountOptions()); - - // Act - const phoneNumberQuestion = wrapper.findComponent({ ref: 'phoneNumberQuestion' }); - - // Assert - expect(phoneNumberQuestion.exists()).toBe(true); - }); - test('Should render text updates checkbox subcomponent', () => { - // Arrange - const checkboxLabel = getRandomString(50, 100); - const mockMixin = { - methods: { - getCmsContent: jest.fn().mockImplementation(() => checkboxLabel), - setCmsContent: jest.fn() + const mountOptions = getMountOptions(); + + const customerStreetAddress = getRandomString(10, 50); + const customerStreetAddress2 = getRandomString(0, 50); + const customerCity = getRandomString(4, 20); + const customerState = getRandomString(2, 2); + const serviceStreetAddress = getRandomString(10, 50); + const serviceStreetAddress2 = getRandomString(0, 50); + const serviceCity = getRandomString(4, 20); + const serviceState = getRandomString(2, 2); + const zipCode = getRandomInt(10000, 99999).toString(); + const mainInitialState = { + order: { + customer: { + address: { + streetAddress: customerStreetAddress, + streetAddress2: customerStreetAddress2, + city: customerCity, + state: customerState, + zipCode + } + }, + serviceLocation: { + streetAddress: serviceStreetAddress, + streetAddress2: serviceStreetAddress2, + city: serviceCity, + state: serviceState, + zipCode + } } }; + mountOptions.global.plugins = [createTestingPinia({ + initialState: { + main: mainInitialState + } + })]; + const wrapper = shallowMount(contactDetails, mountOptions); + + await wrapper.vm.$nextTick(); + + // Act + const sameAsPolicyAddressQuestion = wrapper.findComponent({ ref: 'sameAsPolicyAddressQuestion' }); + + // Assert + expect(sameAsPolicyAddressQuestion.exists()).toBe(true); + }); + test('Should not render same as policy address question subcomponent if service zip is different from customer zip', () => { + // Arrange const mountOptions = getMountOptions(); - mountOptions.mixins = [mockMixin]; + + const firstName = getRandomString(4, 15); + const lastName = getRandomString(4, 15); + const emailAddress = getRandomString(10, 20); + const servicePhone = getRandomInt(1000000000, 9999999999).toString(); + const testZipCode = getRandomInt(10000, 99999); + const customerZipCode = testZipCode.toString(); + const serviceZipCode = (testZipCode + 1).toString(); + const mainInitialState = { + order: { + customer: { + firstName, + lastName, + emailAddress, + address: { + zipCode: customerZipCode + } + }, + contactInfo: { + servicePhone + }, + serviceLocation: { + zipCode: serviceZipCode + } + } + }; + mountOptions.global.plugins = [createTestingPinia({ + initialState: { + main: mainInitialState + } + })]; const wrapper = shallowMount(contactDetails, mountOptions); // Act - const textUpdatesCheckbox = wrapper.findComponent({ ref: 'requestTextUpdatesCheckbox' }); + const sameAsPolicyAddressQuestion = wrapper.findComponent({ ref: 'sameAsPolicyAddressQuestion' }); // Assert - expect(textUpdatesCheckbox.exists()).toBe(true); - expect(wrapper.vm.requestTextUpdatesCheckboxText).toBe(`${checkboxLabel}*`); + expect(sameAsPolicyAddressQuestion.exists()).toBe(false); + }); + test('Should render address question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const addressQuestion = wrapper.findComponent({ ref: 'addressQuestion' }); + + // Assert + expect(addressQuestion.exists()).toBe(true); + }); + test('Should render apartment question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const address2Question = wrapper.findComponent({ ref: 'address2Question' }); + + // Assert + expect(address2Question.exists()).toBe(true); + }); + test('Should render city question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const cityQuestion = wrapper.findComponent({ ref: 'cityQuestion' }); + + // Assert + expect(cityQuestion.exists()).toBe(true); + }); + test('Should render state question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const stateQuestion = wrapper.findComponent({ ref: 'stateQuestion' }); + + // Assert + expect(stateQuestion.exists()).toBe(true); + }); + test('Should render zip code question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const zipCodeQuestion = wrapper.findComponent({ ref: 'zipCodeQuestion' }); + + // Assert + expect(zipCodeQuestion.exists()).toBe(true); + }); + test('Should render change zip code alert', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const changeZipCodeAlert = wrapper.findComponent({ ref: 'changeZipCodeAlert' }); + + // Assert + expect(changeZipCodeAlert.exists()).toBe(true); + }); + test('Should render vehicle protected question subcomponent', () => { + // Arrange + const wrapper = shallowMount(contactDetails, getMountOptions()); + + // Act + const vehicleProtectedQuestion = wrapper.findComponent({ ref: 'vehicleProtectedQuestion' }); + + // Assert + expect(vehicleProtectedQuestion.exists()).toBe(true); }); test('Should render technician notes textarea question subcomponent', () => { // Arrange @@ -102,46 +212,15 @@ describe('contactDetails.vue', () => { // Assert expect(notesQuestion.exists()).toBe(true); }); - test('Should render disclaimer text', () => { - // Arrange - const disclaimerText = getRandomString(50, 100); - const mockMixin = { - methods: { - getCmsContent: jest.fn().mockImplementation(() => disclaimerText), - setCmsContent: jest.fn() - } - }; - const mountOptions = getMountOptions(); - mountOptions.mixins = [mockMixin]; - const wrapper = shallowMount(contactDetails, mountOptions); - const expectedDisclaimerText = `*${disclaimerText} I also agree to Safelite's`; - - // Act - const componentText = wrapper.text(); - - // Assert - expect(wrapper.vm.textUpdateDisclaimerText).toBe(`*${disclaimerText}`); - expect(componentText).toContain(expectedDisclaimerText); - }); - test('Should render privacy policy link', () => { + test('Should render clearance text subcomponent', () => { // Arrange const wrapper = shallowMount(contactDetails, getMountOptions()); // Act - const privacyPolicyLink = wrapper.findComponent({ ref: 'privacyPolicyLink' }); + const clearanceText = wrapper.findComponent({ ref: 'clearanceText' }); // Assert - expect(privacyPolicyLink.exists()).toBe(true); - }); - test('Should render terms of use link', () => { - // Arrange - const wrapper = shallowMount(contactDetails, getMountOptions()); - - // Act - const termsOfUseLink = wrapper.findComponent({ ref: 'termsOfUseLink' }); - - // Assert - expect(termsOfUseLink.exists()).toBe(true); + expect(clearanceText.exists()).toBe(true); }); test('Should render site footer', () => { // Arrange @@ -153,82 +232,48 @@ describe('contactDetails.vue', () => { // Assert expect(footer.exists()).toBe(true); }); - test('Mocked store with no contact info yields expected data', () => { + test('Mocked store yields expected data', () => { // Arrange const mountOptions = getMountOptions(); - const firstName = getRandomString(4, 15); - const lastName = getRandomString(4, 15); - const emailAddress = getRandomString(10, 20); - const servicePhone = getRandomInt(1000000000, 9999999999).toString(); + const address = getRandomString(10, 50); + const address2 = getRandomString(0, 50); + const city = getRandomString(4, 20); + const state = getRandomString(2, 2); + const zipCode = getRandomInt(10000, 99999).toString(); + const notesForTechnician = getRandomString(1, 100); + const isVehicleProtected = getRandomBoolean(); const mainInitialState = { order: { - customer: { - firstName, - lastName, - emailAddress + serviceLocation: { + address, + address2, + city, + state, + zipCode, + isVehicleProtected }, contactInfo: { - servicePhone + notesForTechnician } } }; - mountOptions.global = { - plugins: [createTestingPinia({ - initialState: { - main: mainInitialState - } - })] - }; + mountOptions.global.plugins = [createTestingPinia({ + initialState: { + main: mainInitialState + } + })]; const wrapper = shallowMount(contactDetails, mountOptions); // Assert - expect(wrapper.vm.firstName).toBe(firstName); - expect(wrapper.vm.lastName).toBe(lastName); - expect(wrapper.vm.emailAddress).toBe(emailAddress); - expect(wrapper.vm.phoneNumber).toBe(servicePhone); - }); - test('Mock store with contact info yields expected data', () => { - // Arrange - const customer = { - firstName: getRandomString(4, 15), - lastName: getRandomString(4, 15), - emailAddress: getRandomString(10, 20), - phoneNumber: getRandomInt(1000000000, 9999999999) - }; - const contactInfo = { - firstName: getRandomString(4, 15), - lastName: getRandomString(4, 15), - emailAddress: getRandomString(10, 20), - servicePhone: getRandomInt(1000000000, 9999999999), - requestTextUpdates: getRandomBoolean(), - notesForTechnician: getRandomString(50, 100) - }; - const mainInitialState = { - order: { - customer, - contactInfo - } - }; - const mountOptions = getMountOptions(); - mountOptions.global = { - plugins: [createTestingPinia({ - initialState: { - main: mainInitialState - } - })] - }; - - const wrapper = shallowMount(contactDetails, mountOptions); - - // Assert - expect(wrapper.vm.firstName).toBe(contactInfo.firstName); - expect(wrapper.vm.lastName).toBe(contactInfo.lastName); - expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress); - expect(wrapper.vm.phoneNumber).toBe(contactInfo.servicePhone); - expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates); - expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician); + expect(wrapper.vm.address).toBe(address); + expect(wrapper.vm.address2).toBe(address2); + expect(wrapper.vm.city).toBe(city); + expect(wrapper.vm.state).toBe(state); + expect(wrapper.vm.zipCode).toBe(zipCode); + expect(wrapper.vm.isVehicleProtected).toBe(isVehicleProtected); + expect(wrapper.vm.notesForTechnician).toBe(notesForTechnician); }); }); @@ -250,7 +295,7 @@ describe('contactDetails.vue', () => { expect(wrapper.vm.$router.navigateWithSpinner) .toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, undefined); }); - test('Forward button clicked triggers appropriate navigation when safelite shop', () => { + test('Forward button clicked triggers appropriate navigation', () => { // Arrange const mountOptions = getMountOptions({ router: { @@ -276,37 +321,44 @@ describe('contactDetails.vue', () => { // Assert expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP, undefined); + .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined); }); - test('Forward button clicked triggers appropriate navigation when TPA shop', () => { + test('Forward button click updates service location info', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() - }, - navigationScenarios + } }); - const mainInitialState = { - order: { - serviceLocation: { IsSafeliteProvider: false } - } - }; - mountOptions.global.plugins = [createTestingPinia({ - initialState: { - main: mainInitialState - } - })]; const wrapper = shallowMount(contactDetails, mountOptions); + const address = getRandomString(10, 50); + const address2 = getRandomString(0, 50); + const city = getRandomString(4, 20); + const state = getRandomString(2, 2); + const zipCode = getRandomInt(10000, 99999).toString(); + const isVehicleProtected = getRandomBoolean().toString(); + wrapper.setData({ + address, + address2, + city, + state, + zipCode, + isVehicleProtected + }); // Act wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, undefined); + expect(useMainStore().updateServiceLocation).toHaveBeenCalledWith({ + address, + address2, + city, + isVehicleProtected + }); }); - test('Forward button click updates contact info', () => { + + test('Forward button click updates notes for technician', () => { // Arrange const mountOptions = getMountOptions({ router: { @@ -314,18 +366,8 @@ describe('contactDetails.vue', () => { } }); const wrapper = shallowMount(contactDetails, mountOptions); - const firstName = getRandomString(4, 15); - const lastName = getRandomString(4, 15); - const emailAddress = getRandomString(10, 20); - const phoneNumber = getRandomInt(1000000000, 9999999999).toString(); - const requestTextUpdates = getRandomBoolean(); const notesForTechnician = getRandomString(1, 100); wrapper.setData({ - firstName, - lastName, - emailAddress, - phoneNumber, - requestTextUpdates, notesForTechnician }); @@ -334,146 +376,8 @@ describe('contactDetails.vue', () => { // Assert expect(useMainStore().updateContactInfo).toHaveBeenCalledWith({ - firstName, - lastName, - emailAddress, - requestTextUpdates, notesForTechnician }); }); - - test('Forward button click updates phone numbers request text updates', () => { - // Arrange - const mountOptions = getMountOptions({ - router: { - navigate: jest.fn() - } - }); - const wrapper = shallowMount(contactDetails, mountOptions); - const phoneNumber = getRandomInt(1000000000, 9999999999).toString(); - const requestTextUpdates = true; - wrapper.setData({ - phoneNumber, - requestTextUpdates - }); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(useMainStore().updatePhoneNumbers).toHaveBeenCalledWith({ - service: phoneNumber, - alternative: phoneNumber - }); - }); - - test('Forward button click updates phone numbers dot not request text updates', () => { - // Arrange - const mountOptions = getMountOptions({ - router: { - navigate: jest.fn() - } - }); - const wrapper = shallowMount(contactDetails, mountOptions); - const phoneNumber = getRandomInt(1000000000, 9999999999).toString(); - const requestTextUpdates = false; - wrapper.setData({ - phoneNumber, - requestTextUpdates - }); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(useMainStore().updatePhoneNumbers).toHaveBeenCalledWith({ - home: phoneNumber, - service: phoneNumber - }); - }); - }); - - test('Mocked store with no contact info yields expected data', () => { - // Arrange - const mountOptions = getMountOptions(); - - const firstName = getRandomString(4, 15); - const lastName = getRandomString(4, 15); - const emailAddress = getRandomString(10, 20); - const servicePhone = getRandomInt(1000000000, 9999999999); - const mainInitialState = { - order: { - customer: { - firstName, - lastName, - emailAddress - }, - contactInfo: { - firstName: null, - lastName: null, - emailAddress: null, - servicePhone, - requestTextUpdates: null, - notesForTechnician: null - } - } - }; - mountOptions.global = { - plugins: [createTestingPinia({ - initialState: { - main: mainInitialState - } - })] - }; - - const wrapper = shallowMount(contactDetails, mountOptions); - - // Assert - expect(wrapper.vm.firstName).toBe(firstName); - expect(wrapper.vm.lastName).toBe(lastName); - expect(wrapper.vm.emailAddress).toBe(emailAddress); - expect(wrapper.vm.phoneNumber).toBe(servicePhone); - }); - - test('Mock store with contact info yields expected data', () => { - // Arrange - const customer = { - firstName: getRandomString(4, 15), - lastName: getRandomString(4, 15), - emailAddress: getRandomString(10, 20), - phoneNumber: getRandomInt(1000000000, 9999999999) - }; - const contactInfo = { - firstName: getRandomString(4, 15), - lastName: getRandomString(4, 15), - emailAddress: getRandomString(10, 20), - servicePhone: getRandomInt(1000000000, 9999999999), - requestTextUpdates: getRandomBoolean(), - notesForTechnician: getRandomString(50, 100) - }; - const mainInitialState = { - order: { - customer, - contactInfo - } - }; - const mountOptions = getMountOptions(); - mountOptions.global = { - plugins: [createTestingPinia({ - initialState: { - main: mainInitialState - } - })] - }; - - const wrapper = shallowMount(contactDetails, mountOptions); - - // Assert - expect(wrapper.vm.firstName).toBe(contactInfo.firstName); - expect(wrapper.vm.lastName).toBe(contactInfo.lastName); - expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress); - expect(wrapper.vm.phoneNumber).toBe(contactInfo.servicePhone); - expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates); - expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician); }); }); diff --git a/src/layouts/contact-details/contact-details.vue b/src/layouts/contact-details/contact-details.vue index 7e0b22f1..c28d0d3a 100644 --- a/src/layouts/contact-details/contact-details.vue +++ b/src/layouts/contact-details/contact-details.vue @@ -15,81 +15,92 @@ - - - - + + + v-if="showSameAsPolicyAddressQuestion" + ref="sameAsPolicyAddressQuestion" + v-model="isSameAsPolicyAddress" + checkboxName="sameAsPolicyAddress" + buttonID="sameAsPolicyAddress" + class="form-group same-address-checkbox" + :checkboxLabel="sameAsPolicyAddressQuestionText" /> + + + + + + + + -

- {{ textUpdateDisclaimerText }} I also agree to - Safelite's - - and - . -

diff --git a/src/layouts/order-confirmation/order-confirmation.spec.js b/src/layouts/order-confirmation/order-confirmation.spec.js index 88f9c71c..6a06885a 100644 --- a/src/layouts/order-confirmation/order-confirmation.spec.js +++ b/src/layouts/order-confirmation/order-confirmation.spec.js @@ -79,12 +79,14 @@ const initialStore = { isInsurance: true, paymentMethod: paymentMethods.PAY_AT_TIME_OF_SERVICE }, - contactInfo: { + customer: { firstName: 'Test', lastName: 'Test', - servicePhone: '111-111-1111', emailAddress: 'test@email.com' }, + contactInfo: { + servicePhone: '123-456-7890' + }, damage: { isRepair: false }, @@ -138,7 +140,14 @@ const sessionStorage = { make: 'Honda', model: 'Civic' }, - customer: {}, + customer: { + firstName: 'Test', + lastName: 'Test', + emailAddress: 'test@email.com' + }, + contactInfo: { + servicePhone: '123-456-7890' + }, customerPortalLoginToken: 'token', currentDeductible: { replace: 100, diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index 98edaf23..c3514995 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -373,7 +373,7 @@ export default { ); // Contact Info - const { contactInfo } = useMainStore().order; + const { contactInfo } = useMainStore(); const contactInfoReqs = !!( contactInfo.firstName && contactInfo.lastName diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index e37ce3c9..d1e5641a 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -30,6 +30,8 @@ import { Form } from 'vee-validate'; import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import globalRules from '@/constants/global-rules'; +import bailoutMessage from '@/constants/bailoutMessage'; +import navigationScenarios from '@/router/router-constants/navigation-scenarios'; export default { name: 'part-questions', diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 3dbacbe2..195909ec 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -52,7 +52,7 @@ cmsWidgetName="SiteFooterWidget" :isForwardActionDisabled="!meta.valid" :isStackedVertically="true" - @backClicked="navigateBack" + @backClicked="backButtonAction" @ForwardClicked="forwardButtonAction" />
@@ -230,7 +230,7 @@ export default { const customerReqs = !!(firstName && lastName && emailAddress); // Contact Info - const { contactInfo } = useMainStore().order; + const { contactInfo } = useMainStore(); const contactInfoReqs = !!( contactInfo.firstName && contactInfo.lastName @@ -291,6 +291,15 @@ export default { { [routerParams.SKIP_SAVE_SESSION]: true } ); } + }, + backButtonAction() { + const scenario = this.mainStore.isMobileAppointment + ? this.navigationScenarios.CLICKED_BACK_MOBILE + : this.navigationScenarios.CLICKED_BACK_INSHOP; + this.$router.navigate( + scenario, + this.$route + ); } } }; diff --git a/src/layouts/payment-method/review-dropdown/review-dropdown.vue b/src/layouts/payment-method/review-dropdown/review-dropdown.vue index da2c09cb..d1504da4 100644 --- a/src/layouts/payment-method/review-dropdown/review-dropdown.vue +++ b/src/layouts/payment-method/review-dropdown/review-dropdown.vue @@ -92,7 +92,7 @@ export default { return useMainStore().order.serviceLocation.appointmentType; }, customerInfo() { - return useMainStore().order.contactInfo; + return useMainStore().contactInfo; } }, methods: { diff --git a/src/layouts/payment-page/payment-page.spec.js b/src/layouts/payment-page/payment-page.spec.js index 257a6367..89293dd4 100644 --- a/src/layouts/payment-page/payment-page.spec.js +++ b/src/layouts/payment-page/payment-page.spec.js @@ -182,10 +182,12 @@ const defaultOrder = { }, techNotes: '' }, - contactInfo: { + customer: { firstName: 'first', lastName: 'last', - emailAddress: 'builddigitaltest@safelite.com', + emailAddress: 'builddigitaltest@safelite.com' + }, + contactInfo: { servicePhone: '555-555-5555' }, damage: { diff --git a/src/layouts/payment-page/payment-page.vue b/src/layouts/payment-page/payment-page.vue index 8ac64f7c..7dd6b673 100644 --- a/src/layouts/payment-page/payment-page.vue +++ b/src/layouts/payment-page/payment-page.vue @@ -479,15 +479,15 @@ export default { authSignature: '', authSignatureStart: '', referralSequenceNumber: useMainStore().order.referralSequenceNumber, - emailAddress: useMainStore().order.contactInfo.emailAddress, + emailAddress: useMainStore().contactInfo.emailAddress, address1: this.getAddress1(), address2: this.getAddress2(), city: this.getCity(), state: this.getState(), zipCode: this.getZipCode(), - firstName: useMainStore().order.contactInfo.firstName, - lastName: useMainStore().order.contactInfo.lastName, - phoneNumber: useMainStore().order.contactInfo.servicePhone, + firstName: useMainStore().contactInfo.firstName, + lastName: useMainStore().contactInfo.lastName, + phoneNumber: useMainStore().contactInfo.servicePhone, ctu: useMainStore().order.serviceLocation.provider?.address?.zipCodeCtu ?? useMainStore().order.serviceLocation.zipCodeCtu, referralCorrelationId: useMainStore().order.referralCorrelationId, workOrderNumber: this.getWorkOrderNumber(), @@ -593,7 +593,7 @@ export default { ); // Contact Info - const { contactInfo } = useMainStore().order; + const { contactInfo } = useMainStore(); const contactInfoReqs = !!( contactInfo.firstName && contactInfo.lastName diff --git a/src/layouts/schedule-page/service-location/service-location.vue b/src/layouts/schedule-page/service-location/service-location.vue index ea0911c6..069ec472 100644 --- a/src/layouts/schedule-page/service-location/service-location.vue +++ b/src/layouts/schedule-page/service-location/service-location.vue @@ -372,9 +372,6 @@ export default { } this.mainStore.saveServiceLocation({ - address: this.streetAddress, - address2: this.streetAddress2, - city: this.city, state: this.state, zipCode: this.zipCode, zipCodeCtu: this.zipCodeCtu, @@ -417,6 +414,7 @@ export default { this.zipCode = newZip; const zipCodeData = await getZipCodeData(this.zipCode); this.city = zipCodeData.city; + this.state = zipCodeData.state; this.setCtuForMobile(zipCodeData.zipCodeCtu); this.setContainsMilitaryBase(zipCodeData.containsMilitaryBase); @@ -454,6 +452,7 @@ export default { this.zipContainsMilitaryBase = initialData.zipCodeData.containsMilitaryBase; this.zipCodeCtu = initialData.zipCodeData.zipCodeCtu; this.city = initialData.zipCodeData.city; + this.state = initialData.zipCodeData.state; } if (initialData.serviceabilityDetails) { @@ -523,6 +522,7 @@ export default { this.mobileZipError = errorMessages.NO_SERVICE_IN_AREA(toTitleCase(zipCodeData.city)); } else { this.city = zipCodeData.city; + this.state = zipCodeData.state; this.zipCode = this.mobileZipCode; this.setCtuForMobile(zipCodeData.zipCodeCtu); this.setContainsMilitaryBase(zipCodeData.containsMilitaryBase); @@ -601,12 +601,6 @@ $page-side-padding: 1.5rem; div.alert { margin-top: 0.625rem; - :deep(.alert-header) { - button.btn-collapse { - display: block; - } - } - button.looka-likea-link { background: none; border: none; diff --git a/src/layouts/service-packages/service-packages.vue b/src/layouts/service-packages/service-packages.vue index 692546ce..1bed0a7c 100644 --- a/src/layouts/service-packages/service-packages.vue +++ b/src/layouts/service-packages/service-packages.vue @@ -195,8 +195,12 @@ export default { } store.updateVaps(this.selectedVaps); + const scenario = store.isMobileAppointment + ? this.navigationScenarios.CLICKED_FORWARD_MOBILE + : this.navigationScenarios.CLICKED_FORWARD_INSHOP; + this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD, + scenario, this.$route ); } diff --git a/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js b/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js index 901effe9..04fe6ce6 100644 --- a/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js +++ b/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js @@ -38,10 +38,12 @@ describe('contact-details-drawer', () => { const servicePhone = '606-009-2943'; const mainInitialState = { order: { - contactInfo: { + customer: { firstName, lastName, - emailAddress, + emailAddress + }, + contactInfo: { servicePhone } } @@ -112,10 +114,12 @@ describe('contact-details-drawer', () => { const phoneNumber = '123-456-1234'; const mainInitialState = { order: { - contactInfo: { + customer: { firstName, lastName, - emailAddress, + emailAddress + }, + contactInfo: { phoneNumber } } diff --git a/src/layouts/tpa-submit/tpa-submit.spec.js b/src/layouts/tpa-submit/tpa-submit.spec.js index 63b61c40..11136dd7 100644 --- a/src/layouts/tpa-submit/tpa-submit.spec.js +++ b/src/layouts/tpa-submit/tpa-submit.spec.js @@ -388,10 +388,12 @@ describe('tpa-submit', () => { companyName: providerCompanyName } }, - contactInfo: { + customer: { firstName, lastName, - emailAddress, + emailAddress + }, + contactInfo: { servicePhone } } @@ -433,10 +435,12 @@ describe('tpa-submit', () => { companyName: providerCompanyName } }, - contactInfo: { + customer: { firstName, lastName, - emailAddress, + emailAddress + }, + contactInfo: { servicePhone, extension } diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 6bbc7022..6f17494d 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -90,6 +90,10 @@ const navigationScenarios = Object.freeze({ CLICKED_FORWARD_WITH_TPA_DISABLED: 'CLICKED_FORWARD_WITH_TPA_DISABLED', CLICKED_FORWARD_WITH_POLICY_AND_VEHICLES: 'CLICKED_FORWARD_WITH_POLICY_AND_VEHICLES', + // Service Package + CLICKED_FORWARD_INSHOP: 'CLICKED_FORWARD_INSHOP', + CLICKED_FORWARD_MOBILE: 'CLICKED_FORWARD_MOBILE', + // Review Page CLICKED_CUSTOMER_EDIT: 'CLICKED_CUSTOMER_EDIT', CLICKED_DAMAGE_EDIT: 'CLICKED_DAMAGE_EDIT', @@ -99,6 +103,8 @@ const navigationScenarios = Object.freeze({ CLICKED_VEHICLE_EDIT: 'CLICKED_VEHICLE_EDIT', // Payment + CLICKED_BACK_INSHOP: 'CLICKED_BACK_INSHOP', + CLICKED_BACK_MOBILE: 'CLICKED_BACK_MOBILE', CLICKED_PAY_NOW: 'CLICKED_PAY_NOW', PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR', PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR', diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 42b9ca46..dea1daae 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -608,7 +608,7 @@ const routingTable = () => [ }, { scenario: navigationScenarios.CLICKED_FORWARD, - destinationIssPageValue: issPageValues.CONTACT_DETAILS + destinationIssPageValue: issPageValues.SERVICE_PACKAGES } ] }, @@ -620,12 +620,8 @@ const routingTable = () => [ destinationIssPageValue: issPageValues.SCHEDULE_PAGE }, { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP, - destinationIssPageValue: issPageValues.SERVICE_PACKAGES - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - destinationIssPageValue: issPageValues.TPA_SUBMIT + scenario: navigationScenarios.CLICKED_FORWARD, + destinationIssPageValue: issPageValues.PAYMENT_METHOD } ] }, @@ -634,11 +630,15 @@ const routingTable = () => [ maps: [ { scenario: navigationScenarios.CLICKED_BACK, - destinationIssPageValue: issPageValues.CONTACT_DETAILS + destinationIssPageValue: issPageValues.SCHEDULE_PAGE }, { - scenario: navigationScenarios.CLICKED_FORWARD, + scenario: navigationScenarios.CLICKED_FORWARD_INSHOP, destinationIssPageValue: issPageValues.PAYMENT_METHOD + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_MOBILE, + destinationIssPageValue: issPageValues.CONTACT_DETAILS } ] }, @@ -646,9 +646,13 @@ const routingTable = () => [ issPageValue: issPageValues.PAYMENT_METHOD, maps: [ { - scenario: navigationScenarios.CLICKED_BACK, + scenario: navigationScenarios.CLICKED_BACK_INSHOP, destinationIssPageValue: issPageValues.SERVICE_PACKAGES }, + { + scenario: navigationScenarios.CLICKED_BACK_MOBILE, + destinationIssPageValue: issPageValues.CONTACT_DETAILS + }, { scenario: navigationScenarios.CLICKED_FORWARD, destinationIssPageValue: issPageValues.ORDER_CONFIRMATION diff --git a/src/store/index.js b/src/store/index.js index a29104a6..d74067f7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -191,9 +191,6 @@ export const getDefaultState = () => ({ } }, contactInfo: { - firstName: null, - lastName: null, - emailAddress: null, homePhone: null, alternativePhone: null, servicePhone: null, @@ -358,9 +355,9 @@ export const useMainStore = defineStore({ }; }, contactInfo: (s) => ({ - firstName: s.order.contactInfo.firstName ?? s.order.customer.firstName, - lastName: s.order.contactInfo.lastName ?? s.order.customer.lastName, - emailAddress: s.order.contactInfo.emailAddress ?? s.order.customer.emailAddress, + firstName: s.order.customer.firstName, + lastName: s.order.customer.lastName, + emailAddress: s.order.customer.emailAddress, homePhone: s.order.contactInfo.homePhone, alternativePhone: s.order.contactInfo.alternativePhone, servicePhone: s.order.contactInfo.servicePhone, @@ -1472,9 +1469,9 @@ export const useMainStore = defineStore({ state: customer.address?.state, zipCode: customer.address?.zipCode?.toString() }, - emailAddress: contactInfo.emailAddress || customer.emailAddress, - firstName: contactInfo.firstName || customer.firstName, - lastName: contactInfo.lastName || customer.lastName, + emailAddress: customer.emailAddress, + firstName: customer.firstName, + lastName: customer.lastName, homePhone: contactInfo.extension && contactInfo.homePhone ? contactInfo.homePhone + contactInfo.extension : contactInfo.homePhone, servicePhone: contactInfo.servicePhone, alternativePhone: contactInfo.alternativePhone, @@ -1605,10 +1602,10 @@ export const useMainStore = defineStore({ order.customer.address.city = data.customer?.address?.city; order.customer.address.state = data.customer?.address?.state; order.customer.address.zipCode = data.customer?.address?.zipCode; + order.customer.firstName = data?.customer?.firstName; + order.customer.lastName = data?.customer?.lastName; + order.customer.emailAddress = data?.customer?.emailAddress; - order.contactInfo.firstName = data?.customer?.firstName; - order.contactInfo.lastName = data?.customer?.lastName; - order.contactInfo.emailAddress = data?.customer?.emailAddress; order.contactInfo.extension = data?.customer?.homePhone?.slice(10); order.contactInfo.homePhone = data?.customer?.homePhone?.slice(0, 10); order.contactInfo.servicePhone = data?.customer?.servicePhone; @@ -1673,11 +1670,10 @@ export const useMainStore = defineStore({ order.customer.address.city = data.customer?.address?.city; order.customer.address.state = data.customer?.address?.state; order.customer.address.zipCode = data.customer?.address?.zipCode; - order.customer.emailAddress = data.customer?.emailAddress; + order.customer.firstName = data?.customer?.firstName; + order.customer.lastName = data?.customer?.lastName; + order.customer.emailAddress = data?.customer?.emailAddress; - order.contactInfo.firstName = data?.customer?.firstName; - order.contactInfo.lastName = data?.customer?.lastName; - order.contactInfo.emailAddress = data?.customer?.emailAddress; order.contactInfo.extension = data?.customer?.homePhone?.slice(10); order.contactInfo.homePhone = data?.customer?.homePhone?.slice(0, 10); order.contactInfo.servicePhone = data?.customer?.servicePhone; @@ -1823,27 +1819,29 @@ export const useMainStore = defineStore({ this.order.vehicle.registration.lastName = registrationInfo?.lastName; }, updateServiceLocation(serviceLocationInfo) { - this.order.serviceLocation.address = serviceLocationInfo.address; - this.order.serviceLocation.address2 = serviceLocationInfo.address2; - this.order.serviceLocation.city = serviceLocationInfo.city; - this.order.serviceLocation.state = serviceLocationInfo.state; - this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode; - this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu; - this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType; - this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected; + this.order.serviceLocation.address = serviceLocationInfo.address ?? this.order.serviceLocation.address; + this.order.serviceLocation.address2 = serviceLocationInfo.address2 ?? this.order.serviceLocation.address2; + this.order.serviceLocation.city = serviceLocationInfo.city ?? this.order.serviceLocation.city; + this.order.serviceLocation.state = serviceLocationInfo.state ?? this.order.serviceLocation.state; + this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode ?? this.order.serviceLocation.zipCode; + this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu ?? this.order.serviceLocation.zipCodeCtu; + this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType ?? this.order.serviceLocation.appointmentType; + this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected ?? this.order.serviceLocation.isVehicleProtected; - this.order.serviceLocation.provider = { - providerNumber: serviceLocationInfo.provider?.providerNumber, - address: { - streetAddress: serviceLocationInfo.provider?.address?.streetAddress, - city: serviceLocationInfo.provider?.address?.city, - state: serviceLocationInfo.provider?.address?.state, - zipCode: serviceLocationInfo.provider?.address?.zipCode, - zipCodeCtu: serviceLocationInfo.provider?.address?.zipCodeCtu - }, - companyName: serviceLocationInfo.provider?.companyName, - phoneNumber: serviceLocationInfo.provider?.phoneNumber - }; + if (serviceLocationInfo.provider) { + this.order.serviceLocation.provider = { + providerNumber: serviceLocationInfo.provider?.providerNumber, + address: { + streetAddress: serviceLocationInfo.provider?.address?.streetAddress, + city: serviceLocationInfo.provider?.address?.city, + state: serviceLocationInfo.provider?.address?.state, + zipCode: serviceLocationInfo.provider?.address?.zipCode, + zipCodeCtu: serviceLocationInfo.provider?.address?.zipCodeCtu + }, + companyName: serviceLocationInfo.provider?.companyName, + phoneNumber: serviceLocationInfo.provider?.phoneNumber + }; + } this.order.serviceLocation.searchFilter = serviceLocationInfo.searchFilter; }, @@ -2116,9 +2114,6 @@ export const useMainStore = defineStore({ }, resetContactInfo() { - this.order.contactInfo.firstName = null; - this.order.contactInfo.lastName = null; - this.order.contactInfo.emailAddress = null; this.order.contactInfo.homePhone = null; this.order.contactInfo.alternativePhone = null; this.order.contactInfo.servicePhone = null; @@ -2602,9 +2597,10 @@ export const useMainStore = defineStore({ }, updateContactInfo(contactInfo) { - this.order.contactInfo.firstName = contactInfo?.firstName ?? ''; - this.order.contactInfo.lastName = contactInfo?.lastName ?? ''; - this.order.contactInfo.emailAddress = contactInfo?.emailAddress ?? ''; + this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName; + this.order.customer.lastName = contactInfo?.lastName ?? this.order.customer.lastName; + this.order.customer.emailAddress = contactInfo?.emailAddress ?? this.order.customer.emailAddress; + this.order.contactInfo.requestTextUpdates = contactInfo?.requestTextUpdates ?? false; this.order.contactInfo.notesForTechnician = contactInfo?.notesForTechnician ?? ''; }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 4a035c63..1306221c 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -486,7 +486,7 @@ describe('Store', () => { // Arrange const firstName = getRandomString(4, 10); const lastName = getRandomString(5, 15); - const emailAddress = false; + const emailAddress = getRandomString(5, 15); const requestTextUpdates = getRandomBoolean(); const notesForTechnician = getRandomString(50, 150); @@ -525,14 +525,14 @@ describe('Store', () => { expect(store.contactInfo.alternativePhone).toEqual(altPhone); expect(store.contactInfo.extension).toEqual(extension); }); - it('All null values => contact info set in store to all nulls', () => { + it('All null values => contact info set in store to all null/default', () => { // Act store.updateContactInfo({}); // Assert - expect(store.contactInfo.firstName).toEqual(''); - expect(store.contactInfo.lastName).toEqual(''); - expect(store.contactInfo.emailAddress).toEqual(''); + expect(store.contactInfo.firstName).toEqual(null); + expect(store.contactInfo.lastName).toEqual(null); + expect(store.contactInfo.emailAddress).toEqual(null); expect(store.contactInfo.requestTextUpdates).toEqual(false); expect(store.contactInfo.notesForTechnician).toEqual(''); }); @@ -754,13 +754,13 @@ describe('Store', () => { const contactServicePhone = getRandomString(6, 6); const contactAlternativePhone = getRandomString(6, 6); const requestTextUpdates = getRandomBoolean(); - store.order.contactInfo.firstName = contactFirstName; - store.order.contactInfo.lastName = contactLastName; - store.order.contactInfo.emailAddress = contactEmail; store.order.contactInfo.homePhone = contactHomePhone; store.order.contactInfo.servicePhone = contactServicePhone; store.order.contactInfo.alternativePhone = contactAlternativePhone; store.order.contactInfo.requestTextUpdates = requestTextUpdates; + store.order.customer.firstName = contactFirstName; + store.order.customer.lastName = contactLastName; + store.order.customer.emailAddress = contactEmail; store.order.customer.address.streetAddress = streetAddress; store.order.customer.address.streetAddress2 = streetAddress2; store.order.customer.address.city = city; diff --git a/src/ux-components/alert/alert.vue b/src/ux-components/alert/alert.vue index 1a74bdf9..4d50bc1b 100644 --- a/src/ux-components/alert/alert.vue +++ b/src/ux-components/alert/alert.vue @@ -31,41 +31,44 @@ - - +
+ + +