"use client" import { useIntl } from "react-intl" import { dt } from "@/lib/dt" import { useEnterDetailsStore } from "@/stores/enter-details" import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop" import { ArrowRightIcon, CheckIcon, ChevronDownSmallIcon, ChevronRightSmallIcon, } 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 PriceDetailsTable from "../PriceDetailsTable" import styles from "./ui.module.css" import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" import type { SummaryProps } from "@/types/components/hotelReservation/summary" import type { DetailsState } from "@/types/stores/enter-details" export function storeSelector(state: DetailsState) { return { bedType: state.bedType, booking: state.booking, breakfast: state.breakfast, join: state.guest.join, membershipNo: state.guest.membershipNo, packages: state.packages, roomRate: state.roomRate, roomPrice: state.roomPrice, toggleSummaryOpen: state.actions.toggleSummaryOpen, togglePriceDetailsModalOpen: state.actions.togglePriceDetailsModalOpen, totalPrice: state.totalPrice, vat: state.vat, } } export default function SummaryUI({ cancellationText, isMember, rateDetails, roomType, breakfastIncluded, }: SummaryProps) { const intl = useIntl() const lang = useLang() const { bedType, booking, breakfast, join, membershipNo, packages, roomPrice, roomRate, toggleSummaryOpen, togglePriceDetailsModalOpen, totalPrice, vat, } = useEnterDetailsStore(storeSelector) // TODO: Update for Multiroom later const adults = booking.rooms[0].adults const children = booking.rooms[0].children const childrenBeds = children?.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 = roomRate.memberRate ? { currency: roomRate.memberRate.localPrice.currency, pricePerNight: roomRate.memberRate.localPrice.pricePerNight, amount: roomRate.memberRate.localPrice.pricePerStay, } : null const showMemberPrice = !!(isMember || join || membershipNo) && memberPrice const diff = dt(booking.toDate).diff(booking.fromDate, "days") const nights = intl.formatMessage( { id: "booking.nights" }, { totalNights: diff } ) function handleToggleSummary() { if (toggleSummaryOpen) { toggleSummaryOpen() } } function handleTogglePriceDetailsModal() { if (togglePriceDetailsModalOpen) { togglePriceDetailsModalOpen() } } return (
{intl.formatMessage({ id: "Summary" })} {dt(booking.fromDate).locale(lang).format("ddd, D MMM")} {dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
{roomType} {formatPrice( intl, roomPrice.perStay.local.price, roomPrice.perStay.local.currency )}
{`${intl.formatMessage( { id: "booking.adults" }, { totalAdults: adults } )}${ children?.length ? `, ${intl.formatMessage( { id: "booking.children" }, { totalChildren: children.length } )}` : "" }`} {cancellationText} {intl.formatMessage({ id: "Rate details" })} } title={cancellationText} >
{rateDetails?.map((info) => ( {info} ))}
{packages ? packages.map((roomPackage) => (
{roomPackage.description}
{formatPrice( intl, parseInt(roomPackage.localPrice.price), roomPackage.localPrice.currency )}
)) : null} {bedType ? (
{bedType.description} {formatPrice(intl, 0, roomPrice.perStay.local.currency)}
) : null} {childBedCrib ? (
{`${intl.formatMessage({ id: "Crib (child)" })} × ${childBedCrib}`} {intl.formatMessage({ id: "Based on availability" })}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
) : null} {childBedExtraBed ? (
{`${intl.formatMessage({ id: "Extra bed (child)" })} × ${childBedExtraBed}`}
{formatPrice(intl, 0, roomPrice.perStay.local.currency)}
) : null} {breakfastIncluded ? (
{intl.formatMessage({ id: "Breakfast included" })}
) : breakfast === false ? (
{intl.formatMessage({ id: "No breakfast" })} {formatPrice(intl, 0, roomPrice.perStay.local.currency)}
) : null} {breakfast ? (
{intl.formatMessage({ id: "Breakfast buffet" })}
{intl.formatMessage( { id: "booking.adults" }, { totalAdults: adults } )} {formatPrice( intl, parseInt(breakfast.localPrice.totalPrice), breakfast.localPrice.currency )}
{children?.length ? (
{intl.formatMessage( { id: "booking.children" }, { totalChildren: children.length } )} {formatPrice(intl, 0, breakfast.localPrice.currency)}
) : null}
) : null}
{intl.formatMessage( { id: "Total price (incl VAT)" }, { b: (str) => {str} } )} {intl.formatMessage({ id: "Price details" })} } >
{formatPrice( intl, totalPrice.local.price, totalPrice.local.currency )} {totalPrice.requested && ( {intl.formatMessage({ id: "Approx." })}{" "} {formatPrice( intl, totalPrice.requested.price, totalPrice.requested.currency )} )}
{!showMemberPrice && memberPrice ? ( ) : null}
) }