Refactor TripadvisorChip * feat: create new StaticChip componeny * refactor tripadvisor chip to use ChipStatic * refactor: use TripadvisorChip everywhere * fix: use withChipStatic Approved-by: Erik Tiekstra
129 lines
4.2 KiB
TypeScript
129 lines
4.2 KiB
TypeScript
import { useIntl } from "react-intl"
|
|
|
|
import { getSingleDecimal } from "@scandic-hotels/common/utils/numberFormatting"
|
|
import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
|
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
|
import { FacilityToIcon } from "@scandic-hotels/design-system/FacilityToIcon"
|
|
import HotelLogoIcon from "@scandic-hotels/design-system/Icons/HotelLogoIcon"
|
|
import ImageGallery from "@scandic-hotels/design-system/ImageGallery"
|
|
import { TripAdvisorChip } from "@scandic-hotels/design-system/TripAdvisorChip"
|
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
|
|
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
|
|
|
|
import styles from "./hotelListingItem.module.css"
|
|
|
|
import type { HotelListingHotelData } from "@scandic-hotels/trpc/types/hotel"
|
|
|
|
interface HotelListingItemProps {
|
|
hotel: HotelListingHotelData["hotel"]
|
|
url: string | null
|
|
}
|
|
|
|
export default function HotelListingItem({
|
|
hotel,
|
|
url,
|
|
}: HotelListingItemProps) {
|
|
const intl = useIntl()
|
|
const galleryImages = mapApiImagesToGalleryImages(hotel.galleryImages)
|
|
const tripadvisorRating = hotel.tripadvisor
|
|
const address = `${hotel.address.streetAddress}, ${hotel.address.city}`
|
|
const amenities = hotel.detailedFacilities.slice(0, 5)
|
|
const hotelDescription = hotel.description
|
|
|
|
return (
|
|
<article className={styles.hotelListingItem}>
|
|
<div className={styles.imageWrapper}>
|
|
<ImageGallery
|
|
images={galleryImages}
|
|
fill
|
|
sizes="(min-width: 768px) 450px, 100vw"
|
|
title={intl.formatMessage(
|
|
{
|
|
id: "common.imageGalleryWithTitle",
|
|
defaultMessage: "{title} - Image gallery",
|
|
},
|
|
{ title: hotel.name }
|
|
)}
|
|
/>
|
|
{tripadvisorRating ? (
|
|
<TripAdvisorChip
|
|
color="Neutral"
|
|
rating={tripadvisorRating}
|
|
wrapper="x2"
|
|
size="sm"
|
|
/>
|
|
) : null}
|
|
</div>
|
|
<div className={styles.content}>
|
|
<div className={styles.intro}>
|
|
<HotelLogoIcon
|
|
hotelId={hotel.id}
|
|
hotelType={hotel.hotelType}
|
|
height={30}
|
|
/>
|
|
<Typography variant="Title/Subtitle/md">
|
|
<h3>{hotel.name}</h3>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<div className={styles.captions}>
|
|
<span>{address}</span>
|
|
<span>
|
|
<Divider
|
|
className={styles.divider}
|
|
variant="vertical"
|
|
color="Border/Divider/Default"
|
|
/>
|
|
</span>
|
|
<span>
|
|
{intl.formatMessage(
|
|
{
|
|
id: "common.kmToCityCenter",
|
|
defaultMessage: "{number} km to city center",
|
|
},
|
|
{
|
|
number: getSingleDecimal(
|
|
hotel.location.distanceToCentre / 1000
|
|
),
|
|
}
|
|
)}
|
|
</span>
|
|
</div>
|
|
</Typography>
|
|
</div>
|
|
{hotelDescription ? (
|
|
<Typography variant="Body/Paragraph/mdRegular">
|
|
<p>{hotelDescription}</p>
|
|
</Typography>
|
|
) : null}
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<ul className={styles.amenityList}>
|
|
{amenities.map((amenity) => {
|
|
return (
|
|
<li className={styles.amenityItem} key={amenity.id}>
|
|
<FacilityToIcon
|
|
id={amenity.id}
|
|
color="CurrentColor"
|
|
size={20}
|
|
/>
|
|
{amenity.name}
|
|
</li>
|
|
)
|
|
})}
|
|
</ul>
|
|
</Typography>
|
|
</div>
|
|
{url ? (
|
|
<div className={styles.ctaWrapper}>
|
|
<ButtonLink href={url} variant="Tertiary" color="Primary" size="sm">
|
|
{intl.formatMessage({
|
|
id: "destination.seeHotelDetails",
|
|
defaultMessage: "See hotel details",
|
|
})}
|
|
</ButtonLink>
|
|
</div>
|
|
) : null}
|
|
</article>
|
|
)
|
|
}
|