{"version":3,"sources":["components/WorkshopCard/style.tsx","assets/img/placeholder/workshop_card.png","components/WorkshopCard/index.tsx","pages/WorkshopPage/style.tsx","assets/img/root_marker.svg","components/Pointer/style.tsx","assets/img/workshop-star.svg","components/Pointer/index.tsx","utility/shiftscrollplugin.ts","assets/img/chevron-list.svg","assets/img/current_location.svg","pages/WorkshopPage/index.tsx"],"names":["CardStyle","Styled","div","WorkshopCard","name_id","distance","id","image","name","address","phoneNo","operatingHours","listView","todayDay","moment","format","toLowerCase","todayOperatingHour","find","operatingHour","day","includes","className","to","style","width","padding","src","WorkshopPlaceholder","pathname","textDecoration","locate","phone","clock","time","MapStyle","PointStyle","WorkshopPoints","lat","lng","hoveredId","onClick","hovered","title","star","alt","rootMarker","ShiftScrollPlugin","delta","fromEvent","test","type","shiftKey","x","y","ScrollbarPlugin","pluginName","SmoothScrollbar","use","MapSection","useGeolocated","positionOptions","enableHighAccuracy","userDecisionTimeout","coords","isGeolocationEnabled","mapRef","useRef","search","useLocation","scrollRef","useState","workshops","setWorkshops","points","setPoints","root","setRoot","SETTINGS","defaultMapCenter","defaultLat","setDefaultLat","defaultLng","setDefaultLng","hasTimeout","setHasTimeout","reqHeaders","setReqHeaders","clickLat","setClickLat","clickLng","setClickLng","dragLat","setDragLat","dragLng","setDragLng","zoom","setZoom","bounds","setBounds","myLat","setMyLat","myLng","setMyLng","listStatus","setListStatus","setHoveredId","ClusterMarker","count","cluster","length","height","expansionZoom","Math","min","supercluster","getClusterExpansionZoom","current","panTo","centerLoaded","setCenterLoaded","isLoading","setIsLoading","loadingWidth","setLoadingWidth","loadingHeight","setLoadingHeight","isDragLoading","setIsDragLoading","useEffect","filter","latitude","longitude","map","properties","geometry","coordinates","parseFloat","data","MyLocationDot","handleSpinnerSize","window","innerWidth","addEventListener","getWorkshops","queryParams","URLSearchParams","location","typeId","get","distanceId","productName","params","sort_by","APIV2Service","API","workshop","then","res","catch","error","console","log","finally","total","PageSize","getPoints","meta","i","old","getRoots","Object","keys","getDragWorkshops","cachedLocation","sessionStorage","getItem","JSON","parse","fetchLocation","getLocationByCoords","headers","country","state","city","setTimeout","useSupercluster","options","radius","maxZoom","clusters","handleOnclick","getClickWorkshops","PageLayout","color","bootstrapURLKeys","key","process","language","region","onDragEnd","center","getZoom","yesIWantToUseGoogleMapApiInternals","onGoogleApiLoaded","onChange","nw","se","index","isCluster","pointCount","point_count","currentLocation","chevron","transform","alwaysShowTracks","ref","distance_radius","image_url","phone_number","operating_hours","onMouseEnter","handleHovered"],"mappings":"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","file":"static/js/9.e3de54db.chunk.js","sourcesContent":["import Styled from 'styled-components';\r\n\r\nconst CardStyle = Styled.div`\r\n width: 100%;\r\n position: relative;\r\n\r\n .recent-distance {\r\n width: fit-content;\r\n padding: 2px 8px;\r\n margin-bottom: 7.5px;\r\n border-radius: 15px;\r\n height: fit-content;\r\n background-color: red;\r\n\r\n h2 {\r\n font-family: 'Montserrat';\r\n font-style: normal;\r\n font-weight: 500;\r\n font-size: 10px;\r\n line-height: 12px;\r\n text-align: center;\r\n color: #FFFFFF;\r\n margin: 0;\r\n }\r\n }\r\n\r\n h3 {\r\n font-family: 'Montserrat';\r\n font-style: normal;\r\n font-weight: 700;\r\n font-size: 14px;\r\n line-height: 17px;\r\n color: #00529B;\r\n white-space: pre-wrap; /* Webkit */ \r\n white-space: -moz-pre-wrap; /* Firefox */ \r\n white-space: -pre-wrap; /* Opera <7 */ \r\n white-space: -o-pre-wrap; /* Opera 7 */ \r\n word-wrap: break-word; \r\n }\r\n\r\n .recent-text {\r\n max-width: 300px;\r\n \r\n img {\r\n width: 12px;\r\n height: 12px;\r\n }\r\n\r\n p {\r\n font-family: 'Montserrat';\r\n font-style: normal;\r\n font-weight: 500;\r\n font-size: 10px;\r\n line-height: 12px;\r\n margin-left: 5px;\r\n padding: 0;\r\n color: #343434;\r\n margin-bottom: 0.5rem;\r\n white-space: pre-wrap; /* Webkit */ \r\n white-space: -moz-pre-wrap; /* Firefox */ \r\n white-space: -pre-wrap; /* Opera <7 */ \r\n white-space: -o-pre-wrap; /* Opera 7 */ \r\n word-wrap: break-word; \r\n width: 100%\r\n }\r\n }\r\n \r\n .recent-image {\r\n width: 100%;\r\n height: 91px;\r\n\r\n img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n border-radius: 15px;\r\n }\r\n }\r\n\r\n .list-view {\r\n justify-content: center;\r\n padding-left: auto; \r\n\r\n }\r\n\r\n .has-distance, .grid-margin {\r\n margin-top: 10px;\r\n }\r\n\r\n @media screen and (min-width: 576px) {\r\n .recent-image {\r\n height: 142px;\r\n }\r\n }\r\n\r\n @media screen and (min-width: 768px) {\r\n .recent-distance {\r\n border-radius: 20px;\r\n h2 {\r\n font-size: 14px;\r\n line-height: 17px;\r\n }\r\n }\r\n\r\n h3 {\r\n font-size: 18px;\r\n line-height: 22px;\r\n }\r\n\r\n .recent-text {\r\n max-width: 400px;\r\n\r\n img {\r\n margin-top: 2px;\r\n width: 15px;\r\n height: 15px;\r\n }\r\n\r\n p {\r\n font-size: 16px;\r\n line-height: 20px; \r\n margin-bottom: 0.7rem;\r\n }\r\n }\r\n \r\n .recent-image {\r\n height: 192px;\r\n\r\n img {\r\n border-radius: 20px;\r\n }\r\n }\r\n\r\n .list-view {\r\n padding-left: 30px; \r\n }\r\n }\r\n\r\n @media screen and (min-width: 992px) {\r\n .has-distance, .grid-margin {\r\n margin-top: 25px;\r\n }\r\n\r\n .recent-image {\r\n height: 243px;\r\n }\r\n\r\n .list-view {\r\n justify-content: flex-start;\r\n padding-left: 50px; \r\n }\r\n }\r\n\r\n media screen and (min-width: 1400px) {\r\n }\r\n \r\n`\r\n\r\nexport {CardStyle};","export default __webpack_public_path__ + \"static/media/workshop_card.fff51eeb.png\";","import React from 'react';\r\nimport { Link } from 'react-router-dom';\r\nimport { CardStyle } from './style';\r\n\r\n// Assets\r\nimport WorkshopPlaceholder from 'assets/img/placeholder/workshop_card.png';\r\nimport locate from 'assets/img/locate.svg';\r\nimport phone from 'assets/img/phone.svg';\r\nimport clock from 'assets/img/clock.svg';\r\nimport moment from 'moment';\r\n\r\ninterface WorkshopCardType {\r\n name_id: string;\r\n id: number;\r\n distance: string;\r\n image: string;\r\n name: string;\r\n address: string;\r\n phoneNo: string;\r\n operatingHours: [];\r\n listView?: boolean;\r\n}\r\n\r\nconst WorkshopCard = ({\r\n name_id,\r\n id,\r\n distance,\r\n image,\r\n name,\r\n address,\r\n phoneNo,\r\n operatingHours,\r\n listView,\r\n}: WorkshopCardType): JSX.Element => {\r\n const todayDay = moment().format('ddd').toLowerCase();\r\n\r\n const todayOperatingHour: any = operatingHours.find((operatingHour: any) => {\r\n if (operatingHour && operatingHour.day.toLowerCase().includes(todayDay)) {\r\n return operatingHour;\r\n }\r\n\r\n return null;\r\n });\r\n\r\n return (\r\n <CardStyle>\r\n <div className=\"row\">\r\n {distance && (\r\n <div className=\"col-12\">\r\n <div className=\"recent-distance\">\r\n <h2>{distance} KM away</h2>\r\n </div>\r\n </div>\r\n )}\r\n <div className={'p-0 ' + (listView ? 'col-5 col-lg-4' : 'col-12')}>\r\n <div\r\n className={\r\n 'd-flex flex-column align-items-start ' +\r\n (listView ? 'justify-content-center' : 'justify-content-start')\r\n }\r\n >\r\n <Link to={'/workshop/' + name_id} style={{ width: '100%', padding: '0 12px' }}>\r\n <div className=\"recent-image\">\r\n <img src={image ? image : WorkshopPlaceholder}></img>\r\n </div>\r\n </Link>\r\n </div>\r\n </div>\r\n <div\r\n className={(listView ? 'col-7 col-lg-8' : 'col-12 grid-margin') + (distance ? ' has-distance' : '')}\r\n >\r\n <div\r\n className={\r\n 'h-100 d-flex flex-column justify-content-center justify-content-lg-start ' +\r\n (listView ? 'list-view' : '')\r\n }\r\n >\r\n <Link to={{ pathname: '/workshop/' + name_id }} style={{ textDecoration: 'none' }} >\r\n <h3>{name}</h3>\r\n </Link>\r\n\r\n {address && (\r\n <div className=\"recent-text d-flex align-items-start\">\r\n <img src={locate} />\r\n <p>{address}</p>\r\n </div>\r\n )}\r\n {phoneNo && (\r\n <div className=\"recent-text d-flex align-items-start\">\r\n <img src={phone} />\r\n <p>{phoneNo}</p>\r\n </div>\r\n )}\r\n {todayOperatingHour && (\r\n <div className=\"recent-text d-flex align-items-start\">\r\n <img src={clock} />\r\n <div className=\"d-flex flex-column flex-md-row flex-wrap justify-content-between justify-content-md-start w-100\">\r\n {todayOperatingHour.day && <p className=\"mb-0 me-md-4\">{todayOperatingHour.day}</p>}\r\n {todayOperatingHour.time && <p className=\"mb-0\">{todayOperatingHour.time}</p>}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </CardStyle >\r\n );\r\n};\r\n\r\nexport default WorkshopCard;\r\n","import Styled from 'styled-components';\r\n\r\nconst MapStyle = Styled.div`\r\n height: fit-content;\r\n background: #ffffff;\r\n color: #FFFFFF;\r\n overflow: hidden;\r\n\r\n .cluster-marker {\r\n width: 28px;\r\n height: 28px;\r\n border-radius: 50%;\r\n border: 4px solid #00519E;\r\n background: white;\r\n color: black;\r\n text-align: center;\r\n align-items: center;\r\n display: flex;\r\n justify-content: center;\r\n font-family: 'Montserrat';\r\n font-size: 16px;\r\n font-weight: 700;\r\n z-index: 100;\r\n }\r\n\r\n .map-div {\r\n height: calc(100vh - 108px);\r\n width: 100%;\r\n overflow-y: hidden;\r\n position: relative;\r\n\r\n .my-location-button {\r\n background: white;\r\n border-radius: 2.5px;\r\n position: absolute;\r\n cursor: pointer;\r\n user-select: none;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n width: 40px;\r\n height: 40px;\r\n bottom: 120px;\r\n right: 10px;\r\n z-index: 999;\r\n\r\n img {\r\n width: 22.5px;\r\n height: 22.5px;\r\n }\r\n }\r\n\r\n .my-location {\r\n height: 2em;\r\n width: 2em;\r\n border-radius: 50%;\r\n background-color: #2a6bcc;\r\n z-index: 999;\r\n position: relative;\r\n\r\n .my-location-shine {\r\n height: 3em;\r\n width: 3em;\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background-color: #2a6bcc;\r\n opacity: 0.4;\r\n border-radius: 50%;\r\n animation: shine 2s ease-in-out infinite;\r\n }\r\n\r\n @keyframes shine {\r\n 0% {\r\n width: 3em;\r\n height: 3em;\r\n }\r\n\r\n 20% {\r\n width: 3.75em;\r\n height: 3.75em;\r\n }\r\n\r\n 40% {\r\n width: 3em;\r\n height: 3em;\r\n }\r\n\r\n 100% {\r\n width: 3em;\r\n height: 3em;\r\n }\r\n }\r\n } \r\n }\r\n\r\n .drag-load {\r\n position: absolute;\r\n left: 50%;\r\n top: 50%;\r\n transform:translate(-50%, -50%);\r\n z-index: 999;\r\n }\r\n\r\n .toggle-list {\r\n width: fit-content;\r\n text-align: center;\r\n height: fit-content;\r\n padding: 10px 17.5px 10px 17.5px;\r\n left: 10px;\r\n top: 125px;\r\n border-radius: 25px;\r\n background: white;\r\n position: absolute;\r\n color: #343434;\r\n font-size: 14px;\r\n line-height: 17px;\r\n font-family: 'Montserrat';\r\n user-select: none;\r\n\r\n img {\r\n width: 20px;\r\n height: 20px;\r\n margin-left: 5px\r\n }\r\n\r\n :hover {\r\n cursor: pointer\r\n }\r\n }\r\n \r\n .suggest {\r\n top: 180px;\r\n left: 10px;\r\n padding: 15px 5px 15px 15px;\r\n padding-bottom: 50px;\r\n border-radius: 20px;\r\n background: white;\r\n position: absolute;\r\n width: 180px;\r\n height: calc(100% - 240px);\r\n overflow: hidden;\r\n\r\n .recent-list {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n margin-top: 25px;\r\n margin-bottom: 25px;\r\n padding-bottom: 5px;\r\n overflow-y: hidden;\r\n height: calc(100% - 50px);\r\n\r\n ::-webkit-scrollbar {\r\n appearance: none;\r\n }\r\n\r\n .scrollbar {\r\n overflow: unset !important;\r\n }\r\n\r\n .list-item {\r\n width: 90%;\r\n max-width: 180px;\r\n margin-top: 12.5px;\r\n margin-bottom: 12.5px;\r\n }\r\n }\r\n\r\n h1 {\r\n font-family: 'Montserrat';\r\n font-style: normal;\r\n font-weight: 700;\r\n font-size: 16px;\r\n line-height: 20px;\r\n color: #000000;\r\n opacity: 0.7;\r\n margin-right: 30px;\r\n }\r\n\r\n hr {\r\n opacity: 0.7;\r\n background-color: #000000;\r\n border: 2.5px solid #000000;\r\n width: 120px;\r\n margin: 10px 0;\r\n border-radius: 5px 5px 5px 5px;\r\n }\r\n }\r\n\r\n .scrollbar-track-y {\r\n width: 5px !important;\r\n right: 5px;\r\n display: block !important;\r\n border: 2px solid #ffffff;\r\n background: #4c3d32;\r\n }\r\n\r\n .scrollbar-thumb-y {\r\n width: 8px !important;\r\n background: red;\r\n left: -3.5px;\r\n }\r\n\r\n .scroll-content {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .empty-container {\r\n width: 100%;\r\n display: flex;\r\n justify-content: center;\r\n padding: 30px 0;\r\n\r\n .nofound-text {\r\n font-family: 'Montserrat';\r\n font-style: normal;\r\n font-weight: 700;\r\n font-size: 18px;\r\n line-height: 22px;\r\n color: #343434;\r\n }\r\n }\r\n\r\n .loading-container {\r\n width: 100%;\r\n height: 350px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n }\r\n\r\n @media screen and (min-width: 768px) {\r\n .map-div {\r\n height: calc(100vh - 150px);\r\n }\r\n\r\n .suggest {\r\n height: calc(100% - 280px);\r\n top: 250px;\r\n width: 360px;\r\n left: 50px;\r\n padding: 30px;\r\n overflow-x: hidden;\r\n\r\n .recent-list { \r\n margin-top: 30px;\r\n margin-bottom: 30px;\r\n height: calc(100% - 60px);\r\n\r\n .list-item {\r\n max-width: none;\r\n }\r\n\r\n ::-webkit-scrollbar-button:end:increment {\r\n width: 30%;\r\n }\r\n \r\n ::-webkit-scrollbar-button:start:increment {\r\n width: 30%;\r\n }\r\n }\r\n\r\n h1 {\r\n font-size: 18px;\r\n line-height: 20px;\r\n margin: 0\r\n }\r\n\r\n hr {\r\n width: 240px;\r\n }\r\n }\r\n\r\n .toggle-list {\r\n left: 50px;\r\n top: 180px;\r\n font-size: 18px;\r\n line-height: 22px;\r\n }\r\n\r\n .empty-container {\r\n padding: 50px 0;\r\n\r\n .nofound-text {\r\n font-size: 30px;\r\n line-height: 37px;\r\n }\r\n }\r\n }\r\n\r\n @media screen and (min-width: 992px) {\r\n .toggle-list {\r\n top: 160px;\r\n }\r\n\r\n .suggest {\r\n height: calc(100% - 280px);\r\n top: 220px;\r\n width: 420px;\r\n .recent-list {\r\n ::-webkit-scrollbar-button:end:increment {\r\n width: 40%;\r\n }\r\n \r\n ::-webkit-scrollbar-button:start:increment {\r\n width: 40%;\r\n }\r\n }\r\n\r\n h1 {\r\n font-size: 20px;\r\n line-height: 24px;\r\n }\r\n }\r\n }\r\n\r\n @media screen and (min-width: 1200px) {\r\n\r\n .map-div {\r\n height: calc(100vh - 120px);\r\n }\r\n\r\n .suggest {\r\n top: 200px;\r\n height: calc(100% - 230px);\r\n .recent-list {\r\n .list-item {\r\n width: 90%\r\n }\r\n }\r\n }\r\n\r\n .toggle-list {\r\n top: 140px;\r\n }\r\n }\r\n\r\n @media screen and (min-width: 1400px) {\r\n .suggest {\r\n .recent-list {\r\n .list-item {\r\n width: 90%\r\n }\r\n }\r\n }\r\n }\r\n \r\n\r\n\r\n`;\r\n\r\nexport { MapStyle };\r\n","export default __webpack_public_path__ + \"static/media/root_marker.d845ed0a.svg\";","import Styled from 'styled-components';\r\n\r\nconst PointStyle = Styled.div`\r\n position: relative;\r\n \r\n .root {\r\n height: 25px;\r\n width: 25px;\r\n display: flex;\r\n justify-content: center;\r\n position: relative;\r\n align-items: center;\r\n z-index: 2;\r\n\r\n .root-star {\r\n position: absolute;\r\n width: 22.5px;\r\n top: -12.5%;\r\n left: 50%;\r\n transform: translate(-50%, -12.5%);\r\n z-index: 3;\r\n }\r\n \r\n .root-tail {\r\n width: 100%;\r\n \r\n :hover {\r\n cursor: pointer\r\n }\r\n }\r\n }\r\n\r\n .root-hovered {\r\n z-index: 9;\r\n\r\n .root-star {\r\n z-index: 10;\r\n }\r\n }\r\n`\r\n\r\nexport { PointStyle };","export default __webpack_public_path__ + \"static/media/workshop-star.b031a15f.svg\";","import React, { useState, useRef } from 'react';\r\nimport rootMarker from 'assets/img/root_marker.svg';\r\nimport { PointStyle } from './style';\r\nimport star from 'assets/img/workshop-star.svg';\r\n\r\ninterface pointsInfo {\r\n onClick: (lat: number, lng: number) => void;\r\n name_id: string;\r\n lat: number;\r\n lng: number;\r\n hoveredId: string;\r\n}\r\n\r\nconst WorkshopPoints = ({ name_id, lat, lng, hoveredId, onClick }: pointsInfo): JSX.Element => {\r\n\r\n const hovered = (hoveredId == name_id)\r\n\r\n const handleClick = () => {\r\n onClick(lat, lng)\r\n };\r\n\r\n return (\r\n <PointStyle onClick={handleClick}>\r\n <div className={`root ${hovered ? 'root-hovered' : ''}`} title={name_id}>\r\n {hovered && <img src={star} className='root-star' alt=\"star\"></img>}\r\n <img src={rootMarker} className='root-tail' alt=\"root\" />\r\n </div>\r\n </PointStyle>\r\n );\r\n};\r\n\r\nexport default WorkshopPoints;","import { ScrollbarPlugin } from 'smooth-scrollbar';\r\n\r\nexport default class ShiftScrollPlugin extends ScrollbarPlugin {\r\n static pluginName = 'ShiftScroll';\r\n\r\n transformDelta(delta: { x: any; y: any }, fromEvent: any): any {\r\n return /wheel/.test(fromEvent.type) && fromEvent.shiftKey ? { x: delta.y, y: delta.x } : delta;\r\n }\r\n}\r\n","export default __webpack_public_path__ + \"static/media/chevron-list.9b4537ff.svg\";","export default __webpack_public_path__ + \"static/media/current_location.70291298.svg\";","import React, { useState, useEffect, useRef } from 'react';\r\nimport PageLayout from 'containers/PageLayout';\r\nimport { MapStyle } from './style';\r\nimport { SETTINGS } from 'config/settings';\r\nimport GoogleMapReact from 'google-map-react';\r\nimport WorkshopPointer from 'components/Pointer';\r\nimport WorkshopCard from 'components/WorkshopCard';\r\nimport { Scrollbar } from 'smooth-scrollbar-react';\r\nimport SmoothScrollbar from 'smooth-scrollbar';\r\nimport { TailSpin } from 'react-loader-spinner';\r\nimport { useGeolocated } from 'react-geolocated';\r\nimport { getLocationByCoords } from 'utility/geocode';\r\nimport APIV2Service from 'api/apiV2Service';\r\nimport { API } from 'api';\r\nimport ShiftScrollPlugin from 'utility/shiftscrollplugin';\r\nimport { useLocation } from 'react-router-dom';\r\nimport useSupercluster from 'use-supercluster';\r\n\r\nimport chevron from 'assets/img/chevron-list.svg';\r\nimport currentLocation from 'assets/img/current_location.svg';\r\n\r\nSmoothScrollbar.use(ShiftScrollPlugin);\r\n\r\ninterface MyLocation {\r\n lat: number;\r\n lng: number;\r\n}\r\n\r\ninterface MyCluster {\r\n lat: number;\r\n lng: number;\r\n count: number;\r\n cluster: any;\r\n}\r\n\r\nconst MapSection = (): JSX.Element => {\r\n const { coords, isGeolocationEnabled } = useGeolocated({\r\n positionOptions: {\r\n enableHighAccuracy: false,\r\n },\r\n userDecisionTimeout: 5000,\r\n });\r\n\r\n const mapRef = useRef<any>();\r\n const { search } = useLocation();\r\n const scrollRef = useRef<any>(null);\r\n const [workshops, setWorkshops] = useState<any[]>([]);\r\n const [points, setPoints] = useState<any[]>([]);\r\n const [root, setRoot] = useState<any[]>([]);\r\n const [defaultLat, setDefaultLat] = useState(SETTINGS.defaultMapCenter.lat);\r\n const [defaultLng, setDefaultLng] = useState(SETTINGS.defaultMapCenter.lng);\r\n const [hasTimeout, setHasTimeout] = useState(false);\r\n const [reqHeaders, setReqHeaders] = useState({});\r\n const [clickLat, setClickLat] = useState(0);\r\n const [clickLng, setClickLng] = useState(0);\r\n const [dragLat, setDragLat] = useState(0);\r\n const [dragLng, setDragLng] = useState(0);\r\n const [zoom, setZoom] = useState(14);\r\n const [bounds, setBounds] = useState<any>(null);\r\n const [myLat, setMyLat] = useState(0);\r\n const [myLng, setMyLng] = useState(0);\r\n const [listStatus, setListStatus] = useState(false);\r\n const [hoveredId, setHoveredId] = useState('');\r\n\r\n const ClusterMarker = ({ lat, lng, count, cluster }: MyCluster): JSX.Element => {\r\n return (\r\n <div\r\n className=\"cluster-marker\"\r\n style={{\r\n width: `${50 + (count / points.length) * 20}px`,\r\n height: `${50 + (count / points.length) * 20}px`,\r\n }}\r\n onClick={() => {\r\n const expansionZoom = Math.min(supercluster.getClusterExpansionZoom(cluster.id), 20);\r\n\r\n if (mapRef && mapRef.current) {\r\n mapRef.current.setZoom(expansionZoom);\r\n mapRef.current.panTo({ lat: lat, lng: lng });\r\n }\r\n }}\r\n >\r\n {count}\r\n </div>\r\n );\r\n };\r\n\r\n // Prevent running handleCenterLocation if user drags the map and map reload new data\r\n const [centerLoaded, setCenterLoaded] = useState(false);\r\n\r\n // Handle loading spinner\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [loadingWidth, setLoadingWidth] = useState(100);\r\n const [loadingHeight, setLoadingHeight] = useState(100);\r\n const [isDragLoading, setIsDragLoading] = useState(false);\r\n\r\n useEffect(() => {\r\n const points = root\r\n .filter(({ latitude, longitude }: any) => latitude && longitude)\r\n .map((root) => ({\r\n type: 'Feature',\r\n properties: { cluster: false, id: root.name_id },\r\n geometry: {\r\n type: 'Point',\r\n coordinates: [parseFloat(root.longitude), parseFloat(root.latitude)],\r\n },\r\n data: root,\r\n }));\r\n\r\n setPoints(points);\r\n }, [root]);\r\n\r\n useEffect(() => {\r\n if (coords) {\r\n setMyLat(coords.latitude);\r\n setMyLng(coords.longitude);\r\n }\r\n }, [coords]);\r\n\r\n const handleHovered = (id: string) => {\r\n setHoveredId(id);\r\n };\r\n\r\n const handleList = () => {\r\n if (listStatus) {\r\n setListStatus(false);\r\n } else {\r\n setListStatus(true);\r\n }\r\n };\r\n\r\n const MyLocationDot = ({ lat, lng }: MyLocation): JSX.Element => {\r\n return (\r\n <div className=\"my-location\">\r\n <div className=\"my-location-shine\" />\r\n </div>\r\n );\r\n };\r\n\r\n const handleSpinnerSize = () => {\r\n if (window.innerWidth >= 768) {\r\n setLoadingWidth(100);\r\n setLoadingHeight(100);\r\n } else {\r\n setLoadingWidth(25);\r\n setLoadingHeight(25);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n handleSpinnerSize();\r\n window.addEventListener('resize', handleSpinnerSize);\r\n }, []);\r\n\r\n const getWorkshops = () => {\r\n setIsLoading(true);\r\n\r\n const queryParams = new URLSearchParams(window.location.search);\r\n const typeId = queryParams.get('type');\r\n const distanceId = queryParams.get('distance');\r\n const productName = queryParams.get('product_name');\r\n const name = queryParams.get('name');\r\n const address = queryParams.get('address');\r\n\r\n const params: any = { sort_by: 'distance' };\r\n if (typeId) {\r\n params['workshop_type_id'] = typeId;\r\n }\r\n if (distanceId) {\r\n params['distance_id'] = distanceId;\r\n }\r\n if (productName) {\r\n params['product_name'] = productName;\r\n }\r\n if (name) {\r\n params['name'] = name;\r\n }\r\n if (coords) {\r\n params['latitude'] = coords.latitude;\r\n params['longitude'] = coords.longitude;\r\n }\r\n if (dragLng && dragLat) {\r\n params['latitude'] = dragLat;\r\n params['longitude'] = dragLng;\r\n }\r\n if (address) {\r\n params['address'] = address;\r\n }\r\n\r\n params['PageSize'] = 20;\r\n\r\n APIV2Service.get(API.workshop.getWorkshops, params, reqHeaders)\r\n .then((res) => {\r\n setWorkshops(res.data.data.data);\r\n })\r\n .catch((error) => {\r\n console.log(error);\r\n })\r\n .finally(() => {\r\n setIsLoading(false);\r\n });\r\n };\r\n\r\n const getRoots = () => {\r\n const size = 5000;\r\n let total = 0;\r\n const params: any = { PageSize: size };\r\n\r\n APIV2Service.get(API.workshop.getPoints)\r\n .then((res) => {\r\n total = res.data.data.meta.total;\r\n for (let i = 0; i <= total / size; i++) {\r\n params['Page'] = i + 1;\r\n APIV2Service.get(API.workshop.getPoints, params, reqHeaders)\r\n .then((res) => {\r\n setRoot((old) => [...old, ...res.data.data.data]);\r\n })\r\n .catch((error) => {\r\n console.log(error);\r\n });\r\n }\r\n })\r\n .catch((error) => {\r\n console.log(error);\r\n })\r\n .finally(() => {\r\n setIsDragLoading(false);\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n getRoots();\r\n }, []);\r\n\r\n const getClickWorkshops = () => {\r\n setIsDragLoading(true);\r\n const queryParams = new URLSearchParams(window.location.search);\r\n const typeId = queryParams.get('type');\r\n const distanceId = queryParams.get('distance');\r\n const productName = queryParams.get('product_name');\r\n const name = queryParams.get('name');\r\n const address = queryParams.get('address');\r\n\r\n const params: any = { sort_by: 'distance' };\r\n if (typeId) {\r\n params['workshop_type_id'] = typeId;\r\n }\r\n if (distanceId) {\r\n params['distance_id'] = distanceId;\r\n }\r\n if (productName) {\r\n params['product_name'] = productName;\r\n }\r\n if (name) {\r\n params['name'] = name;\r\n }\r\n if (address) {\r\n params['address'] = address;\r\n }\r\n params['latitude'] = clickLat;\r\n params['longitude'] = clickLng;\r\n params['PageSize'] = 20;\r\n APIV2Service.get(API.workshop.getWorkshops, params, reqHeaders)\r\n .then((res) => {\r\n setWorkshops(res.data.data.data);\r\n })\r\n .catch((error) => {\r\n console.log(error);\r\n })\r\n .finally(() => {\r\n setIsDragLoading(false);\r\n // refresh the clicklatlng as user might click on the same clicklat and useeffect doesnt work due to same value\r\n setClickLat(0)\r\n setClickLng(0)\r\n });\r\n };\r\n\r\n const getDragWorkshops = () => {\r\n setIsDragLoading(true);\r\n const queryParams = new URLSearchParams(window.location.search);\r\n const typeId = queryParams.get('type');\r\n const distanceId = queryParams.get('distance');\r\n const productName = queryParams.get('product_name');\r\n const name = queryParams.get('name');\r\n const address = queryParams.get('address');\r\n\r\n const params: any = { sort_by: 'distance' };\r\n if (typeId) {\r\n params['workshop_type_id'] = typeId;\r\n }\r\n if (distanceId) {\r\n params['distance_id'] = distanceId;\r\n }\r\n if (productName) {\r\n params['product_name'] = productName;\r\n }\r\n if (name) {\r\n params['name'] = name;\r\n }\r\n if (address) {\r\n params['address'] = address;\r\n }\r\n params['latitude'] = dragLat;\r\n params['longitude'] = dragLng;\r\n setDefaultLat(dragLat);\r\n setDefaultLng(dragLng);\r\n params['PageSize'] = 20;\r\n APIV2Service.get(API.workshop.getWorkshops, params, reqHeaders)\r\n .then((res) => {\r\n setWorkshops(res.data.data.data);\r\n })\r\n .catch((error) => {\r\n console.log(error);\r\n })\r\n .finally(() => {\r\n setIsDragLoading(false);\r\n });\r\n };\r\n\r\n // If has request headers set, get workshops with request headers\r\n useEffect(() => {\r\n if (Object.keys(reqHeaders).length > 0 && coords) {\r\n getWorkshops();\r\n }\r\n }, [reqHeaders, coords, search]);\r\n\r\n useEffect(() => {\r\n if (centerLoaded) {\r\n getDragWorkshops();\r\n }\r\n }, [dragLng]);\r\n\r\n useEffect(() => {\r\n const cachedLocation = sessionStorage.getItem('location');\r\n if (cachedLocation && Object.keys(reqHeaders).length === 0) {\r\n setReqHeaders(JSON.parse(cachedLocation));\r\n return;\r\n }\r\n\r\n if (isGeolocationEnabled && coords && !cachedLocation) {\r\n const fetchLocation = async () => {\r\n const location = await getLocationByCoords(coords.latitude, coords.longitude);\r\n\r\n const headers: any = {};\r\n if (location) {\r\n headers['country'] = location.country;\r\n headers['state'] = location.state;\r\n headers['province'] = location.city;\r\n }\r\n\r\n setReqHeaders(headers);\r\n };\r\n\r\n fetchLocation();\r\n }\r\n\r\n setTimeout(() => {\r\n setHasTimeout(true);\r\n }, 5000);\r\n }, [isGeolocationEnabled, coords, search]);\r\n\r\n useEffect(() => {\r\n if (hasTimeout && !isGeolocationEnabled && !coords) {\r\n getWorkshops();\r\n }\r\n }, [hasTimeout, search]);\r\n\r\n const handleDragCenter = (map: any) => {\r\n setDragLat(map.center.lat());\r\n setDragLng(map.center.lng());\r\n setZoom(map.getZoom());\r\n };\r\n\r\n const handleCenterLocation = () => {\r\n if (workshops.length > 0) {\r\n // Set the first workshop coords as center\r\n setDefaultLat(workshops[0].latitude);\r\n setDefaultLng(workshops[0].longitude);\r\n setCenterLoaded(true);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (!centerLoaded && workshops.length > 0) {\r\n handleCenterLocation();\r\n }\r\n }, [workshops]);\r\n\r\n const { clusters, supercluster } = useSupercluster({\r\n points,\r\n bounds,\r\n zoom,\r\n options: { radius: 75, maxZoom: 20 },\r\n });\r\n\r\n const handleOnclick = (lat: number, lng: number) => {\r\n setListStatus(true)\r\n setDefaultLat(lat);\r\n setDefaultLng(lng);\r\n setClickLat(lat);\r\n setClickLng(lng);\r\n };\r\n\r\n useEffect(() => {\r\n // prevent when user click on the same clicklat pointer, the distance doesnt refresh as clicklat is the same\r\n if (centerLoaded && clickLng != 0 && clickLat != 0) {\r\n getClickWorkshops();\r\n }\r\n }, [clickLng]);\r\n\r\n const handleMyLocation = () => {\r\n if (coords) {\r\n setDefaultLat(coords.latitude);\r\n setDefaultLng(coords.longitude);\r\n setClickLat(coords.latitude);\r\n setClickLng(coords.longitude);\r\n }\r\n }\r\n\r\n return (\r\n <PageLayout>\r\n <MapStyle>\r\n <div className=\"map-div\">\r\n {isLoading ? (\r\n <div className=\"loading-container\">\r\n <TailSpin color=\"#E40613\" height={loadingHeight} width={loadingWidth} />\r\n </div>\r\n ) : (\r\n <>\r\n {isDragLoading && (\r\n <div className=\"drag-load\">\r\n <TailSpin color=\"#E40613\" height={loadingHeight} width={loadingWidth} />\r\n </div>\r\n )}\r\n <GoogleMapReact\r\n bootstrapURLKeys={{\r\n key: process.env.REACT_APP_GOOGLE_MAP_API_KEY,\r\n language: 'EN',\r\n region: 'MY',\r\n }}\r\n onDragEnd={handleDragCenter}\r\n yesIWantToUseGoogleMapApiInternals\r\n center={{ lat: defaultLat, lng: defaultLng }}\r\n zoom={zoom}\r\n onGoogleApiLoaded={({ map }: any) => {\r\n mapRef.current = map;\r\n }}\r\n onChange={({ zoom, bounds }: any) => {\r\n setZoom(zoom);\r\n setBounds([bounds.nw.lng, bounds.se.lat, bounds.se.lng, bounds.nw.lat]);\r\n }}\r\n >\r\n {clusters.map((cluster, index) => {\r\n const [longitude, latitude] = cluster.geometry.coordinates;\r\n const { cluster: isCluster, point_count: pointCount } = cluster.properties;\r\n\r\n if (isCluster) {\r\n return (\r\n <ClusterMarker\r\n key={`cluster-${cluster.id}`}\r\n lat={latitude}\r\n lng={longitude}\r\n count={pointCount}\r\n cluster={cluster}\r\n />\r\n );\r\n }\r\n\r\n const { name_id } = cluster.data;\r\n return (\r\n <WorkshopPointer\r\n onClick={handleOnclick}\r\n name_id={name_id}\r\n key={'workshop' + index}\r\n lat={latitude}\r\n lng={longitude}\r\n hoveredId={hoveredId}\r\n />\r\n );\r\n })}\r\n\r\n <MyLocationDot lng={myLng} lat={myLat} />\r\n </GoogleMapReact>\r\n </>\r\n )}\r\n <div className='my-location-button' title='My location' onClick={handleMyLocation}>\r\n <img src={currentLocation} />\r\n </div>\r\n </div>\r\n\r\n {!isLoading && (\r\n <div className=\"toggle-list\" onClick={handleList}>\r\n {listStatus ? 'Hide List' : 'Show List'}\r\n <img src={chevron} style={{ transform: listStatus ? 'rotate(180deg)' : '' }} alt=\"Toggle\" />\r\n </div>\r\n )}\r\n\r\n {listStatus && (\r\n <div className=\"suggest\">\r\n <h1>Nearby Workshop</h1>\r\n <hr />\r\n\r\n {isLoading ? (\r\n <div className=\"loading-container\">\r\n <TailSpin color=\"#E40613\" height={loadingHeight} width={loadingWidth} />\r\n </div>\r\n ) : workshops.length > 0 ? (\r\n <div className=\"recent-list\">\r\n <Scrollbar alwaysShowTracks className=\"scrollbar\" ref={scrollRef}>\r\n <div className=\"scroll-content\">\r\n {workshops.map(\r\n (\r\n {\r\n name_id,\r\n id,\r\n distance_radius,\r\n image_url,\r\n name,\r\n address,\r\n phone_number,\r\n operating_hours,\r\n },\r\n index,\r\n ) => {\r\n return (\r\n <div\r\n key={index}\r\n className=\"list-item\"\r\n onMouseEnter={() => handleHovered(name_id)}\r\n >\r\n <div className=\"list-box\" style={{ width: '100%' }}>\r\n <WorkshopCard\r\n name_id={name_id}\r\n id={id}\r\n distance={distance_radius}\r\n image={image_url}\r\n name={name}\r\n address={address}\r\n phoneNo={phone_number}\r\n operatingHours={operating_hours}\r\n />\r\n </div>\r\n </div>\r\n );\r\n },\r\n )}\r\n </div>\r\n </Scrollbar>\r\n </div>\r\n ) : (\r\n <div className=\"empty-container\">\r\n <div className=\"nofound-text\">Workshop not found</div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </MapStyle>\r\n </PageLayout>\r\n );\r\n};\r\n\r\nexport default MapSection;\r\n"],"sourceRoot":""}