From 4aa6c4ed6415a27bc17ce66409630e37c3a5928c Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Thu, 29 Aug 2024 14:02:02 -0500 Subject: [PATCH] SSR-776 Make Google Maps pins clickable --- src/iss-components/google-map/google-map.vue | 84 +++++++++++++++----- src/layouts/tpa-search/tpa-search.vue | 28 ++++--- 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/iss-components/google-map/google-map.vue b/src/iss-components/google-map/google-map.vue index 0c901dec..9372d6ae 100644 --- a/src/iss-components/google-map/google-map.vue +++ b/src/iss-components/google-map/google-map.vue @@ -8,13 +8,14 @@ export default { name: 'google-map', props: { - addresses: Array, + providers: Array, zipCode: String }, data() { return { country: 'USA', - geocoder: null + geocoder: null, + infoWindow: null }; }, computed: { @@ -23,12 +24,12 @@ export default { } }, watch: { - async addresses(newAddresses) { - this.createMapWithMarkersForAddresses(newAddresses); + async providers(newProviders) { + this.createMapWithMarkersForAddresses(newProviders); } }, beforeMount() { - this.createMapWithMarkersForAddresses(this.addresses); + this.createMapWithMarkersForAddresses(this.providers); }, methods: { async getMap(center) { @@ -50,20 +51,60 @@ export default { this.geocoder = new Geocoder(); } }, - async addMarkersToMap(map, positions) { - const { AdvancedMarkerElement } = await window.google.maps.importLibrary('marker'); - positions?.forEach((position) => new AdvancedMarkerElement({ map, position })); + async addMarkersToMap(map, providers) { + const { AdvancedMarkerElement, PinElement } = await window.google.maps.importLibrary('marker'); + providers?.forEach((provider, index) => { + const pin = new PinElement({ + glyph: String.fromCharCode('A'.charCodeAt(0) + index), + glyphColor: '#000000', + borderColor: '#000000' + }); + const marker = new AdvancedMarkerElement({ + map, + position: provider.position, + title: provider.companyName, + content: pin.element + }); + this.createMarkerInfoWindows(marker, provider); + }); }, - async getLocationsFromAddresses(addresses) { + createMarkerInfoWindows(marker, provider) { + const directionsUrl = this.createGetDirectionsUrl(provider); + const content = `
+ ${provider.companyName} +
${provider.addressLine1} +
${provider.addressLine2} +
Get directions +
`; + + const infoWindow = new window.google.maps.InfoWindow({ + content + }); + + marker.addListener('click', () => { + this.infoWindow?.close(); + this.infoWindow = infoWindow; + infoWindow.open(marker.map, marker); + }); + }, + createGetDirectionsUrl(provider) { + return `https://maps.google.com/maps?saddr=&daddr=${encodeURIComponent(provider.fullAddress)}`; + }, + async getLocationsFromAddresses(providers) { await this.setGeocoder(); - const geocodeShopAddressPromises = addresses?.map((address) => this.geocoder.geocode({ address })) ?? []; + const geocodeShopAddressPromises = providers?.map((provider) => this.geocoder.geocode({ address: provider.fullAddress })) ?? []; const geocodeShopAddressResults = await Promise.all(geocodeShopAddressPromises); - return geocodeShopAddressResults.map((result) => - (result?.results?.length > 0 - ? result.results[0].geometry?.location - : null)) - .filter((loc) => loc != null); + + return providers.map((provider, index) => { + const { results } = geocodeShopAddressResults[index]; + let position = null; + if (results && results.length > 0) { + position = results[0].geometry?.location; + } + + return { ...provider, position }; + }).filter((provider) => provider.position != null); }, async getBoundsFromAddress(address) { await this.setGeocoder(); @@ -72,16 +113,17 @@ export default { ? result.results[0].geometry?.bounds : null; }, - async createMapWithMarkersForAddresses(addresses) { - const shopPositions = await this.getLocationsFromAddresses(addresses); + async createMapWithMarkersForAddresses(providers) { + const providerPositions = await this.getLocationsFromAddresses(providers); const zipBounds = await this.getBoundsFromAddress(this.zipCodeAddress); - const map = await this.getMap(zipBounds?.getCenter()); + const map = await this.getMap(zipBounds.getCenter()); - await this.addMarkersToMap(map, shopPositions); + await this.addMarkersToMap(map, providerPositions); - const positionsToDisplay = shopPositions.concat(zipBounds?.getNorthEast(), zipBounds?.getSouthWest()); + const positionsToDisplay = providerPositions.map((provider) => provider.position) + .concat(zipBounds?.getNorthEast(), zipBounds?.getSouthWest()); const bounds = this.getBounds(positionsToDisplay); - map?.fitBounds(bounds); + map.fitBounds(bounds); } } }; diff --git a/src/layouts/tpa-search/tpa-search.vue b/src/layouts/tpa-search/tpa-search.vue index 4aab4f05..e384eec2 100644 --- a/src/layouts/tpa-search/tpa-search.vue +++ b/src/layouts/tpa-search/tpa-search.vue @@ -46,7 +46,7 @@
- this.getProviderAddress(provider)) ?? [] - ); + return this.providers?.map((provider) => ({ + ...provider, + fullAddress: this.getFullProviderAddress(provider), + addressLine1: this.getProviderAddress(provider), + addressLine2: this.getProviderCityZipState(provider) + })) ?? []; }, providerButtonData() { return ( @@ -350,7 +352,17 @@ export default { this.providers = providers; this.selectedProviderNumber = providerNumber; }, + getFullProviderAddress(provider) { + const addressLine1 = this.getProviderAddress(provider); + const addressLine2 = this.getProviderCityZipState(provider); + const joinString = + addressLine1.length > 0 && addressLine2.length > 0 ? ', ' : ''; + return [addressLine1, addressLine2].join(joinString); + }, getProviderAddress(provider) { + return toTitleCase(provider?.address?.streetAddress); + }, + getProviderCityZipState(provider) { const city = toTitleCase(provider?.address?.city); const state = provider?.address?.state ?? ''; const zipCode = provider?.address?.zipCode ?? ''; @@ -368,11 +380,7 @@ export default { if (zipCode) { addressLine2 += zipCode; } - - const addressLine1 = toTitleCase(provider?.address?.streetAddress); - const joinString = - addressLine1.length > 0 && addressLine2.length > 0 ? ', ' : ''; - return [addressLine1, addressLine2].join(joinString); + return addressLine2; }, async getProviderButtonData() { this.reloadingProviders = true;