From 6979ac0c3be369f93916d3bc805dfd064dd7131d Mon Sep 17 00:00:00 2001 From: Linus Flood Date: Fri, 2 May 2025 13:05:42 +0000 Subject: [PATCH] Merged in revert-pr-1925 (pull request #1927) Revert "Feat/sw 2323 find booking (pull request #1925)" Approved-by: Anton Gunnarsson --- .../booking-confirmation/page.tsx | 78 +--- .../gla-payment-callback/page.tsx | 31 +- .../payment-callback/cancel/page.tsx | 29 -- .../payment-callback/error/page.tsx | 71 ---- .../payment-callback/page.tsx | 93 +++++ .../payment-callback/success/page.tsx | 44 --- .../hotelreservation/my-stay/page.tsx | 69 +--- .../my-stay/receipt/loading.tsx | 1 - .../hotelreservation/my-stay/receipt/page.tsx | 209 +--------- .../webview/hotelreservation/my-stay/page.tsx | 76 +--- .../HotelReservation/AddToCalendar/index.tsx | 1 - .../Confirmation/confirmation.module.css} | 23 -- .../Confirmation/index.tsx | 24 ++ .../Header/Actions/ManageBooking.tsx | 9 +- .../BookingConfirmation/Header/index.tsx | 12 +- .../BookingConfirmation/Promos/index.tsx | 18 +- .../Rooms/LinkedReservation/index.tsx | 22 +- .../BookingConfirmation/Rooms/Room/index.tsx | 40 +- .../BookingConfirmation/Rooms/index.tsx | 53 ++- .../BookingConfirmation/Tracking/index.tsx | 2 +- .../BookingConfirmation/Tracking/tracking.ts | 2 +- .../bookingConfirmation.module.css | 22 ++ .../BookingConfirmation/index.tsx | 87 ++++ .../BookingConfirmation/utils.ts | 4 +- .../PaymentCallback/HandleSuccessCallback.tsx | 10 +- .../EnterDetails/Payment/PaymentClient.tsx | 75 ++-- .../FindMyBooking/AdditionalInfoForm.tsx | 6 +- .../AddAncillaryFlowModal/index.tsx | 8 +- .../AddedAncillaries/RemoveButton.tsx | 6 +- .../Ancillaries/AddedAncillaries/index.tsx | 5 +- .../Ancillaries/GuaranteeCallback/index.tsx | 6 +- .../MyStay/Ancillaries/index.tsx | 6 +- .../MyStay/GuestDetails/Details.tsx | 10 +- .../MyStay/GuestDetails/index.tsx | 1 - .../HotelReservation/MyStay/Receipt/index.tsx | 168 ++++++++ .../MyStay/Receipt/receipt.module.css} | 0 .../Steps/FinalConfirmation/index.tsx | 19 +- .../ChangeDates/Steps/Confirmation/index.tsx | 10 +- .../GuaranteeLateArrival/Form/index.tsx | 4 +- .../MyStay/utils/mapRoomDetails.ts | 1 - apps/scandic-web/constants/booking.ts | 2 + .../hooks/booking/useGuaranteeBooking.ts | 14 +- .../hooks/booking/useHandleBookingStatus.ts | 6 +- apps/scandic-web/lib/api/endpoints.ts | 3 - .../lib/trpc/memoizedRequests/index.ts | 30 +- apps/scandic-web/next.config.js | 5 + apps/scandic-web/providers/MyStay.tsx | 26 +- .../server/routers/booking/input.ts | 53 +-- .../server/routers/booking/mutation.ts | 100 +---- .../server/routers/booking/output.ts | 24 +- .../server/routers/booking/query.ts | 370 ++++-------------- .../server/routers/booking/utils.ts | 260 ++++-------- apps/scandic-web/server/routers/user/utils.ts | 2 +- .../{ => server/routers}/utils/encryption.ts | 0 apps/scandic-web/server/tokenManager.ts | 11 - apps/scandic-web/stores/my-stay/index.ts | 29 +- .../actions/addToCalendar.ts | 8 +- .../actions/manageBooking.ts | 2 +- .../bookingConfirmation.ts | 10 +- .../bookingConfirmation/header.ts | 8 +- .../bookingConfirmation/hotelDetails.ts | 2 +- .../bookingConfirmation/promos.ts | 12 +- .../bookingConfirmation/rooms.ts | 7 + .../rooms/linkedReservation.ts | 2 +- .../bookingConfirmation/rooms/room.ts | 7 +- .../components/myPages/myStay/ancillaries.ts | 1 - apps/scandic-web/types/stores/my-stay.ts | 1 - .../trpc/routers/booking/confirmation.ts | 20 +- apps/scandic-web/utils/refId.ts | 21 - 69 files changed, 883 insertions(+), 1508 deletions(-) delete mode 100644 apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/cancel/page.tsx delete mode 100644 apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/error/page.tsx create mode 100644 apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx delete mode 100644 apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/success/page.tsx delete mode 100644 apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/loading.tsx rename apps/scandic-web/{app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.module.css => components/HotelReservation/BookingConfirmation/Confirmation/confirmation.module.css} (61%) create mode 100644 apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/BookingConfirmation/bookingConfirmation.module.css create mode 100644 apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Receipt/index.tsx rename apps/scandic-web/{app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/page.module.css => components/HotelReservation/MyStay/Receipt/receipt.module.css} (100%) rename apps/scandic-web/{ => server/routers}/utils/encryption.ts (100%) delete mode 100644 apps/scandic-web/utils/refId.ts diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx index 0cc1b897c..2e9ab9faa 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx @@ -1,84 +1,14 @@ -import { notFound } from "next/navigation" - import { getBookingConfirmation } from "@/lib/trpc/memoizedRequests" -import Alerts from "@/components/HotelReservation/BookingConfirmation/Alerts" -import Header from "@/components/HotelReservation/BookingConfirmation/Header" -import HotelDetails from "@/components/HotelReservation/BookingConfirmation/HotelDetails" -import PaymentDetails from "@/components/HotelReservation/BookingConfirmation/PaymentDetails" -import Promos from "@/components/HotelReservation/BookingConfirmation/Promos" -import Receipt from "@/components/HotelReservation/BookingConfirmation/Receipt" -import Rooms from "@/components/HotelReservation/BookingConfirmation/Rooms" -import Tracking from "@/components/HotelReservation/BookingConfirmation/Tracking" -import { mapRoomState } from "@/components/HotelReservation/BookingConfirmation/utils" -import SidePanel from "@/components/HotelReservation/SidePanel" -import Divider from "@/components/TempDesignSystem/Divider" -import { getIntl } from "@/i18n" -import BookingConfirmationProvider from "@/providers/BookingConfirmationProvider" - -import styles from "./page.module.css" +import BookingConfirmation from "@/components/HotelReservation/BookingConfirmation" import type { LangParams, PageArgs } from "@/types/params" export default async function BookingConfirmationPage({ - params, searchParams, -}: PageArgs) { - const refId = searchParams.RefId - - if (!refId) { - notFound() - } - - const bookingConfirmation = await getBookingConfirmation(refId, params.lang) - - if (!bookingConfirmation) { - notFound() - } - - const { booking, hotelData, room } = bookingConfirmation - const { hotel } = hotelData - - const intl = await getIntl() - +}: PageArgs) { + void getBookingConfirmation(searchParams.confirmationNumber) return ( - -
-
-
- - - - - - -
- -
-
- -
- -
+ ) } diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx index 951141819..571a44d89 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx @@ -6,12 +6,10 @@ import { } from "@/constants/booking" import { myStay } from "@/constants/routes/myStay" import { serverClient } from "@/lib/trpc/server" -import { createCounter } from "@/server/telemetry" import GuaranteeCallback from "@/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback" import TrackGuarantee from "@/components/HotelReservation/MyStay/TrackGuarantee" import LoadingSpinner from "@/components/LoadingSpinner" -import { setLang } from "@/i18n/serverContext" import type { LangParams, PageArgs } from "@/types/params" @@ -21,56 +19,45 @@ export default async function GuaranteePaymentCallbackPage({ }: PageArgs< LangParams, { - status?: PaymentCallbackStatusEnum - RefId?: string + status: PaymentCallbackStatusEnum + RefId: string confirmationNumber?: string ancillary?: string } >) { + console.log(`[gla-payment-callback] callback started`) const lang = params.lang const status = searchParams.status - const refId = searchParams.RefId const confirmationNumber = searchParams.confirmationNumber - const isAncillaryFlow = searchParams.ancillary - - setLang(params.lang) - - if (!status || !confirmationNumber || !refId) { + const refId = searchParams.RefId + if (!refId) { notFound() } - - const glaSuccessCounter = createCounter("gla", "success") - const metricsGlaSuccess = glaSuccessCounter.init({ - confirmationNumber, - }) - - metricsGlaSuccess.start() + const isAncillaryFlow = searchParams.ancillary const myStayUrl = `${myStay[lang]}?RefId=${encodeURIComponent(refId)}` + const searchObject = new URLSearchParams() if (status === PaymentCallbackStatusEnum.Success && confirmationNumber) { if (isAncillaryFlow) { return ( ) } - + console.log(`[gla-payment-callback] redirecting to: ${myStayUrl}`) return } let errorMessage = undefined if (confirmationNumber) { - const searchObject = new URLSearchParams() - try { const bookingStatus = await serverClient().booking.status({ - refId, + confirmationNumber, }) const error = bookingStatus.errors.find((e) => e.errorCode) diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/cancel/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/cancel/page.tsx deleted file mode 100644 index 773da8fc6..000000000 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/cancel/page.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { - BookingErrorCodeEnum, - PaymentCallbackStatusEnum, -} from "@/constants/booking" -import { details } from "@/constants/routes/hotelReservation" - -import HandleErrorCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback" - -import type { LangParams, PageArgs } from "@/types/params" - -export default async function PaymentCallbackCancelPage({ - params, -}: PageArgs) { - console.log(`[payment-callback] cancel callback started`) - const lang = params.lang - - const returnUrl = details(lang) - const searchObject = new URLSearchParams() - - searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled) - - return ( - - ) -} diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/error/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/error/page.tsx deleted file mode 100644 index 3dc556d5e..000000000 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/error/page.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { - BookingErrorCodeEnum, - PaymentCallbackStatusEnum, -} from "@/constants/booking" -import { details } from "@/constants/routes/hotelReservation" -import { serverClient } from "@/lib/trpc/server" - -import HandleErrorCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback" -import { calculateRefId } from "@/utils/refId" - -import type { LangParams, PageArgs } from "@/types/params" - -export default async function PaymentCallbackErrorPage({ - params, - searchParams, -}: PageArgs< - LangParams, - { - confirmationNumber?: string - } ->) { - console.log(`[payment-callback] error callback started`) - - const lang = params.lang - const confirmationNumber = searchParams.confirmationNumber - - const returnUrl = details(lang) - const searchObject = new URLSearchParams() - - let errorMessage = undefined - - if (confirmationNumber) { - const refId = calculateRefId(confirmationNumber, "") - - try { - const bookingStatus = await serverClient().booking.confirmationError({ - refId, - }) - - // TODO: how to handle errors for multiple rooms? - const error = bookingStatus.errors.find((e) => e.errorCode) - - errorMessage = - error?.description ?? - `No error message found for booking ${confirmationNumber}` - - searchObject.set( - "errorCode", - error - ? error.errorCode.toString() - : BookingErrorCodeEnum.TransactionFailed - ) - } catch { - console.error( - `[payment-callback] failed to get booking status for ${confirmationNumber}` - ) - - searchObject.set("errorCode", BookingErrorCodeEnum.TransactionFailed) - errorMessage = `Failed to get booking status for ${confirmationNumber}` - } - } - - return ( - - ) -} diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx new file mode 100644 index 000000000..74984d9e0 --- /dev/null +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx @@ -0,0 +1,93 @@ +import { + BOOKING_CONFIRMATION_NUMBER, + BookingErrorCodeEnum, + PaymentCallbackStatusEnum, +} from "@/constants/booking" +import { + bookingConfirmation, + details, +} from "@/constants/routes/hotelReservation" +import { serverClient } from "@/lib/trpc/server" + +import HandleErrorCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback" +import HandleSuccessCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback" + +import type { LangParams, PageArgs } from "@/types/params" + +export default async function PaymentCallbackPage({ + params, + searchParams, +}: PageArgs< + LangParams, + { + status: PaymentCallbackStatusEnum + confirmationNumber?: string + hotel?: string + } +>) { + console.log(`[payment-callback] callback started`) + const lang = params.lang + const status = searchParams.status + const confirmationNumber = searchParams.confirmationNumber + + if (status === PaymentCallbackStatusEnum.Success && confirmationNumber) { + const confirmationUrl = `${bookingConfirmation(lang)}?${BOOKING_CONFIRMATION_NUMBER}=${confirmationNumber}` + console.log( + `[payment-callback] rendering success callback with confirmation number: ${confirmationNumber}` + ) + + return ( + + ) + } + + const returnUrl = details(lang) + const searchObject = new URLSearchParams() + + let errorMessage = undefined + + if (confirmationNumber) { + try { + const bookingStatus = await serverClient().booking.status({ + confirmationNumber, + }) + + // TODO: how to handle errors for multiple rooms? + const error = bookingStatus.errors.find((e) => e.errorCode) + + errorMessage = + error?.description ?? + `No error message found for booking ${confirmationNumber}, status: ${status}` + + searchObject.set( + "errorCode", + error + ? error.errorCode.toString() + : BookingErrorCodeEnum.TransactionFailed + ) + } catch { + console.error( + `[payment-callback] failed to get booking status for ${confirmationNumber}, status: ${status}` + ) + if (status === PaymentCallbackStatusEnum.Cancel) { + searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled) + } + if (status === PaymentCallbackStatusEnum.Error) { + searchObject.set("errorCode", BookingErrorCodeEnum.TransactionFailed) + errorMessage = `Failed to get booking status for ${confirmationNumber}, status: ${status}` + } + } + } + + return ( + + ) +} diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/success/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/success/page.tsx deleted file mode 100644 index fa6185a71..000000000 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/success/page.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { notFound } from "next/navigation" - -import { bookingConfirmation } from "@/constants/routes/hotelReservation" -import { createCounter } from "@/server/telemetry" - -import HandleSuccessCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback" -import { setLang } from "@/i18n/serverContext" -import { calculateRefId } from "@/utils/refId" - -import type { LangParams, PageArgs } from "@/types/params" - -export default async function PaymentCallbackSuccessPage({ - params, - searchParams, -}: PageArgs< - LangParams, - { - confirmationNumber?: string - } ->) { - const confirmationNumber = searchParams.confirmationNumber - - setLang(params.lang) - - if (!confirmationNumber) { - notFound() - } - - const paymentSuccessCounter = createCounter("payment", "success") - const metricsPaymentSuccess = paymentSuccessCounter.init({ - confirmationNumber, - }) - - metricsPaymentSuccess.start() - - const refId = calculateRefId(confirmationNumber, "") - - return ( - - ) -} diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx index b9bc7083a..3308028c0 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx @@ -6,7 +6,6 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { env } from "@/env/server" import { dt } from "@/lib/dt" import { - findBooking, getAncillaryPackages, getBookingConfirmation, getLinkedReservations, @@ -14,8 +13,8 @@ import { getProfileSafely, getSavedPaymentCardsSafely, } from "@/lib/trpc/memoizedRequests" +import { decrypt } from "@/server/routers/utils/encryption" -import { auth } from "@/auth" import AdditionalInfoForm from "@/components/HotelReservation/FindMyBooking/AdditionalInfoForm" import accessBooking, { ACCESS_GRANTED, @@ -33,8 +32,6 @@ import Image from "@/components/Image" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" import MyStayProvider from "@/providers/MyStay" -import { parseRefId } from "@/utils/refId" -import { isValidSession } from "@/utils/session" import { getCurrentWebUrl } from "@/utils/url" import styles from "./page.module.css" @@ -47,48 +44,27 @@ export default async function MyStay({ searchParams, }: PageArgs) { setLang(params.lang) - const refId = searchParams.RefId if (!refId) { notFound() } - const session = await auth() - const isLoggedIn = isValidSession(session) - const { confirmationNumber, lastName } = parseRefId(refId) - const bv = cookies().get("bv")?.value - let bookingConfirmation - if (isLoggedIn) { - bookingConfirmation = await getBookingConfirmation(refId, params.lang) - } else if (bv) { - const params = new URLSearchParams(bv) - const firstName = params.get("firstName") - const email = params.get("email") - - if (firstName && email) { - bookingConfirmation = await findBooking( - confirmationNumber, - lastName, - firstName, - email - ) - } else { - return - } - } else { - return + const value = decrypt(refId) + if (!value) { + return notFound() } + const [confirmationNumber, lastName] = value.split(",") + const bookingConfirmation = await getBookingConfirmation(confirmationNumber) if (!bookingConfirmation) { return notFound() } - const { booking, hotelData } = bookingConfirmation - const { hotel } = hotelData + const { additionalData, booking, hotel, roomCategories } = bookingConfirmation const user = await getProfileSafely() - + const bv = cookies().get("bv")?.value const intl = await getIntl() const access = accessBooking(booking.guest, lastName, user, bv) @@ -98,7 +74,9 @@ export default async function MyStay({ const fromDate = dt(booking.checkInDate).format("YYYY-MM-DD") const toDate = dt(booking.checkOutDate).format("YYYY-MM-DD") - const linkedReservationsPromise = getLinkedReservations(refId, params.lang) + const linkedReservationsPromise = getLinkedReservations({ + rooms: booking.linkedReservations, + }) const packagesInput = { adults: booking.adults, @@ -143,7 +121,7 @@ export default async function MyStay({ const imageSrc = hotel.hotelContent.images.imageSizes.large ?? - hotelData.additionalData.gallery?.heroImages[0]?.imageSizes.large ?? + additionalData.gallery?.heroImages[0]?.imageSizes.large ?? hotel.galleryImages[0]?.imageSizes.large const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com" @@ -160,7 +138,7 @@ export default async function MyStay({ lang={params.lang} linkedReservationsPromise={linkedReservationsPromise} refId={refId} - roomCategories={hotelData.roomCategories} + roomCategories={roomCategories} savedCreditCards={savedCreditCards} >
@@ -219,7 +197,10 @@ export default async function MyStay({ return (
- +
) @@ -251,19 +232,3 @@ export default async function MyStay({ return notFound() } - -function RenderAdditionalInfoForm({ - refId, - lastName, -}: { - refId: string - lastName: string -}) { - return ( -
-
- -
-
- ) -} diff --git a/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/loading.tsx b/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/loading.tsx deleted file mode 100644 index 4b9d47ee6..000000000 --- a/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/loading.tsx +++ /dev/null @@ -1 +0,0 @@ -export { MyStaySkeleton } from "@/components/HotelReservation/MyStay/myStaySkeleton" diff --git a/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/page.tsx b/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/page.tsx index ba0961c62..a5a66c0e0 100644 --- a/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/page.tsx +++ b/apps/scandic-web/app/[lang]/(no-layout)/hotelreservation/my-stay/receipt/page.tsx @@ -1,215 +1,20 @@ -import { cookies } from "next/headers" import { notFound } from "next/navigation" +import { Suspense } from "react" -import ScandicLogoIcon from "@scandic-hotels/design-system/Icons/ScandicLogoIcon" -import { Typography } from "@scandic-hotels/design-system/Typography" +import { MyStaySkeleton } from "@/components/HotelReservation/MyStay/myStaySkeleton" +import { Receipt } from "@/components/HotelReservation/MyStay/Receipt" -import { dt } from "@/lib/dt" -import { - findBooking, - getAncillaryPackages, - getBookingConfirmation, - getProfileSafely, -} from "@/lib/trpc/memoizedRequests" - -import { auth } from "@/auth" -import AdditionalInfoForm from "@/components/HotelReservation/FindMyBooking/AdditionalInfoForm" -import accessBooking, { - ACCESS_GRANTED, - ERROR_BAD_REQUEST, - ERROR_UNAUTHORIZED, -} from "@/components/HotelReservation/MyStay/accessBooking" -import Footer from "@/components/HotelReservation/MyStay/Receipt/Footer" -import Specification from "@/components/HotelReservation/MyStay/Receipt/Specification" -import Total from "@/components/HotelReservation/MyStay/Receipt/Total" -import { getIntl } from "@/i18n" -import { parseRefId } from "@/utils/refId" -import { isValidSession } from "@/utils/session" - -import styles from "./page.module.css" - -import { CurrencyEnum } from "@/types/enums/currency" import type { LangParams, PageArgs } from "@/types/params" export default async function ReceiptPage({ - params, searchParams, }: PageArgs) { - const refId = searchParams.RefId - - if (!refId) { + if (!searchParams.RefId) { notFound() } - - const session = await auth() - const isLoggedIn = isValidSession(session) - const { confirmationNumber, lastName } = parseRefId(refId) - - const bv = cookies().get("bv")?.value - let bookingConfirmation - if (isLoggedIn) { - bookingConfirmation = await getBookingConfirmation(refId, params.lang) - } else if (bv) { - const params = new URLSearchParams(bv) - const firstName = params.get("firstName") - const email = params.get("email") - - if (firstName && email) { - bookingConfirmation = await findBooking( - confirmationNumber, - lastName, - firstName, - email - ) - } else { - return - } - } else { - return - } - - if (!bookingConfirmation) { - return notFound() - } - - const { booking, hotelData, room } = bookingConfirmation - const { hotel } = hotelData - - const intl = await getIntl() - const user = await getProfileSafely() - - const access = accessBooking(booking.guest, lastName, user, bv) - - if (access === ACCESS_GRANTED) { - const ancillaryPackages = await getAncillaryPackages({ - fromDate: dt(booking.checkInDate).format("YYYY-MM-DD"), - hotelId: hotel.operaId, - toDate: dt(booking.checkOutDate).format("YYYY-MM-DD"), - }) - - const currency = - booking.currencyCode !== CurrencyEnum.POINTS - ? booking.currencyCode - : (booking.ancillaries.find((a) => a.currency !== CurrencyEnum.POINTS) - ?.currency ?? - booking.packages.find((p) => p.currency !== CurrencyEnum.POINTS) - ?.currency) - - return ( -
-
- -
-
- -
{hotel.name}
-
- -
- {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - {`${hotel.address.streetAddress}, ${hotel.address.zipCode} ${hotel.address.city}`} -
-
- -
- {hotel.contactInformation.email} -
-
- -
- {hotel.contactInformation.phoneNumber} -
-
-
-
- - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} -
{`${booking.guest.firstName} ${booking.guest.lastName}`}
-
- {booking.guest.membershipNumber && ( - - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} -
{`${intl.formatMessage({ - defaultMessage: "Member", - })} ${booking.guest.membershipNumber}`}
-
- )} - -
- {booking.guest.email} -
-
- -
- {booking.guest.phoneNumber} -
-
-
-
-
- - - -
- -
-
- ) - } - - if (access === ERROR_BAD_REQUEST) { - return ( -
-
- -
-
- ) - } - - if (access === ERROR_UNAUTHORIZED) { - return ( -
-
- -

- {intl.formatMessage({ - defaultMessage: "You need to be logged in to view your booking", - })} -

-
- -

- {intl.formatMessage({ - defaultMessage: - "And you need to be logged in with the same member account that made the booking.", - })} -

-
-
-
- ) - } - - return notFound() -} - -function RenderAdditionalInfoForm({ - refId, - lastName, -}: { - refId: string - lastName: string -}) { return ( -
-
- -
-
+ }> + + ) } diff --git a/apps/scandic-web/app/[lang]/webview/hotelreservation/my-stay/page.tsx b/apps/scandic-web/app/[lang]/webview/hotelreservation/my-stay/page.tsx index 69743c69a..e083c1cde 100644 --- a/apps/scandic-web/app/[lang]/webview/hotelreservation/my-stay/page.tsx +++ b/apps/scandic-web/app/[lang]/webview/hotelreservation/my-stay/page.tsx @@ -6,7 +6,6 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { env } from "@/env/server" import { dt } from "@/lib/dt" import { - findBooking, getAncillaryPackages, getBookingConfirmation, getLinkedReservations, @@ -14,8 +13,8 @@ import { getProfileSafely, getSavedPaymentCardsSafely, } from "@/lib/trpc/memoizedRequests" +import { decrypt } from "@/server/routers/utils/encryption" -import { auth } from "@/auth" import AdditionalInfoForm from "@/components/HotelReservation/FindMyBooking/AdditionalInfoForm" import accessBooking, { ACCESS_GRANTED, @@ -33,8 +32,6 @@ import Image from "@/components/Image" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" import MyStayProvider from "@/providers/MyStay" -import { parseRefId } from "@/utils/refId" -import { isValidSession } from "@/utils/session" import { getCurrentWebUrl } from "@/utils/url" import styles from "./page.module.css" @@ -47,47 +44,27 @@ export default async function MyStay({ searchParams, }: PageArgs) { setLang(params.lang) - const refId = searchParams.RefId if (!refId) { notFound() } - const session = await auth() - const isLoggedIn = isValidSession(session) - const { confirmationNumber, lastName } = parseRefId(refId) - - const bv = cookies().get("bv")?.value - let bookingConfirmation - if (isLoggedIn) { - bookingConfirmation = await getBookingConfirmation(refId, params.lang) - } else if (bv) { - const params = new URLSearchParams(bv) - const firstName = params.get("firstName") - const email = params.get("email") - - if (firstName && email) { - bookingConfirmation = await findBooking( - confirmationNumber, - lastName, - firstName, - email - ) - } else { - return - } - } else { - return + const value = decrypt(refId) + if (!value) { + return notFound() } + + const [confirmationNumber, lastName] = value.split(",") + const bookingConfirmation = await getBookingConfirmation(confirmationNumber) if (!bookingConfirmation) { return notFound() } - const { booking, hotelData } = bookingConfirmation - const { hotel } = hotelData + const { additionalData, booking, hotel, roomCategories } = bookingConfirmation const user = await getProfileSafely() + const bv = cookies().get("bv")?.value const intl = await getIntl() const access = accessBooking(booking.guest, lastName, user, bv) @@ -97,7 +74,9 @@ export default async function MyStay({ const fromDate = dt(booking.checkInDate).format("YYYY-MM-DD") const toDate = dt(booking.checkOutDate).format("YYYY-MM-DD") - const linkedReservationsPromise = getLinkedReservations(refId, params.lang) + const linkedReservationsPromise = getLinkedReservations({ + rooms: booking.linkedReservations, + }) const packagesInput = { adults: booking.adults, @@ -119,9 +98,9 @@ export default async function MyStay({ (pkg) => pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST ) const breakfastIncluded = booking.rateDefinition.breakfastIncluded - const shouldFetchBreakfastPackages = + const alreadyHasABreakfastSelection = !hasBreakfastPackage && !breakfastIncluded - if (shouldFetchBreakfastPackages) { + if (alreadyHasABreakfastSelection) { void getPackages(packagesInput) } void getSavedPaymentCardsSafely(savedPaymentCardsInput) @@ -133,7 +112,7 @@ export default async function MyStay({ }) let breakfastPackages = null - if (shouldFetchBreakfastPackages) { + if (alreadyHasABreakfastSelection) { breakfastPackages = await getPackages(packagesInput) } const savedCreditCards = await getSavedPaymentCardsSafely( @@ -142,7 +121,7 @@ export default async function MyStay({ const imageSrc = hotel.hotelContent.images.imageSizes.large ?? - hotelData.additionalData.gallery?.heroImages[0]?.imageSizes.large ?? + additionalData.gallery?.heroImages[0]?.imageSizes.large ?? hotel.galleryImages[0]?.imageSizes.large const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com" @@ -159,7 +138,7 @@ export default async function MyStay({ lang={params.lang} linkedReservationsPromise={linkedReservationsPromise} refId={refId} - roomCategories={hotelData.roomCategories} + roomCategories={roomCategories} savedCreditCards={savedCreditCards} >
@@ -218,7 +197,10 @@ export default async function MyStay({ return (
- +
) @@ -250,19 +232,3 @@ export default async function MyStay({ return notFound() } - -function RenderAdditionalInfoForm({ - refId, - lastName, -}: { - refId: string - lastName: string -}) { - return ( -
-
- -
-
- ) -} diff --git a/apps/scandic-web/components/HotelReservation/AddToCalendar/index.tsx b/apps/scandic-web/components/HotelReservation/AddToCalendar/index.tsx index be8849787..4830d7543 100644 --- a/apps/scandic-web/components/HotelReservation/AddToCalendar/index.tsx +++ b/apps/scandic-web/components/HotelReservation/AddToCalendar/index.tsx @@ -1,5 +1,4 @@ "use client" - import { createEvent } from "ics" import { useIntl } from "react-intl" diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.module.css b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/confirmation.module.css similarity index 61% rename from apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.module.css rename to apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/confirmation.module.css index 528a447cf..e3d91663e 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.module.css +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/confirmation.module.css @@ -19,26 +19,3 @@ padding-top: var(--Spacing-x9); } } - -.booking { - display: flex; - flex-direction: column; - gap: var(--Spacing-x5); - grid-area: booking; - padding-bottom: var(--Spacing-x9); -} - -.aside { - display: none; -} - -@media screen and (min-width: 1367px) { - .mobileReceipt { - display: none; - } - - .aside { - display: grid; - grid-area: receipt; - } -} diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/index.tsx new file mode 100644 index 000000000..88b99038c --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Confirmation/index.tsx @@ -0,0 +1,24 @@ +"use client" +import { useRef } from "react" + +import Header from "@/components/HotelReservation/BookingConfirmation/Header" + +import styles from "./confirmation.module.css" + +import type { ConfirmationProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation" + +export default function Confirmation({ + booking, + hotel, + children, + refId, +}: React.PropsWithChildren) { + const mainRef = useRef(null) + + return ( +
+
+ {children} +
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Header/Actions/ManageBooking.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Header/Actions/ManageBooking.tsx index ef49a8988..28a81406d 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Header/Actions/ManageBooking.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Header/Actions/ManageBooking.tsx @@ -1,22 +1,15 @@ "use client" - import { useIntl } from "react-intl" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { myStay } from "@/constants/routes/myStay" - import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" -import useLang from "@/hooks/useLang" import type { ManageBookingProps } from "@/types/components/hotelReservation/bookingConfirmation/actions/manageBooking" -export default function ManageBooking({ refId }: ManageBookingProps) { +export default function ManageBooking({ bookingUrl }: ManageBookingProps) { const intl = useIntl() - const lang = useLang() - - const bookingUrl = `${myStay[lang]}?RefId=${refId}` return (