diff --git a/frontend/src/components/Map/index.tsx b/frontend/src/components/Map/index.tsx index 0fc3155..45aab72 100644 --- a/frontend/src/components/Map/index.tsx +++ b/frontend/src/components/Map/index.tsx @@ -56,17 +56,23 @@ function Map({ children, boundsFromJson, baseMapStyle, + onViewportChange, ...props }: { viewportFromUrl?: boolean children: React.ReactNode boundsFromJson: GeoJSON.Geometry baseMapStyle: string + onViewportChange: (viewport: Viewport) => void, }) { const [viewportState, setViewportState] = useState(EMPTY_VIEWPORT) const [viewportUrl, setViewportUrl] = useViewportFromUrl() - const [viewport, setViewport] = viewportFromUrl ? [viewportUrl, setViewportUrl] : [viewportState, setViewportState] + const [viewport, setViewport_] = viewportFromUrl ? [viewportUrl, setViewportUrl] : [viewportState, setViewportState] + const setViewport = useCallback((viewport: Viewport) => { + setViewport_(viewport); + onViewportChange?.(viewport); + }, [setViewport_, onViewportChange]) const config = useConfig() useEffect(() => { diff --git a/frontend/src/pages/MapPage/RegionInfo.tsx b/frontend/src/pages/MapPage/RegionInfo.tsx new file mode 100644 index 0000000..cf29948 --- /dev/null +++ b/frontend/src/pages/MapPage/RegionInfo.tsx @@ -0,0 +1,33 @@ +import React, { useState, useCallback } from "react"; +import { createPortal } from "react-dom"; +import _ from "lodash"; +import { List, Header, Icon, Button } from "semantic-ui-react"; + +import styles from "./styles.module.less"; + +export default function RegionInfo({ region, mapInfoPortal, onClose }) { + const content = ( + <> +
+
{region.properties.name || "Unnamed region"}
+ +
+ + + + Number of events + {region.properties.overtaking_event_count ?? 0} + + + + ); + + return content && mapInfoPortal + ? createPortal( +
{content}
, + mapInfoPortal + ) + : null; +} diff --git a/frontend/src/pages/MapPage/RoadInfo.tsx b/frontend/src/pages/MapPage/RoadInfo.tsx index 5d2758e..8a96103 100644 --- a/frontend/src/pages/MapPage/RoadInfo.tsx +++ b/frontend/src/pages/MapPage/RoadInfo.tsx @@ -1,6 +1,7 @@ import React, {useState, useCallback} from 'react' +import {createPortal} from 'react-dom' import _ from 'lodash' -import {Segment, Menu, Header, Label, Icon, Table} from 'semantic-ui-react' +import {Menu, Header, Label, Icon, Table, Button} from 'semantic-ui-react' import {Layer, Source} from 'react-map-gl' import {of, from, concat} from 'rxjs' import {useObservable} from 'rxjs-hooks' @@ -110,7 +111,7 @@ function HistogramChart({bins, counts}) { ) } -export default function RoadInfo({clickLocation}) { +export default function RoadInfo({roadInfo: info, mapInfoPortal, onClose}) { const [direction, setDirection] = useState('forwards') const onClickDirection = useCallback( @@ -122,72 +123,42 @@ export default function RoadInfo({clickLocation}) { [setDirection] ) - const info = useObservable( - (_$, inputs$) => - inputs$.pipe( - distinctUntilChanged(_.isEqual), - switchMap(([location]) => - location - ? concat( - of(null), - from( - api.get('/mapdetails/road', { - query: { - ...location, - radius: 100, - }, - }) - ) - ) - : of(null) - ) - ), - null, - [clickLocation] - ) + const offsetDirection = info.road.oneway ? 0 : direction === 'forwards' ? 1 : -1 // TODO: change based on left-hand/right-hand traffic - if (!clickLocation) { - return null - } - - const loading = info == null - - const offsetDirection = info?.road?.oneway ? 0 : direction === 'forwards' ? 1 : -1 // TODO: change based on left-hand/right-hand traffic - - const content = - !loading && !info.road ? ( - 'No road found.' - ) : ( + const content = ( <> -
{loading ? '...' : info?.road.name || 'Unnamed way'}
+
+
{info.road.name || 'Unnamed way'}
+ +
- {info?.road.zone && ( -