INSR-7759: Finish adding SMS Opt-In

This commit is contained in:
Alex Humphries 2026-02-18 11:30:04 -05:00
parent b4977cd63c
commit 066362e0f7
2 changed files with 99 additions and 16 deletions

View file

@ -94,6 +94,7 @@
</div> </div>
<cartDropdown <cartDropdown
v-if="showCart" v-if="showCart"
class="cart-dropdown"
:showAsPaid="payment.isPayInAdvance" :showAsPaid="payment.isPayInAdvance"
:readOnly="true" :readOnly="true"
recyclingModalCmsWidgetName="RecycleModal" recyclingModalCmsWidgetName="RecycleModal"
@ -230,7 +231,7 @@ export default {
address: this.appointmentLocation, address: this.appointmentLocation,
inShopDuration: this.inShopAppointmentDuration, inShopDuration: this.inShopAppointmentDuration,
email: this.customerEmail, email: this.customerEmail,
phone: this.contactInfo.servicePhone, phone: this.contactPhone,
workOrderNumber: this.workOrderNumber, workOrderNumber: this.workOrderNumber,
CUSTOMER_PORTAL_URL: applicationConfig.CUSTOMER_PORTAL_URL, CUSTOMER_PORTAL_URL: applicationConfig.CUSTOMER_PORTAL_URL,
CUSTOMER_PORTAL_LOGIN_TOKEN: this.customerPortalLoginToken CUSTOMER_PORTAL_LOGIN_TOKEN: this.customerPortalLoginToken
@ -492,6 +493,13 @@ export default {
widgetFields.TEXT_BLOCK_WIDGET.TEXT widgetFields.TEXT_BLOCK_WIDGET.TEXT
); );
} }
},
contactPhone() {
let phoneNumber = this.contactInfo.servicePhone;
if (this.contactInfo.extension) {
phoneNumber += `-${this.contactInfo.extension}`;
}
return phoneNumber;
} }
}, },
mounted() { mounted() {
@ -718,5 +726,10 @@ export default {
color: $black; color: $black;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
} }
.cart-dropdown:deep(.deductible-value) {
font-size: 1rem;
font-weight: $font-weight-bold;
}
} }
</style> </style>

View file

@ -53,8 +53,9 @@
v-if="!isOptedInSMSPreviously" v-if="!isOptedInSMSPreviously"
class="sms-opt-in-section"> class="sms-opt-in-section">
<hr class="sms-divider" /> <hr class="sms-divider" />
<span class="sms-opt-in-header">{{ smsOptInHeaderText }}</span> <div class="sms-opt-in-header">{{ smsOptInHeaderText }}</div>
<buttonQuestion <buttonQuestion
class="sms-opt-in-question"
v-model="smsOptIn" v-model="smsOptIn"
groupName="sms-opt-in" groupName="sms-opt-in"
buttonTypeString="listButtonHorizontal" buttonTypeString="listButtonHorizontal"
@ -62,14 +63,28 @@
:answers="smsOptinQuestionAnswers" :answers="smsOptinQuestionAnswers"
isRequired isRequired
:validationRules="rules.optionRequired" /> :validationRules="rules.optionRequired" />
<textboxQuestion
v-if="smsOptIn === 'Yes'"
v-model="smsPhoneNumber"
inputId="phoneNumber"
:cmsWidgetName="widget.smsPhoneNumber"
isRequired
:mask="phoneMask"
placeholderText="###-###-####"
disableAutoFill
:validationRules="rules.phoneNumber" />
</div> </div>
<siteFooter <siteFooter
ref="siteFooter" ref="siteFooter"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
:isStackedVertically="true"
@backClicked="backButtonAction" @backClicked="backButtonAction"
@ForwardClicked="forwardButtonAction" /> @ForwardClicked="forwardButtonAction" />
<div
v-if="!isOptedInSMSPreviously"
class="disclaimer">
<textBlock :cmsWidgetName="widget.smsDisclaimer" />
</div>
</div> </div>
</div> </div>
</div> </div>
@ -111,6 +126,8 @@ import { formatAmountInDollars } from '@/helpers/text-helper';
import widgetFields from '@/constants/cms-widget-fields'; import widgetFields from '@/constants/cms-widget-fields';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
import MaskaFormattedMasks from '@/constants/maska-masks';
defineRule('option-required', required(errorMessages.PAYMENT_METHOD_PAGE_OPTION_REQUIRED)); defineRule('option-required', required(errorMessages.PAYMENT_METHOD_PAGE_OPTION_REQUIRED));
@ -126,7 +143,8 @@ export default {
paymentMethodQuestion, paymentMethodQuestion,
alert, alert,
textBlock, textBlock,
buttonQuestion buttonQuestion,
textboxQuestion
}, },
mixins: [baseFormMixin], mixins: [baseFormMixin],
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
@ -159,13 +177,16 @@ export default {
amountDue: 'AmountDueCartHeaderTextWidget', amountDue: 'AmountDueCartHeaderTextWidget',
payAtAppointment: 'PayAtAppointmentTextWidget', payAtAppointment: 'PayAtAppointmentTextWidget',
smsOptInHeader: 'SMSOptInHeaderWidget', smsOptInHeader: 'SMSOptInHeaderWidget',
smsOptInQuestion: 'SMSOptInQuestionWidget' smsOptInQuestion: 'SMSOptInQuestionWidget',
smsPhoneNumber: 'SMSPhoneNumberWidget',
smsDisclaimer: 'SMSDisclaimerWidget'
}, },
rules: { rules: {
optionRequired: globalRules.OPTION_REQUIRED optionRequired: globalRules.OPTION_REQUIRED,
phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`
}, },
smsOptIn: null, smsOptIn: null,
smsPhoneNumber: this.mainStore.contactInfo?.alternativePhone smsPhoneNumber: this.getSMSPhoneFromStore()
}; };
}, },
computed: { computed: {
@ -192,8 +213,8 @@ export default {
return supportsApplePay() ? this.widget.paymentMethodApplePay : this.widget.paymentMethod; return supportsApplePay() ? this.widget.paymentMethodApplePay : this.widget.paymentMethod;
}, },
showCartTotal() { showCartTotal() {
return this.mainStore.isITAC || this.mainStore.isNoComp return this.mainStore.isVerified && (this.mainStore.isITAC || this.mainStore.isNoComp
|| this.mainStore.order.lineItems?.vaps?.length > 0; || this.mainStore.order.lineItems?.vaps?.length > 0);
}, },
cartHeaderText() { cartHeaderText() {
if (this.isPayInAdvanceDisabled) { if (this.isPayInAdvanceDisabled) {
@ -225,6 +246,9 @@ export default {
}, },
smsOptinQuestionAnswers() { smsOptinQuestionAnswers() {
return this.getCmsContent(this.widget.smsOptInQuestion, widgetFields.INPUT_QUESTION_WIDGET.ANSWERS) || []; return this.getCmsContent(this.widget.smsOptInQuestion, widgetFields.INPUT_QUESTION_WIDGET.ANSWERS) || [];
},
phoneMask() {
return MaskaFormattedMasks.PHONE_NUMBER;
} }
}, },
watch: { watch: {
@ -327,11 +351,11 @@ export default {
this.$refs.siteFooter.updateButtonText(newValue); this.$refs.siteFooter.updateButtonText(newValue);
}, },
async forwardButtonAction() { async forwardButtonAction() {
useMainStore().savePaymentMethodChoice(this.paymentMethod); this.mainStore.savePaymentMethodChoice(this.paymentMethod);
if (this.smsOptIn !== null) { const requestTextUpdates = this.smsOptIn === 'Yes';
useMainStore().updateContactInfo({ this.mainStore.updateContactInfo({ requestTextUpdates });
requestTextUpdates: this.smsOptIn === 'Yes' if (requestTextUpdates) {
}); this.mainStore.updatePhoneNumbers({ alternative: this.smsPhoneNumber, service: this.smsPhoneNumber });
} }
if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) { if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) {
try { try {
@ -371,6 +395,9 @@ export default {
scenario, scenario,
this.$route this.$route
); );
},
getSMSPhoneFromStore() {
return useMainStore().contactInfo.servicePhone;
} }
} }
}; };
@ -408,6 +435,7 @@ $page-side-padding: 1.5rem;
p { p {
margin-bottom: 0; margin-bottom: 0;
color: #4d4e53;
} }
} }
} }
@ -425,8 +453,7 @@ $page-side-padding: 1.5rem;
.cart-label { .cart-label {
color: $black; color: $black;
font-weight: 600; font-weight: $font-weight-bold;
line-height: 1.625rem;
} }
.cart-value { .cart-value {
@ -444,6 +471,49 @@ $page-side-padding: 1.5rem;
margin-top: .5rem; margin-top: .5rem;
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
} }
.sms-divider {
margin-top: 1.75rem;
margin-bottom: 1.875rem;
}
.sms-opt-in-section {
margin-bottom: 1.875rem;
}
.sms-opt-in-header {
color: $black;
font-weight: $font-weight-bold;
margin-bottom: 1.125rem;
}
.sms-opt-in-question {
margin-bottom: 1.25rem;
:deep(.question-text) {
margin-bottom: .625rem;
}
}
.disclaimer {
margin-bottom: 1.875rem;
font-weight: $font-weight-light;
font-size: .8125rem;
line-height: 1.54;
color: #4d4e53;
:deep(a) {
color: $heritage-blue-primary;
text-decoration: none;
font-weight: $font-weight-bold;
&:hover,
&:focus {
color: $heritage-blue-secondary;
text-decoration: underline;
}
}
}
} }
} }
</style> </style>