@abcagency/hc-ui-components 1.3.14 → 1.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/_virtual/_rollupPluginBabelHelpers.js +1 -1
  2. package/dist/apis/hcApi.js +1 -1
  3. package/dist/apis/hcApi.js.map +1 -1
  4. package/dist/clientToken.js.map +1 -1
  5. package/dist/components/HireControlMap.js +15 -5
  6. package/dist/components/HireControlMap.js.map +1 -1
  7. package/dist/components/modules/accordions/MapAccordionItem.js +11 -1
  8. package/dist/components/modules/accordions/MapAccordionItem.js.map +1 -1
  9. package/dist/components/modules/accordions/default.js.map +1 -1
  10. package/dist/components/modules/accordions/filterItem.js +2 -1
  11. package/dist/components/modules/accordions/filterItem.js.map +1 -1
  12. package/dist/components/modules/accordions/filters.js +0 -3
  13. package/dist/components/modules/accordions/filters.js.map +1 -1
  14. package/dist/components/modules/buttons/button-group-apply.js +36 -15
  15. package/dist/components/modules/buttons/button-group-apply.js.map +1 -1
  16. package/dist/components/modules/buttons/commute-pill.js.map +1 -1
  17. package/dist/components/modules/buttons/default.js.map +1 -1
  18. package/dist/components/modules/buttons/items-pill.js.map +1 -1
  19. package/dist/components/modules/buttons/pill-wrapper.js.map +1 -1
  20. package/dist/components/modules/buttons/show-all-button.js.map +1 -1
  21. package/dist/components/modules/cards/default.js.map +1 -1
  22. package/dist/components/modules/cards/filter.js.map +1 -1
  23. package/dist/components/modules/dialogs/apply-dialog.js.map +1 -1
  24. package/dist/components/modules/filter/commute.js +22 -6
  25. package/dist/components/modules/filter/commute.js.map +1 -1
  26. package/dist/components/modules/filter/index.js +7 -0
  27. package/dist/components/modules/filter/index.js.map +1 -1
  28. package/dist/components/modules/filter/item.js +16 -1
  29. package/dist/components/modules/filter/item.js.map +1 -1
  30. package/dist/components/modules/filter/location.js +1 -1
  31. package/dist/components/modules/filter/location.js.map +1 -1
  32. package/dist/components/modules/filter/points-of-interest.js.map +1 -1
  33. package/dist/components/modules/filter/radio-item.js +7 -0
  34. package/dist/components/modules/filter/radio-item.js.map +1 -1
  35. package/dist/components/modules/filter/search.js.map +1 -1
  36. package/dist/components/modules/filter/sort.js.map +1 -1
  37. package/dist/components/modules/grid.js.map +1 -1
  38. package/dist/components/modules/icon.js.map +1 -1
  39. package/dist/components/modules/jobListing/listing-details.js +6 -0
  40. package/dist/components/modules/jobListing/listing-details.js.map +1 -1
  41. package/dist/components/modules/maps/info-window-card.js.map +1 -1
  42. package/dist/components/modules/maps/info-window-content.js +20 -0
  43. package/dist/components/modules/maps/info-window-content.js.map +1 -1
  44. package/dist/components/modules/maps/list/field-mapper.js.map +1 -1
  45. package/dist/components/modules/maps/list/header-item.js.map +1 -1
  46. package/dist/components/modules/maps/list/header.js.map +1 -1
  47. package/dist/components/modules/maps/list/index.js +21 -12
  48. package/dist/components/modules/maps/list/index.js.map +1 -1
  49. package/dist/components/modules/maps/list/item-expand-card/index.js.map +1 -1
  50. package/dist/components/modules/maps/list/item-expand-card/recruiter-contact-nav.js.map +1 -1
  51. package/dist/components/modules/maps/list/item-expand-card/recruiter-details.js.map +1 -1
  52. package/dist/components/modules/maps/list/item-expand-card/recruiter-headshot.js.map +1 -1
  53. package/dist/components/modules/maps/list/list-item/index.js +12 -2
  54. package/dist/components/modules/maps/list/list-item/index.js.map +1 -1
  55. package/dist/components/modules/maps/map-list.js.map +1 -1
  56. package/dist/components/modules/maps/map-marker.js +10 -0
  57. package/dist/components/modules/maps/map-marker.js.map +1 -1
  58. package/dist/components/modules/maps/map.js.map +1 -1
  59. package/dist/components/modules/maps/place-marker.js.map +1 -1
  60. package/dist/components/modules/maps/tabs.js.map +1 -1
  61. package/dist/constants/eventTypes.js +16 -0
  62. package/dist/constants/eventTypes.js.map +1 -0
  63. package/dist/constants/placeTypes.js.map +1 -1
  64. package/dist/contexts/mapContext.js +9 -27
  65. package/dist/contexts/mapContext.js.map +1 -1
  66. package/dist/contexts/mapListContext.js +57 -38
  67. package/dist/contexts/mapListContext.js.map +1 -1
  68. package/dist/contexts/placesContext.js.map +1 -1
  69. package/dist/contexts/trackEventContext.js +20 -0
  70. package/dist/contexts/trackEventContext.js.map +1 -0
  71. package/dist/hooks/useList.js +1 -13
  72. package/dist/hooks/useList.js.map +1 -1
  73. package/dist/services/apis/hcApi.js +1 -1
  74. package/dist/services/apis/hcApi.js.map +1 -1
  75. package/dist/services/clientToken.js.map +1 -1
  76. package/dist/services/configService.js.map +1 -1
  77. package/dist/services/googlePlacesNearbyService.js.map +1 -1
  78. package/dist/services/listingAggregatorService.js +43 -16
  79. package/dist/services/listingAggregatorService.js.map +1 -1
  80. package/dist/services/listingEntityService.js.map +1 -1
  81. package/dist/services/listingService.js.map +1 -1
  82. package/dist/services/recruiterService.js.map +1 -1
  83. package/dist/util/filterUtil.js.map +1 -1
  84. package/dist/util/loading.js.map +1 -1
  85. package/dist/util/localStorageUtil.js.map +1 -1
  86. package/dist/util/mapIconUtil.js.map +1 -1
  87. package/dist/util/mapUtil.js.map +1 -1
  88. package/dist/util/sortUtil.js.map +1 -1
  89. package/dist/util/stringUtils.js.map +1 -1
  90. package/jsconfig.json +7 -7
  91. package/package.json +60 -60
  92. package/postcss.config.js +13 -13
  93. package/preset.default.js +15 -15
  94. package/rollup.config.mjs +88 -87
  95. package/src/apis/hcApi.js +93 -93
  96. package/src/clientToken.js +9 -9
  97. package/src/components/HireControlMap.js +129 -124
  98. package/src/components/modules/accordions/MapAccordionItem.js +74 -72
  99. package/src/components/modules/accordions/default.js +171 -171
  100. package/src/components/modules/accordions/filterItem.js +55 -53
  101. package/src/components/modules/accordions/filters.js +47 -47
  102. package/src/components/modules/buttons/button-group-apply.js +123 -116
  103. package/src/components/modules/buttons/commute-pill.js +22 -22
  104. package/src/components/modules/buttons/default.js +194 -194
  105. package/src/components/modules/buttons/items-pill.js +35 -35
  106. package/src/components/modules/buttons/pill-wrapper.js +27 -27
  107. package/src/components/modules/buttons/show-all-button.js +20 -20
  108. package/src/components/modules/cards/default.js +167 -167
  109. package/src/components/modules/cards/filter.js +56 -56
  110. package/src/components/modules/dialogs/apply-dialog.js +48 -48
  111. package/src/components/modules/filter/commute.js +154 -149
  112. package/src/components/modules/filter/index.js +89 -87
  113. package/src/components/modules/filter/item.js +87 -76
  114. package/src/components/modules/filter/location.js +71 -71
  115. package/src/components/modules/filter/points-of-interest.js +44 -44
  116. package/src/components/modules/filter/radio-item.js +57 -53
  117. package/src/components/modules/filter/search.js +92 -92
  118. package/src/components/modules/filter/sort.js +83 -83
  119. package/src/components/modules/grid.js +54 -54
  120. package/src/components/modules/icon.js +33 -33
  121. package/src/components/modules/jobListing/listing-details.js +99 -95
  122. package/src/components/modules/maps/info-window-card.js +17 -17
  123. package/src/components/modules/maps/info-window-content.js +81 -74
  124. package/src/components/modules/maps/list/field-mapper.js +112 -112
  125. package/src/components/modules/maps/list/header-item.js +91 -91
  126. package/src/components/modules/maps/list/header.js +47 -47
  127. package/src/components/modules/maps/list/index.js +112 -107
  128. package/src/components/modules/maps/list/item-expand-card/index.js +22 -22
  129. package/src/components/modules/maps/list/item-expand-card/recruiter-contact-nav.js +50 -50
  130. package/src/components/modules/maps/list/item-expand-card/recruiter-details.js +68 -68
  131. package/src/components/modules/maps/list/item-expand-card/recruiter-headshot.js +22 -22
  132. package/src/components/modules/maps/list/list-item/index.js +135 -133
  133. package/src/components/modules/maps/map-list.js +74 -74
  134. package/src/components/modules/maps/map-marker.js +88 -86
  135. package/src/components/modules/maps/map.js +230 -230
  136. package/src/components/modules/maps/place-marker.js +41 -41
  137. package/src/components/modules/maps/tabs.js +81 -81
  138. package/src/constants/eventTypes.js +13 -0
  139. package/src/constants/placeTypes.js +8 -8
  140. package/src/contexts/mapContext.js +101 -115
  141. package/src/contexts/mapListContext.js +242 -222
  142. package/src/contexts/placesContext.js +102 -102
  143. package/src/contexts/trackEventContext.js +14 -0
  144. package/src/hooks/useList.js +89 -100
  145. package/src/index.js +3 -3
  146. package/src/services/configService.js +16 -16
  147. package/src/services/googlePlacesNearbyService.js +33 -33
  148. package/src/services/listingAggregatorService.js +50 -45
  149. package/src/services/listingEntityService.js +15 -15
  150. package/src/services/listingService.js +26 -26
  151. package/src/services/recruiterService.js +17 -17
  152. package/src/styles/index.css +23 -23
  153. package/src/util/arrayUtil.js +3 -3
  154. package/src/util/fieldMapper.js +22 -22
  155. package/src/util/filterUtil.js +195 -195
  156. package/src/util/loading.js +17 -17
  157. package/src/util/localStorageUtil.js +26 -26
  158. package/src/util/mapIconUtil.js +180 -180
  159. package/src/util/mapUtil.js +91 -91
  160. package/src/util/sortUtil.js +32 -32
  161. package/src/util/stringUtils.js +6 -6
  162. package/src/util/urlFilterUtil.js +90 -90
  163. package/tailwind.config.js +126 -126
  164. package/.editorconfig +0 -12
  165. package/.eslintrc +0 -105
  166. package/.prettierignore +0 -3
@@ -1,86 +1,88 @@
1
- import React, { useEffect, useRef } from 'react';
2
- import { MarkerF, InfoWindow } from '@react-google-maps/api';
3
-
4
- import InfoWindowCard from '~/components/modules/maps/info-window-card';
5
- import InfoWindowContent from "~/components/modules/maps/info-window-content";
6
-
7
- import { useMap } from "~/contexts/mapContext";
8
- import { useMapList } from "~/contexts/mapListContext";
9
-
10
- const MapMarker = ({
11
- item,
12
- markerRefs,
13
- infoWindowClasses,
14
- markerClickHandler,
15
- clusterer,
16
- markerIconSelected,
17
- markerIcon,
18
- selectedLocation,
19
- setMapInteracted
20
- }) => {
21
- const { setLocation, commuteLocation } = useMap();
22
- const isSelected = item.id === selectedLocation?.id;
23
- const markerRef = useRef(null);
24
-
25
- const {
26
- handleFilterListingsByLocation
27
- } = useMapList();
28
-
29
- useEffect(() => {
30
- markerRefs.current[item.id] = markerRef.current;
31
- }, []);
32
-
33
- const onMarkerClick = () => {
34
- setMapInteracted(true);
35
- markerClickHandler(item);
36
- };
37
-
38
- const getInfoWindow = () => {
39
- if (!isSelected || !item || !item.id || !selectedLocation) {
40
- return;
41
- }
42
- //Direct dom removal of empty info windows
43
- document.querySelectorAll("div.gm-style-iw.gm-style-iw-c").forEach(x => { if (!x.innerHTML.includes(item.id)) x.parentElement.remove(); });
44
- return (
45
- <InfoWindow
46
- position={{ lat: item.latitude, lng: item.longitude }}
47
- anchor={markerRefs.current[item.id]}
48
- onCloseClick={() => {
49
- setMapInteracted(true);
50
- setLocation(null);
51
- }}
52
- options={{ maxWidth: 400 }}
53
- >
54
- <InfoWindowCard
55
- className={infoWindowClasses}
56
- id={item.id}
57
- content={<InfoWindowContent
58
- item={item}
59
- commuteLocation={commuteLocation}
60
- filterListingsByLocation={() =>
61
- handleFilterListingsByLocation(selectedLocation)
62
- }
63
- />}
64
- />
65
- </InfoWindow>
66
- );
67
- };
68
- return (
69
- <MarkerF
70
- key={item.id}
71
- position={{ lat: item.latitude, lng: item.longitude }}
72
- title={item.name}
73
- options={{
74
- icon: isSelected ? markerIconSelected : markerIcon
75
- }}
76
- zIndex={isSelected ? 9999 : 1}
77
- onLoad={marker => (markerRef.current = marker)}
78
- onClick={onMarkerClick}
79
- clusterer={clusterer}
80
- >
81
- {isSelected && getInfoWindow()}
82
- </MarkerF>
83
- );
84
- };
85
-
86
- export default MapMarker;
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { MarkerF, InfoWindow } from '@react-google-maps/api';
3
+
4
+ import InfoWindowCard from '~/components/modules/maps/info-window-card';
5
+ import InfoWindowContent from "~/components/modules/maps/info-window-content";
6
+
7
+ import { useMap } from "~/contexts/mapContext";
8
+ import { useMapList } from "~/contexts/mapListContext";
9
+ import { useTrackEvent } from '~/contexts/trackEventContext';
10
+
11
+ const MapMarker = ({
12
+ item,
13
+ markerRefs,
14
+ infoWindowClasses,
15
+ markerClickHandler,
16
+ clusterer,
17
+ markerIconSelected,
18
+ markerIcon,
19
+ selectedLocation,
20
+ setMapInteracted
21
+ }) => {
22
+ const { setLocation, commuteLocation } = useMap();
23
+ const isSelected = item.id === selectedLocation?.id;
24
+ const markerRef = useRef(null);
25
+ const { trackEvent, eventTypes } = useTrackEvent();
26
+ const {
27
+ handleFilterListingsByLocation
28
+ } = useMapList();
29
+
30
+ useEffect(() => {
31
+ markerRefs.current[item.id] = markerRef.current;
32
+ }, []);
33
+
34
+ const onMarkerClick = () => {
35
+ trackEvent(eventTypes.MAP_MARKER_CLICKED, { entityDisplayName: item.entityDisplayName, lat: item.latitude, lng: item.longitude, travelTime: item.travelTime });
36
+ setMapInteracted(true);
37
+ markerClickHandler(item);
38
+ };
39
+
40
+ const getInfoWindow = () => {
41
+ if (!isSelected || !item || !item.id || !selectedLocation) {
42
+ return;
43
+ }
44
+ //Direct dom removal of empty info windows
45
+ document.querySelectorAll("div.gm-style-iw.gm-style-iw-c").forEach(x => { if (!x.innerHTML.includes(item.id)) x.parentElement.remove(); });
46
+ return (
47
+ <InfoWindow
48
+ position={{ lat: item.latitude, lng: item.longitude }}
49
+ anchor={markerRefs.current[item.id]}
50
+ onCloseClick={() => {
51
+ setMapInteracted(true);
52
+ setLocation(null);
53
+ }}
54
+ options={{ maxWidth: 400 }}
55
+ >
56
+ <InfoWindowCard
57
+ className={infoWindowClasses}
58
+ id={item.id}
59
+ content={<InfoWindowContent
60
+ item={item}
61
+ commuteLocation={commuteLocation}
62
+ filterListingsByLocation={() =>
63
+ handleFilterListingsByLocation(selectedLocation)
64
+ }
65
+ />}
66
+ />
67
+ </InfoWindow>
68
+ );
69
+ };
70
+ return (
71
+ <MarkerF
72
+ key={item.id}
73
+ position={{ lat: item.latitude, lng: item.longitude }}
74
+ title={item.name}
75
+ options={{
76
+ icon: isSelected ? markerIconSelected : markerIcon
77
+ }}
78
+ zIndex={isSelected ? 9999 : 1}
79
+ onLoad={marker => (markerRef.current = marker)}
80
+ onClick={onMarkerClick}
81
+ clusterer={clusterer}
82
+ >
83
+ {isSelected && getInfoWindow()}
84
+ </MarkerF>
85
+ );
86
+ };
87
+
88
+ export default MapMarker;
@@ -1,230 +1,230 @@
1
- /* eslint-disable no-undef */
2
- import React, { useEffect, useRef } from 'react';
3
- import { GoogleMap, MarkerClustererF } from "@react-google-maps/api";
4
-
5
- import MapMarker from "~/components/modules/maps/map-marker";
6
- import PlaceMarker from "~/components/modules/maps/place-marker";
7
- import ShowAllButton from "~/components/modules/buttons/show-all-button";
8
-
9
- import { usePlaces } from "~/contexts/placesContext";
10
- import { useMap } from "~/contexts/mapContext";
11
- import { useMapList } from "~/contexts/mapListContext";
12
-
13
- import { markerIconSelected, markerIcon, pinIcon } from "~/util/mapIconUtil";
14
- import { clusterOptions } from "~/util/mapUtil";
15
-
16
- const Map = ({
17
- markerConfigs,
18
- infoWindowClasses,
19
- clusterGridSize = 60
20
- }) => {
21
- const {
22
- location,
23
- zoom,
24
- center,
25
- commuteLocation,
26
- selectLocationEntity,
27
- setLocation,
28
- mapInteracted,
29
- setMapInteracted
30
- } = useMap();
31
-
32
- const {
33
- mapItems, filteredListings, setSelectedFilters,
34
- setQuery
35
- } = useMapList();
36
-
37
- const mapRef = useRef();
38
- const markerRefs = useRef({});
39
- const mapContainerRef = useRef(null);
40
- const {
41
- poiMarkers,
42
- setCurrentCenter,
43
- currentCenter,
44
- setCurrentZoom,
45
- currentZoom,
46
- selectedPlaceMarker,
47
- setSelectedPlaceMarker,
48
- placesWindow,
49
- setPlacesWindow } = usePlaces();
50
-
51
- const onIdle = () => {
52
- if (!currentCenter || !mapRef.current) return;
53
- const newCenter = mapRef.current.getCenter().toJSON();
54
- const newZoom = mapRef.current.zoom;
55
-
56
- setCurrentCenter(newCenter);
57
-
58
- if (newZoom != currentZoom) {
59
- setCurrentZoom(newZoom);
60
- }
61
- };
62
-
63
- useEffect(() => {
64
- if (mapContainerRef.current) {
65
- const handleScroll = () => {
66
- setMapInteracted(true);
67
- };
68
- var mapContainerRefCurrent = mapContainerRef.current;
69
- mapContainerRef.current.addEventListener('wheel', handleScroll);
70
- return () => mapContainerRefCurrent.removeEventListener('wheel', handleScroll);
71
- }
72
- }, [mapContainerRef.current]);
73
-
74
- useEffect(() => {
75
- if (mapRef.current) {
76
- const mapInstance = mapRef.current;
77
- const dragStartListener = mapInstance.addListener('dragstart', () => setMapInteracted(true));
78
- const mouseDownListener = mapInstance.addListener('mousedown', () => setMapInteracted(true));
79
- return () => {
80
- google.maps.event.removeListener(dragStartListener);
81
- google.maps.event.removeListener(mouseDownListener);
82
- };
83
- }
84
- }, [mapRef.current, mapContainerRef.current]);
85
-
86
- useEffect(() => {
87
- if ((mapItems && mapItems.length > 0 || poiMarkers.length > 0) && mapRef.current) {
88
- fitBounds(mapRef.current);
89
- }
90
- }, [mapItems, mapRef.current, location]);
91
-
92
- useEffect(() => {
93
- if (mapItems && mapItems.length > 0 || poiMarkers.length > 0 && mapRef.current && mapInteracted) {
94
- fitBounds(mapRef.current, true);
95
- }
96
- if (mapRef.current) {
97
- let currZoom = mapRef.current.zoom;
98
- let setZoomVal = currZoom < 13 ? currZoom : 12;
99
- mapRef.current.setZoom(setZoomVal);
100
- }
101
- }, [filteredListings]);
102
-
103
- useEffect(() => {
104
- if (!mapRef.current || !location || mapInteracted) return;
105
- mapRef.current.panTo(
106
- new google.maps.LatLng(location.latitude, location.longitude)
107
- );
108
- if (mapRef.current) {
109
- let setZoomVal = zoom < 13 ? zoom : 12;
110
- mapRef.current.setZoom(setZoomVal);
111
- }
112
- }, [location, zoom, mapRef.current]);
113
-
114
- const fitBounds = (map, overload = false) => {
115
- if ((mapInteracted === false || overload) && mapItems != null) {
116
- const bounds = new window.google.maps.LatLngBounds();
117
- mapItems.forEach(item => {
118
- bounds.extend(new google.maps.LatLng(item.latitude, item.longitude));
119
- });
120
- if (!map) return;
121
- map.fitBounds(bounds);
122
- }
123
- if (mapRef.current.zoom > 17) {
124
- mapRef.current.setZoom(16);
125
- }
126
- };
127
-
128
- const markerClickHandler = mapLocation => {
129
- setMapInteracted(true);
130
- selectLocationEntity(mapLocation);
131
- };
132
-
133
- const onLoad = map => {
134
- if (!location || location === null) {
135
- mapRef.current = map;
136
- fitBounds(map, true);
137
- return;
138
- }
139
- mapRef.current = map;
140
-
141
- if (mapInteracted === false) {
142
- mapRef.current.panTo(
143
- new google.maps.LatLng(location.latitude, location.longitude)
144
- );
145
-
146
- mapRef.current.setZoom(zoom);
147
- }
148
- };
149
-
150
- const pinIconUrl = pinIcon({
151
- fillColor: markerConfigs.fillColor,
152
- strokeColor: markerConfigs.strokeColor
153
- });
154
-
155
- return (
156
- <>{zoom && center && <div ref={mapContainerRef} className="hc-h-full hc-relative">
157
- <GoogleMap
158
- zoom={zoom}
159
- onLoad={onLoad}
160
- onIdle={onIdle}
161
- center={center}
162
- mapContainerStyle={{
163
- width: "100%",
164
- height: "100%"
165
- }}
166
- options={{
167
- styles: [
168
- {
169
- featureType: "poi",
170
- elementType: "labels",
171
- stylers: [{ visibility: "off" }]
172
- }
173
- ]
174
- }}
175
- >
176
- <MarkerClustererF options={clusterOptions(clusterGridSize, markerConfigs.fillColor)}>
177
- {clusterer => (
178
- <>
179
- {mapItems.map(item => (
180
- <MapMarker
181
- key={item.id}
182
- item={item}
183
- selectedLocation={location}
184
- markerRefs={markerRefs}
185
- infoWindowClasses={infoWindowClasses}
186
- setSelectedLocation={setLocation}
187
- markerClickHandler={markerClickHandler}
188
- clusterer={clusterer}
189
- markerIcon={markerIcon(markerConfigs)}
190
- markerIconSelected={markerIconSelected(markerConfigs)}
191
- setMapInteracted={setMapInteracted}
192
- />
193
- ))}
194
- {poiMarkers && poiMarkers.markers.map((marker, index) => {
195
- return (
196
- <PlaceMarker
197
- key={`marker-${marker.title}-${index}`}
198
- marker={marker}
199
- index={index}
200
- selectedPlaceMarker={selectedPlaceMarker}
201
- placesWindow={placesWindow}
202
- setPlacesWindow={setPlacesWindow}
203
- setSelectedPlaceMarker={setSelectedPlaceMarker}
204
- />
205
- );
206
- })}
207
- </>
208
- )}
209
- </MarkerClustererF>
210
- </GoogleMap>
211
- {mapInteracted && markerConfigs && (
212
- <ShowAllButton
213
- mapInteracted={mapInteracted}
214
- markerConfigs={markerConfigs}
215
- setMapInteracted={setMapInteracted}
216
- fitBounds={fitBounds}
217
- mapRef={mapRef}
218
- pinIconUrl={pinIconUrl}
219
- setQuery={setQuery}
220
- listingCount={filteredListings.length}
221
- setSelectedFilters={setSelectedFilters}
222
- />
223
- )}
224
- </div>
225
- }
226
- </>
227
- );
228
- };
229
-
230
- export default Map;
1
+ /* eslint-disable no-undef */
2
+ import React, { useEffect, useRef } from 'react';
3
+ import { GoogleMap, MarkerClustererF } from "@react-google-maps/api";
4
+
5
+ import MapMarker from "~/components/modules/maps/map-marker";
6
+ import PlaceMarker from "~/components/modules/maps/place-marker";
7
+ import ShowAllButton from "~/components/modules/buttons/show-all-button";
8
+
9
+ import { usePlaces } from "~/contexts/placesContext";
10
+ import { useMap } from "~/contexts/mapContext";
11
+ import { useMapList } from "~/contexts/mapListContext";
12
+
13
+ import { markerIconSelected, markerIcon, pinIcon } from "~/util/mapIconUtil";
14
+ import { clusterOptions } from "~/util/mapUtil";
15
+
16
+ const Map = ({
17
+ markerConfigs,
18
+ infoWindowClasses,
19
+ clusterGridSize = 60
20
+ }) => {
21
+ const {
22
+ location,
23
+ zoom,
24
+ center,
25
+ commuteLocation,
26
+ selectLocationEntity,
27
+ setLocation,
28
+ mapInteracted,
29
+ setMapInteracted
30
+ } = useMap();
31
+
32
+ const {
33
+ mapItems, filteredListings, setSelectedFilters,
34
+ setQuery
35
+ } = useMapList();
36
+
37
+ const mapRef = useRef();
38
+ const markerRefs = useRef({});
39
+ const mapContainerRef = useRef(null);
40
+ const {
41
+ poiMarkers,
42
+ setCurrentCenter,
43
+ currentCenter,
44
+ setCurrentZoom,
45
+ currentZoom,
46
+ selectedPlaceMarker,
47
+ setSelectedPlaceMarker,
48
+ placesWindow,
49
+ setPlacesWindow } = usePlaces();
50
+
51
+ const onIdle = () => {
52
+ if (!currentCenter || !mapRef.current) return;
53
+ const newCenter = mapRef.current.getCenter().toJSON();
54
+ const newZoom = mapRef.current.zoom;
55
+
56
+ setCurrentCenter(newCenter);
57
+
58
+ if (newZoom != currentZoom) {
59
+ setCurrentZoom(newZoom);
60
+ }
61
+ };
62
+
63
+ useEffect(() => {
64
+ if (mapContainerRef.current) {
65
+ const handleScroll = () => {
66
+ setMapInteracted(true);
67
+ };
68
+ var mapContainerRefCurrent = mapContainerRef.current;
69
+ mapContainerRef.current.addEventListener('wheel', handleScroll);
70
+ return () => mapContainerRefCurrent.removeEventListener('wheel', handleScroll);
71
+ }
72
+ }, [mapContainerRef.current]);
73
+
74
+ useEffect(() => {
75
+ if (mapRef.current) {
76
+ const mapInstance = mapRef.current;
77
+ const dragStartListener = mapInstance.addListener('dragstart', () => setMapInteracted(true));
78
+ const mouseDownListener = mapInstance.addListener('mousedown', () => setMapInteracted(true));
79
+ return () => {
80
+ google.maps.event.removeListener(dragStartListener);
81
+ google.maps.event.removeListener(mouseDownListener);
82
+ };
83
+ }
84
+ }, [mapRef.current, mapContainerRef.current]);
85
+
86
+ useEffect(() => {
87
+ if ((mapItems && mapItems.length > 0 || poiMarkers.length > 0) && mapRef.current) {
88
+ fitBounds(mapRef.current);
89
+ }
90
+ }, [mapItems, mapRef.current, location]);
91
+
92
+ useEffect(() => {
93
+ if (mapItems && mapItems.length > 0 || poiMarkers.length > 0 && mapRef.current && mapInteracted) {
94
+ fitBounds(mapRef.current, true);
95
+ }
96
+ if (mapRef.current) {
97
+ let currZoom = mapRef.current.zoom;
98
+ let setZoomVal = currZoom < 13 ? currZoom : 12;
99
+ mapRef.current.setZoom(setZoomVal);
100
+ }
101
+ }, [filteredListings]);
102
+
103
+ useEffect(() => {
104
+ if (!mapRef.current || !location || mapInteracted) return;
105
+ mapRef.current.panTo(
106
+ new google.maps.LatLng(location.latitude, location.longitude)
107
+ );
108
+ if (mapRef.current) {
109
+ let setZoomVal = zoom < 13 ? zoom : 12;
110
+ mapRef.current.setZoom(setZoomVal);
111
+ }
112
+ }, [location, zoom, mapRef.current]);
113
+
114
+ const fitBounds = (map, overload = false) => {
115
+ if ((mapInteracted === false || overload) && mapItems != null) {
116
+ const bounds = new window.google.maps.LatLngBounds();
117
+ mapItems.forEach(item => {
118
+ bounds.extend(new google.maps.LatLng(item.latitude, item.longitude));
119
+ });
120
+ if (!map) return;
121
+ map.fitBounds(bounds);
122
+ }
123
+ if (mapRef.current.zoom > 17) {
124
+ mapRef.current.setZoom(16);
125
+ }
126
+ };
127
+
128
+ const markerClickHandler = mapLocation => {
129
+ setMapInteracted(true);
130
+ selectLocationEntity(mapLocation);
131
+ };
132
+
133
+ const onLoad = map => {
134
+ if (!location || location === null) {
135
+ mapRef.current = map;
136
+ fitBounds(map, true);
137
+ return;
138
+ }
139
+ mapRef.current = map;
140
+
141
+ if (mapInteracted === false) {
142
+ mapRef.current.panTo(
143
+ new google.maps.LatLng(location.latitude, location.longitude)
144
+ );
145
+
146
+ mapRef.current.setZoom(zoom);
147
+ }
148
+ };
149
+
150
+ const pinIconUrl = pinIcon({
151
+ fillColor: markerConfigs.fillColor,
152
+ strokeColor: markerConfigs.strokeColor
153
+ });
154
+
155
+ return (
156
+ <>{zoom && center && <div ref={mapContainerRef} className="hc-h-full hc-relative">
157
+ <GoogleMap
158
+ zoom={zoom}
159
+ onLoad={onLoad}
160
+ onIdle={onIdle}
161
+ center={center}
162
+ mapContainerStyle={{
163
+ width: "100%",
164
+ height: "100%"
165
+ }}
166
+ options={{
167
+ styles: [
168
+ {
169
+ featureType: "poi",
170
+ elementType: "labels",
171
+ stylers: [{ visibility: "off" }]
172
+ }
173
+ ]
174
+ }}
175
+ >
176
+ <MarkerClustererF options={clusterOptions(clusterGridSize, markerConfigs.fillColor)}>
177
+ {clusterer => (
178
+ <>
179
+ {mapItems.map(item => (
180
+ <MapMarker
181
+ key={item.id}
182
+ item={item}
183
+ selectedLocation={location}
184
+ markerRefs={markerRefs}
185
+ infoWindowClasses={infoWindowClasses}
186
+ setSelectedLocation={setLocation}
187
+ markerClickHandler={markerClickHandler}
188
+ clusterer={clusterer}
189
+ markerIcon={markerIcon(markerConfigs)}
190
+ markerIconSelected={markerIconSelected(markerConfigs)}
191
+ setMapInteracted={setMapInteracted}
192
+ />
193
+ ))}
194
+ {poiMarkers && poiMarkers.markers.map((marker, index) => {
195
+ return (
196
+ <PlaceMarker
197
+ key={`marker-${marker.title}-${index}`}
198
+ marker={marker}
199
+ index={index}
200
+ selectedPlaceMarker={selectedPlaceMarker}
201
+ placesWindow={placesWindow}
202
+ setPlacesWindow={setPlacesWindow}
203
+ setSelectedPlaceMarker={setSelectedPlaceMarker}
204
+ />
205
+ );
206
+ })}
207
+ </>
208
+ )}
209
+ </MarkerClustererF>
210
+ </GoogleMap>
211
+ {mapInteracted && markerConfigs && (
212
+ <ShowAllButton
213
+ mapInteracted={mapInteracted}
214
+ markerConfigs={markerConfigs}
215
+ setMapInteracted={setMapInteracted}
216
+ fitBounds={fitBounds}
217
+ mapRef={mapRef}
218
+ pinIconUrl={pinIconUrl}
219
+ setQuery={setQuery}
220
+ listingCount={filteredListings.length}
221
+ setSelectedFilters={setSelectedFilters}
222
+ />
223
+ )}
224
+ </div>
225
+ }
226
+ </>
227
+ );
228
+ };
229
+
230
+ export default Map;