"use client" import { useEffect } from "react" import { useIntl } from "react-intl" import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon" 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 Button from "@/components/TempDesignSystem/Button" import Divider from "@/components/TempDesignSystem/Divider" import IconChip from "@/components/TempDesignSystem/IconChip" import Link from "@/components/TempDesignSystem/Link" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import { useGuaranteePaymentFailedToast } from "@/hooks/booking/useGuaranteePaymentFailedToast" import useLang from "@/hooks/useLang" import ManageStay from "../ManageStay" import TotalPrice from "../Rooms/TotalPrice" import { mapRoomDetails } from "../utils/mapRoomDetails" import ReferenceCardSkeleton from "./ReferenceCardSkeleton" import styles from "./referenceCard.module.css" import type { Hotel, Room } from "@/types/hotel" import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" import type { CreditCard } from "@/types/user" interface ReferenceCardProps { booking: BookingConfirmation["booking"] hotel: Hotel room: | (Room & { bedType: Room["roomTypes"][number] }) | null savedCreditCards: CreditCard[] | null refId: string isLoggedIn: boolean } export function ReferenceCard({ booking, hotel, room, savedCreditCards, refId, isLoggedIn, }: ReferenceCardProps) { const intl = useIntl() const lang = useLang() const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom) const linkedReservationRooms = useMyStayRoomDetailsStore( (state) => state.linkedReservationRooms ) const addBookedRoom = useMyStayRoomDetailsStore( (state) => state.actions.addBookedRoom ) const addRoomPrice = useMyStayTotalPriceStore( (state) => state.actions.addRoomPrice ) // Initialize store with server data useEffect(() => { // Add price and details for booked room (main room or single room) addRoomPrice({ id: booking.confirmationNumber, totalPrice: booking.reservationStatus === BookingStatusEnum.Cancelled ? 0 : booking.totalPrice, currencyCode: booking.currencyCode, isMainBooking: true, roomPoints: booking.roomPoints, }) addBookedRoom( mapRoomDetails({ booking, room, roomNumber: 1, }) ) }, [booking, room, addBookedRoom, addRoomPrice]) useGuaranteePaymentFailedToast() if (!bookedRoom.roomNumber) return const { confirmationNumber, cancellationNumber, checkInDate, checkOutDate, isCancelled, bookingCode, rateDefinition, priceType, } = bookedRoom const isMultiRoom = bookedRoom.linkedReservations.length > 0 const directionsUrl = `https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}` const allRooms = [bookedRoom, ...linkedReservationRooms] const adults = allRooms .filter((room) => !room.isCancelled) .reduce((acc, room) => acc + room.adults, 0) const children = allRooms .filter((room) => !room.isCancelled) .reduce((acc, room) => acc + (room.childrenAges?.length ?? 0), 0) const cancelledRooms = allRooms.filter((room) => room.isCancelled).length const allRoomsCancelled = allRooms.every((room) => room.isCancelled) 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: children, } ) const cancelledRoomsMsg = intl.formatMessage( { defaultMessage: "{rooms, plural, one {# room} other {# rooms}}", }, { rooms: cancelledRooms, } ) const roomCancelledRoomsMsg = intl.formatMessage({ defaultMessage: "Room cancelled", }) const roomsMsg = intl.formatMessage( { defaultMessage: "{rooms, plural, one {# room} other {# rooms}}", }, { rooms: allRooms.filter((room) => !room.isCancelled).length, } ) const adultsOnlyMsg = adultsMsg const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") const adultsAndRoomsMsg = [adultsMsg, roomsMsg].join(", ") const adultsAndChildrenAndRoomsMsg = [adultsMsg, childrenMsg, roomsMsg].join( ", " ) return (
{!isMultiRoom && ( <>
{intl.formatMessage({ defaultMessage: "Reference", })} {isCancelled && !isMultiRoom ? intl.formatMessage({ defaultMessage: "Cancellation number", }) : intl.formatMessage({ defaultMessage: "Reference number", })} {isCancelled && !isMultiRoom ? cancellationNumber : confirmationNumber}
)} {!allRoomsCancelled && (

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

{allRooms.length > 1 ? children > 0 ? adultsAndChildrenAndRoomsMsg : adultsAndRoomsMsg : children > 0 ? adultsAndChildrenMsg : adultsOnlyMsg}

)} {allRooms.some((room) => room.isCancelled) && (

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

{isMultiRoom ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx `${cancelledRoomsMsg} ${intl.formatMessage({ defaultMessage: "cancelled", })}` : roomCancelledRoomsMsg}

)} {!allRoomsCancelled && ( <>

{intl.formatMessage({ defaultMessage: "Check-in", })}

{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {`${dt(checkInDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage( { defaultMessage: "from", } )} ${hotel.hotelFacts.checkin.checkInTime}`}

{intl.formatMessage({ defaultMessage: "Check-out", })}

{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {`${dt(checkOutDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage( { defaultMessage: "until", } )} ${hotel.hotelFacts.checkin.checkOutTime}`}

)} {booking.guaranteeInfo && !allRoomsCancelled && ( <>

{intl.formatMessage({ defaultMessage: "Booking guaranteed.", })} {/* eslint-disable formatjs/no-literal-string-in-jsx */}{" "} {/* eslint-enable formatjs/no-literal-string-in-jsx */} {intl.formatMessage({ defaultMessage: "Your stay remains available for check-in after 18:00.", })}

)}

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

{bookingCode && (

{intl.formatMessage({ defaultMessage: "Booking code", })}

} > {intl.formatMessage( { defaultMessage: "Booking code: {value}", }, { value: bookingCode, strong: (text) => ( {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {text} ), } )}
)}
{isMultiRoom && (

{intl.formatMessage({ defaultMessage: "Multi-room stay", })}

)}

{rateDefinition.generalTerms.map((term) => ( {term} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {term.endsWith(".") ? " " : ". "} ))}

) }