"use client" import { cx } from "class-variance-authority" import { useRef, useState } from "react" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { Button } from "@scandic-hotels/design-system/Button" import { MaterialIcon, type MaterialIconProps, } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { useHotelListingDataStore } from "@/stores/hotel-listing-data" import CampaignHotelListingSkeleton from "@/components/Blocks/CampaignHotelListing/CampaignHotelListingSkeleton" import HotelFilterAndSort from "@/components/HotelFilterAndSort" import HotelListingItem from "./HotelListingItem" import styles from "./campaignHotelListing.module.css" interface CampaignHotelListingClientProps { heading: string preamble?: string | null bookingCode?: string | null visibleCountMobile: 3 | 6 visibleCountDesktop: 3 | 6 isMainBlock: boolean } export default function CampaignHotelListingClient({ heading, preamble, visibleCountMobile, visibleCountDesktop, isMainBlock, bookingCode, }: CampaignHotelListingClientProps) { const intl = useIntl() const isMobile = useMediaQuery("(max-width: 767px)") const scrollRef = useRef(null) const { activeHotels, isLoading } = useHotelListingDataStore((state) => ({ activeHotels: state.activeHotels, isLoading: state.isLoading, })) const initialCount = isMobile ? visibleCountMobile : visibleCountDesktop // Initial number of activeHotels to show const thresholdCount = initialCount + 3 // This is the threshold at which we start showing the "Show More" button const showAllThreshold = initialCount * 3 // This is the threshold at which we show the "Show All" button const incrementCount = initialCount // Number of activeHotels to increment when the button is clicked const [visibleCount, setVisibleCount] = useState(() => // Set initial visible count based on the number of activeHotels and the threshold activeHotels.length <= thresholdCount ? activeHotels.length : initialCount ) // Only show the show more/less button if the length of activeHotels exceeds the threshold count const showButton = activeHotels.length > thresholdCount // Determine if we are at the stage where the user can click to show all activeHotels const canShowAll = activeHotels.length > visibleCount && (visibleCount + incrementCount > showAllThreshold || visibleCount + incrementCount >= activeHotels.length) function handleButtonClick() { if (visibleCount < activeHotels.length) { if (canShowAll) { setVisibleCount(activeHotels.length) } else { setVisibleCount((prev) => Math.min(prev + incrementCount, activeHotels.length) ) } } else { setVisibleCount(initialCount) if (scrollRef.current) { scrollRef.current.scrollIntoView({ behavior: "smooth" }) } } } let buttonText = intl.formatMessage({ id: "common.showMore", defaultMessage: "Show more", }) let iconDirection: MaterialIconProps["icon"] = "keyboard_arrow_down" if (visibleCount === activeHotels.length) { buttonText = intl.formatMessage({ id: "common.showLess", defaultMessage: "Show less", }) iconDirection = "keyboard_arrow_up" } else if (canShowAll) { buttonText = intl.formatMessage({ id: "common.showAll", defaultMessage: "Show all", }) } if (isLoading) { return } return (

{heading}

{isMainBlock ? : null} {preamble ? (

{preamble}

) : null}
    {activeHotels.map(({ hotel, url }, index) => { const urlWithOptionalBookingCode = bookingCode ? `${url}?bookingCode=${bookingCode}` : url return (
  • = visibleCount, })} >
  • ) })}
{showButton ? ( ) : null}
) }