@abcagency/hc-ui-components 1.3.23 → 1.3.25
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.
- package/package.json +4 -5
- package/src/.editorconfig +12 -0
- package/src/apis/hcApi.ts +109 -0
- package/src/bundleIndex.js +14 -0
- package/src/clientToken.js +9 -0
- package/src/components/HireControlMap.js +135 -0
- package/src/components/containers/accordions/filter-container.js +48 -0
- package/src/components/containers/accordions/filter-item-container.js +66 -0
- package/src/components/containers/accordions/map-accordion-item-container.js +70 -0
- package/src/components/containers/filter/commute-container.js +89 -0
- package/src/components/containers/filter/filter-container.js +76 -0
- package/src/components/containers/filter/filter-item-container.js +71 -0
- package/src/components/containers/filter/location-container.js +45 -0
- package/src/components/containers/filter/points-of-interest-container.js +33 -0
- package/src/components/containers/filter/points-of-interest-radio-item-container.js +35 -0
- package/src/components/containers/filter/search-container.js +50 -0
- package/src/components/containers/jobListing/listing-details-container.js +40 -0
- package/src/components/containers/list/item-list-container.tsx +81 -0
- package/src/components/containers/list/list-item/list-item-container.js +43 -0
- package/src/components/containers/maps/info-window-content-container.js +51 -0
- package/src/components/containers/maps/map-container.js +204 -0
- package/src/components/containers/maps/map-list-container.js +48 -0
- package/src/components/containers/maps/map-marker-container.js +78 -0
- package/src/components/modules/accordions/MapAccordionItem.js +30 -0
- package/src/components/modules/accordions/default.js +171 -0
- package/src/components/modules/accordions/filterItem.js +27 -0
- package/src/components/modules/accordions/filters.js +32 -0
- package/src/components/modules/buttons/button-group-apply.js +123 -0
- package/src/components/modules/buttons/commute-pill.js +22 -0
- package/src/components/modules/buttons/default.js +194 -0
- package/src/components/modules/buttons/items-pill.js +35 -0
- package/src/components/modules/buttons/pill-wrapper.js +27 -0
- package/src/components/modules/buttons/show-all-button.js +20 -0
- package/src/components/modules/cards/default.js +167 -0
- package/src/components/modules/cards/filter.js +56 -0
- package/src/components/modules/dialogs/apply-dialog.js +48 -0
- package/src/components/modules/filter/commute.js +108 -0
- package/src/components/modules/filter/index.js +55 -0
- package/src/components/modules/filter/item.js +48 -0
- package/src/components/modules/filter/location.js +48 -0
- package/src/components/modules/filter/radio-item.js +42 -0
- package/src/components/modules/filter/search.js +65 -0
- package/src/components/modules/filter/sort.js +83 -0
- package/src/components/modules/grid.js +54 -0
- package/src/components/modules/icon.js +33 -0
- package/src/components/modules/jobListing/listing-details.js +109 -0
- package/src/components/modules/list/field-mapper.js +114 -0
- package/src/components/modules/list/header-item.js +91 -0
- package/src/components/modules/list/header.js +49 -0
- package/src/components/modules/list/item-expand-card/index.js +22 -0
- package/src/components/modules/list/item-expand-card/recruiter-contact-nav.js +50 -0
- package/src/components/modules/list/item-expand-card/recruiter-details.js +68 -0
- package/src/components/modules/list/item-expand-card/recruiter-headshot.js +22 -0
- package/src/components/modules/list/item-list.tsx +84 -0
- package/src/components/modules/list/list-item/list-item.js +130 -0
- package/src/components/modules/maps/info-window-card.js +17 -0
- package/src/components/modules/maps/info-window-content.js +35 -0
- package/src/components/modules/maps/map-list.js +28 -0
- package/src/components/modules/maps/map-marker.js +29 -0
- package/src/components/modules/maps/map.js +76 -0
- package/src/components/modules/maps/place-marker.js +41 -0
- package/src/components/modules/maps/tabs.js +81 -0
- package/src/constants/eventTypes.js +13 -0
- package/src/constants/placeTypes.js +8 -0
- package/src/contexts/mapContext.tsx +129 -0
- package/src/contexts/mapListContext.tsx +311 -0
- package/src/contexts/placesContext.js +102 -0
- package/src/contexts/trackEventContext.js +14 -0
- package/src/enums/SectionType.ts +9 -0
- package/src/hooks/useList.js +89 -0
- package/src/index.js +3 -0
- package/src/services/configService.ts +16 -0
- package/src/services/googlePlacesNearbyService.ts +42 -0
- package/src/services/listingAggregatorService.ts +76 -0
- package/src/services/listingEntityService.ts +16 -0
- package/src/services/listingService.ts +40 -0
- package/src/services/recruiterService.ts +18 -0
- package/src/styles/bundle.css +268 -0
- package/src/styles/index.css +24 -0
- package/src/types/Address.ts +7 -0
- package/src/types/ContentSection.ts +9 -0
- package/src/types/GetListingParams.ts +8 -0
- package/src/types/LatLng.ts +4 -0
- package/src/types/ListingEntity.ts +11 -0
- package/src/types/ListingFields.ts +25 -0
- package/src/types/Listings.ts +32 -0
- package/src/types/Recruiter.ts +9 -0
- package/src/types/SimilarListing.ts +24 -0
- package/src/types/config/Colors.ts +8 -0
- package/src/types/config/MapConfig.ts +31 -0
- package/src/types/config/PointsOfInterestConfig.ts +13 -0
- package/src/types/config/SearchConfig.ts +4 -0
- package/src/util/arrayUtil.js +3 -0
- package/src/util/fieldMapper.js +22 -0
- package/src/util/filterUtil.js +239 -0
- package/src/util/loading.js +17 -0
- package/src/util/localStorageUtil.ts +34 -0
- package/src/util/mapIconUtil.js +180 -0
- package/src/util/mapUtil.js +91 -0
- package/src/util/sortUtil.js +33 -0
- package/src/util/stringUtils.js +6 -0
- package/src/util/urlFilterUtil.js +85 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export const getDistinctItemsByProximity = (items, listingEntitiesDetails) => {
|
|
2
|
+
const clusters = {};
|
|
3
|
+
|
|
4
|
+
if (!listingEntitiesDetails) return [];
|
|
5
|
+
|
|
6
|
+
const closeItemPairs = findCloseItems(listingEntitiesDetails);
|
|
7
|
+
if (closeItemPairs.length > 0) {
|
|
8
|
+
listingEntitiesDetails = adjustItemPositions(
|
|
9
|
+
listingEntitiesDetails,
|
|
10
|
+
closeItemPairs
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
items?.forEach(item => {
|
|
15
|
+
if(item.entityId !== -1){
|
|
16
|
+
|
|
17
|
+
const entityDetails = listingEntitiesDetails[item.entityId];
|
|
18
|
+
|
|
19
|
+
if (!entityDetails) {
|
|
20
|
+
console.error(`Details not found for entityId: ${item.entityId}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
item.mapDetails = entityDetails;
|
|
25
|
+
|
|
26
|
+
if (!clusters[item.entityId]) {
|
|
27
|
+
clusters[item.entityId] = {
|
|
28
|
+
...item.mapDetails,
|
|
29
|
+
items: { [item.id]: item }
|
|
30
|
+
};
|
|
31
|
+
} else {
|
|
32
|
+
clusters[item.entityId].items[item.id] = item;
|
|
33
|
+
}}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return Object.values(clusters);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const findCloseItems = itemsObj => {
|
|
40
|
+
const closeItems = [];
|
|
41
|
+
const items = Object.values(itemsObj); // Convert object to array for iteration
|
|
42
|
+
const proximityThreshold = 0.0001;
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < items.length; i++) {
|
|
45
|
+
for (let j = i + 1; j < items.length; j++) {
|
|
46
|
+
const distanceLat = Math.abs(items[i].latitude - items[j].latitude);
|
|
47
|
+
const distanceLng = Math.abs(items[i].longitude - items[j].longitude);
|
|
48
|
+
if (
|
|
49
|
+
distanceLat < proximityThreshold &&
|
|
50
|
+
distanceLng < proximityThreshold
|
|
51
|
+
) {
|
|
52
|
+
closeItems.push({ item1: items[i], item2: items[j] });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return closeItems;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const adjustItemPositions = (itemsObj, closeItemPairs) => {
|
|
61
|
+
const adjustmentValue = 0.0001;
|
|
62
|
+
const adjustedItems = { ...itemsObj }; // Create a shallow copy of the object
|
|
63
|
+
|
|
64
|
+
closeItemPairs.forEach(pair => {
|
|
65
|
+
if (adjustedItems[pair.item1.id] && adjustedItems[pair.item2.id]) {
|
|
66
|
+
adjustedItems[pair.item2.id].latitude += adjustmentValue;
|
|
67
|
+
adjustedItems[pair.item2.id].longitude += adjustmentValue;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return adjustedItems;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const clusterOptions = (clusterGridSize, fillColor) => {
|
|
75
|
+
return {
|
|
76
|
+
gridSize: clusterGridSize,
|
|
77
|
+
styles:[{
|
|
78
|
+
url: createSvgDataUri(fillColor),
|
|
79
|
+
textColor:'white',
|
|
80
|
+
height: 40,
|
|
81
|
+
width: 40
|
|
82
|
+
}]
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
function createSvgDataUri(fillColor) {
|
|
87
|
+
const svg = `<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
|
|
88
|
+
<circle cx="25" cy="25" r="20" fill="${fillColor}" />
|
|
89
|
+
</svg>`;
|
|
90
|
+
return `data:image/svg+xml;base64,${btoa(svg)}`;
|
|
91
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const dynamicSort = (items, fieldName, order = "asc") => {
|
|
2
|
+
if (!items || !items.length) {
|
|
3
|
+
return [];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const inferType = value => {
|
|
7
|
+
if (!isNaN(Date.parse(value)) && isNaN(value)) {
|
|
8
|
+
return "date";
|
|
9
|
+
} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
|
|
10
|
+
return "number";
|
|
11
|
+
} else {
|
|
12
|
+
return "string";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const dataType = inferType(items[0].fields[fieldName]);
|
|
17
|
+
|
|
18
|
+
return items.sort((a, b) => {
|
|
19
|
+
let valA = a.fields[fieldName];
|
|
20
|
+
let valB = b.fields[fieldName];
|
|
21
|
+
if (!valA || !valB) return;
|
|
22
|
+
let comparison = 0;
|
|
23
|
+
|
|
24
|
+
if (dataType === "string") {
|
|
25
|
+
comparison = valA.localeCompare(valB);
|
|
26
|
+
} else if (dataType === "number") {
|
|
27
|
+
comparison = valA - valB;
|
|
28
|
+
} else if (dataType === "date") {
|
|
29
|
+
comparison = new Date(valA) - new Date(valB);
|
|
30
|
+
}
|
|
31
|
+
return order === "desc" ? comparison * -1 : comparison;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const updateURLWithFilters = (filters, location, query) => {
|
|
2
|
+
const searchParams = new URLSearchParams(location.search);
|
|
3
|
+
|
|
4
|
+
for (const key of searchParams.keys()) {
|
|
5
|
+
if (key.includes('.') || key === 'query') {
|
|
6
|
+
searchParams.delete(key);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (query) {
|
|
11
|
+
searchParams.set('query', query);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for (const category in filters) {
|
|
15
|
+
for (const filter in filters[category]) {
|
|
16
|
+
const key = `${category}.${filter}`;
|
|
17
|
+
if (filters[category][filter]) {
|
|
18
|
+
searchParams.set(key, 'true');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const newUrl = `${location.pathname}?${searchParams.toString()}`;
|
|
24
|
+
window.history.replaceState({}, '', newUrl);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function notifyParentOfUrlChange() {
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
var message = {
|
|
30
|
+
type: 'URL_CHANGE',
|
|
31
|
+
url: window.location.href
|
|
32
|
+
};
|
|
33
|
+
window.parent.postMessage(message, "*");
|
|
34
|
+
}, 500);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const parseQueryParams = search => {
|
|
38
|
+
const queryParams = {};
|
|
39
|
+
if (!search) return queryParams;
|
|
40
|
+
let queryString = search.split('?')[1];
|
|
41
|
+
if (!queryString) {
|
|
42
|
+
return queryParams;
|
|
43
|
+
}
|
|
44
|
+
queryString = queryString.replaceAll('+', ' ');
|
|
45
|
+
queryString.split('&').forEach(param => {
|
|
46
|
+
const [key, value] = param.split('=');
|
|
47
|
+
queryParams[decodeURIComponent(key)] = decodeURIComponent(value);
|
|
48
|
+
});
|
|
49
|
+
return queryParams;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const filtersFromURL = location => {
|
|
53
|
+
if (!location || !location.search) return;
|
|
54
|
+
const filters = {};
|
|
55
|
+
let queryParam = null;
|
|
56
|
+
const queryParams = parseQueryParams(location.search);
|
|
57
|
+
if (!queryParams) return;
|
|
58
|
+
Object.keys(queryParams).forEach(key => {
|
|
59
|
+
if (key && key.includes('.')) {
|
|
60
|
+
const [category, filter] = key.split('.');
|
|
61
|
+
if (!filters[category]) {
|
|
62
|
+
filters[category] = {};
|
|
63
|
+
}
|
|
64
|
+
filters[category][filter] = queryParams[key] === 'true';
|
|
65
|
+
} else if (key === 'query') {
|
|
66
|
+
queryParam = queryParams[key];
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return { filters, query: queryParam };
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const hasFiltersInURL = location => {
|
|
74
|
+
if (!location || !location.search) return;
|
|
75
|
+
const queryParams = parseQueryParams(location.search);
|
|
76
|
+
if (!queryParams) return;
|
|
77
|
+
return Object.keys(queryParams).some(key => key.includes('.'));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const hasQueryInUrl = location => {
|
|
81
|
+
if (!location || !location.search) return;
|
|
82
|
+
const queryParams = parseQueryParams(location.search);
|
|
83
|
+
if (!queryParams) return;
|
|
84
|
+
return Object.keys(queryParams).includes('query');
|
|
85
|
+
};
|