"use client" import { createElement, useCallback } from "react" import { useIntl } from "react-intl" import ToggleSidePeek from "@/components/HotelReservation/EnterDetails/SelectedRoom/ToggleSidePeek" import FlexibilityOption from "@/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption" import { ErrorCircleIcon } from "@/components/Icons" import ImageGallery from "@/components/ImageGallery" import Caption from "@/components/TempDesignSystem/Text/Caption" import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import { getIconForFeatureCode } from "../../utils" import { cardVariants } from "./cardVariants" import styles from "./roomCard.module.css" import type { RoomCardProps } from "@/types/components/hotelReservation/selectRate/roomCard" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" import { HotelTypeEnum } from "@/types/enums/hotelType" import type { RateDefinition } from "@/server/routers/hotels/output" export default function RoomCard({ hotelId, hotelType, rateDefinitions, roomConfiguration, roomCategories, selectedPackages, packages, handleSelectRate, }: RoomCardProps) { const intl = useIntl() const rates = { saveRate: rateDefinitions.find( (rate) => rate.cancellationRule === "NotCancellable" ), changeRate: rateDefinitions.find( (rate) => rate.cancellationRule === "Changeable" ), flexRate: rateDefinitions.find( (rate) => rate.cancellationRule === "CancellableBefore6PM" ), } function findProductForRate(rate: RateDefinition | undefined) { return rate ? roomConfiguration.products.find( (product) => product.productType.public?.rateCode === rate.rateCode || product.productType.member?.rateCode === rate.rateCode ) : undefined } function getRateDefinitionForRate(rate: RateDefinition | undefined) { return rateDefinitions.find((def) => def.rateCode === rate?.rateCode) } const getBreakfastMessage = (rate: RateDefinition | undefined) => { if (hotelType === HotelTypeEnum.ScandicGo) { return intl.formatMessage({ id: "Breakfast deal can be purchased at the hotel.", }) } return getRateDefinitionForRate(rate)?.breakfastIncluded ? intl.formatMessage({ id: "Breakfast is included." }) : intl.formatMessage({ id: "Breakfast selection in next step." }) } const petRoomPackage = (selectedPackages.includes(RoomPackageCodeEnum.PET_ROOM) && packages?.find((pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM)) || undefined const selectedRoom = roomCategories.find((roomCategory) => roomCategory.roomTypes.some( (roomType) => roomType.code === roomConfiguration.roomTypeCode ) ) const { name, roomSize, occupancy, images } = selectedRoom || {} const freeCancelation = intl.formatMessage({ id: "Free cancellation" }) const nonRefundable = intl.formatMessage({ id: "Non-refundable" }) const freeBooking = intl.formatMessage({ id: "Free rebooking" }) const payLater = intl.formatMessage({ id: "Pay later" }) const payNow = intl.formatMessage({ id: "Pay now" }) const rateKey = useCallback( (key: string) => { switch (key) { case "flexRate": return freeCancelation case "saveRate": return nonRefundable default: return freeBooking } }, [freeCancelation, freeBooking, nonRefundable] ) const classNames = cardVariants({ availability: roomConfiguration.status === "NotAvailable" ? "noAvailability" : "default", }) return (
{roomConfiguration.roomsLeft > 0 && roomConfiguration.roomsLeft < 5 && ( {`${roomConfiguration.roomsLeft} ${intl.formatMessage({ id: "Left" })}`} )} {roomConfiguration.features .filter((feature) => selectedPackages.includes(feature.code)) .map((feature) => ( {createElement(getIconForFeatureCode(feature.code), { width: 16, height: 16, color: "burgundy", })} ))}
{/*NOTE: images from the test API are hosted on test3.scandichotels.com, which can't be accessed unless on Scandic's Wifi or using Citrix. */}
{occupancy && ( {intl.formatMessage( { id: "booking.guests", }, { nrOfGuests: occupancy?.total } )} )} {roomSize && ( {roomSize.min === roomSize.max ? roomSize.min : `${roomSize.min}-${roomSize.max}`} m² )}
{roomConfiguration.roomTypeCode && ( )}
{name} {/* Out of scope for now {descriptions?.short} */}
{getBreakfastMessage(rates.flexRate)} {roomConfiguration.status === "NotAvailable" ? (
{intl.formatMessage({ id: "This room is not available", })}
) : (
{Object.entries(rates).map(([key, rate]) => ( ))}
)}
) }