import { cx } from "class-variance-authority" import { useIntl } from "react-intl" import { RateEnum } from "@scandic-hotels/common/constants/rate" import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting" import Caption from "@scandic-hotels/design-system/Caption" import Footnote from "@scandic-hotels/design-system/Footnote" import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton" import { Typography } from "@scandic-hotels/design-system/Typography" import { useIsLoggedIn } from "../../../../hooks/useIsLoggedIn" import SignupPromoDesktop from "../../../SignupPromo/Desktop" import { isSpecialRate } from "./utils" import styles from "./rateSummary.module.css" import type { useSelectRateContext } from "../../../../contexts/SelectRate/SelectRateContext" import type { SelectedRate } from "../../../../contexts/SelectRate/types" export function DesktopSummary({ input, selectedRates, isSubmitting, }: { selectedRates: ReturnType["selectedRates"] isSubmitting: boolean input: ReturnType["input"] }) { const intl = useIntl() const isUserLoggedIn = useIsLoggedIn() if (!selectedRates.totalPrice) { return null } const hasMemberRates = selectedRates.rates.some( (rate) => rate && "member" in rate && rate.member ) const showMemberDiscountBanner = hasMemberRates && !isUserLoggedIn const totalNights = intl.formatMessage( { id: "booking.numberOfNights", defaultMessage: "{totalNights, plural, one {# night} other {# nights}}", }, { totalNights: input.nights } ) const totalAdults = intl.formatMessage( { id: "booking.numberOfAdults", defaultMessage: "{adults, plural, one {# adult} other {# adults}}", }, { adults: input.data?.booking.rooms.reduce((acc, room) => acc + room.adults, 0) ?? 0, } ) const childrenInOneOrMoreRooms = input.data?.booking.rooms.some( (room) => room.childrenInRoom?.length ) const childrenInroom = intl.formatMessage( { id: "booking.numberOfChildren", defaultMessage: "{children, plural, one {# child} other {# children}}", }, { children: input.data?.booking.rooms.reduce( (acc, room) => acc + (room.childrenInRoom?.length ?? 0), 0 ), } ) const totalChildren = childrenInOneOrMoreRooms ? `, ${childrenInroom}` : "" const totalRooms = intl.formatMessage( { id: "booking.numberOfRooms", defaultMessage: "{totalRooms, plural, one {# room} other {# rooms}}", }, { totalRooms: input.roomCount } ) const summaryPriceText = `${totalNights}, ${totalAdults}${totalChildren}, ${totalRooms}` const isAllRoomsSelected = selectedRates.state === "ALL_SELECTED" const showDiscounted = isUserLoggedIn || selectedRates.rates.some(isSpecialRate) const mainRoomRate = selectedRates.rates.at(0) const mainRoomCurrency = getRoomCurrency(mainRoomRate) return ( <>
{selectedRates.rates.map((room, index) => { return ( 1} /> ) })}
{showMemberDiscountBanner && (
{ if (!rate) { return total } const memberExists = "member" in rate && rate.member const publicExists = "public" in rate && rate.public if (!memberExists && !publicExists) { return total } const price = rate.member?.localPrice.pricePerStay || rate.public?.localPrice.pricePerStay if (!price) { return total } const selectedPackagesPrice = rate.roomInfo.selectedPackages.reduce( (acc, pkg) => acc + pkg.localPrice.totalPrice, 0 ) return total + price + selectedPackagesPrice }, 0), currency: mainRoomCurrency ?? "", }} />
)}

{intl.formatMessage( { id: "booking.totalPriceInclVat", defaultMessage: "Total price (incl VAT)", }, { b: (str) => {str} } )}

{summaryPriceText}

{formatPrice( intl, selectedRates.totalPrice.local.price, selectedRates.totalPrice.local.currency, selectedRates.totalPrice.local.additionalPrice, selectedRates.totalPrice.local.additionalPriceCurrency )}

{showDiscounted && selectedRates.totalPrice.local.regularPrice && ( {formatPrice( intl, selectedRates.totalPrice.local.regularPrice, selectedRates.totalPrice.local.currency )} )} {!!selectedRates.totalPrice.requested && (

{intl.formatMessage( { id: "booking.approxValue", defaultMessage: "Approx. {value}", }, { value: formatPrice( intl, selectedRates.totalPrice.requested.price, selectedRates.totalPrice.requested.currency, selectedRates.totalPrice.requested.additionalPrice, selectedRates.totalPrice.requested .additionalPriceCurrency ), } )}

)}
{intl.formatMessage({ id: "common.totalPrice", defaultMessage: "Total price", })}

{formatPrice( intl, selectedRates.totalPrice.local.price, selectedRates.totalPrice.local.currency, selectedRates.totalPrice.local.additionalPrice, selectedRates.totalPrice.local.additionalPriceCurrency )}

{summaryPriceText}
) } function RateSummary({ roomIndex, room, isMultiRoom, }: { room: SelectedRate | undefined roomIndex: number isMultiRoom: boolean }) { const intl = useIntl() const getRateDetails = useRateDetails() if (!room || !room.isSelected) { return (

{intl.formatMessage( { id: "booking.roomIndex", defaultMessage: "Room {roomIndex}", }, { roomIndex: roomIndex + 1 } )}

{intl.formatMessage({ id: "booking.selectRoom", defaultMessage: "Select room", })}

) } return (
{isMultiRoom ? ( <>

{intl.formatMessage( { id: "booking.roomIndex", defaultMessage: "Room {roomIndex}" }, { roomIndex: roomIndex + 1 } )}

{room.roomInfo.roomType}

{getRateDetails(room.rate)} ) : ( <>

{room.roomInfo.roomType}

{getRateDetails(room.rate)}

)}
) } function useRateDetails() { const intl = useIntl() const freeCancelation = intl.formatMessage({ id: "booking.freeCancellation", defaultMessage: "Free cancellation", }) const nonRefundable = intl.formatMessage({ id: "booking.nonRefundable", defaultMessage: "Non-refundable", }) const freeBooking = intl.formatMessage({ id: "booking.freeRebooking", defaultMessage: "Free rebooking", }) const payLater = intl.formatMessage({ id: "booking.payLater", defaultMessage: "Pay later", }) const payNow = intl.formatMessage({ id: "booking.payNow", defaultMessage: "Pay now", }) return (rate: RateEnum) => { switch (rate) { case RateEnum.change: return `${freeBooking}, ${payNow}` case RateEnum.flex: return `${freeCancelation}, ${payLater}` case RateEnum.save: default: return `${nonRefundable}, ${payNow}` } } } function getRoomCurrency(rate: SelectedRate | undefined) { if (!rate) { return null } if ("member" in rate && rate.member?.localPrice) { return rate.member.localPrice.currency } if ("public" in rate && rate.public?.localPrice) { return rate.public.localPrice.currency } }