import React, { useEffect, useState } from "react"; import useStyles from "../useStyles"; import L from "leaflet"; import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet"; import { Button } from "@material-ui/core"; import { useUserContext } from "../Contexts/UserContext"; import { useVehicleContext, VehicleProvider } from "../Contexts/VehicleContext"; import { VehiclePopUp } from "./popup"; import GreenMarkerIcon from "../../assets/green-marker.png"; import GrayMarkerIcon from "../../assets/gray-marker.png"; import { logger } from "../../services/monitoring"; const Component = () => { const classes = useStyles(); const { token: { idToken: { jwtToken: token }, }, } = useUserContext(); const { getConnections, getLocations, getState } = useVehicleContext(); const REQUEST_INTERVAL = 10000; const [center, setCenter] = useState([0, 0]); const [zoom, setZoom] = useState(2); const [markers, setMarkers] = useState([]); const [connections, setConnections] = useState({}); useEffect(() => { if (!token) return; retrieveAndStoreLocations(token).then((points) => { centerAroundMarkers(points); }); const id = setInterval(function () { retrieveAndStoreLocations(token); }, REQUEST_INTERVAL); return () => { clearInterval(id); }; // eslint-disable-next-line }, [token]); const retrieveAndStoreLocations = (accessToken) => { return getLocations(accessToken) .then((result) => { if (result.data != null) { const points = result.data.map((point) => [ point.latitude, point.longitude, point.vin, ]); setMarkers(points); return points; } return []; }) .catch((error) => logger.warn(error.stack)); }; const centerAroundMarkers = (points) => { // if (markers == null) { // markers = [] // } // const coord = markers.reduce((coord, marker) => { // coord[0] += marker[0] / markers.length; // coord[1] += marker[1] / markers.length; // return coord; // }, [0, 0]) setCenter([37.0902, -95.7129]); setZoom(4.5); }; useEffect(() => { if (!token) return; if (markers.length > 0) { const vins = markers.map((marker) => marker[2]); getConnections(vins, token).then((conns) => { setConnections(conns); }); } // eslint-disable-next-line }, [markers, token]); const [selectedVIN, setSelectedVIN] = useState(null); const [carState, setCarState] = useState(null); useEffect(() => { if (selectedVIN != null) { retrieveAndStoreCarState(selectedVIN); const id = setInterval(function () { retrieveAndStoreCarState(selectedVIN); }, REQUEST_INTERVAL); return () => { clearInterval(id); }; } // eslint-disable-next-line }, [selectedVIN]); const selectCar = (e, vin) => { e.preventDefault(); setSelectedVIN(vin); }; const retrieveAndStoreCarState = (vin) => { getState(token, vin).then((results) => { setCarState({ ...results.data, vin: vin }); }); }; const handleClose = () => { setSelectedVIN(null); setCarState(null); }; const isOnline = (vin) => { return connections[vin]; }; const getZIndex = (vin) => { if (isOnline(vin)) return 1000; return 0; }; function getCarIcon(vin) { let icon = GrayMarkerIcon; if (isOnline(vin)) { icon = GreenMarkerIcon; } return new L.Icon({ iconUrl: icon, iconAnchor: [24, 42], }); } return ( {markers.map((marker) => (

{marker[2]}

))} {carState ? ( ) : null}
); }; const CenterFocus = ({ center, zoom }) => { const map = useMap(); useEffect(() => { if (center[0] === 0 && center[1] === 0) { map.flyTo([0, 0], 2, { duration: 1.5 }); } else { map.flyTo(center, zoom, { duration: 1.5 }); } }, [center, zoom, map]); return null; }; const VehicleMap = () => ( ); export default VehicleMap;