diff --git a/src/helpers/text-helper.js b/src/helpers/text-helper.js index d08e0c04..41e19a66 100644 --- a/src/helpers/text-helper.js +++ b/src/helpers/text-helper.js @@ -17,9 +17,30 @@ export function stripRteStyle(stringWithStyleTag) { * @returns {string} */ export function toTitleCase(text) { - const temp = text.toLowerCase().split(' '); + const temp = text?.toLowerCase()?.split(' ') ?? []; for (let i = 0; i < temp.length; i++) { temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1); } return temp.join(' '); } + +/** + * @function toDisplayPhoneNumber + * @summary If 10 or 11 digits are in phoneNumber, then the expected number including dashes will be returned + * in either d-ddd-ddd-dddd or ddd-ddd-dddd format. Otherwise, an empty string will be returned. + * @param {string} phoneNumber + * @returns {string} + */ +export function toDisplayPhoneNumber(phoneNumber) { + let result = ''; + if (!phoneNumber) { return result; } + let remainingDigits = phoneNumber.match(/\d+/g).join(''); + if (remainingDigits.length === 11) { + result += `${remainingDigits[0]}-`; + remainingDigits = remainingDigits.substring(1); + } + if (remainingDigits.length === 10) { + result += remainingDigits.replace(/^(\d{3})(\d{3})(\d{4})/, '$1-$2-$3'); + } + return result; +} diff --git a/src/helpers/text-helper.spec.js b/src/helpers/text-helper.spec.js new file mode 100644 index 00000000..1b2daf64 --- /dev/null +++ b/src/helpers/text-helper.spec.js @@ -0,0 +1,42 @@ +import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js'; + +describe('text-helper', () => { + test.each([ + [undefined, ''], + [null, ''], + ['', ''], + ['hello world', 'Hello World'], + ['hello world', 'Hello World'], + ['HEllO worLD', 'Hello World'], + ['a991,,:A froG FAMILY', 'A991,,:a Frog Family'] + ])( + 'toTitleCase given "%p" returns "%p"', + (input, expected) => { + // Act + const result = toTitleCase(input); + + // Assert + expect(result).toEqual(expected); + } + ); + test.each([ + [undefined, ''], + [null, ''], + ['', ''], + ['119', ''], + ['1111999900', '111-199-9900'], + ['111199-9900', '111-199-9900'], + ['111-199-9900', '111-199-9900'], + ['01111999900', '0-111-199-9900'], + ['0-111-199-9900', '0-111-199-9900'] + ])( + 'getDisplayPhoneNumber', + (input, expected) => { + // Act + const result = toDisplayPhoneNumber(input); + + // Assert + expect(result).toEqual(expected); + } + ); +}); diff --git a/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap b/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap index fc429c1b..b34c010c 100644 --- a/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap +++ b/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap @@ -5,25 +5,11 @@ Object { "additionalButtonData": Object { "displayAvailabilityIndicators": false, }, + "dataLoaded": false, "filter": "", - "initialLoading": false, "mapZipCode": "12663", "providers": Array [], - "radiusFilterPairs": Array [ - Object { - "filter": "25 miles", - "radius": 25, - }, - Object { - "filter": "50 miles", - "radius": 50, - }, - Object { - "filter": "100 miles", - "radius": 100, - }, - ], - "reloadProviders": false, + "reloadingProviders": false, "rules": Object { "filter": "option-required", "provider": "option-required", diff --git a/src/layouts/tpa-search/tpa-search.spec.js b/src/layouts/tpa-search/tpa-search.spec.js index d8185733..99754c6b 100644 --- a/src/layouts/tpa-search/tpa-search.spec.js +++ b/src/layouts/tpa-search/tpa-search.spec.js @@ -132,7 +132,7 @@ describe('TPA search page', () => { // Assert expect(searchQuestionField.exists()).toBeTruthy(); - expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionField'); + expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionFieldInput'); expect(searchQuestionField.props().isRequired).toBeTruthy(); expect(searchQuestionField.props().cmsWidgetName).toBe(expectedWidgetName); expect(searchQuestionField.props().includeSearchIcon).toBeTruthy(); @@ -150,18 +150,7 @@ describe('TPA search page', () => { // Assert expect(providerSelectionForm.exists()).toBeTruthy(); }); - test('map loader when initialLoading is true', async () => { - // Arrange - const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ initialLoading: true }); - - // Act - const mapLoader = wrapper.findComponent('#mapLoader'); - - // Assert - expect(mapLoader.exists()).toBeTruthy(); - }); - test('map when initialLoading is false', async () => { + test('map', async () => { // Arrange const zipCode = '12345'; const { wrapper } = getMountedComponent(); @@ -174,8 +163,7 @@ describe('TPA search page', () => { zipCode: '99230' } }], - mapZipCode: zipCode, - initialLoading: false + mapZipCode: zipCode }); const expectedAddresses = ['123 Lane Ave, New York, NY 99230']; @@ -188,10 +176,9 @@ describe('TPA search page', () => { expect(map.props().addresses).toEqual(expectedAddresses); expect(map.props().zipCode).toBe(zipCode); }); - test('search radius filter when initialLoading is false', async () => { + test('search radius filter', async () => { // Arrange const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ initialLoading: false }); const expectedWidgetName = 'FilterByQuestion'; // Act @@ -202,10 +189,10 @@ describe('TPA search page', () => { expect(searchRadiusFilter.props().cmsWidgetName).toBe(expectedWidgetName); expect(searchRadiusFilter.props().validationRules).toBe(globalRules.OPTION_REQUIRED); }); - test('providers loader when initialLoading is false and reloadProviders is true', async () => { + test('providers loader when reloadingProviders is true', async () => { // Arrange const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ initialLoading: false, reloadProviders: true }); + await wrapper.setData({ reloadingProviders: true }); // Act const providersLoader = wrapper.findComponent('#providersLoader'); @@ -213,7 +200,7 @@ describe('TPA search page', () => { // Assert expect(providersLoader.exists()).toBeTruthy(); }); - test('select provider question when initialLoading and reloadProviders are false', async () => { + test('select provider question when reloadingProviders are false', async () => { // Arrange const wrapper = shallowMount(tpaSearch, getMountOptions()); await wrapper.setData({ @@ -229,8 +216,7 @@ describe('TPA search page', () => { zipCode: '99230' } }], - initialLoading: false, - reloadProviders: false + reloadingProviders: false }); const expectedAnswers = [{ buttonLabel: 'Shop Auto Glass', @@ -257,17 +243,14 @@ describe('TPA search page', () => { expect(selectProviderQuestion.props().additionalButtonData).toEqual(expectedAdditionalButtonData); }); test.each([[], null, undefined])( - 'no network providers alert when providers length is 0, undefined, or null and initialLoading and reloadProviders are false', + 'no network providers alert when providers length is 0, undefined, or null and reloadingProviders is false', async (providers) => { // Arrange const initialData = { providers }; const wrapper = shallowMount(tpaSearch, getMountOptions({}, initialData)); - await wrapper.setData({ - initialLoading: false, - reloadProviders: false - }); + await wrapper.setData({ reloadingProviders: false }); // Act const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders'); @@ -279,13 +262,10 @@ describe('TPA search page', () => { expect(noNetworkProvidersAlert.props().isDismissible).toBeFalsy(); } ); - test('preferred shop not listed link when initialLoading and reloadProviders are false', async () => { + test('preferred shop not listed link when reloadingProviders is false', async () => { // Arrange const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ - initialLoading: false, - reloadProviders: false - }); + await wrapper.setData({ reloadingProviders: false }); // Act const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); @@ -308,62 +288,16 @@ describe('TPA search page', () => { }); }); describe('should not render', () => { - test('map loader when initialLoading is false', async () => { - // Arrange - const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ initialLoading: false }); - - // Act - const mapLoader = wrapper.findComponent('#mapLoader'); - - // Assert - expect(mapLoader.exists()).toBeFalsy(); - }); - test('map when initialLoading is true', async () => { + test('select provider question when reloadingProviders is true', async () => { // Arrange const { wrapper } = getMountedComponent(); - await wrapper.setData({ initialLoading: true }); + await wrapper.setData({ reloadingProviders: true }); // Act - const map = wrapper.findComponent('#map'); + const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion'); // Assert - expect(map.exists()).toBeFalsy(); - }); - test('search radius filter when initialLoading is true', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ initialLoading: true }); - - // Act - const searchRadiusFilter = wrapper.findComponent('#searchRadiusFilter'); - - // Assert - expect(searchRadiusFilter.exists()).toBeFalsy(); - }); - describe('select provider question', () => { - test('when initialLoading is true', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ initialLoading: true }); - - // Act - const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion'); - - // Assert - expect(selectProviderQuestion.exists()).toBeFalsy(); - }); - test('when reloadProviders is true', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ reloadProviders: true }); - - // Act - const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion'); - - // Assert - expect(selectProviderQuestion.exists()).toBeFalsy(); - }); + expect(selectProviderQuestion.exists()).toBeFalsy(); }); describe('no network providers alert', () => { test('when providers length is not 0', async () => { @@ -377,21 +311,10 @@ describe('TPA search page', () => { // Assert expect(noNetworkProvidersAlert.exists()).toBeFalsy(); }); - test('when initialLoading is true', async () => { + test('when reloadingProviders is true', async () => { // Arrange const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ providers: [], initialLoading: true }); - - // Act - const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders'); - - // Assert - expect(noNetworkProvidersAlert.exists()).toBeFalsy(); - }); - test('when reloadProviders is true', async () => { - // Arrange - const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ providers: [], reloadProviders: true }); + await wrapper.setData({ providers: [], reloadingProviders: true }); // Act const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders'); @@ -400,29 +323,16 @@ describe('TPA search page', () => { expect(noNetworkProvidersAlert.exists()).toBeFalsy(); }); }); - describe('preferred shop not listed link', () => { - test('when initialLoading is true', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ initialLoading: true }); + test('preferred shop not listed link when reloadingProviders is true', async () => { + // Arrange + const { wrapper } = getMountedComponent(); + await wrapper.setData({ reloadingProviders: true }); - // Act - const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); + // Act + const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); - // Assert - expect(preferredShopNotListedLink.exists()).toBeFalsy(); - }); - test('when reloadProviders is true', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ reloadProviders: true }); - - // Act - const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); - - // Assert - expect(preferredShopNotListedLink.exists()).toBeFalsy(); - }); + // Assert + expect(preferredShopNotListedLink.exists()).toBeFalsy(); }); }); describe('computed', () => { @@ -538,41 +448,27 @@ describe('TPA search page', () => { } ); describe('radiusInMiles', () => { - test('returns 25 when filter is "25 miles"', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ filter: '25 miles' }); + test.each([ + [15, '15 miles'], + [25, '25 miles'], + [50, '50 miles'], + [100, '100 miles'] + ])( + 'returns %p when filter is "%p"', + async (expectedRadius, filter) => { + // Arrange + const { wrapper } = getMountedComponent(); + await wrapper.setData({ filter }); - // Act - const result = wrapper.vm.radiusInMiles; + // Act + const result = wrapper.vm.radiusInMiles; - // Assert - expect(result).toEqual(25); - }); - test('returns 50 when filter is "50 miles"', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ filter: '50 miles' }); - - // Act - const result = wrapper.vm.radiusInMiles; - - // Assert - expect(result).toEqual(50); - }); - test('returns 100 when filter is "100 miles"', async () => { - // Arrange - const { wrapper } = getMountedComponent(); - await wrapper.setData({ filter: '100 miles' }); - - // Act - const result = wrapper.vm.radiusInMiles; - - // Assert - expect(result).toEqual(100); - }); + // Assert + expect(result).toEqual(expectedRadius); + } + ); test.each([null, undefined, 'some random string'])( - 'returns 0 when filter is not "25 miles", "50 miles", or "100 miles"', + 'returns 0 when filter is "%p"', async (filter) => { // Arrange const { wrapper } = getMountedComponent(); @@ -787,7 +683,10 @@ describe('TPA search page', () => { expect(result).toEqual(false); } ); - test.each([[true, true], [false, false]])( + test.each([ + [true, true], + [false, false] + ])( 'returns %p when first instance of multiple matching providerNumbers has isSafeliteShop value %p', async (expectedOutput, isSafeliteShop) => { // Arrange @@ -803,7 +702,8 @@ describe('TPA search page', () => { } ]; const wrapper = shallowMount(tpaSearch, getMountOptions()); - await wrapper.setData({ selectedProviderNumber, providers }); + await wrapper.setData({ providers }); + await wrapper.setData({ selectedProviderNumber }); // Act const result = wrapper.vm.selectedProviderIsSafeliteShop; @@ -841,9 +741,10 @@ describe('TPA search page', () => { const initialMapZipCode = '88800'; const { wrapper } = getMountedComponent({}, { zipCode, - mapZipCode: initialMapZipCode + mapZipCode: initialMapZipCode, + dataLoaded: true }); - const providers = { data: { shopProviders: ['some data', 'some more data']} }; + const providers = { data: { shopProviders: ['some data', 'some more data'] } }; useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers)); const newFilter = 'new filter'; @@ -855,6 +756,50 @@ describe('TPA search page', () => { expect(wrapper.vm.providers).toEqual(providers.data.shopProviders); expect(wrapper.vm.mapZipCode).toBe(zipCode); }); + describe('on filter', () => { + test('calls getTpaProviders once and sets providers when dataLoaded is true', async () => { + // Arrange + const zipCode = '78220'; + const initialMapZipCode = '88800'; + const { wrapper } = getMountedComponent({}, { + zipCode, + mapZipCode: initialMapZipCode, + dataLoaded: true + }); + const providers = { data: { shopProviders: ['some data', 'some more data'] } }; + useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers)); + const newFilter = 'new filter'; + + // Act + await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter); + + // Assert + expect(useMainStore().getTpaProviders).toBeCalled(); + expect(wrapper.vm.providers).toEqual(providers.data.shopProviders); + expect(wrapper.vm.mapZipCode).toBe(zipCode); + }); + test('never calls getTpaProviders and does not set providers when dataLoaded is false', async () => { + // Arrange + const zipCode = '78220'; + const initialMapZipCode = '88800'; + const { wrapper } = getMountedComponent({}, { + zipCode, + mapZipCode: initialMapZipCode, + dataLoaded: false + }); + const providers = { data: { shopProviders: ['some data', 'some more data'] } }; + useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers)); + const newFilter = 'new filter'; + + // Act + await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter); + + // Assert + expect(useMainStore().getTpaProviders).not.toBeCalled(); + expect(wrapper.vm.providers).not.toEqual(providers.data.shopProviders); + expect(wrapper.vm.mapZipCode).toBe(initialMapZipCode); + }); + }); // TODO confirm tests appropriate. Also should this method be async? describe('on providers', () => { test.each([null, undefined, []])( @@ -897,10 +842,10 @@ describe('TPA search page', () => { }); describe('method', () => { test.each([ - ['address', 'city', 'ST', 'zip', 'address, city, ST zip'], - ['address', null, 'ST', 'zip', 'address, ST zip'], - ['address', 'city', null, 'zip', 'address, city zip'], - ['address', 'city', 'ST', null, 'address, city, ST'], + ['address', 'city', 'ST', 'zip', 'Address, City, ST zip'], + ['address', null, 'ST', 'zip', 'Address, ST zip'], + ['address', 'city', null, 'zip', 'Address, City zip'], + ['address', 'city', 'ST', null, 'Address, City, ST'], [null, null, null, null, ''] ])( 'getProviderAddress returns expected', @@ -1240,6 +1185,32 @@ describe('TPA search page', () => { }); }); describe('before route enter', () => { + test('when providers exist at 15 mile radius, filter is set to "15 miles" and providers set to expected', async () => { + // Arrange + const { wrapper } = getMountedComponent(); + const zipCode = '18394'; + useMainStore().order.customer.address.zipCode = zipCode; + const providers = [{ companyName: 'provider' }]; + useMainStore().getTpaProviders = jest.fn().mockImplementation((_, radius) => + ({ data: { shopProviders: radius === 15 ? providers : [] } })); + const expectedFilter = '15 miles'; + + // Act + await tpaSearch.beforeRouteEnter.call( + wrapper.vm, + { query: { issPage: 'tpa-search' } }, + undefined, + (c) => c(wrapper.vm) + ); + + await wrapper.vm.$nextTick(); + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.vm.filter).toBe(expectedFilter); + expect(wrapper.vm.providers).toEqual(providers); + expect(useMainStore().getTpaProviders).toBeCalledTimes(1); + }); test('when providers exist at 25 mile radius, filter is set to "25 miles" and providers set to expected', async () => { // Arrange const { wrapper } = getMountedComponent(); @@ -1264,7 +1235,7 @@ describe('TPA search page', () => { // Assert expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.providers).toEqual(providers); - expect(useMainStore().getTpaProviders).toBeCalledTimes(1); + expect(useMainStore().getTpaProviders).toBeCalledTimes(2); }); test('when providers exist at 50 mile radius but not 25, filter is set to "50 miles" and providers set to expected', async () => { // Arrange @@ -1290,7 +1261,7 @@ describe('TPA search page', () => { // Assert expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.providers).toEqual(providers); - expect(useMainStore().getTpaProviders).toBeCalledTimes(2); + expect(useMainStore().getTpaProviders).toBeCalledTimes(3); }); test( 'when providers exist at 100 mile radius but not 50 or 25, filter is set to "100 miles" and providers set to expected', @@ -1318,7 +1289,7 @@ describe('TPA search page', () => { // Assert expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.providers).toEqual(providers); - expect(useMainStore().getTpaProviders).toBeCalledTimes(3); + expect(useMainStore().getTpaProviders).toBeCalledTimes(4); } ); test( @@ -1345,7 +1316,7 @@ describe('TPA search page', () => { // Assert expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.providers).toEqual([]); - expect(useMainStore().getTpaProviders).toBeCalledTimes(3); + expect(useMainStore().getTpaProviders).toBeCalledTimes(4); } ); }); diff --git a/src/layouts/tpa-search/tpa-search.vue b/src/layouts/tpa-search/tpa-search.vue index 00ebacdc..8ec7742e 100644 --- a/src/layouts/tpa-search/tpa-search.vue +++ b/src/layouts/tpa-search/tpa-search.vue @@ -26,95 +26,88 @@ - -
- -
-
-
- - -
-
- - -
-
- -
+ + +
+
+ + +
+
+ + +
+
+
-
- -
+ +
+
@@ -134,12 +127,40 @@ import loader from '@/ux-components/loader/loader.vue'; // Supporting files import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; -import settleAllPromises from '@/helpers/layout-helper'; import { useMainStore } from '@/store'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import globalRules from '@/constants/global-rules.js'; import widgetFields from '@/constants/cms-widget-fields.js'; import { shallowRef } from 'vue'; +import routerParams from '@/router/router-constants/router-params'; +import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js'; + +const radiusFilterPairs = [ + { radius: 15, filter: '15 miles' }, + { radius: 25, filter: '25 miles' }, + { radius: 50, filter: '50 miles' }, + { radius: 100, filter: '100 miles' } +]; + +async function getInitialFilterAndProviders() { + const { zipCode } = useMainStore().order.customer.address; + + let pairIndex = 0; + let providers = []; + let filter = ''; + while (providers.length === 0 && pairIndex < radiusFilterPairs.length) { + const pair = radiusFilterPairs[pairIndex]; + const { radius } = pair; + filter = pair.filter; + // eslint-disable-next-line no-await-in-loop + const result = await useMainStore().getTpaProviders(zipCode, radius); + providers = result?.data?.shopProviders ?? []; + + pairIndex += 1; + } + + return { filter, providers }; +} export default { name: 'tpa-search', @@ -158,30 +179,25 @@ export default { }, mixins: [BaseFormMixin], async beforeRouteEnter(to, from, next) { - const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); - const promiseResultMap = [ - { - resultKey: 'cmsContent', - promise: cmsContentPromise - } - ]; - const resultMap = await settleAllPromises(promiseResultMap); + const { filter, providers } = await getInitialFilterAndProviders(); + const cmsContent = await fetchCmsContentForPage(to.query.issPage); next(async (vm) => { - vm.setCmsContent(resultMap.cmsContent); - await vm.setInitialFilterAndProviders(); + vm.setCmsContent(cmsContent); + vm.setFilter(filter); + vm.setProviders(providers); }); }, data() { const { zipCode } = useMainStore().order.customer.address; return { + dataLoaded: false, zipCode, mapZipCode: zipCode, filter: '', providers: [], selectedProviderNumber: '', - initialLoading: false, - reloadProviders: false, + reloadingProviders: false, additionalButtonData: { displayAvailabilityIndicators: false }, @@ -199,21 +215,7 @@ export default { filter: globalRules.OPTION_REQUIRED, // TODO do we even need this? provider: globalRules.OPTION_REQUIRED }, - shopListButton: shallowRef(shopListButton), - radiusFilterPairs: [ - { - radius: 25, - filter: '25 miles' - }, - { - radius: 50, - filter: '50 miles' - }, - { - radius: 100, - filter: '100 miles' - } - ] + shopListButton: shallowRef(shopListButton) }; }, computed: { @@ -247,7 +249,7 @@ export default { ); }, radiusInMiles() { - const pair = this.radiusFilterPairs.find((p) => p.filter === this.filter); + const pair = radiusFilterPairs.find((p) => p.filter === this.filter); return pair?.radius ?? 0; }, noNetworkShopsAlertHeaderText() { @@ -268,122 +270,108 @@ export default { }, watch: { async filter() { - if (!this.initialLoading) { - this.reloadProviders = true; + if (this.dataLoaded) { await this.getProviderButtonData().then((providers) => { this.providers = providers; }); this.mapZipCode = this.zipCode; - this.reloadProviders = false; - } else { - this.initialLoading = false; } }, - async providers(newProviders) { - if (newProviders?.length === 1 ?? false) { - this.selectedProviderNumber = newProviders[0]?.providerNumber ?? ''; - } + providers(newProviders) { + this.selectedProviderNumber = newProviders?.length === 1 ?? false + ? newProviders[0]?.providerNumber ?? '' + : ''; } }, - methods: - { - getProviderAddress(provider) { - const city = provider?.address?.city ?? ''; - const state = provider?.address?.state ?? ''; - const zipCode = provider?.address?.zipCode ?? ''; - let addressLine2 = ''; - if (city) { - addressLine2 = city; - if (state || zipCode) { - if (state) { - addressLine2 += ','; - } - addressLine2 += ' '; - } - } - if (state) { - addressLine2 += `${state}`; - if (zipCode) { - addressLine2 += ' '; - } - } - if (zipCode) { - addressLine2 += `${zipCode}`; - } - return provider?.address?.streetAddress - ? `${provider.address.streetAddress}, ${addressLine2}` - : addressLine2; - }, - async setInitialFilterAndProviders() { - this.initialLoading = true; - const { zipCode } = useMainStore().order.customer.address; - - let pairIndex = 0; - let providers = []; - let filter = ''; - while (providers.length === 0 && pairIndex < this.radiusFilterPairs.length) { - const pair = this.radiusFilterPairs[pairIndex]; - const { radius } = pair; - filter = pair.filter; - // eslint-disable-next-line no-await-in-loop - const result = await useMainStore().getTpaProviders(zipCode, radius); - providers = result?.data?.shopProviders ?? []; - - pairIndex += 1; - } - - this.filter = filter; - this.providers = providers; - }, - async getProviderButtonData() { - const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles); - return getTpaProvidersResult?.data?.shopProviders ?? []; - }, - doNotSeeMyShopLinkClick() { - this.$router.navigate( - this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK, - this.$route - ); - }, - async searchClick() { - this.reloadProviders = true; - this.providers = await this.getProviderButtonData(); - this.mapZipCode = this.zipCode; - this.reloadProviders = false; - }, - backButtonAction() { - this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); - }, - forwardButtonAction() { - const scenario = this.selectedProviderIsSafeliteShop - ? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP - : this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP; - this.$router.navigate(scenario, this.$route); - }, - getCustomValueFromString(str) { - switch (str) { - case 'radiusInMiles': - return this.radiusInMiles; - default: - return null; - } - }, - getShopButtonDataFromProvider(provider) { - const cellNumber = provider?.phoneNumber ?? ''; - const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles)) - ? +provider.distanceInMiles.toFixed(1) - : null; - - return { - buttonLabel: provider?.companyName ?? '', - buttonLabelSubCopy: distance === null - ? '' - : `${distance} mi`, - buttonBodyCopy: `${this.getProviderAddress(provider)}
${cellNumber ?? ''}`, - value: provider?.providerNumber ?? '' - }; - } + beforeUpdate() { + if (!this.dataLoaded) { + this.dataLoaded = true; } + }, + methods: { + setFilter(filter) { + this.filter = filter; + }, + setProviders(providers) { + this.providers = providers; + }, + getProviderAddress(provider) { + const city = toTitleCase(provider?.address?.city); + const state = provider?.address?.state ?? ''; + const zipCode = provider?.address?.zipCode ?? ''; + let addressLine2 = ''; + if (city) { + addressLine2 += city; + if (state || zipCode) { + addressLine2 += state ? ', ' : ' '; + } + } + if (state) { + addressLine2 += state; + addressLine2 += zipCode ? ' ' : ''; + } + if (zipCode) { + addressLine2 += zipCode; + } + + const addressLine1 = this.toTitleCase(provider?.address?.streetAddress); + const joinString = addressLine1.length > 0 && addressLine2.length > 0 ? ', ' : ''; + return [addressLine1, addressLine2].join(joinString); + }, + async getProviderButtonData() { + this.reloadingProviders = true; + const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles); + this.reloadingProviders = false; + return getTpaProvidersResult?.data?.shopProviders ?? []; + }, + doNotSeeMyShopLinkClick() { + this.$router.navigate( + this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK, + this.$route, + {}, + {}, + { [routerParams.NOT_SEEING_PREFERRED_SHOP]: true } + ); + }, + async searchClick() { + this.providers = await this.getProviderButtonData(); + this.mapZipCode = this.zipCode; + }, + backButtonAction() { + this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); + }, + forwardButtonAction() { + const scenario = this.selectedProviderIsSafeliteShop + ? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP + : this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP; + this.$router.navigate(scenario, this.$route); + }, + getCustomValueFromString(str) { + switch (str) { + case 'radiusInMiles': + return this.radiusInMiles; + default: + return null; + } + }, + getShopButtonDataFromProvider(provider) { + const cellNumber = this.toDisplayPhoneNumber(provider?.phoneNumber); + const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles)) + ? +provider.distanceInMiles.toFixed(1) + : null; + + return { + buttonLabel: provider?.companyName ?? '', + buttonLabelSubCopy: distance === null + ? '' + : `${distance} mi`, + buttonBodyCopy: `${this.getProviderAddress(provider)}
${cellNumber ?? ''}`, + value: provider?.providerNumber ?? '' + }; + }, + toDisplayPhoneNumber, + toTitleCase + } }; diff --git a/src/router/index.js b/src/router/index.js index 06c209b1..e9945601 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -186,7 +186,7 @@ router.overrideNavigation = ( isSavingNavigation, optionalQuery = {}, optionalParams = {}, - optionalPageData + optionalPageData = {} ) => { navigate( scenario,