166 lines
4.8 KiB
TypeScript
166 lines
4.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {
|
|
APIProvider,
|
|
Map,
|
|
AdvancedMarker,
|
|
Pin,
|
|
InfoWindow,
|
|
useMap,
|
|
useMapsLibrary,
|
|
MapCameraChangedEvent,
|
|
} from '@vis.gl/react-google-maps';
|
|
import { Box, Typography, useTheme, Button } from '@mui/material';
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { PropertiesAPI } from 'types';
|
|
import DrawingManager from '../sections/dashboard/Home/Profile/DrawingManager';
|
|
import { cloneSourceShallow } from 'echarts/types/src/data/Source.js';
|
|
|
|
// Custom Marker component
|
|
interface MapMarkerProps {
|
|
property: PropertiesAPI;
|
|
onMarkerClick: (propertyId: number) => void;
|
|
onMarkerHover: (property: PropertiesAPI) => void;
|
|
onMarkerUnhover: () => void;
|
|
isListItemSelected: boolean;
|
|
centerMapToMarker: (position: google.maps.LatLngLiteral) => void;
|
|
}
|
|
|
|
const MapMarker: React.FC<MapMarkerProps> = ({
|
|
property,
|
|
onMarkerClick,
|
|
onMarkerHover,
|
|
onMarkerUnhover,
|
|
isListItemSelected,
|
|
centerMapToMarker,
|
|
}) => {
|
|
const theme = useTheme();
|
|
const [infowindowOpen, setInfowindowOpen] = useState(false);
|
|
const position = { lat: Number(property.latitude)!, lng: Number(property.longitude)! };
|
|
|
|
const handleMarkerClick = (e: any) => {
|
|
//e.stopPropagation();
|
|
setInfowindowOpen(true);
|
|
centerMapToMarker(position);
|
|
};
|
|
|
|
return (
|
|
<AdvancedMarker
|
|
position={position}
|
|
onClick={handleMarkerClick}
|
|
onMouseOver={() => {
|
|
onMarkerHover(property);
|
|
}}
|
|
onMouseOut={() => {
|
|
onMarkerUnhover();
|
|
}}
|
|
// You can use a custom pin or a regular one
|
|
// We'll use the Pin component for a simple custom look
|
|
// The isListItemSelected state will be handled by the parent
|
|
>
|
|
<Pin
|
|
background={isListItemSelected ? theme.palette.primary.main : theme.palette.secondary.main}
|
|
borderColor={isListItemSelected ? theme.palette.primary.dark : theme.palette.secondary.dark}
|
|
glyphColor={'white'}
|
|
/>
|
|
{infowindowOpen && (
|
|
<InfoWindow position={position} onCloseClick={() => setInfowindowOpen(false)}>
|
|
<Box sx={{ p: 1, minWidth: 150 }}>
|
|
<Typography variant="body2" sx={{ fontWeight: 'bold' }}>
|
|
{property.address}
|
|
</Typography>
|
|
<Typography variant="caption" color="text.secondary">
|
|
{property.city}, {property.state}
|
|
</Typography>
|
|
<Button size="small" onClick={() => onMarkerClick(property.id)} sx={{ mt: 1 }}>
|
|
View Details
|
|
</Button>
|
|
</Box>
|
|
</InfoWindow>
|
|
)}
|
|
</AdvancedMarker>
|
|
);
|
|
};
|
|
|
|
// Main Map Component
|
|
interface MapProps {
|
|
center: google.maps.LatLngLiteral;
|
|
zoom: number;
|
|
properties: PropertiesAPI[];
|
|
selectedPropertyId: number | null;
|
|
onBoundsChanged: (bounds: any) => void;
|
|
onBoxDrawn: (bounds: any) => void;
|
|
onMarkerClick: (propertyId: number) => void;
|
|
onMarkerHover: (property: PropertiesAPI) => void;
|
|
onMarkerUnhover: () => void;
|
|
}
|
|
|
|
const MapSerachComponent: React.FC<MapProps> = ({
|
|
center,
|
|
zoom,
|
|
properties,
|
|
selectedPropertyId,
|
|
onBoundsChanged,
|
|
onBoxDrawn,
|
|
onMarkerClick,
|
|
onMarkerHover,
|
|
onMarkerUnhover,
|
|
}) => {
|
|
const navigate = useNavigate();
|
|
const [map, setMap] = useState<google.maps.Map | null>(null);
|
|
|
|
const onMapChange = (event: MapCameraChangedEvent) => {
|
|
const bounds = event.bounds;
|
|
onBoundsChanged({
|
|
ne: bounds.northEast,
|
|
sw: bounds.southWest,
|
|
});
|
|
};
|
|
|
|
const handleMarkerClick = (propertyId: number) => {
|
|
console.log('clicked a marker');
|
|
navigate(`/property/${propertyId}`);
|
|
onMarkerClick(propertyId);
|
|
};
|
|
|
|
const centerMapToMarker = (position: google.maps.LatLngLiteral) => {
|
|
map?.setCenter(position);
|
|
map?.setZoom(15);
|
|
};
|
|
console.log(properties);
|
|
|
|
return (
|
|
<Box sx={{ height: '70vh', width: '100%', position: 'relative' }}>
|
|
<APIProvider apiKey={'AIzaSyDJTApP1OoMbo7b1CPltPu8IObxe8UQt7w'}>
|
|
<Map
|
|
defaultCenter={center}
|
|
defaultZoom={zoom}
|
|
//onCameraChanged={onMapChange}
|
|
mapId={'MapSearchComponent'} // Replace with your Map ID from Google Cloud Console
|
|
onLoad={setMap}
|
|
disableDefaultUI={true}
|
|
>
|
|
{properties.map(
|
|
(property) =>
|
|
property.latitude &&
|
|
property.longitude && (
|
|
<MapMarker
|
|
key={property.id}
|
|
property={property}
|
|
onMarkerClick={handleMarkerClick}
|
|
onMarkerHover={onMarkerHover}
|
|
onMarkerUnhover={onMarkerUnhover}
|
|
isListItemSelected={selectedPropertyId === property.id}
|
|
centerMapToMarker={centerMapToMarker}
|
|
/>
|
|
),
|
|
)}
|
|
{/* <DrawingManager onBoxDrawn={onBoxDrawn} /> */}
|
|
</Map>
|
|
</APIProvider>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default MapSerachComponent;
|