diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 4326a5412..45841f21f 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -18,6 +18,8 @@ const errorMessages = { LAST_NAME_REQUIRED: "Please enter your last name", EMAIL_ADDRESS_REQUIRED: "Please enter your email address", EMAIL_ADDRESS_FORMAT: "Please enter a valid email address", + EMAIL_SMS_REQUIRED: "Please enter your mobile phone number or email", + EMAIL_SMS_FORMAT: "Please enter a valid mobile phone number or email", SERVICE_ZIP_REQUIRED: "Please enter your service ZIP", SERVICE_ZIP_FORMAT: "Please enter a valid service ZIP", VIN_REQUIRED: "Please enter your VIN", diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index ec6b0db0c..833645578 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -1,6 +1,7 @@ const storeActions = { // Content Actions GET_PAGE_DATA: "getPageData", + SAVE_PAGE_DATA: "savePageData", // Vehicle Actions GET_VEHICLE_YEARS: "getVehicleYears", diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 0739a9af6..804ed5608 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -121,9 +121,9 @@ export default { const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers; if (partsOrQuestions) { - partsOrQuestions.forEach(pqa => { + partsOrQuestions.forEach((pqa) => { const payloadPartQuestions = []; - pqa.answeredQuestions.forEach(answer => { + pqa.answeredQuestions.forEach((answer) => { payloadPartQuestions.push({ questionSeq: answer?.questionNum, questionText: answer?.questionText, diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index b74db95dc..18a8b3362 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -23,11 +23,11 @@ @@ -88,16 +88,17 @@ import vinPagesMixin from "@/mixins/vin-pages-mixin"; import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import baseMixin from "@/mixins/base-mixin.js"; import { queryStrings } from "@/constants/query-strings"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Define Validation Rules defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); +defineRule("email-sms-required", required(errorMessages.EMAIL_SMS_REQUIRED)); defineRule( - "email-address-format", + "email-sms-format", regex( - /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/, - errorMessages.EMAIL_ADDRESS_FORMAT + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$|^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/, + errorMessages.EMAIL_SMS_FORMAT ) ); defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,7 +109,7 @@ export default { data() { return { serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode, - emailAddress: this.getEmailFromStore(), + emailOrSms: this.getEmailOrSmsFromStore(), displayInvalidZipAlert: false, displayNonServiceableZipAlert: false, }; @@ -160,11 +161,11 @@ export default { store.getters.order.serviceLocation.zipCode ); }, - getEmailFromStore() { - return ( - store.getters.externalParameterServiceZip.emailAddress ?? - store.getters.order.customer.emailAddress - ); + getEmailOrSmsFromStore() { + return store.getters.emailOrSms; + }, + getPhoneFromStore() { + return store.getters.order.customer.phoneNumber; }, arePagePrerequisitesValid() { return store.getters.damage.isRepair || store.getters.damage.glassToReplace?.length > 0; @@ -186,7 +187,23 @@ export default { }, async forwardButtonAction() { const zipCodeData = await this.getZipCodeData(this.serviceZipCode); - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false); + + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } + + await this.dispatchStoreAction( + storeActions.SAVE_PAGE_DATA, + { + page: fmgPageValues.EMAIL_SMS_PAGES, + data: { emailOrSmsValue: this.emailOrSms }, + }, + false + ); + await this.dispatchStoreAction( storeActions.SAVE_SERVICE_ZIP_CODE_INFO, { diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index 7d15066c5..fc195d910 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -16,6 +16,11 @@ export default { ? "email-address-format" : "email-address-required|email-address-format"; }, + EmailOrSmsValidationRules() { + return this.IsEmailOptional + ? "email-sms-format" + : "email-sms-required|email-sms-format"; + }, }, methods: { async navigateForwardWithSingleCarMatch() { @@ -56,5 +61,9 @@ export default { false ); }, + isPhoneNumber(input) { + const phoneRegex = /^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/; + return phoneRegex.test(input); + }, }, }; diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 5fade6506..1cba0414b 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -23,6 +23,7 @@ const fmgPageValues = { PAYMENT_PIA_RETURN: "payment-pia-return", CONFIRMATION: "confirmation", RETURN_USER: "return-user", + EMAIL_SMS_PAGES: "email-or-sms-related-pages", }; const funnelStartPageName = fmgPageValues.VEHICLE; diff --git a/src/store/index.js b/src/store/index.js index c591d493d..a137dd7ef 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -997,6 +997,26 @@ export const getters = { externalParameterEstimate: (state) => externalParameterState?.estimate, externalParameterCustomer: (state) => externalParameterState?.customer, isExternalParameter: (state) => externalParameterState?.isExternalParameter, + + emailOrSms: (state) => { + const email = externalParameterState.serviceZip.emailAddress ?? state.order.customer.emailAddress; + const phone = state.order.customer.phoneNumber; + + if (!phone && !email) { + return null; + } + + if (phone && !email) { + return phone; + } + + if (email && !phone) { + return email; + } + + // if we're here, then we have both email and phone so get the value from pageData to reflect what they entered on the page + return state.applicationUser.pageData[fmgPageValues.EMAIL_SMS_PAGES]?.emailOrSmsValue; + }, }; function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { @@ -3042,7 +3062,14 @@ export const actions = { }, savePhoneNumber(context, phoneNumber) { - context.commit(storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, phoneNumber === "" ? null : phoneNumber); + context.commit( + storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, + phoneNumber === "" ? null : phoneNumber + ); + }, + + savePageData(context, emailOrSms) { + context.commit(storeMutations.UPDATE_PAGE_DATA, emailOrSms); }, saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) {