"use client" import { useCallback, useEffect, useRef } from "react" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { useHotelsMapStore } from "@/stores/hotels-map" import useClickOutside from "@/hooks/useClickOutside" import HotelCardDialog from "../HotelCardDialog" import { getHotelPins } from "./utils" import styles from "./hotelCardDialogListing.module.css" import type { HotelCardDialogListingProps } from "@/types/components/hotelReservation/selectHotel/map" export default function HotelCardDialogListing({ hotels, }: HotelCardDialogListingProps) { const intl = useIntl() const isRedemption = hotels?.find( (hotel) => hotel.availability.productType?.redemptions?.length ) const currencyValue = isRedemption ? intl.formatMessage({ id: "Points" }) : undefined const hotelsPinData = hotels ? getHotelPins(hotels, currencyValue) : [] const activeCardRef = useRef(null) const observerRef = useRef(null) const dialogRef = useRef(null) const isMobile = useMediaQuery("(max-width: 767px)") const { activeHotelCard, setActiveHotelCard, setActiveHotelPin } = useHotelsMapStore() function handleClose() { setActiveHotelCard(null) setActiveHotelPin(null) } useClickOutside(dialogRef, !!activeHotelCard && isMobile, handleClose) const handleIntersection = useCallback( (entries: IntersectionObserverEntry[]) => { entries.forEach((entry) => { if (entry.isIntersecting) { const cardName = entry.target.getAttribute("data-name") if (cardName) { setActiveHotelCard(cardName) } } }) }, [setActiveHotelCard] ) useEffect(() => { observerRef.current = new IntersectionObserver(handleIntersection, { root: null, threshold: 0.5, }) const elements = document.querySelectorAll("[data-name]") elements.forEach((el) => observerRef.current?.observe(el)) return () => { elements.forEach((el) => observerRef.current?.unobserve(el)) observerRef.current?.disconnect() } }, [handleIntersection]) useEffect(() => { if (activeCardRef.current) { // Temporarily disconnect the observer observerRef.current?.disconnect() activeCardRef.current.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center", }) // Reconnect the observer after scrolling const elements = document.querySelectorAll("[data-name]") setTimeout(() => { elements.forEach((el) => observerRef.current?.observe(el)) }, 1000) } }, [activeHotelCard]) return (
{!!hotelsPinData?.length && hotelsPinData.map((data) => { const isActive = data.name === activeHotelCard return (
) })}
) }