"use client" import { use, useEffect } from "react" import { useIntl } from "react-intl" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { BookingStatusEnum } from "@/constants/booking" import { dt } from "@/lib/dt" import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore" import { useMyStayTotalPriceStore } from "@/stores/my-stay/myStayTotalPrice" import Image from "@/components/Image" import Divider from "@/components/TempDesignSystem/Divider" import IconChip from "@/components/TempDesignSystem/IconChip" import useLang from "@/hooks/useLang" import { IconForFeatureCode } from "../../utils" import { hasModifiableRate } from "../utils" import { hasBreakfastPackageFromBookingFlow } from "../utils/hasBreakfastPackage" import { mapRoomDetails } from "../utils/mapRoomDetails" import MultiRoomSkeleton from "./MultiRoomSkeleton" import PriceType from "./PriceType" import ToggleSidePeek from "./ToggleSidePeek" import styles from "./multiRoom.module.css" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" import type { Room } from "@/types/hotel" import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" import type { User } from "@/types/user" interface MultiRoomProps { booking?: BookingConfirmation["booking"] room?: | (Room & { bedType: Room["roomTypes"][number] }) | null bookingPromise?: Promise index?: number user: User | null } export default function MultiRoom({ room: initialRoom, booking: initialBooking, bookingPromise, index, user, }: MultiRoomProps) { const intl = useIntl() const lang = useLang() const addRoomPrice = useMyStayTotalPriceStore( (state) => state.actions.addRoomPrice ) const addLinkedReservationRoom = useMyStayRoomDetailsStore( (state) => state.actions.addLinkedReservationRoom ) const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom) const linkedReservationRooms = useMyStayRoomDetailsStore( (state) => state.linkedReservationRooms ) const allRooms = [bookedRoom, ...linkedReservationRooms] // Resolve promise data directly without setState let bookingInfo = initialBooking let roomInfo = initialRoom if (bookingPromise) { const promiseData = use(bookingPromise) if (promiseData) { bookingInfo = promiseData.booking roomInfo = promiseData.room } } const isBookingCancelled = bookingInfo?.reservationStatus === BookingStatusEnum.Cancelled const multiRoom = allRooms.find( (room) => room.confirmationNumber === bookingInfo?.confirmationNumber ) // Update stores when data is available useEffect(() => { if (bookingInfo) { addRoomPrice({ id: bookingInfo.confirmationNumber, totalPrice: isBookingCancelled ? 0 : bookingInfo.totalPrice, currencyCode: bookingInfo.currencyCode, isMainBooking: false, roomPoints: bookingInfo.roomPoints, }) // Add room details to the store addLinkedReservationRoom( mapRoomDetails({ booking: bookingInfo, room: roomInfo ?? null, roomNumber: index !== undefined ? index + 2 : 1, }) ) } }, [ bookingInfo, roomInfo, index, isBookingCancelled, addRoomPrice, addLinkedReservationRoom, ]) if (!multiRoom?.roomNumber) return const { adults, checkInDate, cheques, childrenAges, confirmationNumber, cancellationNumber, hotelId, roomPoints, packages, rateDefinition, isCancelled, priceType, vouchers, totalPrice, } = multiRoom const fromDate = dt(checkInDate).locale(lang) const adultsMsg = intl.formatMessage( { defaultMessage: "{adults, plural, one {# adult} other {# adults}}", }, { adults: adults, } ) const childrenMsg = intl.formatMessage( { defaultMessage: "{children, plural, one {# child} other {# children}}", }, { children: childrenAges.length, } ) const adultsOnlyMsg = adultsMsg const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") return (

{roomInfo?.name}

{isCancelled ? ( } > {intl.formatMessage({ defaultMessage: "Cancelled", })} ) : (
{intl.formatMessage( { defaultMessage: "Room {roomIndex}", }, { roomIndex: index !== undefined ? index + 2 : 1, } )}
)}
{isCancelled ? ( {intl.formatMessage({ defaultMessage: "Cancellation no", })} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {":"} ) : ( {intl.formatMessage({ defaultMessage: "Reference", })} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {":"} )} {isCancelled ? ( {cancellationNumber} ) : ( {confirmationNumber} )}
{packages?.some((item) => Object.values(RoomPackageCodeEnum).includes( item.code as RoomPackageCodeEnum ) ) && (
{packages .filter((item) => Object.values(RoomPackageCodeEnum).includes( item.code as RoomPackageCodeEnum ) ) .map((item) => { return ( ) })}
)}
{roomInfo?.name

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

{childrenAges.length > 0 ? adultsAndChildrenMsg : adultsOnlyMsg}

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

{rateDefinition.cancellationText}

{hasModifiableRate(rateDefinition.cancellationRule) && (

{intl.formatMessage({ defaultMessage: "Modify By", })}

{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}

18:00, {fromDate.format("dddd D MMM")}

)}

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

{hasBreakfastPackageFromBookingFlow( packages?.map((pkg) => ({ code: pkg.code, })) ?? [] ) ? intl.formatMessage({ defaultMessage: "Included", }) : intl.formatMessage({ defaultMessage: "Not included", })}

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

) }