import { useIntl } from "react-intl" import { getRoomFeatureDescription } from "@scandic-hotels/booking-flow/utils/getRoomFeatureDescription" import { sumPackages } from "@scandic-hotels/booking-flow/utils/SelectRate" import { changeOrCancelDateFormat } from "@scandic-hotels/common/constants/dateFormats" import { dt } from "@scandic-hotels/common/dt" import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting" import Accordion from "@scandic-hotels/design-system/Accordion" import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem" import IconChip from "@scandic-hotels/design-system/IconChip" import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import ImageGallery from "@scandic-hotels/design-system/ImageGallery" import { Typography } from "@scandic-hotels/design-system/Typography" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" import GuestDetails from "@/components/HotelReservation/MyStay/GuestDetails" import PriceType from "@/components/HotelReservation/MyStay/PriceType" import { hasModifiableRate } from "@/components/HotelReservation/MyStay/utils" import useLang from "@/hooks/useLang" import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" import RoomDetails from "./RoomDetails" import styles from "./bookedRoomSidePeekContent.module.css" import type { BedTypeSchema } from "@scandic-hotels/booking-flow/stores/enter-details/types" import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages" import type { BookingConfirmationSchema } from "@scandic-hotels/trpc/types/bookingConfirmation" import type { Child } from "@scandic-hotels/trpc/types/child" import type { Room as HotelRoom } from "@scandic-hotels/trpc/types/hotel" import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay" import type { SafeUser } from "@/types/user" type PartialHotelRoom = Pick< HotelRoom, "descriptions" | "images" | "name" | "roomFacilities" | "roomTypes" > type Room = Pick< BookingConfirmationSchema, | "adults" | "bookingCode" | "cancellationNumber" | "checkInDate" | "cheques" | "confirmationNumber" | "refId" | "currencyCode" | "guest" | "rateDefinition" | "totalPoints" | "totalPrice" | "vouchers" > & { bedType: BedTypeSchema breakfast: Omit | false | undefined childrenInRoom: Child[] isCancelled: boolean packages: Packages | null priceType: PriceTypeEnum room: PartialHotelRoom | null roomName: string roomNumber: number terms: string | null } interface BookedRoomSidepeekContentProps { room: Room user: SafeUser } export default function BookedRoomSidePeekContent({ room, user, }: BookedRoomSidepeekContentProps) { const intl = useIntl() const lang = useLang() const { adults, bedType, bookingCode, breakfast, cancellationNumber, checkInDate, cheques, childrenInRoom, confirmationNumber, refId, currencyCode, guest, isCancelled, roomName, packages, priceType, rateDefinition, room: hotelRoom, roomNumber, totalPoints, terms, totalPrice, vouchers, } = room let totalRoomPrice = totalPrice // API returns negative values for totalPrice // on voucher bookings (╯°□°)╯︵ ┻━┻ if (vouchers && totalRoomPrice < 0) { const pkgsSum = sumPackages(packages) totalRoomPrice = pkgsSum.price } const fromDate = dt(checkInDate).locale(lang) const galleryImages = hotelRoom ? mapApiImagesToGalleryImages(hotelRoom.images) : null const adultsMsg = intl.formatMessage( { id: "booking.numberOfAdults", defaultMessage: "{adults, plural, one {# adult} other {# adults}}", }, { adults: adults, } ) const childrenMsg = intl.formatMessage( { id: "booking.numberOfChildren", defaultMessage: "{children, plural, one {# child} other {# children}}", }, { children: childrenInRoom.length, } ) const adultsOnlyMsg = adultsMsg const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") const formattedTotalPrice = formatPrice(intl, totalPrice, currencyCode) let breakfastPrice = intl.formatMessage({ id: "common.noBreakfast", defaultMessage: "No breakfast", }) if (rateDefinition.breakfastIncluded) { breakfastPrice = intl.formatMessage({ id: "common.included", defaultMessage: "Included", }) } else if (breakfast) { breakfastPrice = formatPrice( intl, breakfast.localPrice.totalPrice, breakfast.localPrice.currency ) } const hotelRoomName = hotelRoom?.name || roomName return (
{isCancelled ? ( } > {intl.formatMessage({ id: "common.cancelled", defaultMessage: "Cancelled", })} ) : (
{intl.formatMessage( { id: "booking.roomIndex", defaultMessage: "Room {roomIndex}", }, { roomIndex: roomNumber } )}
)}
{isCancelled ? ( {intl.formatMessage({ id: "booking.cancellationNo", defaultMessage: "Cancellation no", })} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {":"} ) : ( {intl.formatMessage({ id: "common.bookingNumber", defaultMessage: "Booking number", })} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {":"} )} {isCancelled ? ( {cancellationNumber} ) : ( {confirmationNumber} )}
{galleryImages ? ( ) : null}

{intl.formatMessage({ id: "booking.guests", defaultMessage: "Guests", })}

{childrenInRoom.length > 0 ? adultsAndChildrenMsg : adultsOnlyMsg}

{intl.formatMessage({ id: "booking.terms", defaultMessage: "Terms", })}

{terms}

{hasModifiableRate(rateDefinition.cancellationRule) && (

{intl.formatMessage({ id: "myStay.modifyBy", defaultMessage: "Modify by", })}

{intl.formatMessage( { id: "common.untilWithTimeAndDate", defaultMessage: "Until {time}, {date}", }, { time: "18:00", date: fromDate.format(changeOrCancelDateFormat[lang]), } )}

)}

{intl.formatMessage({ id: "common.breakfast", defaultMessage: "Breakfast", })}

{breakfastPrice}

{packages?.some((item) => Object.values(RoomPackageCodeEnum).includes( item.code as RoomPackageCodeEnum ) ) && (

{intl.formatMessage({ id: "booking.roomClassification", defaultMessage: "Room classification", })}

{packages ?.filter((item) => Object.values(RoomPackageCodeEnum).includes( item.code as RoomPackageCodeEnum ) ) .map((item) => getRoomFeatureDescription( item.code, item.description, intl ) ) .join(", ")}

)}

{intl.formatMessage({ id: "booking.bedPreference", defaultMessage: "Bed preference", })}

{bedType?.description}

{intl.formatMessage({ id: "booking.roomTotal", defaultMessage: "Room total", })}

{bookingCode && ( } > {intl.formatMessage( { id: "booking.bookingCodeWithValue", defaultMessage: "Booking code: {value}", }, { value: bookingCode, strong: (text) => ( {text} ), } )} )}
{hotelRoom ? ( ) : null}
) }