fix(SW-2824): move pin latitude on mobile to make space for hotel card on map * fix(SW-2824): move pin latitude on mobile to make space for hotel card on map Approved-by: Anton Gunnarsson
121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
"use client"
|
|
|
|
import { Map, type MapProps, useMap } from "@vis.gl/react-google-maps"
|
|
import { useEffect, useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
|
|
import { MAP_RESTRICTIONS } from "@/constants/map"
|
|
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
|
|
import HotelListingMapContent from "./HotelListingMapContent"
|
|
import PoiMapMarkers from "./PoiMapMarkers"
|
|
|
|
import styles from "./interactiveMap.module.css"
|
|
|
|
import type { InteractiveMapProps } from "@/types/components/hotelPage/map/interactiveMap"
|
|
|
|
export default function InteractiveMap({
|
|
coordinates,
|
|
pointsOfInterest,
|
|
activePoi,
|
|
hotelPins,
|
|
mapId,
|
|
closeButton,
|
|
markerInfo,
|
|
fitBounds = true,
|
|
onTilesLoaded,
|
|
onActivePoiChange,
|
|
}: InteractiveMapProps) {
|
|
const intl = useIntl()
|
|
const map = useMap()
|
|
const [hasInitializedBounds, setHasInitializedBounds] = useState(false)
|
|
|
|
const mapOptions: MapProps = {
|
|
defaultZoom: 14,
|
|
defaultCenter: coordinates,
|
|
disableDefaultUI: true,
|
|
clickableIcons: false,
|
|
mapId,
|
|
gestureHandling: "greedy",
|
|
restriction: MAP_RESTRICTIONS,
|
|
}
|
|
|
|
function zoomIn() {
|
|
const currentZoom = map && map.getZoom()
|
|
if (currentZoom) {
|
|
map.setZoom(currentZoom + 1)
|
|
}
|
|
}
|
|
function zoomOut() {
|
|
const currentZoom = map && map.getZoom()
|
|
if (currentZoom) {
|
|
map.setZoom(currentZoom - 1)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (map && hotelPins?.length && !hasInitializedBounds) {
|
|
if (fitBounds) {
|
|
const bounds = new google.maps.LatLngBounds()
|
|
hotelPins.forEach((marker) => {
|
|
bounds.extend(marker.coordinates)
|
|
})
|
|
|
|
map.fitBounds(bounds, 100)
|
|
}
|
|
setHasInitializedBounds(true)
|
|
}
|
|
}, [map, fitBounds, hotelPins, hasInitializedBounds])
|
|
|
|
return (
|
|
<div className={styles.mapContainer}>
|
|
<Map {...mapOptions} onTilesLoaded={onTilesLoaded}>
|
|
{hotelPins && <HotelListingMapContent hotelPins={hotelPins} />}
|
|
{pointsOfInterest && markerInfo && (
|
|
<PoiMapMarkers
|
|
coordinates={coordinates}
|
|
pointsOfInterest={pointsOfInterest}
|
|
onActivePoiChange={onActivePoiChange}
|
|
activePoi={activePoi}
|
|
markerInfo={markerInfo}
|
|
/>
|
|
)}
|
|
</Map>
|
|
<div className={styles.ctaButtons}>
|
|
{closeButton}
|
|
<div className={styles.zoomButtons}>
|
|
<Button
|
|
theme="base"
|
|
intent="inverted"
|
|
variant="icon"
|
|
size="small"
|
|
className={styles.zoomButton}
|
|
onClick={zoomOut}
|
|
aria-label={intl.formatMessage({
|
|
defaultMessage: "Zoom in",
|
|
})}
|
|
>
|
|
<MaterialIcon icon="remove" color="CurrentColor" />
|
|
</Button>
|
|
<Button
|
|
theme="base"
|
|
intent="inverted"
|
|
variant="icon"
|
|
size="small"
|
|
className={styles.zoomButton}
|
|
onClick={zoomIn}
|
|
aria-label={intl.formatMessage({
|
|
defaultMessage: "Zoom out",
|
|
})}
|
|
>
|
|
<MaterialIcon icon="add" color="CurrentColor" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|