"use client" import { useParams } from "next/dist/client/components/navigation" import { useRouter, useSearchParams } from "next/navigation" import { memo } from "react" import { useIntl } from "react-intl" import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon" import HotelLogoIcon from "@scandic-hotels/design-system/Icons/HotelLogoIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { selectHotelMap, selectRate } from "@/constants/routes/hotelReservation" import { useHotelsMapStore } from "@/stores/hotels-map" import { FacilityToIcon } from "@/components/ContentType/HotelPage/data" import ImageGallery from "@/components/ImageGallery" import Button from "@/components/TempDesignSystem/Button" import Divider from "@/components/TempDesignSystem/Divider" import IconChip from "@/components/TempDesignSystem/IconChip" import Link from "@/components/TempDesignSystem/Link" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import { Tooltip } from "@/components/TempDesignSystem/Tooltip" import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" import { getSingleDecimal } from "@/utils/numberFormatting" import ReadMore from "../ReadMore" import TripAdvisorChip from "../TripAdvisorChip" import HotelChequeCard from "./HotelChequeCard" import HotelPointsRow from "./HotelPointsRow" import HotelPriceCard from "./HotelPriceCard" import HotelVoucherCard from "./HotelVoucherCard" import NoPriceAvailableCard from "./NoPriceAvailableCard" import { hotelCardVariants } from "./variants" import styles from "./hotelCard.module.css" import { HotelCardListingTypeEnum } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps" import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" import { RateTypeEnum } from "@/types/enums/rateType" import type { Lang } from "@/constants/languages" function HotelCard({ hotelData: { availability, hotel }, isUserLoggedIn, state = "default", type = HotelCardListingTypeEnum.PageListing, bookingCode = "", }: HotelCardProps) { const params = useParams() const searchParams = useSearchParams() const lang = params.lang as Lang const intl = useIntl() const { activate, engage, disengageAfterDelay } = useHotelsMapStore() const amenities = hotel.detailedFacilities.slice(0, 5) const router = useRouter() const classNames = hotelCardVariants({ type, state, }) const handleAddressClick = (event: React.MouseEvent) => { event.preventDefault() activate(hotel.name) router.push(`${selectHotelMap(lang)}?${searchParams.toString()}`) } const addressStr = `${hotel.address.streetAddress}, ${hotel.address.city}` const galleryImages = mapApiImagesToGalleryImages(hotel.galleryImages || []) const fullPrice = availability.productType?.public?.rateType === RateTypeEnum.Regular || availability.productType?.member?.rateType === RateTypeEnum.Regular const price = availability.productType const hasInsufficientPoints = !price?.redemptions?.some( (r) => r.hasEnoughPoints ) const notEnoughPointsLabel = intl.formatMessage({ defaultMessage: "Not enough points", }) return (
engage(hotel.name)} onMouseLeave={() => disengageAfterDelay()} >
{hotel.ratings?.tripAdvisor && ( )}
{hotel.name}
{type == HotelCardListingTypeEnum.MapListing ? (

{addressStr}

) : (

{addressStr}

)}
{intl.formatMessage( { defaultMessage: "{number} km to city center", }, { number: getSingleDecimal( hotel.location.distanceToCentre / 1000 ), } )}
{hotel.hotelContent.texts.descriptions?.short}
{amenities.map((facility) => { const Icon = ( ) return (
{Icon && Icon} {facility.name}
) })}
{!availability.productType ? ( ) : ( <> {bookingCode && (
} > {intl.formatMessage( { defaultMessage: "Booking code: {value}", }, { value: bookingCode, strong: (text) => ( {text} ), } )}
)} {(!isUserLoggedIn || !price?.member || (bookingCode && !fullPrice)) && price?.public && ( )} {availability.productType.member && ( )} {price?.voucher && ( )} {price?.bonusCheque && ( )} {price?.redemptions?.length ? (
{intl.formatMessage({ defaultMessage: "Available rates", })} {price.redemptions.map((redemption) => ( ))}
) : null} {price?.redemptions?.length && hasInsufficientPoints ? ( ) : ( )} )}
) } export default memo(HotelCard)