diff --git a/src/digital-components/modal/modal.vue b/src/digital-components/modal/modal.vue index e337a7bb..24dfeb02 100644 --- a/src/digital-components/modal/modal.vue +++ b/src/digital-components/modal/modal.vue @@ -257,6 +257,9 @@ export default { border-radius: 1.5rem; overflow: auto; } + .modal-header { + justify-content: center; + } } } &.show .modal-dialog { diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index 70149cad..855a7d4d 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -16,7 +16,8 @@ class="input-wrapper" :class="[ includeSearchIcon ? 'has-search-icon' : '', - includeSelectIcon ? 'has-select-icon' : '' + includeSelectIcon ? 'has-select-icon' : '', + hasTextButton ? 'has-text-button' : '' ]"> + +
import { useField, validate } from 'vee-validate'; import { extractSpanText } from '@/helpers/text-helper'; +import buttonMain from '@/ux-components/button-main/button-main.vue'; export default { name: 'textbox-question', + components: { + buttonMain + }, props: { type: { type: String, @@ -118,7 +130,11 @@ export default { includeSelectIcon: Boolean, min: String, max: String, - disableAutoFill: Boolean + disableAutoFill: Boolean, + buttonCallback: { + type: Function, + default: () => {} + } }, emits: ['focus', 'update:modelValue', 'textboxQuestionEvent.inputIdAssigned', 'click-event'], setup(props) { @@ -161,6 +177,12 @@ export default { questionTextForAria() { return extractSpanText(this.getCmsContent(this.cmsWidgetName, 'QuestionText')); }, + buttonText() { + return this.getCmsContent(this.cmsWidgetName, 'ButtonText'); + }, + hasTextButton() { + return this.buttonText && this.buttonText.length > 0; + }, value: { get() { return this.modelValue; @@ -318,6 +340,12 @@ input::-webkit-date-and-time-value { display: flex; } } + &.has-text-button { + display: flex; + input[type='text'] { + border-radius: 1.5rem; + } + } } input { &.has-icon { diff --git a/src/iss-components/shop-list-button/shop-list-button.vue b/src/iss-components/shop-list-button/shop-list-button.vue index 041fa184..44812a90 100644 --- a/src/iss-components/shop-list-button/shop-list-button.vue +++ b/src/iss-components/shop-list-button/shop-list-button.vue @@ -5,7 +5,7 @@ + buttonWrapperClasses="list-group base-input-button list-button rounded-3 d-flex flex-column w-100 no-hover">
@@ -15,9 +15,10 @@ class="m-0 button-label-copy" :class="textPosition">{{ buttonLabel }} + {{ buttonLabelSubCopy }}
@import "@/styles/ux-variables-svg-strings.scss"; +$heritage-border-radius: 60px; +$heritage-border-color: #CACBCC; +$heritage-box-shadow: 0 1px 5px rgba($black, 0.2); +$heritage-checked-background-color: #e7f1f6; +$heritage-checked-border-color: #0070d1; .list-button { - outline: none; - input[type="radio"], - input[type="checkbox"] { - position: static; //override bootstrap - - &:focus-visible + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } - &:focus + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } - &:checked + .list-button-content { - color: $black; - font-weight: 500; - background: $blue-100; - box-shadow: 0 0 0 1px $blue; - } - &:checked:focus + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } - &:checked + .list-button-content p, - &:checked + .list-button-content span { - font-weight: 500; - } - } + outline: none; + input[type="radio"], + input[type="checkbox"] { + position: static; //override bootstrap + &:checked + .list-button-content { + background: $heritage-checked-background-color; + border-color: $heritage-checked-border-color; + .button-label-copy { + font-weight: 500; + color: $black; + } + } + &:focus:checked + .list-button-content { + border-width: 2.5px; + } + } } .list-button-content { - color: $gray-600; - position: relative; - background: $white; - transition: all 150ms linear; - border-radius: $border-radius-lg; - border: 1px solid $gray-500; - width: 100%; - outline: none; - - span { - &.small { - font-size: 0.75rem; - color: $gray-550; - } - } + color: $darker-gray; + font-weight: $font-weight-normal; + position: relative; + background: $white; + transition: all 150ms linear; + border-radius: $heritage-border-radius; + border: 1px solid $heritage-border-color; + box-shadow: $heritage-box-shadow; + width: 100%; + outline: none; + margin-bottom: .625rem; + height: 4.375rem; } .button-content { - row-gap: 0.25rem; + row-gap: 0.25rem; - .row-one { - display: flex; - align-items: center; - line-height: 1.5rem; + .row-one { + display: flex; + align-items: center; + justify-content: center; + line-height: 1.5rem; - .button-label-copy { - font-weight: 500; - } + .separator { + height: 1.25rem; + margin: 0rem .3125rem; + border-left: 1px solid $heritage-border-color; + } - .availability-indicator { - background-repeat: no-repeat; - display: flex; - align-items: center; - margin-left: auto; - padding: 0.125rem 0.5rem; + .availability-indicator { + background-repeat: no-repeat; + display: flex; + align-items: center; + margin-left: auto; + padding: 0.125rem 0.5rem; - .availability-badge { - display: inline-flex; - width: 13px; - height: 12px; - background-position: center; - background-repeat: no-repeat; - margin: 0 0.25rem 0 0; + .availability-badge { + display: inline-flex; + width: 13px; + height: 12px; + background-position: center; + background-repeat: no-repeat; + margin: 0 0.25rem 0 0; - &.green { - background-image: url($svg-shop-list-button-green-availability); - } + &.green { + background-image: url($svg-shop-list-button-green-availability); + } - &.orange { - background-image: url($svg-shop-list-button-orange-availability); - } - } - .button-auxillary-copy { - box-sizing: border-box; - justify-content: right; - line-height: 1.25rem; - font-weight: 500; - font-size: 0.75rem; - align-items: center; - } + &.orange { + background-image: url($svg-shop-list-button-orange-availability); + } + } + .button-auxillary-copy { + box-sizing: border-box; + justify-content: right; + line-height: 1.25rem; + font-weight: 500; + font-size: 0.75rem; + align-items: center; + } - &.green { - color: $green-700; - background-color: $green-100; - } + &.green { + color: $green-700; + background-color: $green-100; + } - &.orange { - color: $orange-600; - background-color: $orange-100; - } + &.orange { + color: $orange-600; + background-color: $orange-100; + } - &.gray { - color: $gray-600; - background-color: $gray-100; - padding-left: 0.125rem; - padding-right: 0.125rem; - } - } - } + &.gray { + color: $gray-600; + background-color: $gray-100; + padding-left: 0.125rem; + padding-right: 0.125rem; + } + } + } - .row-two { - text-align: left; - } + .row-two { + text-align: center; + } } diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index deddc2a1..5fe675da 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -77,6 +77,7 @@ @updated-mobile-ctu="setCtuForMobile" /> 0) { + let foundMatch = false; + if(this.selectedProvider && this.selectedProvider.providerNumber) { + const matchedProvider = providers.shopProviders.find( + (provider) => provider.providerNumber === this.selectedProvider.providerNumber + ); + if (matchedProvider) { + foundMatch = true; + this.selectedProvider = matchedProvider; + } + } + if(providers.shopProviders.length > 0 && !foundMatch) { this.selectedProvider = providers.shopProviders[0]; } } diff --git a/src/layouts/service-location/service-zip-question/service-zip-question.vue b/src/layouts/service-location/service-zip-question/service-zip-question.vue index 478ab789..dc5224a3 100644 --- a/src/layouts/service-location/service-zip-question/service-zip-question.vue +++ b/src/layouts/service-location/service-zip-question/service-zip-question.vue @@ -1,14 +1,13 @@ @@ -31,21 +30,32 @@ export default { }, // TODO: Correct prop def. props: { - modelValue: { - serviceZipCode: String - }, + modelValue: String, cmsWidgetName: String }, + data() { + return { + internalZipcode: this.modelValue + } + }, emits: ['update:modelValue'], - computed: { - value: { - get() { - return this.modelValue; - }, - set(newValue) { - this.$emit('update:modelValue', newValue); - } + methods: { + updateModelValue() { + this.$emit('update:modelValue', this.internalZipcode); + }, + }, + watch: { + modelValue(newValue) { + this.internalZipcode = newValue; } } }; + diff --git a/src/layouts/service-location/shop-address/shop-address.vue b/src/layouts/service-location/shop-address/shop-address.vue index 2989e0da..a44e6f62 100644 --- a/src/layouts/service-location/shop-address/shop-address.vue +++ b/src/layouts/service-location/shop-address/shop-address.vue @@ -17,11 +17,11 @@
{{ displayedShopName }} - {{ modelValue.distanceInMiles.toFixed(2) }} mi + {{ modelValue.distanceInMiles?.toFixed(2) }} mi
-
{{ toTitleCase(modelValue.address.streetAddress) }}
+
{{ toTitleCase(modelValue.address?.streetAddress) }}
- {{ toTitleCase(modelValue.address.city) }}, {{ modelValue.address.state }} {{ modelValue.address.zipCode }} + {{ toTitleCase(modelValue.address?.city) }}, {{ modelValue.address?.state }} {{ modelValue.address?.zipCode }}
+ + {{ serviceZipPrompt }} + null }, + serviceZipcode: String, cmsWidgetName: String, validationRules: String, isDisplayed: Boolean, @@ -109,13 +113,13 @@ export default { toTitleCase, serviceZipCodeTextInputId: '', displayInvalidZipAlert: false, - internalZipcode: this.modelValue.address.zipCode, + internalZipcode: this.serviceZipcode, internalProviderNumber: this.modelValue.providerNumber, textboxQuestionWidgetName: 'ChangeLocationZipQuestionWidget', alertInvalidZipWidgetName: 'AlertInvalidZipWidget', shopListButton: markRaw(shopListButton), searchRadiusInMiles: 25, - nearbyShops: this.getNearbyShops(25) + nearbyShops: [] }; }, emits: ['update:modelValue'], @@ -150,18 +154,37 @@ export default { const formattedEndDate = endDate.toISOString().split('T')[0]; return { - displayAvailabilityIndicators: true, + displayAvailabilityIndicators: false, availabilityRatingCallback: getAvailabilityRating, startDate: formattedStartDate, endDate: formattedEndDate, shopAppointmentType: this.selectedAppointmentType }; + }, + serviceZipPrompt() { + return this.getCmsContent(this.modalWidgetName, 'BodyText2'); + }, + nearbyShopsData() { + return this.nearbyShops.map((shopProvider) => { + const streetAddress = toTitleCase(shopProvider.address.streetAddress); + const city = toTitleCase(shopProvider.address.city); + const { state } = shopProvider.address; + const { zipCode } = shopProvider.address; + const distanceInMiles = shopProvider.distanceInMiles.toFixed(2); + + return { + buttonLabel: city, + buttonLabelSubCopy: `${distanceInMiles} mi`, + buttonBodyCopy: `${streetAddress}, ${city}, ${state} ${zipCode}`, + value: shopProvider.providerNumber + }; + }); } }, watch: { - internalZipcode(newZipcode) { + internalZipcode() { this.resetsOnZipInput(); - }, + } }, methods: { resetAlerts() { @@ -171,10 +194,6 @@ export default { this.resetAlerts(); this.nearbyShops = await this.getNearbyShops(this.searchRadiusInMiles); }, - focusOnZipInput() { - const input = document.getElementById(this.serviceZipCodeTextInputId); - input?.focus(); - }, openModal() { this.$refs[this.modalName].openModal(); }, @@ -185,39 +204,29 @@ export default { this.serviceZipCodeTextInputId = inputId; }, onModalOpened() { - this.internalZipcode = this.modelValue.address.zipCode; - this.internalProviderNumber = this.modelValue.providerNumber; - this.focusOnZipInput(); + this.internalZipcode = this.serviceZipcode; + this.resetsOnZipInput().then(() => { + this.internalProviderNumber = this.nearbyShops[0]?.providerNumber; + }); }, onModalClosed() { - this.internalZipcode = this.modelValue.address.zipCode; - this.internalProviderNumber = this.modelValue.providerNumber; - this.resetsOnZipInput(); + this.internalZipcode = this.serviceZipcode; + this.resetsOnZipInput().then(() => { + this.internalProviderNumber = this.nearbyShops[0]?.providerNumber; + }); }, async updateSelectedProvider() { - // TODO: Do something with the zipcode? + if (this.internalProviderNumber !== this.modelValue.providerNumber) { + const selectedShop = this.nearbyShops.find(shop => shop.providerNumber === this.internalProviderNumber); + if (selectedShop) { + this.$emit('update:modelValue', selectedShop); + } + } + this.closeModal(); }, async getNearbyShops(radiusInMiles) { const result = await useMainStore().getProviders(this.internalZipcode, radiusInMiles); - - const mappedData = result.data.shopProviders.map((shopProvider) => { - const streetAddress = toTitleCase(shopProvider.address.streetAddress); - const city = toTitleCase(shopProvider.address.city); - const { state } = shopProvider.address; - const { zipCode } = shopProvider.address; - const distanceInMiles = Math.round(shopProvider.distanceInMiles * 2) / 2; - - return { - buttonLabel: city, - buttonLabelSubCopy: `${distanceInMiles} mi`, - buttonBodyCopy: `${streetAddress}, ${city}, ${state} ${zipCode}`, - value: shopProvider.providerNumber - }; - }); - - console.log('Internal provider number after getting shops:', this.internalProviderNumber); - - return mappedData; + return result.data.shopProviders; } } }; @@ -227,6 +236,7 @@ export default { @import "@/styles/ux-variables-svg-strings.scss"; .shop-address { .address-header { + color: $black; font-weight: 600; margin-bottom: 0.625rem; } @@ -242,6 +252,14 @@ export default { :deep(.modal-title) { font-weight: 400; display: block; + width: fit-content; + } + .radioQuestion { + margin-bottom: .625rem; + } + .service-zip-prompt { + color: $black; + font-weight: 600; } } diff --git a/src/store/index.js b/src/store/index.js index ef1b7f52..00995f29 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1798,6 +1798,7 @@ export const useMainStore = defineStore({ this.order.vehicle.registration.lastName = registrationInfo?.lastName; }, updateServiceLocation(serviceLocationInfo) { + console.log('Updating service location info:', serviceLocationInfo); this.order.serviceLocation.address = serviceLocationInfo.address; this.order.serviceLocation.address2 = serviceLocationInfo.address2; this.order.serviceLocation.city = serviceLocationInfo.city; @@ -2707,6 +2708,7 @@ export const useMainStore = defineStore({ }, saveServiceLocation(serviceLocationInfo) { + console.log('Saving service location info:', serviceLocationInfo); if (this.order.serviceLocation) { if ( serviceLocationInfo.zipCode !== this.order.serviceLocation.zipCode @@ -2717,6 +2719,7 @@ export const useMainStore = defineStore({ || serviceLocationInfo.appointmentType !== this.order.serviceLocation.appointmentType ) { + console.log('Service location info has changed, resetting dependent state.'); this.resetSchedule(); } } diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss index 56bd5bad..206716b6 100644 --- a/src/styles/ux-variables.scss +++ b/src/styles/ux-variables.scss @@ -70,6 +70,10 @@ $orange: #fd7e14; $teal: #20c997; $cyan: #0dcaf0; +//Heritage +$heritage-blue-primary: #0070D1; +$heritage-blue-secondary: #167cac; + // Darker gray $darker-gray: #525656; @@ -145,7 +149,7 @@ $font-weight-lighter: lighter; $font-weight-light: 300; $font-weight-normal: 400; $font-weight-bold: 500; -$font-weight-bolder: 600; +$font-weight-bolder: bolder; //Border Radius @@ -217,8 +221,4 @@ $enable-important-utilities: false; $letter-spacing-primary: 0.03em; // Borders $border-input: 1px solid rgba(179, 180, 181); -$border-input-focus: 2.5px solid $blue; - -//Heritage -$heritage-blue-primary: #0070D1; -$heritage-blue-secondary: #167cac; \ No newline at end of file +$border-input-focus: 2.5px solid $heritage-blue-primary; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index 942d2154..c3566b68 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -87,15 +87,18 @@ $heritage-checked-border-color: #0070d1; &:checked + .list-button-content { background: $heritage-checked-background-color; border-color: $heritage-checked-border-color; - box-shadow: 0 0 0 1px $blue; &:not(.has-sub-copy) { font-weight: 500; + color: $black; } } &:checked + .list-button-content span:nth-child(2) { font-weight: 400; color: $gray-600; } + &:focus:checked + .list-button-content { + border-width: 2.5px; + } } } .list-button-content { @@ -110,9 +113,12 @@ $heritage-checked-border-color: #0070d1; width: 100%; outline: none; margin-bottom: .625rem; + height: 4.375rem; &:not(.has-sub-copy) { font-weight: 400; + height: 2.8125rem; + color: $darker-gray; } span {