Files
web/components/HotelReservation/HotelCardDialogListing/index.tsx
2024-11-12 14:34:02 +01:00

84 lines
2.1 KiB
TypeScript

"use client"
import { useCallback, useEffect, useRef } from "react"
import HotelCardDialog from "../HotelCardDialog"
import { getHotelPins } from "./utils"
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
interface HotelCardDialogListingProps {
hotels: HotelData[]
activeCard: string | null | undefined
onActiveCardChange: (hotelName: string | null) => void
}
export default function HotelCardDialogListing({
hotels,
activeCard,
onActiveCardChange,
}: HotelCardDialogListingProps) {
const hotelsPinData = getHotelPins(hotels)
const activeCardRef = useRef<HTMLDivElement | null>(null)
const handleIntersection = useCallback(
(entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const cardName = entry.target.getAttribute("data-name")
if (cardName) {
onActiveCardChange(cardName)
}
}
})
},
[onActiveCardChange]
)
useEffect(() => {
const observer = new IntersectionObserver(handleIntersection, {
root: null,
threshold: 0.5, // Adjust threshold as needed
})
const elements = document.querySelectorAll("[data-name]")
elements.forEach((el) => observer.observe(el))
return () => {
elements.forEach((el) => observer.unobserve(el))
}
}, [handleIntersection])
useEffect(() => {
if (activeCardRef.current) {
activeCardRef.current.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "center",
})
}
}, [activeCard])
return (
<>
{hotelsPinData?.length &&
hotelsPinData.map((data) => {
const isActive = data.name === activeCard
return (
<div
key={data.name}
ref={isActive ? activeCardRef : null}
data-name={data.name}
>
<HotelCardDialog
data={data}
isOpen={!!activeCard}
handleClose={() => {}}
/>
</div>
)
})}
</>
)
}