Merge branch 'develop' into feature/humphries/INSR-7760

This commit is contained in:
Alex Humphries 2026-02-26 15:26:21 -05:00
commit 3a5e1b5021
11 changed files with 209 additions and 80 deletions

View file

@ -29,7 +29,10 @@ export default {
} }
}, },
async beforeMount() { async beforeMount() {
await this.createMapWithMarkersForAddresses(this.markers); await this.createMapWithMarkersForAddresses(this.markers)
.catch(() => {
console.error('Error creating map with markers: if handled jest fails to run tests');
});
}, },
methods: { methods: {
async getMap(center) { async getMap(center) {

View file

@ -330,6 +330,30 @@ describe('contactDetails.vue', () => {
navigate: jest.fn() navigate: jest.fn()
} }
}); });
const provider = {
address: {
city: getRandomString(4, 20),
state: getRandomString(2, 2),
streetAddress: getRandomString(10, 50),
zipCode: getRandomInt(10000, 99999).toString(),
zipCodeCtu: getRandomInt(10000, 99999).toString()
},
companyName: getRandomString(5, 15),
phoneNumber: getRandomInt(1000000000, 9999999999).toString(),
providerNumber: getRandomInt(100000, 999999).toString()
}
const mainInitialState = {
order: {
serviceLocation: {
provider
}
}
};
mountOptions.global.plugins = [createTestingPinia({
initialState: {
main: mainInitialState
}
})];
const wrapper = shallowMount(contactDetails, mountOptions); const wrapper = shallowMount(contactDetails, mountOptions);
const address = getRandomString(10, 50); const address = getRandomString(10, 50);
const address2 = getRandomString(0, 50); const address2 = getRandomString(0, 50);
@ -354,7 +378,8 @@ describe('contactDetails.vue', () => {
address, address,
address2, address2,
city, city,
isVehicleProtected isVehicleProtected,
provider
}); });
}); });

View file

@ -245,11 +245,14 @@ export default {
}; };
useMainStore().updateContactInfo(contactInfo); useMainStore().updateContactInfo(contactInfo);
const provider = useMainStore().serviceLocation.provider;
useMainStore().updateServiceLocation({ useMainStore().updateServiceLocation({
address: this.address, address: this.address,
address2: this.address2, address2: this.address2,
city: this.city, city: this.city,
isVehicleProtected: this.isVehicleProtected || 'false' isVehicleProtected: this.isVehicleProtected || 'false',
provider
}); });
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route); this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);

View file

@ -20,6 +20,7 @@
:schedulingInshopAvailabilityRating="inShopAvailabilityRating" :schedulingInshopAvailabilityRating="inShopAvailabilityRating"
@appointmentTypeChanged="appointmentTypeChangedFromServiceLocation" @appointmentTypeChanged="appointmentTypeChangedFromServiceLocation"
@cityUpdated="cityUpdatedFromServiceLocation" @cityUpdated="cityUpdatedFromServiceLocation"
@clearMobileData="clearMobileDataFromServiceLocation"
@inShopZipUpdated="inShopZipUpdatedFromServiceLocation" @inShopZipUpdated="inShopZipUpdatedFromServiceLocation"
@mobileZipUpdated="mobileZipUpdatedFromServiceLocation" @mobileZipUpdated="mobileZipUpdatedFromServiceLocation"
@providerChanged="providerChangedFromServiceLocation" /> @providerChanged="providerChangedFromServiceLocation" />
@ -89,9 +90,8 @@ import {
import settleAllPromises from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import showIssLoadingModal from '@/helpers/loading-modal-helper.js'; import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
import { import {
getProviderData, getPricedMobileFeePart,
getZipCodeData, getZipCodeData
onProviderChanged
} from '@/helpers/service-location-helper'; } from '@/helpers/service-location-helper';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
@ -225,9 +225,16 @@ export default {
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
// Call APIs // Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const { isMobileAppointment, storeServiceLocation, storeSelectedProvider, serviceZipCode } = getProviderData(); const storeServiceLocation = useMainStore().order.serviceLocation;
const storeSelectedAppointmentType = storeServiceLocation?.appointmentType;
const isMobileAppointment = storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE
|| storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
const storeSelectedProvider = storeServiceLocation?.provider;
const serviceZipCode = storeServiceLocation?.zipCode || useMainStore().order.customer.address.zipCode;
const zipCodeData = getZipCodeData(serviceZipCode); const zipCodeData = getZipCodeData(serviceZipCode);
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode);
const serviceabilityDetailsPromise = useMainStore().getServiceabilityDetails(serviceZipCode); const serviceabilityDetailsPromise = useMainStore().getServiceabilityDetails(serviceZipCode);
const getGlassFeesPromise = useMainStore().getGlassFees();
const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode, 150); const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode, 150);
const premiumFeePromise = useMainStore().getMobilePremiumFee(); const premiumFeePromise = useMainStore().getMobilePremiumFee();
@ -244,6 +251,14 @@ export default {
resultKey: 'cmsContent', resultKey: 'cmsContent',
promise: cmsContentPromise promise: cmsContentPromise
}, },
{
resultKey: 'mobileFeePart',
promise: mobileFeePartPromise
},
{
resultKey: 'glassFees',
promise: getGlassFeesPromise
},
{ {
resultKey: 'serviceabilityDetails', resultKey: 'serviceabilityDetails',
promise: serviceabilityDetailsPromise promise: serviceabilityDetailsPromise
@ -256,10 +271,6 @@ export default {
resultKey: 'providers', resultKey: 'providers',
promise: providersPromise promise: providersPromise
}, },
{
resultKey: 'providerChanged',
promise: onProviderChanged()
},
{ {
resultKey: 'premiumFeeWithPrice', resultKey: 'premiumFeeWithPrice',
promise: premiumFeeWithPricePromise promise: premiumFeeWithPricePromise
@ -319,8 +330,10 @@ export default {
return { return {
inShopAvailabilityRating: 'high', inShopAvailabilityRating: 'high',
inShopDatesData: [], inShopDatesData: [],
isDatePickerRefreshing: false,
isMobileView: false, isMobileView: false,
mobileDatesData: [], mobileDatesData: [],
mobileFeePart: null,
mobilePremiumAppointmentFee: null, mobilePremiumAppointmentFee: null,
mobileProviderNumber: null, mobileProviderNumber: null,
selectableDatesData: [], selectableDatesData: [],
@ -341,14 +354,18 @@ export default {
return false; return false;
} }
const validMobileAppointmentType = ((this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
&& serviceLocationToUse.mobileProviderNumber);
const validInShopAppointmentType = ((this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP
|| this.selectedAppointmentType === AppointmentTypeStrings.DROP_OFF)
&& (this.selectedProvider?.providerNumber || serviceLocationToUse.provider?.providerNumber));
const serviceLocationPreReqs = serviceLocationToUse.zipCode !== null const serviceLocationPreReqs = serviceLocationToUse.zipCode !== null
&& serviceLocationToUse.zipCodeCtu !== null && serviceLocationToUse.zipCodeCtu !== null
&& serviceLocationToUse.appointmentType !== null && serviceLocationToUse.appointmentType !== null
&& (((this.selectedAppointmentType === AppointmentTypeStrings.MOBILE && (validMobileAppointmentType || validInShopAppointmentType)
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) && !this.isDatePickerRefreshing;
&& serviceLocationToUse.mobileProviderNumber)
|| ((this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP || this.selectedAppointmentType === AppointmentTypeStrings.DROP_OFF)
&& (this.selectedProvider?.providerNumber || serviceLocationToUse.provider?.providerNumber)));
const damageInfo = useMainStore().order.damage.isRepair const damageInfo = useMainStore().order.damage.isRepair
|| (useMainStore().order.lineItems?.glassParts != null && useMainStore().order.lineItems.glassParts.length > 0); || (useMainStore().order.lineItems?.glassParts != null && useMainStore().order.lineItems.glassParts.length > 0);
@ -453,6 +470,14 @@ export default {
cityUpdatedFromServiceLocation(newCity) { cityUpdatedFromServiceLocation(newCity) {
this.selectedServiceLocationCity = newCity; this.selectedServiceLocationCity = newCity;
}, },
clearMobileDataFromServiceLocation() {
if (this.selectedServiceLocation) {
this.selectedServiceLocation.mobileProviderNumber = null;
}
this.mobileDatesData = [];
this.mobileProviderNumber = null;
this.selectedMobileZipCode = null;
},
dateSelectedFromPicker(date) { dateSelectedFromPicker(date) {
this.selectedDate = date; this.selectedDate = date;
this.showDatePickerError = false; this.showDatePickerError = false;
@ -647,9 +672,7 @@ export default {
} }
}, },
mobileZipUpdatedFromServiceLocation(mobileZipServiceLocation) { mobileZipUpdatedFromServiceLocation(mobileZipServiceLocation) {
if (mobileZipServiceLocation if (mobileZipServiceLocation) {
&& (this.mobileProviderNumber !== mobileZipServiceLocation.mobileProviderNumber
|| !this.hasNeededServiceLocationData)) {
this.mobileProviderNumber = mobileZipServiceLocation.mobileProviderNumber; this.mobileProviderNumber = mobileZipServiceLocation.mobileProviderNumber;
this.selectedMobileZipCode = mobileZipServiceLocation.zipCode; this.selectedMobileZipCode = mobileZipServiceLocation.zipCode;
this.selectedServiceLocation = mobileZipServiceLocation; this.selectedServiceLocation = mobileZipServiceLocation;
@ -661,22 +684,27 @@ export default {
}, },
async providerChangedFromServiceLocation(newProvider) { async providerChangedFromServiceLocation(newProvider) {
this.selectedProvider = newProvider?.provider; this.selectedProvider = newProvider?.provider;
if (newProvider?.provider) { if (newProvider?.refreshDatePicker && newProvider.provider) {
this.mainStore.updateServiceLocation(newProvider); this.mainStore.updateServiceLocationProvider(newProvider.provider);
showIssLoadingModal(true); showIssLoadingModal(true);
await onProviderChanged(); await this.mainStore.getBillToInfo(newProvider.provider?.providerNumber)
if (newProvider.refreshDatePicker) { .then(() => {
await this.refreshDatePicker(); this.refreshDatePicker();
} else { })
showIssLoadingModal(false); .catch(() => {
} console.warn('Error fetching bill to info...');
showIssLoadingModal(false);
});
} }
}, },
async refreshDatePicker() { async refreshDatePicker() {
this.resetLocalFlags(); this.resetLocalFlags();
this.isDatePickerRefreshing = true;
await this.getDatePickerInitialData().then((data) => { await this.getDatePickerInitialData().then((data) => {
this.selectableDatesData = data.initialShopTimeSlotsResponse; this.selectableDatesData = data.initialShopTimeSlotsResponse;
this.$refs.datePicker.initializeComponent(data); this.$refs.datePicker.initializeComponent(data);
this.isDatePickerRefreshing = false;
showIssLoadingModal(false); showIssLoadingModal(false);
}); });
}, },
@ -700,7 +728,7 @@ export default {
appointmentTypeToUse = AppointmentTypeStrings.DROP_OFF; appointmentTypeToUse = AppointmentTypeStrings.DROP_OFF;
} }
this.mainStore.updateAppointmentType(appointmentTypeToUse); await this.$refs.serviceLocation.forwardButtonAction(appointmentTypeToUse);
this.mainStore.saveSchedule(this.selectedTimeSlotInfo.timeSlot); this.mainStore.saveSchedule(this.selectedTimeSlotInfo.timeSlot);
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD, this.navigationScenarios.CLICKED_FORWARD,

View file

@ -203,7 +203,7 @@ describe('service-location.vue', () => {
const newMobileServiceZipCode = '45433'; const newMobileServiceZipCode = '45433';
// Act // Act
mobileServiceZipCodeQuestion.vm.$emit('update:modelValue', newMobileServiceZipCode); mobileServiceZipCodeQuestion.vm.$emit('service-zip-code-updated', newMobileServiceZipCode);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Assert // Assert

View file

@ -96,13 +96,14 @@
</div> </div>
<serviceZipQuestion <serviceZipQuestion
ref="mobileServiceZipCodeQuestion" ref="mobileServiceZipCodeQuestion"
v-model="mobileZipCode"
customInputId="mobileServiceZipCode" customInputId="mobileServiceZipCode"
class="mobile-service-zip-question" class="mobile-service-zip-question"
:parentZipCode="mobileZipCode"
:placeholderText="mobileZipPlaceholder" :placeholderText="mobileZipPlaceholder"
:serviceZipFormatErrorMessage="errorMessages.MOBILE_SERVICE_ZIP_FORMAT" :serviceZipFormatErrorMessage="errorMessages.MOBILE_SERVICE_ZIP_FORMAT"
:hasError="mobileZipError !== ''" :hasError="mobileZipError !== ''"
cmsWidgetName="MobileZipWidget" /> cmsWidgetName="MobileZipWidget"
@serviceZipCodeUpdated="handleServiceZipCodeChanged" />
<div <div
v-if="mobileZipError" v-if="mobileZipError"
ref="errorMessageDiv" ref="errorMessageDiv"
@ -157,7 +158,7 @@ export default {
serviceZipQuestion serviceZipQuestion
}, },
mixins: [baseFormMixin], mixins: [baseFormMixin],
emits: ['appointment-type-changed', 'city-updated', 'in-shop-zip-updated', 'mobile-zip-updated', 'provider-changed'], emits: ['appointment-type-changed', 'city-updated', 'clear-mobile-data', 'in-shop-zip-updated', 'mobile-zip-updated', 'provider-changed'],
props: { props: {
schedulingInshopAvailabilityRating: { schedulingInshopAvailabilityRating: {
type: String, type: String,
@ -182,6 +183,7 @@ export default {
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
selectedAppointmentType: this.getSelectedAppointmentType(), selectedAppointmentType: this.getSelectedAppointmentType(),
selectedProvider: this.getSelectedProvider(), selectedProvider: this.getSelectedProvider(),
mobileFeePart: null,
mobileProviderNumber: null, mobileProviderNumber: null,
zipContainsMilitaryBase: false, zipContainsMilitaryBase: false,
zipCodeCtu: null, zipCodeCtu: null,
@ -236,7 +238,8 @@ export default {
); );
}, },
isMobile() { isMobile() {
return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE; return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
}, },
isServiceableInshop() { isServiceableInshop() {
if (this.isRecalibrationServiceableInshop !== null) { if (this.isRecalibrationServiceableInshop !== null) {
@ -298,16 +301,7 @@ export default {
}, },
async mobileZipCode(newZip, oldZip) { async mobileZipCode(newZip, oldZip) {
if (newZip !== '' && newZip !== oldZip && !this.initializingData) { if (newZip !== '' && newZip !== oldZip && !this.initializingData) {
showIssLoadingModal(true); await this.processMobileZipCodeChange();
await this.updateMobileZip();
const updateMobileZipServiceLocationObj = {
mobileProviderNumber: this.mobileProviderNumber,
provider: null,
refreshDatePicker: true,
zipCode: this.zipCode,
zipCodeCtu: this.zipCodeCtu
};
this.$emit('mobile-zip-updated', updateMobileZipServiceLocationObj);
} }
}, },
schedulingInshopAvailabilityRating(newRating) { schedulingInshopAvailabilityRating(newRating) {
@ -339,27 +333,16 @@ export default {
} }
}, },
selectedProvider(newProvider, oldProvider) { selectedProvider(newProvider, oldProvider) {
if (newProvider?.providerNumber !== oldProvider?.providerNumber) { if (newProvider?.providerNumber !== oldProvider?.providerNumber || this.availabilityRating === null) {
const appointmentIsInshop = this.isInshop; const appointmentIsInshop = this.isInshop;
const returnedProvider = { const returnedProvider = {
refreshDatePicker: appointmentIsInshop && oldProvider?.providerNumber !== null, provider: newProvider,
state: this.state, refreshDatePicker: appointmentIsInshop && oldProvider?.providerNumber !== null
zipCode: this.zipCode,
zipCodeCtu: this.zipCodeCtu,
appointmentType: this.selectedAppointmentType,
provider: !this.isMobile ? newProvider : {
providerNumber: this.mobileProviderNumber,
address: {
streetAddress: null,
city: null,
state: null,
zipCode: null,
zipCodeCtu: null
}
}
}; };
this.$emit('provider-changed', returnedProvider); if (newProvider?.providerNumber !== oldProvider?.providerNumber) {
this.$emit('provider-changed', returnedProvider);
}
} }
} }
}, },
@ -369,6 +352,34 @@ export default {
await this.setData(initialData); await this.setData(initialData);
this.initializingData = false; this.initializingData = false;
}, },
async forwardButtonAction(appointmentType) {
let provider = this.selectedProvider;
this.mainStore.updateMobileFee(null);
if (this.isMobile) {
if (this.mainStore.isNoComp || this.mainStore.isITAC) {
this.mainStore.updateMobileFee(this.mobileFeePart);
}
provider = {
providerNumber: this.mobileProviderNumber,
address: {
streetAddress: null,
city: null,
state: null,
zipCode: null,
zipCodeCtu: null
}
};
}
this.mainStore.updateServiceLocation({
state: this.state,
zipCode: this.zipCode,
zipCodeCtu: this.zipCodeCtu,
appointmentType: appointmentType || this.selectedAppointmentType,
provider
});
},
openModalAction(modalName) { openModalAction(modalName) {
this.$refs[modalName].openModal(); this.$refs[modalName].openModal();
}, },
@ -427,6 +438,32 @@ export default {
this.$emit('in-shop-zip-updated', inShopZipServiceLocationObj); this.$emit('in-shop-zip-updated', inShopZipServiceLocationObj);
}); });
}, },
async handleServiceZipCodeChanged(serviceZipCodeFromQuestion) {
if (serviceZipCodeFromQuestion !== this.mobileZipCode) {
// Can probs just make this one call but have to think about initialization flow and not wanting to trigger extra calls on load
this.mobileZipCode = serviceZipCodeFromQuestion;
} else {
await this.processMobileZipCodeChange();
}
},
async processMobileZipCodeChange() {
showIssLoadingModal(true);
await this.updateMobileZip();
if (!this.mobileZipError) {
const updateMobileZipServiceLocationObj = {
mobileProviderNumber: this.mobileProviderNumber,
provider: null,
refreshDatePicker: true,
zipCode: this.zipCode,
zipCodeCtu: this.zipCodeCtu
};
this.$emit('mobile-zip-updated', updateMobileZipServiceLocationObj);
} else {
this.$emit('clear-mobile-data');
showIssLoadingModal(false);
}
},
setCtuForMobile(val) { setCtuForMobile(val) {
this.zipCodeCtu = val; this.zipCodeCtu = val;
}, },
@ -446,6 +483,10 @@ export default {
this.setServiceabilityDetails(initialData.serviceabilityDetails); this.setServiceabilityDetails(initialData.serviceabilityDetails);
} }
if (initialData.mobileFeePart) {
this.mobileFeePart = initialData.mobileFeePart;
}
if (initialData.providers) { if (initialData.providers) {
this.setMobileProviderNumber(initialData.providers.mobileProviderNumber); this.setMobileProviderNumber(initialData.providers.mobileProviderNumber);
let foundMatch = false; let foundMatch = false;
@ -462,12 +503,22 @@ export default {
this.selectedProvider = null; this.selectedProvider = null;
} }
} }
if (initialData.glassFees) {
useMainStore().getCombinedQuote(initialData.glassFees)
.then((combinedQuote) => {
this.setGlassFeeItems(combinedQuote);
});
}
}, },
setContainsMilitaryBase(val) { setContainsMilitaryBase(val) {
if (this.zipContainsMilitaryBase !== val) { if (this.zipContainsMilitaryBase !== val) {
this.zipContainsMilitaryBase = val; this.zipContainsMilitaryBase = val;
} }
}, },
setGlassFeeItems(newGlassFeeItems) {
this.mainStore.updateGlassFees(newGlassFeeItems);
},
setMobileProviderNumber(providerNumber) { setMobileProviderNumber(providerNumber) {
this.mobileProviderNumber = providerNumber; this.mobileProviderNumber = providerNumber;
}, },
@ -571,6 +622,22 @@ $page-side-padding: 1.5rem;
div.alert { div.alert {
margin-top: 0.625rem; margin-top: 0.625rem;
&.widget-name-AlertLowAvailabilityInshopWidget {
@include media-breakpoint-up(xs) {
:deep(.alert-headline-text-container) {
padding-left: 0.5rem;
padding-right: 0.375rem;
letter-spacing: 0.45px;
}
}
@include media-breakpoint-up(xl) {
:deep(.alert-headline-text-container) {
padding: 0rem 0.625rem;
}
}
}
button.looka-likea-link { button.looka-likea-link {
background: none; background: none;
border: none; border: none;

View file

@ -7,7 +7,7 @@ describe('service-zip-question.vue', () => {
const text = '12345'; const text = '12345';
const wrapper = shallowMount(serviceZipQuestion, { const wrapper = shallowMount(serviceZipQuestion, {
props: { props: {
modelValue: text parentZipCode: text
}, },
attachTo: document.body attachTo: document.body
}); });
@ -32,9 +32,9 @@ describe('service-zip-question.vue', () => {
// Act // Act
wrapper.vm.internalZipcode = '55555'; wrapper.vm.internalZipcode = '55555';
wrapper.vm.updateModelValue(); wrapper.vm.emitZipCodeUpdate();
// Assert // Assert
expect(wrapper.emitted('update:modelValue')).toEqual([['55555']]); expect(wrapper.emitted('service-zip-code-updated')).toEqual([['55555']]);
}); });
}); });

View file

@ -10,7 +10,7 @@
isRequired isRequired
:hasError="hasError" :hasError="hasError"
:validationRules="`zip-required|${cmsWidgetName}-zip-format`" :validationRules="`zip-required|${cmsWidgetName}-zip-format`"
@clickEvent="updateModelValue" @clickEvent="emitZipCodeUpdate"
@fieldHasError="handleFieldError" /> @fieldHasError="handleFieldError" />
</template> </template>
@ -32,7 +32,7 @@ export default {
}, },
// TODO: Correct prop def. // TODO: Correct prop def.
props: { props: {
modelValue: String, parentZipCode: String,
cmsWidgetName: String, cmsWidgetName: String,
serviceZipFormatErrorMessage: { serviceZipFormatErrorMessage: {
type: String, type: String,
@ -43,14 +43,14 @@ export default {
default: false default: false
} }
}, },
emits: ['update:modelValue', 'field-has-error'], emits: ['service-zip-code-updated', 'field-has-error'],
data() { data() {
return { return {
internalZipcode: this.modelValue internalZipcode: this.parentZipCode
}; };
}, },
watch: { watch: {
modelValue(newValue) { parentZipCode(newValue) {
if (newValue !== this.internalZipcode) { if (newValue !== this.internalZipcode) {
this.internalZipcode = newValue; this.internalZipcode = newValue;
} }
@ -63,8 +63,8 @@ export default {
handleFieldError(hasError) { handleFieldError(hasError) {
this.$emit('field-has-error', hasError); this.$emit('field-has-error', hasError);
}, },
updateModelValue() { emitZipCodeUpdate() {
this.$emit('update:modelValue', this.internalZipcode); this.$emit('service-zip-code-updated', this.internalZipcode);
} }
} }
}; };

View file

@ -68,17 +68,18 @@
groupName="chooseShop" groupName="chooseShop"
textPosition="text-start" textPosition="text-start"
isRequired isRequired
validationRules="option-required" /> validationRules="provider-required" />
<span class="service-zip-prompt"> <span class="service-zip-prompt">
{{ serviceZipPrompt }} {{ serviceZipPrompt }}
</span> </span>
<serviceZipQuestion <serviceZipQuestion
v-if="renderServiceZip" v-if="renderServiceZip"
:ref="SERVICE_ZIP_QUESTION_REF_NAME" :ref="SERVICE_ZIP_QUESTION_REF_NAME"
v-model="internalZipcode" :parentZipCode="internalZipcode"
customInputId="serviceZipCode" customInputId="serviceZipCode"
:cmsWidgetName="textboxQuestionWidgetName" :cmsWidgetName="textboxQuestionWidgetName"
@fieldHasError="handleFieldError" /> @fieldHasError="handleFieldError"
@serviceZipCodeUpdated="handleServiceZipCodeChanged" />
<div <div
v-if="errorMessage" v-if="errorMessage"
ref="errorMessageDiv" ref="errorMessageDiv"
@ -115,7 +116,7 @@ import errorMessages from '@/constants/error-messages';
import { defineRule } from 'vee-validate'; import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
defineRule('option-required', required(errorMessages.PROVIDER_REQUIRED)); defineRule('provider-required', required(errorMessages.PROVIDER_REQUIRED));
const SERVICE_ZIP_QUESTION_REF_NAME = 'serviceZipCodeQuestion'; const SERVICE_ZIP_QUESTION_REF_NAME = 'serviceZipCodeQuestion';
@ -243,7 +244,7 @@ export default {
showIssLoadingModal(false); showIssLoadingModal(false);
} }
}, },
methods: { methods: {
async updateShops(autoExpand = false) { async updateShops(autoExpand = false) {
this.errorMessage = ''; this.errorMessage = '';
let result = await this.getNearbyShops(this.searchRadiusInMiles); let result = await this.getNearbyShops(this.searchRadiusInMiles);
@ -333,6 +334,11 @@ export default {
this.errorMessage = ''; this.errorMessage = '';
} }
}, },
async handleServiceZipCodeChanged(serviceZipCodeFromQuestion) {
if (serviceZipCodeFromQuestion !== this.internalZipcode) {
this.internalZipcode = serviceZipCodeFromQuestion;
}
},
forceServiceZipRerender() { forceServiceZipRerender() {
this.renderServiceZip = false; this.renderServiceZip = false;
this.$nextTick(() => { this.$nextTick(() => {

View file

@ -426,7 +426,7 @@ export default {
`+${formatAmountInDollars(getPriceOfLineItem(this.premiumAppointmentFee))}`; `+${formatAmountInDollars(getPriceOfLineItem(this.premiumAppointmentFee))}`;
return { return {
// Unique value is required for each <input> and the premium appoinment shares an id // Unique value is required for each <input> and the premium appointment shares an id
value: this.addPremiumFlagToInput(timeSlotData.id), value: this.addPremiumFlagToInput(timeSlotData.id),
buttonLabel: this.premiumAppointmentButtonText, buttonLabel: this.premiumAppointmentButtonText,
buttonLabelSubCopy: formattedPrice, buttonLabelSubCopy: formattedPrice,

View file

@ -1842,7 +1842,7 @@ export const useMainStore = defineStore({
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu ?? this.order.serviceLocation.zipCodeCtu; this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu ?? this.order.serviceLocation.zipCodeCtu;
this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType ?? this.order.serviceLocation.appointmentType; this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType ?? this.order.serviceLocation.appointmentType;
this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected ?? this.order.serviceLocation.isVehicleProtected; this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected ?? this.order.serviceLocation.isVehicleProtected;
this.updateServiceLocationProvider(serviceLocationInfo.provider) this.updateServiceLocationProvider(serviceLocationInfo.provider);
this.order.serviceLocation.tpaSearchRadius = serviceLocationInfo.tpaSearchRadius; this.order.serviceLocation.tpaSearchRadius = serviceLocationInfo.tpaSearchRadius;
}, },
updateAppointmentType(appointmentType) { updateAppointmentType(appointmentType) {
@ -1865,7 +1865,6 @@ export const useMainStore = defineStore({
resetState() { resetState() {
Object.assign(this, getDefaultState()); Object.assign(this, getDefaultState());
}, },
resetRegistrationState() { resetRegistrationState() {
this.order.vehicle.registration.licensePlate = null; this.order.vehicle.registration.licensePlate = null;
this.order.vehicle.registration.address = null; this.order.vehicle.registration.address = null;
@ -1904,14 +1903,12 @@ export const useMainStore = defineStore({
this.order.serviceLocation.state = null; this.order.serviceLocation.state = null;
this.order.serviceLocation.isVehicleProtected = null; this.order.serviceLocation.isVehicleProtected = null;
}, },
resetBailout() { resetBailout() {
this.updatePageData({ this.updatePageData({
page: issPageValues.BAILOUT_PAGE, page: issPageValues.BAILOUT_PAGE,
data: null data: null
}); });
}, },
resetInsurance() { resetInsurance() {
this.order.insuranceCoverage.coverageStatus = coverageStatuses.PENDING; this.order.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
this.order.insuranceCoverage.coverageType = coverageType.NONE; this.order.insuranceCoverage.coverageType = coverageType.NONE;