import { algoliasearch } from "algoliasearch"; const ALGOLIA_KEY = "9fb3db0222f7b5aef0e2b30791ee6201"; const INDEX_NAME = "pubfinder"; const client = algoliasearch("YSWWVAX5RB", ALGOLIA_KEY); const algolia_params = { hitsPerPage: 1000, }; const dataController = (function () { const londonBounds = { north: 51.532, south: 51.478, east: -0.072, west: -0.16, }; const maxMapSpace = { north: 51.74, south: 51.27, west: -0.51, east: 0.23, }; const centralPosition = { lat: 51.508616, lng: -0.125319 }; return { londonBounds, centralPosition, maxMapSpace, getSearchResults: async function (bounds) { const res = await client.searchSingleIndex({ indexName: INDEX_NAME, searchParams: { ...algolia_params, insideBoundingBox: [bounds], attributesToRetrieve: ["_geoloc", "name"], }, }); return res; }, }; })(); const interfaceController = (function () { let markers = []; let shape; let map; return { generateMap: async function (bounds, position, maxSpace) { const { Map, Polygon, Rectangle } = await google.maps.importLibrary( "maps" ); map = new Map(document.getElementById("map"), { zoom: 4, center: position, mapId: "pub_map", restriction: { latLngBounds: maxSpace, strictBounds: true, }, }); shape = new Rectangle({ bounds: bounds, editable: true, draggable: true, }); shape.setMap(map); }, embedSearchResults: async function (hits) { const { AdvancedMarkerElement } = await google.maps.importLibrary( "marker" ); const { InfoWindow } = await google.maps.importLibrary("maps"); hits.forEach((hit) => { const marker = new AdvancedMarkerElement({ map: map, position: { lat: hit._geoloc.lat, lng: hit._geoloc.lng, }, }); const window = new InfoWindow({ content: hit.name, }); marker.addListener("click", function () { window.open({ anchor: marker, map, }); }); markers.push(marker); }); }, handleBoundChange: function () { const { south, west, north, east } = shape.getBounds()?.toJSON(); return [north, east, south, west]; }, getActiveShape: function () { return shape; }, removeMarkers: function () { for (let i = 0; i < markers.length; i++) { markers[i].setMap(null); } }, }; })(); const controller = (function (dataCTRL, uiCTRL) { const initialSetup = async function () { const londonBounds = dataCTRL.londonBounds; const centralPoint = dataCTRL.centralPosition; const mapBounds = dataCTRL.maxMapSpace; uiCTRL.generateMap(londonBounds, centralPoint, mapBounds); const searchResults = await dataCTRL.getSearchResults([ londonBounds.north, londonBounds.east, londonBounds.south, londonBounds.west, ]); await uiCTRL.embedSearchResults(searchResults.hits); }; const setupEventListeners = function () { const shape = uiCTRL.getActiveShape(); shape.addListener("bounds_changed", async () => { uiCTRL.removeMarkers(); const newAlgoliaBounds = uiCTRL.handleBoundChange(); const searchResults = await dataCTRL.getSearchResults(newAlgoliaBounds); await uiCTRL.embedSearchResults(searchResults.hits); }); }; return { init: async function () { await initialSetup(); setupEventListeners(); }, }; })(dataController, interfaceController); controller.init();