Files
web/apps/scandic-web/components/HotelReservation/MyStay/index.tsx
Chuma Mcphoy (We Ahead) 27aef3982e Merged in fix/LOY-222-find-my-booking-urls-for-prod (pull request #1817)
Fix(LOY-222): Find my booking url handling

* fix(LOY-222): adapt findMyBooking url based on HIDE_FOR_NEXT_RELEASE

* feat(LOY-222): add current web paths for findMyBooking in multiple languages

* refactor(LOY-222): better env and new url constructions

* refactor(LOY-222): decouple env var handling from getCurrentWebUrl

* fix(LOY-222): update findMyBooking URL construction to use baseUrl

* fix(LOY-222): simplify findMyBooking URL handling for new web urls

* fix(LOY-222): Update Finnish path for hotel reservation lookup

* refactor(LOY-222): rename PUBLIC_URL to NEXT_PUBLIC_PUBLIC_URL for consistency


Approved-by: Christian Andolf
Approved-by: Linus Flood
2025-04-22 07:03:23 +00:00

193 lines
5.7 KiB
TypeScript

import { cookies } from "next/headers"
import { notFound } from "next/navigation"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { env } from "@/env/server"
import { dt } from "@/lib/dt"
import {
getAncillaryPackages,
getBookingConfirmation,
getPackages,
getProfileSafely,
getSavedPaymentCardsSafely,
} from "@/lib/trpc/memoizedRequests"
import { decrypt } from "@/server/routers/utils/encryption"
import Image from "@/components/Image"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { getCurrentWebUrl } from "@/utils/url"
import AdditionalInfoForm from "../FindMyBooking/AdditionalInfoForm"
import accessBooking, {
ACCESS_GRANTED,
ERROR_BAD_REQUEST,
ERROR_UNAUTHORIZED,
} from "./accessBooking"
import { Ancillaries } from "./Ancillaries"
import BookingSummary from "./BookingSummary"
import { Header } from "./Header"
import Promo from "./Promo"
import { ReferenceCard } from "./ReferenceCard"
import Rooms from "./Rooms"
import styles from "./myStay.module.css"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
export async function MyStay({ refId }: { refId: string }) {
const value = decrypt(refId)
if (!value) {
return notFound()
}
const [confirmationNumber, lastName] = value.split(",")
const bookingConfirmation = await getBookingConfirmation(confirmationNumber)
if (!bookingConfirmation) {
return notFound()
}
const { booking, hotel, additionalData, room } = bookingConfirmation
const user = await getProfileSafely()
const bv = cookies().get("bv")?.value
const intl = await getIntl()
const access = accessBooking(booking.guest, lastName, user, bv)
if (access === ACCESS_GRANTED) {
const lang = getLang()
const ancillaryPackages = await getAncillaryPackages({
fromDate: dt(booking.checkInDate).format("YYYY-MM-DD"),
hotelId: hotel.operaId,
toDate: dt(booking.checkOutDate).format("YYYY-MM-DD"),
})
const packages = await getPackages({
startDate: dt(booking.checkInDate).format("YYYY-MM-DD"),
hotelId: hotel.operaId,
endDate: dt(booking.checkOutDate).format("YYYY-MM-DD"),
adults: booking.adults,
children: booking.childrenAges.length,
packageCodes: [
BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST,
BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST,
BreakfastPackageEnum.FREE_CHILD_BREAKFAST,
],
lang,
})
const supportedCards = hotel.merchantInformationData.cards
const savedCreditCards = await getSavedPaymentCardsSafely({
supportedCards,
})
const imageSrc =
hotel.hotelContent.images.imageSizes.large ??
additionalData.gallery?.heroImages[0]?.imageSizes.large ??
hotel.galleryImages[0]?.imageSizes.large
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
const promoUrl = env.HIDE_FOR_NEXT_RELEASE
? new URL(getCurrentWebUrl({ path: "/", lang, baseUrl }))
: new URL(`${baseUrl}/${lang}/`)
promoUrl.searchParams.set("hotel", hotel.operaId)
return (
<main className={styles.main}>
<div className={styles.imageContainer}>
<div className={styles.blurOverlay} />
{imageSrc && (
<Image
className={styles.image}
src={imageSrc}
alt={hotel.name}
fill
/>
)}
</div>
<div className={styles.content}>
<div className={styles.headerContainer}>
<Header hotel={hotel} />
<ReferenceCard
booking={booking}
hotel={hotel}
savedCreditCards={savedCreditCards}
refId={refId}
room={room}
isLoggedIn={!!user}
/>
</div>
{booking.showAncillaries && (
<Ancillaries
ancillaries={ancillaryPackages}
booking={booking}
packages={packages}
user={user}
savedCreditCards={savedCreditCards}
refId={refId}
/>
)}
<Rooms booking={booking} room={room} hotel={hotel} user={user} />
<BookingSummary hotel={hotel} />
<Promo
title={intl.formatMessage({
defaultMessage: "Book your next stay",
})}
text={intl.formatMessage({
defaultMessage:
"Get inspired and start dreaming beyond your next trip. Explore more Scandic destinations.",
})}
buttonText={intl.formatMessage({
defaultMessage: "Explore Scandic hotels",
})}
href={promoUrl.toString()}
image={hotel.hotelContent.images}
/>
</div>
</main>
)
}
if (access === ERROR_BAD_REQUEST) {
return (
<main className={styles.main}>
<div className={styles.form}>
<AdditionalInfoForm
confirmationNumber={confirmationNumber}
lastName={lastName}
/>
</div>
</main>
)
}
if (access === ERROR_UNAUTHORIZED) {
return (
<main className={styles.main}>
<div className={styles.logIn}>
<Typography variant="Title/md">
<h1>
{intl.formatMessage({
defaultMessage: "You need to be logged in to view your booking",
})}
</h1>
</Typography>
<Typography variant="Body/Lead text">
<p>
{intl.formatMessage({
defaultMessage:
"And you need to be logged in with the same member account that made the booking.",
})}
</p>
</Typography>
</div>
</main>
)
}
return notFound()
}