From 285070942224170b738b94b037d9d18f006433ee Mon Sep 17 00:00:00 2001 From: Michael Dratch Date: Sat, 6 Jul 2024 12:47:27 -0400 Subject: [PATCH 1/2] added error message when map data fails to load --- .../find-properties/[[...opa_id]]/page.tsx | 209 +++++++++--------- src/components/PropertyDetailSection.tsx | 13 +- src/components/PropertyMap.tsx | 63 +++--- 3 files changed, 154 insertions(+), 131 deletions(-) diff --git a/src/app/find-properties/[[...opa_id]]/page.tsx b/src/app/find-properties/[[...opa_id]]/page.tsx index ece48965..e835f4d0 100644 --- a/src/app/find-properties/[[...opa_id]]/page.tsx +++ b/src/app/find-properties/[[...opa_id]]/page.tsx @@ -33,6 +33,7 @@ const MapPage = ({ params }: MapPageProps) => { const [featureCount, setFeatureCount] = useState(0); const [currentView, setCurrentView] = useState("detail"); const [loading, setLoading] = useState(true); + const [loadingError, setLoadingError] = useState(false); const [selectedProperty, setSelectedProperty] = useState(null); const [isStreetViewModalOpen, setIsStreetViewModalOpen] = @@ -208,118 +209,116 @@ const MapPage = ({ params }: MapPageProps) => { }, [currentView, selectedProperty, shouldFilterSavedProperties]); return ( - -
-
- setIsStreetViewModalOpen(false)} - > - +
+
+ setIsStreetViewModalOpen(false)} + > + + +
+
+ +
+ {isLinkedPropertyParsed ? ( + (prevCoordinateRef.current = null)} /> - -
-
+ ) : ( +
+ +
+ )} +
+ + {!selectedProperty && ( +
- {isLinkedPropertyParsed ? ( - (prevCoordinateRef.current = null)} + )} + {currentView === "download" ? ( +
+ } + onPress={() => updateCurrentView("detail")} /> - ) : ( -
- -
- )} -
- - {!selectedProperty && ( -
- +
+

+ Access Our Data +

+

+ If you are interested in accessing the data behind this + dashboard, please reach out to us at + + {" "} + cleanandgreenphl@gmail.com + + . Let us know who you are and why you want the data. We are + happy to share the data with anyone with community-oriented + interests. +

- )} - {currentView === "download" ? ( -
- } - onPress={() => updateCurrentView("detail")} - /> -
-

- Access Our Data -

-

- If you are interested in accessing the data behind this - dashboard, please reach out to us at - - {" "} - cleanandgreenphl@gmail.com - - . Let us know who you are and why you want the data. We - are happy to share the data with anyone with - community-oriented interests. -

-
-
- ) : currentView === "filter" ? ( - +
+ ) : currentView === "filter" ? ( + + ) : ( + + )} +
+ ) : ( - - )} -
- - ) : ( - - ) - } - /> -
+ + ) + } + />
- +
+ ); }; diff --git a/src/components/PropertyDetailSection.tsx b/src/components/PropertyDetailSection.tsx index 35f9d8a9..3432faf2 100644 --- a/src/components/PropertyDetailSection.tsx +++ b/src/components/PropertyDetailSection.tsx @@ -50,6 +50,7 @@ interface PropertyDetailSectionProps { featuresInView: MapGeoJSONFeature[]; display: "detail" | "list"; loading: boolean; + loadingError: boolean; selectedProperty: MapGeoJSONFeature | null; setSelectedProperty: (property: MapGeoJSONFeature | null) => void; setIsStreetViewModalOpen: Dispatch>; @@ -63,6 +64,7 @@ const PropertyDetailSection: FC = ({ featuresInView, display, loading, + loadingError, selectedProperty, setSelectedProperty, setIsStreetViewModalOpen, @@ -172,7 +174,16 @@ const PropertyDetailSection: FC = ({ return featuresInView.slice(start, end); }, [page, featuresInView, smallScreenMode]); - return loading ? ( + return loadingError ? ( +
+
+

We are having technical issues.

+
+
+

Please try again later.

+
+
+ ) : loading ? (
{/* Center vertically in screen */}
diff --git a/src/components/PropertyMap.tsx b/src/components/PropertyMap.tsx index 79cb440d..ce09eb3c 100644 --- a/src/components/PropertyMap.tsx +++ b/src/components/PropertyMap.tsx @@ -13,7 +13,7 @@ import { maptilerApiKey, mapboxAccessToken, useStagingTiles, - googleCloudBucketName + googleCloudBucketName, } from "../config/config"; import { useFilter } from "@/context/FilterContext"; import Map, { @@ -116,25 +116,32 @@ const MapControls = () => { - {(smallScreenToggle || window.innerWidth > 640) ? - - : + {smallScreenToggle || window.innerWidth > 640 ? ( + + ) : (
} - onPress={() => setSmallScreenToggle(s => !s)} + startContent={ + + } + onPress={() => setSmallScreenToggle((s) => !s)} />
- } + )} - ) + ); }; interface PropertyMapProps { featuresInView: MapGeoJSONFeature[]; setFeaturesInView: Dispatch>; setLoading: Dispatch>; + setLoadingError: Dispatch>; selectedProperty: MapGeoJSONFeature | null; setSelectedProperty: (property: MapGeoJSONFeature | null) => void; setFeatureCount: Dispatch>; @@ -146,6 +153,7 @@ const PropertyMap: FC = ({ featuresInView, setFeaturesInView, setLoading, + setLoadingError, selectedProperty, setSelectedProperty, setFeatureCount, @@ -189,7 +197,7 @@ const PropertyMap: FC = ({ layers, }); - setSearchedProperty({...searchedProperty, address: "" }) + setSearchedProperty({ ...searchedProperty, address: "" }); if (features.length > 0) { setSelectedProperty(features[0]); } else { @@ -217,7 +225,7 @@ const PropertyMap: FC = ({ } return acc; }, - 0, + 0 ); setFeatureCount(clusteredFeatureCount); @@ -252,7 +260,7 @@ const PropertyMap: FC = ({ map.project(searchedProperty.coordinates), { layers, - }, + } ); if (features.length > 0) { setSelectedProperty(features[0]); @@ -293,7 +301,7 @@ const PropertyMap: FC = ({ tabIndex={0} /> , - legendSummary, + legendSummary ); } @@ -302,13 +310,15 @@ const PropertyMap: FC = ({ const center = map.getCenter(); geocoderRef.current = new MapboxGeocoder({ accessToken: mapboxAccessToken, - bbox: [-75.288283,39.864114,-74.945063,40.140129], + bbox: [-75.288283, 39.864114, -74.945063, 40.140129], filter: function (item) { return item.context.some((i) => { - return ( - (i.id.split('.').shift() === 'place' && i.text === 'Philadelphia') || - (i.id.split('.').shift() === 'district' && i.text === 'Philadelphia County') - ); + return ( + (i.id.split(".").shift() === "place" && + i.text === "Philadelphia") || + (i.id.split(".").shift() === "district" && + i.text === "Philadelphia County") + ); }); }, mapboxgl: mapboxgl, @@ -321,7 +331,7 @@ const PropertyMap: FC = ({ map.addControl(geocoderRef.current as unknown as IControl, "top-right"); - geocoderRef.current.on("result", e => { + geocoderRef.current.on("result", (e) => { const address = e.result.place_name.split(",")[0]; setSelectedProperty(null); setSearchedProperty({ @@ -370,7 +380,7 @@ const PropertyMap: FC = ({ const updateFilter = () => { if (!map) return; - const isAnyFilterEmpty = Object.values(appFilter).some(filterItem => { + const isAnyFilterEmpty = Object.values(appFilter).some((filterItem) => { return filterItem.values.length === 0; }); @@ -385,7 +395,7 @@ const PropertyMap: FC = ({ (acc, [property, filterItem]) => { if (filterItem.values.length) { const thisFilterGroup: any = ["any"]; - filterItem.values.forEach(item => { + filterItem.values.forEach((item) => { if (filterItem.useIndexOfFilter) { thisFilterGroup.push([ ">=", @@ -401,7 +411,7 @@ const PropertyMap: FC = ({ } return acc; }, - [] as any[], + [] as any[] ); map.setFilter("vacant_properties_tiles_points", ["all", ...mapFilter]); @@ -424,16 +434,19 @@ const PropertyMap: FC = ({ mapLib={maplibregl as any} initialViewState={initialViewState} mapStyle={`https://api.maptiler.com/maps/dataviz/style.json?key=${maptilerApiKey}`} - onMouseEnter={e => changeCursor(e, "pointer")} - onMouseLeave={e => changeCursor(e, "default")} + onMouseEnter={(e) => changeCursor(e, "pointer")} + onMouseLeave={(e) => changeCursor(e, "default")} onClick={onMapClick} minZoom={MIN_MAP_ZOOM} maxZoom={MAX_MAP_ZOOM} interactiveLayerIds={layers} - onLoad={e => { + onError={(e) => { + setLoadingError(true); + }} + onLoad={(e) => { setMap(e.target); }} - onSourceData={e => { + onSourceData={(e) => { handleSetFeatures(e); }} onMoveEnd={handleSetFeatures} From 4d43b079288ebd1c2493455726bd2e0d8a090ff1 Mon Sep 17 00:00:00 2001 From: Michael Dratch Date: Sun, 7 Jul 2024 16:38:37 -0400 Subject: [PATCH 2/2] updated variable name to communicate boolean value --- src/app/find-properties/[[...opa_id]]/page.tsx | 6 +++--- src/components/PropertyDetailSection.tsx | 6 +++--- src/components/PropertyMap.tsx | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app/find-properties/[[...opa_id]]/page.tsx b/src/app/find-properties/[[...opa_id]]/page.tsx index e835f4d0..be946064 100644 --- a/src/app/find-properties/[[...opa_id]]/page.tsx +++ b/src/app/find-properties/[[...opa_id]]/page.tsx @@ -33,7 +33,7 @@ const MapPage = ({ params }: MapPageProps) => { const [featureCount, setFeatureCount] = useState(0); const [currentView, setCurrentView] = useState("detail"); const [loading, setLoading] = useState(true); - const [loadingError, setLoadingError] = useState(false); + const [hasLoadingError, setHasLoadingError] = useState(false); const [selectedProperty, setSelectedProperty] = useState(null); const [isStreetViewModalOpen, setIsStreetViewModalOpen] = @@ -233,7 +233,7 @@ const MapPage = ({ params }: MapPageProps) => { featuresInView={featuresInView} setFeaturesInView={setFeaturesInView} setLoading={setLoading} - setLoadingError={setLoadingError} + setHasLoadingError={setHasLoadingError} selectedProperty={selectedProperty} setSelectedProperty={setSelectedProperty} setFeatureCount={setFeatureCount} @@ -292,7 +292,7 @@ const MapPage = ({ params }: MapPageProps) => { featuresInView={featuresInView} display={currentView as "detail" | "list"} loading={loading} - loadingError={loadingError} + hasLoadingError={hasLoadingError} selectedProperty={selectedProperty} setSelectedProperty={setSelectedProperty} setIsStreetViewModalOpen={setIsStreetViewModalOpen} diff --git a/src/components/PropertyDetailSection.tsx b/src/components/PropertyDetailSection.tsx index 3432faf2..4bfa2ec3 100644 --- a/src/components/PropertyDetailSection.tsx +++ b/src/components/PropertyDetailSection.tsx @@ -50,7 +50,7 @@ interface PropertyDetailSectionProps { featuresInView: MapGeoJSONFeature[]; display: "detail" | "list"; loading: boolean; - loadingError: boolean; + hasLoadingError: boolean; selectedProperty: MapGeoJSONFeature | null; setSelectedProperty: (property: MapGeoJSONFeature | null) => void; setIsStreetViewModalOpen: Dispatch>; @@ -64,7 +64,7 @@ const PropertyDetailSection: FC = ({ featuresInView, display, loading, - loadingError, + hasLoadingError, selectedProperty, setSelectedProperty, setIsStreetViewModalOpen, @@ -174,7 +174,7 @@ const PropertyDetailSection: FC = ({ return featuresInView.slice(start, end); }, [page, featuresInView, smallScreenMode]); - return loadingError ? ( + return hasLoadingError ? (

We are having technical issues.

diff --git a/src/components/PropertyMap.tsx b/src/components/PropertyMap.tsx index ce09eb3c..15482c39 100644 --- a/src/components/PropertyMap.tsx +++ b/src/components/PropertyMap.tsx @@ -141,7 +141,7 @@ interface PropertyMapProps { featuresInView: MapGeoJSONFeature[]; setFeaturesInView: Dispatch>; setLoading: Dispatch>; - setLoadingError: Dispatch>; + setHasLoadingError: Dispatch>; selectedProperty: MapGeoJSONFeature | null; setSelectedProperty: (property: MapGeoJSONFeature | null) => void; setFeatureCount: Dispatch>; @@ -153,7 +153,7 @@ const PropertyMap: FC = ({ featuresInView, setFeaturesInView, setLoading, - setLoadingError, + setHasLoadingError, selectedProperty, setSelectedProperty, setFeatureCount, @@ -441,7 +441,7 @@ const PropertyMap: FC = ({ maxZoom={MAX_MAP_ZOOM} interactiveLayerIds={layers} onError={(e) => { - setLoadingError(true); + setHasLoadingError(true); }} onLoad={(e) => { setMap(e.target);