Skip to content

Commit

Permalink
feat: new empty state for additional map markers
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyjablonski committed Jan 13, 2025
1 parent e7b2647 commit efc5741
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 112 deletions.
166 changes: 91 additions & 75 deletions sites/public/src/components/listings/ListingsCombined.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from "react"
import { APIProvider } from "@vis.gl/react-google-maps"
import { useJsApiLoader } from "@react-google-maps/api"
import { Listing, ListingMapMarker } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import CustomSiteFooter from "../shared/CustomSiteFooter"
import { ListingsMap, MapMarkerData } from "./ListingsMap"
Expand Down Expand Up @@ -33,90 +35,69 @@ type ListingsCombinedProps = {
}

const ListingsCombined = (props: ListingsCombinedProps) => {
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: props.googleMapsApiKey,
})

if (!isLoaded) return <></>

const getListLoading = () => {
if (!props.googleMapsApiKey || !props.googleMapsMapId || !props.loading) return false
return true
}

const getListingsList = () => {
return (
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
<div
className={`${styles["listings-map-list-container"]} ${styles["listings-map-list-container-list-only"]}`}
>
<div id="listings-list-expanded" className={styles["listings-list-expanded"]}>
<ListingsList
listings={props.searchResults.listings}
currentPage={props.searchResults.currentPage}
lastPage={props.searchResults.lastPage}
onPageChange={props.onPageChange}
loading={getListLoading() || (props.isFirstBoundsLoad && props.isDesktop)}
/>
</div>
<div>
<CustomSiteFooter />
<APIProvider apiKey={props.googleMapsApiKey}>
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
<div
className={`${styles["listings-map-list-container"]} ${styles["listings-map-list-container-list-only"]}`}
>
<div id="listings-list-expanded" className={styles["listings-list-expanded"]}>
<ListingsList
listings={props.searchResults.listings}
currentPage={props.searchResults.currentPage}
lastPage={props.searchResults.lastPage}
onPageChange={props.onPageChange}
loading={getListLoading() || (props.isFirstBoundsLoad && props.isDesktop)}
mapMarkers={props.markers}
/>
</div>
<div>
<CustomSiteFooter />
</div>
</div>
</div>
</div>
</APIProvider>
)
}

const getListingsMap = () => {
return (
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
<div className={styles["listings-map-expanded"]}>
<ListingsMap
listings={props.markers}
googleMapsApiKey={props.googleMapsApiKey}
googleMapsMapId={props.googleMapsMapId}
isMapExpanded={true}
setVisibleMarkers={props.setVisibleMarkers}
visibleMarkers={props.visibleMarkers}
setIsLoading={props.setIsLoading}
searchFilter={props.searchFilter}
isFirstBoundsLoad={props.isFirstBoundsLoad}
setIsFirstBoundsLoad={props.setIsFirstBoundsLoad}
isDesktop={props.isDesktop}
<APIProvider apiKey={props.googleMapsApiKey}>
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
</div>
</div>
)
}

const getListingsCombined = () => {
return (
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
<div className={styles["listings-map-list-container"]}>
<div className={styles["listings-map"]}>
<div className={styles["listings-map-expanded"]}>
<ListingsMap
listings={props.markers}
googleMapsApiKey={props.googleMapsApiKey}
googleMapsMapId={props.googleMapsMapId}
isMapExpanded={false}
isMapExpanded={true}
setVisibleMarkers={props.setVisibleMarkers}
visibleMarkers={props.visibleMarkers}
setIsLoading={props.setIsLoading}
Expand All @@ -126,20 +107,55 @@ const ListingsCombined = (props: ListingsCombinedProps) => {
isDesktop={props.isDesktop}
/>
</div>
<div id="listings-outer-container" className={styles["listings-outer-container"]}>
<div id="listings-list" className={styles["listings-list"]}>
<ListingsList
listings={props.searchResults.listings}
currentPage={props.searchResults.currentPage}
lastPage={props.searchResults.lastPage}
loading={getListLoading() || (props.isFirstBoundsLoad && props.isDesktop)}
onPageChange={props.onPageChange}
</div>
</APIProvider>
)
}

const getListingsCombined = () => {
return (
<APIProvider apiKey={props.googleMapsApiKey}>
<div className={styles["listings-combined"]}>
<ListingsSearchMetadata
loading={props.loading}
setModalOpen={props.setModalOpen}
filterCount={props.filterCount}
searchResults={props.searchResults}
setListView={props.setListView}
listView={props.listView}
/>
<div className={styles["listings-map-list-container"]}>
<div className={styles["listings-map"]}>
<ListingsMap
listings={props.markers}
googleMapsApiKey={props.googleMapsApiKey}
googleMapsMapId={props.googleMapsMapId}
isMapExpanded={false}
setVisibleMarkers={props.setVisibleMarkers}
visibleMarkers={props.visibleMarkers}
setIsLoading={props.setIsLoading}
searchFilter={props.searchFilter}
isFirstBoundsLoad={props.isFirstBoundsLoad}
setIsFirstBoundsLoad={props.setIsFirstBoundsLoad}
isDesktop={props.isDesktop}
/>
<CustomSiteFooter />
</div>
<div id="listings-outer-container" className={styles["listings-outer-container"]}>
<div id="listings-list" className={styles["listings-list"]}>
<ListingsList
listings={props.searchResults.listings}
currentPage={props.searchResults.currentPage}
lastPage={props.searchResults.lastPage}
loading={getListLoading() || (props.isFirstBoundsLoad && props.isDesktop)}
onPageChange={props.onPageChange}
mapMarkers={props.markers}
/>
<CustomSiteFooter />
</div>
</div>
</div>
</div>
</div>
</APIProvider>
)
}

Expand Down
35 changes: 31 additions & 4 deletions sites/public/src/components/listings/ListingsList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from "react"
import { Listing } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import { Heading } from "@bloom-housing/ui-seeds"
import { useMap } from "@vis.gl/react-google-maps"
import { Listing, ListingMapMarker } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import { Heading, Button } from "@bloom-housing/ui-seeds"
import { ZeroListingsItem } from "@bloom-housing/doorway-ui-components"
import { LoadingOverlay, t, InfoCard, LinkButton } from "@bloom-housing/ui-components"
import { getListings } from "../../lib/helpers"
import { getBoundsZoomLevel, getListings } from "../../lib/helpers"
import { Pagination } from "./Pagination"
import styles from "./ListingsCombined.module.scss"

Expand All @@ -13,9 +14,14 @@ type ListingsListProps = {
lastPage: number
onPageChange: (page: number) => void
loading: boolean
mapMarkers: ListingMapMarker[] | null
}

const ListingsList = (props: ListingsListProps) => {
const map = useMap()

if (!map) return null

const listingsDiv = (
<div id="listingsList">
<Heading className={"sr-only"} priority={2}>
Expand All @@ -25,7 +31,28 @@ const ListingsList = (props: ListingsListProps) => {
<div className={styles["listings-list-container"]}>{getListings(props.listings)}</div>
) : (
<ZeroListingsItem title={t("t.noMatchingListings")} description={t("t.tryRemovingFilters")}>
{/* <Button>{t("t.clearAllFilters")}</Button> */}
{props.mapMarkers.length > 0 && (
<Button
onClick={() => {
const bounds = new window.google.maps.LatLngBounds()

if (!map) return
props.mapMarkers?.map((marker) => {
bounds.extend({
lat: marker.lat,
lng: marker.lng,
})
})
map.fitBounds(bounds, document.getElementById("listings-map").clientWidth * 0.05)
if (props.mapMarkers.length === 1) {
const zoomLevel = getBoundsZoomLevel(bounds)
map.setZoom(zoomLevel - 7)
}
}}
>
Zoom out to more listings
</Button>
)}
</ZeroListingsItem>
)}
</div>
Expand Down
57 changes: 24 additions & 33 deletions sites/public/src/components/listings/ListingsMap.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState } from "react"
import { APIProvider, Map } from "@vis.gl/react-google-maps"
import { useJsApiLoader } from "@react-google-maps/api"
import { Map } from "@vis.gl/react-google-maps"
import { Heading } from "@bloom-housing/ui-seeds"
import { t } from "@bloom-housing/ui-components"
import { ListingMapMarker } from "@bloom-housing/shared-helpers/src/types/backend-swagger"
Expand Down Expand Up @@ -60,16 +59,10 @@ const getMarkers = (listings: ListingMapMarker[]) => {
}

const ListingsMap = (props: ListingsMapProps) => {
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: props.googleMapsApiKey,
})

const [infoWindowIndex, setInfoWindowIndex] = useState<number>(null)

const markers: MapMarkerData[] | null = getMarkers(props.listings)

if (!isLoaded) return <></>

return (
<div id={"listings-map"} className={styles["listings-map"]}>
<a className={styles["listings-map-skip-link"]} href={`#listingsList`}>
Expand All @@ -78,31 +71,29 @@ const ListingsMap = (props: ListingsMapProps) => {
<Heading className={"sr-only"} priority={2}>
{t("t.listingsMap")}
</Heading>
<APIProvider apiKey={props.googleMapsApiKey}>
<Map
mapId={props.googleMapsMapId}
style={containerStyle}
gestureHandling={"greedy"}
disableDefaultUI={true}
defaultZoom={defaultZoom}
defaultCenter={defaultCenter}
clickableIcons={false}
>
<MapControl />
<MapClusterer
mapMarkers={markers}
infoWindowIndex={infoWindowIndex}
setInfoWindowIndex={setInfoWindowIndex}
setVisibleMarkers={props.setVisibleMarkers}
visibleMarkers={props.visibleMarkers}
setIsLoading={props.setIsLoading}
searchFilter={props.searchFilter}
isFirstBoundsLoad={props.isFirstBoundsLoad}
setIsFirstBoundsLoad={props.setIsFirstBoundsLoad}
isDesktop={props.isDesktop}
/>
</Map>
</APIProvider>
<Map
mapId={props.googleMapsMapId}
style={containerStyle}
gestureHandling={"greedy"}
disableDefaultUI={true}
defaultZoom={defaultZoom}
defaultCenter={defaultCenter}
clickableIcons={false}
>
<MapControl />
<MapClusterer
mapMarkers={markers}
infoWindowIndex={infoWindowIndex}
setInfoWindowIndex={setInfoWindowIndex}
setVisibleMarkers={props.setVisibleMarkers}
visibleMarkers={props.visibleMarkers}
setIsLoading={props.setIsLoading}
searchFilter={props.searchFilter}
isFirstBoundsLoad={props.isFirstBoundsLoad}
setIsFirstBoundsLoad={props.setIsFirstBoundsLoad}
isDesktop={props.isDesktop}
/>
</Map>
</div>
)
}
Expand Down
4 changes: 4 additions & 0 deletions sites/public/src/components/listings/MapClusterer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ export const MapClusterer = ({
return
} else {
map.fitBounds(bounds, document.getElementById("listings-map").clientWidth * 0.05)
if (visibleMarkers.length === 1) {
const zoomLevel = getBoundsZoomLevel(bounds)
map.setZoom(zoomLevel - 7)
}
setTimeout(() => {
setIsFirstBoundsLoad(false)
}, 1000)
Expand Down

0 comments on commit efc5741

Please sign in to comment.