55 ToggleButton ,
66 Tooltip ,
77 Skeleton ,
8+ Button ,
89} from '@mui/material' ;
910import MapIcon from '@mui/icons-material/Map' ;
1011import TravelExploreIcon from '@mui/icons-material/TravelExplore' ;
@@ -16,10 +17,13 @@ import { Map } from './Map';
1617import { useTranslation } from 'react-i18next' ;
1718import type { LatLngExpression } from 'leaflet' ;
1819import { useTheme } from '@mui/material/styles' ;
20+ import { type GBFSFeedType , type AllFeedType } from '../services/feeds/utils' ;
21+ import { OpenInNew } from '@mui/icons-material' ;
1922
2023interface CoveredAreaMapProps {
2124 boundingBox ?: LatLngExpression [ ] ;
2225 latestDataset ?: { hosted_url ?: string } ;
26+ feed : AllFeedType ;
2327}
2428
2529export const fetchGeoJson = async (
@@ -40,6 +44,7 @@ export const fetchGeoJson = async (
4044const CoveredAreaMap : React . FC < CoveredAreaMapProps > = ( {
4145 boundingBox,
4246 latestDataset,
47+ feed,
4348} ) => {
4449 const { t } = useTranslation ( 'feeds' ) ;
4550 const theme = useTheme ( ) ;
@@ -82,45 +87,67 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
8287 if ( newView !== null ) setView ( newView ) ;
8388 } ;
8489
90+ const getGbfsLatestVersionVisualizationUrl = ( feed : GBFSFeedType ) : string => {
91+ // TODO: Redo logic when versions all have the auto discovery
92+ return `https://gbfs-validator.mobilitydata.org/visualization?url=${ feed ?. source_info ?. producer_url } ` ;
93+ } ;
94+
8595 return (
8696 < ContentBox
8797 sx = { {
8898 flexGrow : 1 ,
8999 display : 'flex' ,
90100 flexDirection : 'column' ,
101+ maxHeight : {
102+ xs : '100%' ,
103+ md : '70vh' ,
104+ } ,
91105 } }
92106 title = { t ( 'coveredAreaTitle' ) + ' - ' + t ( view ) }
93107 width = { { xs : '100%' } }
94108 outlineColor = { theme . palette . primary . dark }
95109 padding = { 2 }
96110 action = {
97- < ToggleButtonGroup
98- value = { view }
99- color = 'primary'
100- exclusive
101- aria-label = 'map view selection'
102- onChange = { handleViewChange }
103- >
104- < Tooltip title = { t ( 'detailedCoveredAreaViewTooltip' ) } >
105- < ToggleButton
106- value = 'detailedCoveredAreaView'
107- disabled = {
108- geoJsonLoading || geoJsonError || boundingBox === undefined
109- }
110- aria-label = 'Detailed Covered Area View'
111+ < >
112+ { feed ?. data_type === 'gbfs' ? (
113+ < Button
114+ href = { getGbfsLatestVersionVisualizationUrl ( feed as GBFSFeedType ) }
115+ target = '_blank'
116+ rel = 'noreferrer'
117+ endIcon = { < OpenInNew /> }
111118 >
112- < TravelExploreIcon />
113- </ ToggleButton >
114- </ Tooltip >
115- < Tooltip title = { t ( 'boundingBoxViewTooltip' ) } >
116- < ToggleButton
117- value = 'boundingBoxView'
118- aria-label = 'Bounding Box View'
119+ { t ( 'viewRealtimeVisualization' ) }
120+ </ Button >
121+ ) : (
122+ < ToggleButtonGroup
123+ value = { view }
124+ color = 'primary'
125+ exclusive
126+ aria-label = 'map view selection'
127+ onChange = { handleViewChange }
119128 >
120- < MapIcon />
121- </ ToggleButton >
122- </ Tooltip >
123- </ ToggleButtonGroup >
129+ < Tooltip title = { t ( 'detailedCoveredAreaViewTooltip' ) } >
130+ < ToggleButton
131+ value = 'detailedCoveredAreaView'
132+ disabled = {
133+ geoJsonLoading || geoJsonError || boundingBox === undefined
134+ }
135+ aria-label = 'Detailed Covered Area View'
136+ >
137+ < TravelExploreIcon />
138+ </ ToggleButton >
139+ </ Tooltip >
140+ < Tooltip title = { t ( 'boundingBoxViewTooltip' ) } >
141+ < ToggleButton
142+ value = 'boundingBoxView'
143+ aria-label = 'Bounding Box View'
144+ >
145+ < MapIcon />
146+ </ ToggleButton >
147+ </ Tooltip >
148+ </ ToggleButtonGroup >
149+ ) }
150+ </ >
124151 }
125152 >
126153 { boundingBox === undefined && view === 'boundingBoxView' && (
0 commit comments