159 lines
5.2 KiB
TypeScript
159 lines
5.2 KiB
TypeScript
"use client"
|
|
import { useParams } from "next/dist/client/components/navigation"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { Lang } from "@/constants/languages"
|
|
import { selectHotelMap } from "@/constants/routes/hotelReservation"
|
|
|
|
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
|
|
import ImageGallery from "@/components/ImageGallery"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Divider from "@/components/TempDesignSystem/Divider"
|
|
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 ReadMore from "../ReadMore"
|
|
import TripAdvisorChip from "../TripAdvisorChip"
|
|
import HotelLogo from "./HotelLogo"
|
|
import HotelPriceList from "./HotelPriceList"
|
|
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"
|
|
|
|
export default function HotelCard({
|
|
hotel,
|
|
type = HotelCardListingTypeEnum.PageListing,
|
|
state = "default",
|
|
onHotelCardHover,
|
|
}: HotelCardProps) {
|
|
const params = useParams()
|
|
const lang = params.lang as Lang
|
|
const intl = useIntl()
|
|
|
|
const { hotelData } = hotel
|
|
const { price } = hotel
|
|
|
|
const amenities = hotelData.detailedFacilities.slice(0, 5)
|
|
|
|
const classNames = hotelCardVariants({
|
|
type,
|
|
state,
|
|
})
|
|
|
|
const handleMouseEnter = () => {
|
|
if (onHotelCardHover) {
|
|
onHotelCardHover(hotelData.name)
|
|
}
|
|
}
|
|
const handleMouseLeave = () => {
|
|
if (onHotelCardHover) {
|
|
onHotelCardHover(null)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<article
|
|
className={classNames}
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseLeave={handleMouseLeave}
|
|
>
|
|
<div>
|
|
<div className={styles.imageContainer}>
|
|
<ImageGallery
|
|
title={hotelData.name}
|
|
images={hotelData.galleryImages}
|
|
fill
|
|
/>
|
|
{hotelData.ratings?.tripAdvisor && (
|
|
<TripAdvisorChip rating={hotelData.ratings.tripAdvisor.rating} />
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className={styles.hotelContent}>
|
|
<section className={styles.hotelInformation}>
|
|
<div className={styles.titleContainer}>
|
|
<HotelLogo
|
|
hotelId={hotel.hotelData.operaId}
|
|
hotelType={hotel.hotelData.hotelType}
|
|
/>
|
|
<Subtitle textTransform="capitalize" color="uiTextHighContrast">
|
|
{hotelData.name}
|
|
</Subtitle>
|
|
<div className={styles.addressContainer}>
|
|
<address className={styles.address}>
|
|
<Caption color="uiTextPlaceholder">
|
|
{hotelData.address.streetAddress}, {hotelData.address.city}
|
|
</Caption>
|
|
</address>
|
|
<Link
|
|
className={styles.addressMobile}
|
|
href={`${selectHotelMap[lang]}?selectedHotel=${hotelData.name}`}
|
|
keepSearchParams
|
|
>
|
|
<Caption color="baseTextMediumContrast" type="underline">
|
|
{hotelData.address.streetAddress}, {hotelData.address.city}
|
|
</Caption>
|
|
</Link>
|
|
<div>
|
|
<Divider variant="vertical" color="subtle" />
|
|
</div>
|
|
<Caption color="uiTextPlaceholder">
|
|
{intl.formatMessage(
|
|
{ id: "Distance to city centre" },
|
|
{ number: hotelData.location.distanceToCentre }
|
|
)}
|
|
</Caption>
|
|
</div>
|
|
</div>
|
|
<Body className={styles.hotelDescription}>
|
|
{hotelData.hotelContent.texts.descriptions.short}
|
|
</Body>
|
|
<div className={styles.facilities}>
|
|
{amenities.map((facility) => {
|
|
const IconComponent = mapFacilityToIcon(facility.id)
|
|
return (
|
|
<div className={styles.facilitiesItem} key={facility.id}>
|
|
{IconComponent && <IconComponent color="grey80" />}
|
|
<Caption color="uiTextMediumContrast">
|
|
{facility.name}
|
|
</Caption>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
<ReadMore
|
|
label={intl.formatMessage({ id: "About the hotel" })}
|
|
hotelId={hotelData.operaId}
|
|
hotel={hotelData}
|
|
showCTA={true}
|
|
/>
|
|
</section>
|
|
<div className={styles.prices}>
|
|
<HotelPriceList price={price} />
|
|
<Button
|
|
asChild
|
|
theme="base"
|
|
intent="primary"
|
|
size="small"
|
|
className={styles.button}
|
|
>
|
|
{/* TODO: Localize link and also use correct search params */}
|
|
<Link
|
|
href={`/en/hotelreservation/select-rate?hotel=${hotelData.operaId}`}
|
|
color="none"
|
|
keepSearchParams
|
|
>
|
|
{intl.formatMessage({ id: "See rooms" })}
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
)
|
|
}
|