Fix/BOOK-662 handle overlapping dates timezone * fix(BOOK-662): handle overlapping dates alerts * fix(BOOK-662): handle overlapping dates alerts * fix(BOOK-662): add test same dates Approved-by: Anton Gunnarsson
132 lines
4.5 KiB
TypeScript
132 lines
4.5 KiB
TypeScript
import { notFound } from "next/navigation"
|
|
|
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
|
import { dt } from "@scandic-hotels/common/dt"
|
|
import { Alert } from "@scandic-hotels/design-system/Alert"
|
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
|
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
|
|
|
|
import { env } from "../../../env/server"
|
|
import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
|
|
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
|
|
import { filterOverlappingDates } from "../../utils/SelectRate"
|
|
import { SidePanel } from "../SidePanel"
|
|
import { Confirmation } from "./Confirmation"
|
|
import { HotelDetails } from "./HotelDetails"
|
|
import { PaymentDetails } from "./PaymentDetails"
|
|
import { Promos } from "./Promos"
|
|
import { Receipt } from "./Receipt"
|
|
import { Rooms } from "./Rooms"
|
|
import BookingConfirmationTracking from "./Tracking"
|
|
import { mapRoomState } from "./utils"
|
|
|
|
import styles from "./bookingConfirmation.module.css"
|
|
|
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
import type { IntlShape } from "react-intl"
|
|
|
|
type BookingConfirmationProps = {
|
|
intl: IntlShape
|
|
refId: string
|
|
membershipFailedError: boolean
|
|
}
|
|
|
|
export async function BookingConfirmation({
|
|
intl,
|
|
refId,
|
|
membershipFailedError,
|
|
}: BookingConfirmationProps) {
|
|
const bookingConfirmation = await getBookingConfirmation(refId)
|
|
|
|
if (!bookingConfirmation) {
|
|
return notFound()
|
|
}
|
|
|
|
const { booking, url, hotel, room, roomCategories } = bookingConfirmation
|
|
|
|
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
|
|
const hotelUrl = new URL(`${baseUrl}${url}`)
|
|
|
|
if (!room) {
|
|
return notFound()
|
|
}
|
|
const validAlerts = filterOverlappingDates(
|
|
hotel.specialAlerts.filter((alert) => alert.displayInBookingFlow),
|
|
dt.utc(booking.checkInDate),
|
|
dt.utc(booking.checkOutDate)
|
|
)
|
|
|
|
return (
|
|
<BookingConfirmationProvider
|
|
bookingCode={booking.bookingCode}
|
|
currencyCode={booking.currencyCode}
|
|
fromDate={booking.checkInDate}
|
|
hotelOffersBreakfast={hotel.hotelType !== HotelTypeEnum.ScandicGo}
|
|
toDate={booking.checkOutDate}
|
|
roomCategories={roomCategories}
|
|
rooms={[
|
|
mapRoomState(booking, room, intl),
|
|
// null represents "known but not yet fetched rooms" and is used to render placeholders correctly
|
|
...Array(booking.linkedReservations.length).fill(null),
|
|
]}
|
|
vat={booking.vatPercentage}
|
|
>
|
|
<Confirmation
|
|
url={hotelUrl.toString()}
|
|
booking={booking}
|
|
hotel={hotel}
|
|
room={room}
|
|
>
|
|
<div className={styles.booking}>
|
|
{membershipFailedError && (
|
|
<Alert
|
|
type={AlertTypeEnum.Info}
|
|
heading={intl.formatMessage({
|
|
id: "bookingConfirmation.membershipVerificationFailed",
|
|
defaultMessage: "Failed to verify membership",
|
|
})}
|
|
text={intl.formatMessage({
|
|
id: "bookingConfirmation.bookingConfirmedMembershipFailedInfo",
|
|
defaultMessage:
|
|
"Your booking(s) is confirmed but we could not verify your membership. If you have booked with a member discount, you'll either need to present your existing membership number upon check-in, become a member or pay the price difference at the hotel. Signing up is preferably done online before the stay.",
|
|
})}
|
|
/>
|
|
)}
|
|
<Rooms
|
|
booking={booking}
|
|
checkInTime={hotel.hotelFacts.checkin.checkInTime}
|
|
checkOutTime={hotel.hotelFacts.checkin.checkOutTime}
|
|
mainRoom={room}
|
|
/>
|
|
<PaymentDetails />
|
|
<Divider color="Border/Divider/Subtle" />
|
|
<HotelDetails url={hotelUrl.toString()} hotel={hotel} />
|
|
{validAlerts.map((alert) => (
|
|
<div key={alert.id}>
|
|
<Alert
|
|
type={alert.type}
|
|
heading={alert.heading}
|
|
text={alert.text}
|
|
/>
|
|
</div>
|
|
))}
|
|
<Promos booking={booking} />
|
|
<div className={styles.mobileReceipt}>
|
|
<Receipt />
|
|
</div>
|
|
</div>
|
|
<aside className={styles.aside}>
|
|
<SidePanel variant="receipt">
|
|
<Receipt />
|
|
</SidePanel>
|
|
</aside>
|
|
</Confirmation>
|
|
|
|
<BookingConfirmationTracking
|
|
bookingConfirmation={bookingConfirmation}
|
|
refId={refId}
|
|
/>
|
|
</BookingConfirmationProvider>
|
|
)
|
|
}
|