"use client" import { useSearchParams } from "next/navigation" import { useSession } from "next-auth/react" import { useEffect, useMemo, useRef } from "react" import { useIntl } from "react-intl" import { useBookingCodeFilterStore } from "@/stores/bookingCode-filter" import { useHotelFilterStore } from "@/stores/hotel-filters" import { useHotelsMapStore } from "@/stores/hotels-map" import Alert from "@/components/TempDesignSystem/Alert" import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton" import { useScrollToTop } from "@/hooks/useScrollToTop" import { isValidClientSession } from "@/utils/clientSession" import HotelCard from "../HotelCard" import { DEFAULT_SORT } from "../SelectHotel/HotelSorter" import { getSortedHotels } from "./utils" import styles from "./hotelCardListing.module.css" import { type HotelCardListingProps, HotelCardListingTypeEnum, } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import { AlertTypeEnum } from "@/types/enums/alert" import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter" export default function HotelCardListing({ hotelData, unfilteredHotelCount, type = HotelCardListingTypeEnum.PageListing, }: HotelCardListingProps) { const { data: session } = useSession() const isUserLoggedIn = isValidClientSession(session) const searchParams = useSearchParams() const activeFilters = useHotelFilterStore((state) => state.activeFilters) const setResultCount = useHotelFilterStore((state) => state.setResultCount) const intl = useIntl() const { activeHotel } = useHotelsMapStore() const { showBackToTop, scrollToTop } = useScrollToTop({ threshold: 490 }) const activeCardRef = useRef(null) const sortBy = searchParams.get("sort") ?? DEFAULT_SORT const bookingCode = searchParams.get("bookingCode") // Special rates (corporate cheque, voucher) will not show regular rate hotels availability const isSpecialRate = bookingCode ? hotelData.find( (hotel) => hotel.availability.productType?.bonusCheque || hotel.availability.productType?.voucher ) : false const activeCodeFilter = useBookingCodeFilterStore( (state) => state.activeCodeFilter ) const isBookingCodeRateAvailable = bookingCode && !isSpecialRate ? hotelData.some((hotel) => hotel.availability.bookingCode) : false const showOnlyBookingCodeRates = isBookingCodeRateAvailable && activeCodeFilter === BookingCodeFilterEnum.Discounted const hotels = useMemo(() => { const sortedHotels = getSortedHotels({ hotels: hotelData, sortBy, bookingCode: isSpecialRate ? null : bookingCode, }) const updatedHotelsList = showOnlyBookingCodeRates ? sortedHotels.filter((hotel) => hotel.availability.bookingCode) : sortedHotels if (!activeFilters.length) { return updatedHotelsList } return updatedHotelsList.filter((hotel) => activeFilters.every((appliedFilterId) => hotel.hotel.detailedFacilities.some( (facility) => facility.id.toString() === appliedFilterId ) ) ) }, [ activeFilters, bookingCode, hotelData, sortBy, showOnlyBookingCodeRates, isSpecialRate, ]) useEffect(() => { if (activeCardRef.current && type === HotelCardListingTypeEnum.MapListing) { activeCardRef.current.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center", }) } }, [activeHotel, type]) useEffect(() => { setResultCount(hotels.length, unfilteredHotelCount) }, [hotels, setResultCount, unfilteredHotelCount]) function isHotelActiveInMapView(hotelName: string): boolean { return ( hotelName === activeHotel && type === HotelCardListingTypeEnum.MapListing ) } return (
{hotels?.length ? hotels.map((hotel) => (
)) : null} {!hotels?.length && activeFilters ? ( ) : null} {showBackToTop && ( )}
) }