1- import React , { useState } from 'react' ;
2- import { Box , ToggleButtonGroup , ToggleButton , Tooltip } from '@mui/material' ;
1+ import React , { useState , useEffect } from 'react' ;
2+ import {
3+ Box ,
4+ ToggleButtonGroup ,
5+ ToggleButton ,
6+ Tooltip ,
7+ Skeleton ,
8+ } from '@mui/material' ;
39import MapIcon from '@mui/icons-material/Map' ;
410import TravelExploreIcon from '@mui/icons-material/TravelExplore' ;
511import { ContentBox } from './ContentBox' ;
@@ -10,8 +16,9 @@ import { Map } from './Map';
1016import { useTranslation } from 'react-i18next' ;
1117import type { LatLngExpression } from 'leaflet' ;
1218import { useTheme } from '@mui/material/styles' ;
19+
1320interface CoveredAreaMapProps {
14- boundingBox ?: LatLngExpression [ ] ; // Replace 'any' with your actual type
21+ boundingBox ?: LatLngExpression [ ] ;
1522 latestDataset ?: { hosted_url ?: string } ;
1623}
1724
@@ -36,35 +43,43 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
3643} ) => {
3744 const { t } = useTranslation ( 'feeds' ) ;
3845 const theme = useTheme ( ) ;
39- const [ geoJsonError , setGeoJsonError ] = React . useState ( false ) ;
40- const [ geoJsonData , setGeoJsonData ] = React . useState < GeoJSONData | null > (
41- null ,
42- ) ;
43- React . useEffect ( ( ) => {
44- if ( latestDataset ?. hosted_url != undefined ) {
45- fetchGeoJson ( latestDataset . hosted_url ) . then (
46- ( data ) => {
47- setGeoJsonData ( data ) ;
48- } ,
49- ( _ ) => {
50- setGeoJsonError ( true ) ;
51- } ,
52- ) ;
53- }
54- } , [ latestDataset ] ) ;
5546
47+ const [ geoJsonData , setGeoJsonData ] = useState < GeoJSONData | null > ( null ) ;
48+ const [ geoJsonError , setGeoJsonError ] = useState ( false ) ;
49+ const [ geoJsonLoading , setGeoJsonLoading ] = useState ( false ) ;
5650 const [ view , setView ] = useState <
5751 'boundingBoxView' | 'detailedCoveredAreaView'
5852 > ( 'detailedCoveredAreaView' ) ;
5953
54+ useEffect ( ( ) => {
55+ if ( latestDataset ?. hosted_url !== undefined ) {
56+ setGeoJsonLoading ( true ) ;
57+ fetchGeoJson ( latestDataset . hosted_url )
58+ . then ( ( data ) => {
59+ setGeoJsonData ( data ) ;
60+ setGeoJsonError ( false ) ;
61+ setView ( 'detailedCoveredAreaView' ) ;
62+ } )
63+ . catch ( ( ) => {
64+ setGeoJsonError ( true ) ;
65+ setView ( 'boundingBoxView' ) ;
66+ } )
67+ . finally ( ( ) => {
68+ setGeoJsonLoading ( false ) ;
69+ } ) ;
70+ } else {
71+ // No dataset, fallback to bounding box
72+ setGeoJsonData ( null ) ;
73+ setGeoJsonError ( true ) ;
74+ setView ( 'boundingBoxView' ) ;
75+ }
76+ } , [ latestDataset ] ) ;
77+
6078 const handleViewChange = (
6179 _ : React . MouseEvent < HTMLElement > ,
6280 newView : 'boundingBoxView' | 'detailedCoveredAreaView' | null ,
6381 ) : void => {
64- // Only update state if a non-null value is returned
65- if ( newView !== null ) {
66- setView ( newView ) ;
67- }
82+ if ( newView !== null ) setView ( newView ) ;
6883 } ;
6984
7085 return (
@@ -89,7 +104,9 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
89104 < Tooltip title = { t ( 'detailedCoveredAreaViewTooltip' ) } >
90105 < ToggleButton
91106 value = 'detailedCoveredAreaView'
92- disabled = { geoJsonError || boundingBox === undefined }
107+ disabled = {
108+ geoJsonLoading || geoJsonError || boundingBox === undefined
109+ }
93110 aria-label = 'Detailed Covered Area View'
94111 >
95112 < TravelExploreIcon />
@@ -114,7 +131,14 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
114131
115132 { boundingBox !== undefined && (
116133 < Box sx = { mapBoxPositionStyle } >
117- { view === 'boundingBoxView' ? (
134+ { geoJsonLoading ? (
135+ < Skeleton
136+ variant = 'rectangular'
137+ width = '100%'
138+ height = '100%'
139+ animation = 'wave'
140+ />
141+ ) : view === 'boundingBoxView' ? (
118142 < Map polygon = { boundingBox } />
119143 ) : (
120144 < MapGeoJSON geoJSONData = { geoJsonData } polygon = { boundingBox } />
0 commit comments