import { Button } from "@material-ui/core"; import L from "leaflet"; import React, { useEffect, useState } from "react"; import { MapContainer, Marker, Polyline, Popup, TileLayer, useMap } from "react-leaflet"; import useStyles from "../useStyles"; import GrayMarkerIcon from "../../assets/gray-marker.png"; import GreenMarkerIcon from "../../assets/green-marker.png"; import { logger } from "../../services/monitoring"; import { ValidateLocationData, ValidateLocationVehiclePathsData } from "../../utils/locations"; import { useUserContext } from "../Contexts/UserContext"; import { useVehicleContext, VehicleProvider } from "../Contexts/VehicleContext"; import { VehiclePopUp } from "../VehicleMap/popup"; const ComponentVehiclePathsMap = (props) => { const classes = useStyles(); const { token: { idToken: { jwtToken: token }, }, } = useUserContext(); const { getConnections, getLocationsVehiclePaths, 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 react-hooks/exhaustive-deps }, [token]); const retrieveAndStoreLocations = (accessToken) => { let vinsToShowOnMap = [...props.vinsToShowOnMapColors.keys()]; let vinsParam = "" for (let vinToShowOnMap of vinsToShowOnMap) { vinsParam += "vins=" vinsParam += vinToShowOnMap vinsParam += "&" } vinsParam += "lookback_hours=" vinsParam += props.lookbackHours return getLocationsVehiclePaths(accessToken, vinsParam) .then(async (result) => { let resultArray = Object.entries(result) const points = [] // validate each location for (let vinLocations of resultArray) { if (vinLocations[0]) { let path = []; path[0] = vinLocations[0]; path[1] = []; if (vinLocations[1] && vinLocations[1][0]) { for (let location of vinLocations[1]) { if (ValidateLocationVehiclePathsData(location) !== false) { path[1].push(location); } } } else { await getState(token, vinLocations[0]).then((stateResult) => { if (stateResult.data && stateResult.data.location) { if (ValidateLocationData(stateResult.data.location) !== false) { path[1].push([stateResult.data.location.latitude, stateResult.data.location.longitude]); } } }); } points.push(path); } } setMarkers(points); return points; }) .catch((error) => logger.warn(error.stack)); }; const centerAroundMarkers = (points) => { // default center let center = [37.0902, -95.7129] // center is the very first geographical point if (points && points[0] && points[0][1] && points[0][1][0]) { center = points[0][1][0] } setCenter(center); setZoom(4.5); }; useEffect(() => { if (!token) return; const vins = [] for (let vinLocations of markers) { vins.push(vinLocations[0]) } if (vins.length === 0) return; 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 && markers.map((vinLocations) => (
{vinLocations[1][0] && { setCenter(vinLocations[1][0]); setZoom(16); }, }} >

{vinLocations[0]}

}
))} {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 VehiclePathsMap = (props) => ( ); export default VehiclePathsMap;