"use client" import React from "react" import { useIntl } from "react-intl" import { dt } from "@/lib/dt" import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal" import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop" import { ArrowRightIcon, CheckIcon, ChevronDownSmallIcon, } from "@/components/Icons" import Modal from "@/components/Modal" import Button from "@/components/TempDesignSystem/Button" import Divider from "@/components/TempDesignSystem/Divider" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import useLang from "@/hooks/useLang" import { formatPrice } from "@/utils/numberFormatting" import styles from "./ui.module.css" import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" import type { RoomRate } from "@/types/components/hotelReservation/enterDetails/details" import type { EnterDetailsSummaryProps } from "@/types/components/hotelReservation/summary" export default function SummaryUI({ booking, rooms, totalPrice, isMember, breakfastIncluded, vat, toggleSummaryOpen, }: EnterDetailsSummaryProps) { const intl = useIntl() const lang = useLang() const diff = dt(booking.toDate).diff(booking.fromDate, "days") const nights = intl.formatMessage( { id: "{totalNights, plural, one {# night} other {# nights}}" }, { totalNights: diff } ) function handleToggleSummary() { if (toggleSummaryOpen) { toggleSummaryOpen() } } function getMemberPrice(roomRate: RoomRate) { return roomRate?.memberRate ? { currency: roomRate.memberRate.localPrice.currency, pricePerNight: roomRate.memberRate.localPrice.pricePerNight, amount: roomRate.memberRate.localPrice.pricePerStay, } : null } const showSignupPromo = rooms.length === 1 && rooms .slice(0, 1) .some((r) => !isMember || !r.guest.join || !r.guest.membershipNo) const memberPrice = getMemberPrice(rooms[0].roomRate) return (
{intl.formatMessage({ id: "Booking summary" })} {dt(booking.fromDate).locale(lang).format("ddd, D MMM")} {dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
{rooms.map((room, idx) => { const roomNumber = idx + 1 const adults = room.adults const childrenInRoom = room.childrenInRoom const childrenBeds = childrenInRoom?.reduce( (acc, value) => { const bedType = Number(value.bed) if (bedType === ChildBedMapEnum.IN_ADULTS_BED) { return acc } const count = acc.get(bedType) ?? 0 acc.set(bedType, count + 1) return acc }, new Map([ [ChildBedMapEnum.IN_CRIB, 0], [ChildBedMapEnum.IN_EXTRA_BED, 0], ]) ) const childBedCrib = childrenBeds?.get(ChildBedMapEnum.IN_CRIB) const childBedExtraBed = childrenBeds?.get(ChildBedMapEnum.IN_EXTRA_BED) const memberPrice = getMemberPrice(room.roomRate) const isFirstRoomMember = roomNumber === 1 && isMember const showMemberPrice = !!(isFirstRoomMember || room.guest.join || room.guest.membershipNo) && memberPrice const adultsMsg = intl.formatMessage( { id: "{totalAdults, plural, one {# adult} other {# adults}}" }, { totalAdults: adults } ) const guestsParts = [adultsMsg] if (childrenInRoom?.length) { const childrenMsg = intl.formatMessage( { id: "{totalChildren, plural, one {# child} other {# children}}", }, { totalChildren: childrenInRoom.length } ) guestsParts.push(childrenMsg) } return (
{rooms.length > 1 ? ( {intl.formatMessage({ id: "Room" })} {roomNumber} ) : null}
{room.roomType} {formatPrice( intl, room.roomPrice.perStay.local.price, room.roomPrice.perStay.local.currency )}
{guestsParts.join(", ")} {room.cancellationText} {intl.formatMessage({ id: "Rate details" })} } title={room.cancellationText} >
{room.rateDetails?.map((info) => ( {info} ))}
{room.roomFeatures ? room.roomFeatures.map((feature) => (
{feature.description}
{formatPrice( intl, parseInt(feature.localPrice.price), feature.localPrice.currency )}
)) : null} {room.bedType ? (
{room.bedType.description} {formatPrice( intl, 0, room.roomPrice.perStay.local.currency )}
) : null} {childBedCrib ? (
{intl.formatMessage( { id: "Crib (child) × {count}" }, { count: childBedCrib } )} {intl.formatMessage({ id: "Based on availability" })}
{formatPrice( intl, 0, room.roomPrice.perStay.local.currency )}
) : null} {childBedExtraBed ? (
{intl.formatMessage( { id: "Extra bed (child) × {count}" }, { count: childBedExtraBed, } )}
{formatPrice( intl, 0, room.roomPrice.perStay.local.currency )}
) : null} {breakfastIncluded ? (
{intl.formatMessage({ id: "Breakfast included" })}
) : room.breakfast === false ? (
{intl.formatMessage({ id: "No breakfast" })} {formatPrice( intl, 0, room.roomPrice.perStay.local.currency )}
) : null} {room.breakfast ? (
{intl.formatMessage({ id: "Breakfast buffet" })}
{intl.formatMessage( { id: "{totalAdults, plural, one {# adult} other {# adults}}", }, { totalAdults: adults } )} {formatPrice( intl, parseInt(room.breakfast.localPrice.totalPrice), room.breakfast.localPrice.currency )}
{childrenInRoom?.length ? (
{intl.formatMessage( { id: "{totalChildren, plural, one {# child} other {# children}}", }, { totalChildren: childrenInRoom.length } )} {formatPrice( intl, 0, room.breakfast.localPrice.currency )}
) : null}
) : null}
) })}
{intl.formatMessage( { id: "Total price (incl VAT)" }, { b: (str) => {str} } )} ({ adults: r.adults, childrenInRoom: r.childrenInRoom, roomPrice: r.roomPrice, roomType: r.roomType, bedType: r.bedType, breakfast: r.breakfast, }))} totalPrice={totalPrice} vat={vat} />
{formatPrice( intl, totalPrice.local.price, totalPrice.local.currency )} {totalPrice.requested && ( {intl.formatMessage( { id: "Approx. {value}" }, { value: formatPrice( intl, totalPrice.requested.price, totalPrice.requested.currency ), } )} )}
{showSignupPromo && memberPrice ? ( ) : null}
) }