"use client" import { useRouter, useSearchParams } from "next/navigation" import { useSession } from "next-auth/react" import { useState, useTransition } from "react" import { useIntl } from "react-intl" import { dt } from "@/lib/dt" import { useRatesStore } from "@/stores/select-rate" import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop" import Button from "@/components/TempDesignSystem/Button" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import { isValidClientSession } from "@/utils/clientSession" import { formatPrice } from "@/utils/numberFormatting" import MobileSummary from "./MobileSummary" import { getTotalPrice } from "./utils" import styles from "./rateSummary.module.css" import { RateEnum } from "@/types/enums/rate" import { RateTypeEnum } from "@/types/enums/rateType" export default function RateSummary() { const { bookingCode, bookingRooms, dates, isFetchingPackages, rateSummary, roomsAvailability, } = useRatesStore((state) => ({ bookingCode: state.booking.bookingCode, bookingRooms: state.booking.rooms, dates: { checkInDate: state.booking.fromDate, checkOutDate: state.booking.toDate, }, isFetchingPackages: state.rooms.some((room) => room.isFetchingPackages), rateSummary: state.rateSummary, roomsAvailability: state.roomsAvailability, })) const { data: session } = useSession() const isUserLoggedIn = isValidClientSession(session) const [isSubmitting, setIsSubmitting] = useState(false) const intl = useIntl() const router = useRouter() const params = useSearchParams() const [_, startTransition] = useTransition() if (!roomsAvailability) { return null } const checkInDate = new Date(dates.checkInDate) const checkOutDate = new Date(dates.checkOutDate) const nights = dt(checkOutDate).diff(dt(checkInDate), "days") const totalNights = intl.formatMessage( { defaultMessage: "{totalNights, plural, one {# night} other {# nights}}", }, { totalNights: nights } ) const totalAdults = intl.formatMessage( { defaultMessage: "{totalAdults, plural, one {# adult} other {# adults}}", }, { totalAdults: bookingRooms.reduce((acc, room) => acc + room.adults, 0) } ) const childrenInOneOrMoreRooms = bookingRooms.some( (room) => room.childrenInRoom?.length ) const childrenInroom = intl.formatMessage( { defaultMessage: "{totalChildren, plural, one {# child} other {# children}}", }, { totalChildren: bookingRooms.reduce( (acc, room) => acc + (room.childrenInRoom?.length ?? 0), 0 ), } ) const totalChildren = childrenInOneOrMoreRooms ? `, ${childrenInroom}` : "" const totalRooms = intl.formatMessage( { defaultMessage: "{totalRooms, plural, one {# room} other {# rooms}}", }, { totalRooms: bookingRooms.length } ) const summaryPriceText = `${totalNights}, ${totalAdults}${totalChildren}, ${totalRooms}` const totalRoomsRequired = bookingRooms.length const isAllRoomsSelected = rateSummary.filter((rate) => rate !== null).length === totalRoomsRequired const hasMemberRates = rateSummary.some( (room) => room && "member" in room.product && room.product.member ) const showMemberDiscountBanner = hasMemberRates && !isUserLoggedIn const freeCancelation = intl.formatMessage({ defaultMessage: "Free cancellation", }) const nonRefundable = intl.formatMessage({ defaultMessage: "Non-refundable", }) const freeBooking = intl.formatMessage({ defaultMessage: "Free rebooking", }) const payLater = intl.formatMessage({ defaultMessage: "Pay later", }) const payNow = intl.formatMessage({ defaultMessage: "Pay now", }) function getRateDetails(rate: RateEnum) { switch (rate) { case RateEnum.change: return `${freeBooking}, ${payNow}` case RateEnum.flex: return `${freeCancelation}, ${payLater}` case RateEnum.save: default: return `${nonRefundable}, ${payNow}` } } function handleSubmit(e: React.FormEvent) { e.preventDefault() setIsSubmitting(true) startTransition(() => { router.push(`details?${params}`) }) } if (!rateSummary.length || isFetchingPackages) { return null } const isBookingCodeRate = rateSummary.some( (rate) => rate && "public" in rate.product && rate.product.public?.rateType !== RateTypeEnum.Regular ) const isVoucherRate = rateSummary.some( (rate) => rate && "voucher" in rate.product ) const isCorporateChequeRate = rateSummary.some( (rate) => rate && "corporateCheque" in rate.product ) const showDiscounted = isUserLoggedIn || isBookingCodeRate || isVoucherRate || isCorporateChequeRate const mainRoomProduct = rateSummary[0] const totalPriceToShow = getTotalPrice( mainRoomProduct, rateSummary, isUserLoggedIn ) const rateProduct = rateSummary.find((rate) => rate?.product)?.product if (!totalPriceToShow || !rateProduct) { return null } let mainRoomCurrency = "" if ("member" in rateProduct && rateProduct.member?.localPrice) { mainRoomCurrency = rateProduct.member.localPrice.currency } if ( !mainRoomCurrency && "public" in rateProduct && rateProduct.public?.localPrice ) { mainRoomCurrency = rateProduct.public.localPrice.currency } // attribute data-footer-spacing used to add spacing // beneath footer to be able to show entire footer upon // scrolling down to the bottom of the page return (
) }