Files
web/apps/scandic-web/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx
Bianca Widstam 47abd7d5ef Merged in fix/SW-2165-map-navigate-hotel-card (pull request #2246)
fix(SW-2165): map navigate on enter press 

* fix(SW-2165): navigate on enter press and refactor

* fix(SW-2165): responsive design

* fix(SW-2165): replace spacing variables

* fix(SW-2165): resolve pr comment

* fix(SW-2165): remove isOpen, hide/show logic already handled

* fix(SW-2165): remove dialog

* fix(SW-2165): use buttonicon

* fix(SW-2165): do not focus on close button without tab

* fix(SW-2165): remove unneccessary css


Approved-by: Christian Andolf
2025-06-02 11:10:27 +00:00

106 lines
3.2 KiB
TypeScript

import {
AdvancedMarker,
AdvancedMarkerAnchorPoint,
InfoWindow,
} from "@vis.gl/react-google-maps"
import { useCallback } from "react"
import { useMediaQuery } from "usehooks-ts"
import { useHotelsMapStore } from "@/stores/hotels-map"
import StandaloneHotelCardDialog from "@/components/HotelReservation/HotelCardDialog/StandaloneHotelCardDialog"
import { trackEvent } from "@/utils/tracking/base"
import HotelPin from "./HotelPin"
import styles from "./hotelListingMapContent.module.css"
import type { HotelListingMapContentProps } from "@/types/components/hotelReservation/selectHotel/map"
function HotelListingMapContent({ hotelPins }: HotelListingMapContentProps) {
const { activeHotel, hoveredHotel, activate, deactivate, engage, disengage } =
useHotelsMapStore()
const isDesktop = useMediaQuery("(min-width: 768px)")
const toggleActiveHotelPin = useCallback(
(pinName: string | null, hotelId: string) => {
if (activeHotel === pinName || pinName === null) {
deactivate()
return
}
trackEvent({
event: "hotelClickMap",
map: {
action: "hotel click - map",
},
hotelInfo: {
hotelId,
},
})
activate(pinName)
},
[activeHotel, activate, deactivate]
)
return (
<div>
{hotelPins.map((pin) => {
const isActiveOrHovered =
activeHotel === pin.name || hoveredHotel === pin.name
const hotelPrice =
pin.memberPrice ??
pin.publicPrice ??
pin.redemptionPrice ??
pin.voucherPrice ??
pin.chequePrice?.numberOfCheques ??
null
const hotelAdditionalPrice = pin.chequePrice
? pin.chequePrice.additionalPricePerStay
: undefined
const hotelAdditionalCurrency = pin.chequePrice
? pin.chequePrice.currency?.toString()
: undefined
return (
<AdvancedMarker
key={pin.name}
className={styles.advancedMarker}
position={pin.coordinates}
anchorPoint={AdvancedMarkerAnchorPoint.CENTER}
zIndex={isActiveOrHovered ? 2 : 0}
onMouseEnter={() => engage(pin.name)}
onMouseLeave={() => disengage()}
onClick={() => toggleActiveHotelPin(pin.name, pin.operaId)}
>
{isActiveOrHovered && isDesktop && (
<InfoWindow
position={pin.coordinates}
pixelOffset={[0, -24]}
headerDisabled={true}
shouldFocus={false}
>
<StandaloneHotelCardDialog
data={pin}
handleClose={() => {
deactivate()
disengage()
}}
/>
</InfoWindow>
)}
<HotelPin
isActive={isActiveOrHovered}
hotelPrice={hotelPrice}
currency={pin.currency}
hotelAdditionalPrice={hotelAdditionalPrice}
hotelAdditionalCurrency={hotelAdditionalCurrency}
/>
</AdvancedMarker>
)
})}
</div>
)
}
export default HotelListingMapContent