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 { 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((result) => {
let resultArray = Object.entries(result)
const points = []
// validate each location
for (let vinLocations of resultArray) {
// if there are points for the vin; skip if empty points array
if (vinLocations[0] && vinLocations[1] && vinLocations[1][0]) {
let path = []
path[0] = vinLocations[0]
path[1] = []
for (let location of vinLocations[1]) {
if (ValidateLocationVehiclePathsData(location) !== false) {
path[1].push(location);
}
}
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;