Merged in SW-3459-setup-booking-confirmation-page-in-sas (pull request #2794)
Setup booking-confirmation page in SAS * Setup booking-confirmation page in SAS move booking-confirmation tracking to booking-flow * remove unused param * Add test cards to documentation * Fix payment callback page to use correct status Approved-by: Anton Gunnarsson Approved-by: Hrishikesh Vaipurkar
This commit is contained in:
@@ -25,7 +25,7 @@ Inside the `/packages` directory, you'll find our shared libraries and utilities
|
|||||||
|
|
||||||
> A note about dependencies between our apps and packages:
|
> A note about dependencies between our apps and packages:
|
||||||
> In general all apps are allowed to depend on any package, but packages have a few caveats:
|
> In general all apps are allowed to depend on any package, but packages have a few caveats:
|
||||||
>
|
>
|
||||||
> `design-system` should never import from `booking-flow` or `trpc`.
|
> `design-system` should never import from `booking-flow` or `trpc`.
|
||||||
> `common` should never import from anything except `typescript-config`.
|
> `common` should never import from anything except `typescript-config`.
|
||||||
|
|
||||||
@@ -48,4 +48,5 @@ For more details see the respective apps and packages' README files.
|
|||||||
## More documentation
|
## More documentation
|
||||||
|
|
||||||
- [Icons](./docs/icons.md)
|
- [Icons](./docs/icons.md)
|
||||||
- [Translations (i18n)](./docs/translations.md)
|
- [Payment](./docs/payment.md)
|
||||||
|
- [Translations (i18n)](./docs/translations.md)
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
export default async function BookingConfirmationPage() {
|
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
|
||||||
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
|
||||||
return <div>booking-confirmation</div>
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function BookingConfirmationPage(
|
||||||
|
props: PageArgs<LangParams>
|
||||||
|
) {
|
||||||
|
const searchParams = await props.searchParams
|
||||||
|
const lang = await getLang()
|
||||||
|
const intl = await getIntl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BookingConfirmationPagePrimitive
|
||||||
|
intl={intl}
|
||||||
|
lang={lang}
|
||||||
|
searchParams={searchParams}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { PaymentCallbackPage as PaymentCallbackPagePrimitive } from "@scandic-hotels/booking-flow/pages/PaymentCallbackPage"
|
import { PaymentCallbackPage as PaymentCallbackPagePrimitive } from "@scandic-hotels/booking-flow/pages/PaymentCallbackPage"
|
||||||
import { logger } from "@scandic-hotels/common/logger"
|
import { logger } from "@scandic-hotels/common/logger"
|
||||||
|
|
||||||
|
import type { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum"
|
||||||
|
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function PaymentCallbackPage(props: PageArgs<LangParams>) {
|
export default async function PaymentCallbackPage(
|
||||||
|
props: PageArgs<LangParams & { status: string }>
|
||||||
|
) {
|
||||||
const searchParams = await props.searchParams
|
const searchParams = await props.searchParams
|
||||||
const params = await props.params
|
const params = await props.params
|
||||||
logger.debug(`[payment-callback] callback started`)
|
logger.debug(`[payment-callback] callback started`)
|
||||||
@@ -21,6 +25,7 @@ export default async function PaymentCallbackPage(props: PageArgs<LangParams>) {
|
|||||||
lang={lang}
|
lang={lang}
|
||||||
userAccessToken={userAccessToken}
|
userAccessToken={userAccessToken}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
|
status={params.status as PaymentCallbackStatusEnum}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "PORT=3001 NEXT_PUBLIC_PORT=3001 next dev",
|
"dev": "NODE_OPTIONS=--openssl-legacy-provider PORT=3001 NEXT_PUBLIC_PORT=3001 next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "node .next/standalone/server.js",
|
"start": "node .next/standalone/server.js",
|
||||||
"lint": "next lint --max-warnings 0 && tsc --noEmit",
|
"lint": "next lint --max-warnings 0 && tsc --noEmit",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
|
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
|
||||||
|
|
||||||
import Tracking from "@/components/HotelReservation/BookingConfirmation/Tracking"
|
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
@@ -18,12 +17,6 @@ export default async function BookingConfirmationPage(
|
|||||||
intl={intl}
|
intl={intl}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
renderTracking={(props) => (
|
|
||||||
<Tracking
|
|
||||||
bookingConfirmation={props.bookingConfirmation}
|
|
||||||
refId={props.refId}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ export default async function PaymentCallbackPage(
|
|||||||
lang={lang}
|
lang={lang}
|
||||||
userAccessToken={userAccessToken}
|
userAccessToken={userAccessToken}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
|
// TODO refactor this route to get this from params instead of rewriting in next.config
|
||||||
|
status={searchParams.status as PaymentCallbackStatusEnum}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
13
docs/payment.md
Normal file
13
docs/payment.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Payment
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
| Type | Card number | CVV |
|
||||||
|
| ---- | --------------------- | --- |
|
||||||
|
| Visa | `4111 1111 1111 1111` | 123 |
|
||||||
|
| Visa | `4242 4242 4242 4242` | 123 |
|
||||||
|
|
||||||
|
- Expiration date needs to be in the future
|
||||||
|
- For OTP
|
||||||
|
- ✅ 4000 for success
|
||||||
|
- ❌ 4001 for failure
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react"
|
||||||
|
|
||||||
|
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||||
|
|
||||||
|
import { clearPaymentInfoSessionStorage } from "../../../components/EnterDetails/Payment/helpers"
|
||||||
|
import useLang from "../../../hooks/useLang"
|
||||||
|
import { useSearchHistory } from "../../../hooks/useSearchHistory"
|
||||||
|
import { useBookingConfirmationStore } from "../../../stores/booking-confirmation"
|
||||||
|
import { getTracking } from "./tracking"
|
||||||
|
|
||||||
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
|
||||||
|
import type { Room } from "../../../types/stores/booking-confirmation"
|
||||||
|
|
||||||
|
export default function BookingConfirmationTracking({
|
||||||
|
bookingConfirmation,
|
||||||
|
refId,
|
||||||
|
}: {
|
||||||
|
bookingConfirmation: BookingConfirmation
|
||||||
|
refId: string
|
||||||
|
}) {
|
||||||
|
const lang = useLang()
|
||||||
|
const bookingRooms = useBookingConfirmationStore((state) => state.rooms)
|
||||||
|
|
||||||
|
const [loadedBookingConfirmationRefId] = useState(() => {
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
return sessionStorage.getItem("loadedBookingConfirmationRefId")
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sessionStorage.setItem("loadedBookingConfirmationRefId", refId)
|
||||||
|
}, [refId])
|
||||||
|
|
||||||
|
const searchHistory = useSearchHistory()
|
||||||
|
const searchTerm = searchHistory.searchHistory[0]?.name
|
||||||
|
|
||||||
|
let trackingData = null
|
||||||
|
|
||||||
|
if (bookingRooms.every(Boolean)) {
|
||||||
|
const rooms = bookingRooms.filter((room): room is Room => !!room)
|
||||||
|
trackingData = getTracking(
|
||||||
|
lang,
|
||||||
|
bookingConfirmation.booking,
|
||||||
|
bookingConfirmation.hotel,
|
||||||
|
rooms,
|
||||||
|
searchTerm
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (trackingData?.paymentInfo) {
|
||||||
|
clearPaymentInfoSessionStorage()
|
||||||
|
}
|
||||||
|
}, [trackingData])
|
||||||
|
|
||||||
|
if (!trackingData) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
|
||||||
|
trackingData
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TrackingSDK
|
||||||
|
pageData={pageTrackingData}
|
||||||
|
hotelInfo={
|
||||||
|
loadedBookingConfirmationRefId === refId
|
||||||
|
? undefined
|
||||||
|
: hotelsTrackingData
|
||||||
|
}
|
||||||
|
paymentInfo={
|
||||||
|
loadedBookingConfirmationRefId === refId ? undefined : paymentInfo
|
||||||
|
}
|
||||||
|
ancillaries={
|
||||||
|
loadedBookingConfirmationRefId === refId ? undefined : ancillaries
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
import { createHash } from "crypto"
|
||||||
|
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
||||||
|
|
||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
|
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
|
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||||
|
import {
|
||||||
|
TrackingChannelEnum,
|
||||||
|
type TrackingSDKAncillaries,
|
||||||
|
type TrackingSDKHotelInfo,
|
||||||
|
type TrackingSDKPageData,
|
||||||
|
type TrackingSDKPaymentInfo,
|
||||||
|
} from "@scandic-hotels/tracking/types"
|
||||||
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
|
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
|
|
||||||
|
import { readPaymentInfoFromSessionStorage } from "../../../components/EnterDetails/Payment/helpers"
|
||||||
|
import { invertedBedTypeMap } from "../../../utils/SelectRate"
|
||||||
|
import { getSpecialRoomType } from "../../../utils/specialRoomType"
|
||||||
|
|
||||||
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||||
|
|
||||||
|
import type { Room } from "../../../types/stores/booking-confirmation"
|
||||||
|
|
||||||
|
function getRate(cancellationRule: RateDefinition["cancellationRule"] | null) {
|
||||||
|
switch (cancellationRule) {
|
||||||
|
case "CancellableBefore6PM":
|
||||||
|
return RateEnum.flex
|
||||||
|
case "Changeable":
|
||||||
|
return RateEnum.change
|
||||||
|
case "NotCancellable":
|
||||||
|
return RateEnum.save
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapAncillaryPackage(
|
||||||
|
ancillaryPackage: BookingConfirmation["booking"]["packages"][number],
|
||||||
|
operaId: string
|
||||||
|
) {
|
||||||
|
const isPoints = ancillaryPackage.currency === CurrencyEnum.POINTS
|
||||||
|
return {
|
||||||
|
hotelid: operaId,
|
||||||
|
productCategory: "", // TODO: Add category
|
||||||
|
productId: ancillaryPackage.code,
|
||||||
|
productName: ancillaryPackage.description,
|
||||||
|
productPoints: isPoints ? ancillaryPackage.totalPrice : 0,
|
||||||
|
productPrice: isPoints ? 0 : ancillaryPackage.totalPrice,
|
||||||
|
productType:
|
||||||
|
ancillaryPackage.code === BreakfastPackageEnum.REGULAR_BREAKFAST
|
||||||
|
? "food"
|
||||||
|
: "room preference",
|
||||||
|
productUnits: ancillaryPackage.totalUnit,
|
||||||
|
productDeliveryTime: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTracking(
|
||||||
|
lang: Lang,
|
||||||
|
booking: BookingConfirmation["booking"],
|
||||||
|
hotel: BookingConfirmation["hotel"],
|
||||||
|
rooms: Room[],
|
||||||
|
searchTerm?: string
|
||||||
|
) {
|
||||||
|
const arrivalDate = new Date(booking.checkInDate)
|
||||||
|
const departureDate = new Date(booking.checkOutDate)
|
||||||
|
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
|
||||||
|
|
||||||
|
const pageTrackingData: TrackingSDKPageData = {
|
||||||
|
channel: TrackingChannelEnum.hotelreservation,
|
||||||
|
domainLanguage: lang,
|
||||||
|
pageId: "booking-confirmation",
|
||||||
|
pageName: `hotelreservation|confirmation`,
|
||||||
|
pageType: "confirmation",
|
||||||
|
siteSections: `hotelreservation|confirmation`,
|
||||||
|
siteVersion: "new-web",
|
||||||
|
}
|
||||||
|
|
||||||
|
const noOfAdults = rooms.map((r) => r.adults).join(",")
|
||||||
|
const noOfChildren = rooms.map((r) => r.childrenAges?.length ?? 0).join(",")
|
||||||
|
const noOfRooms = rooms.length
|
||||||
|
const isFlexBooking =
|
||||||
|
booking.rateDefinition.cancellationRule ===
|
||||||
|
CancellationRuleEnum.CancellableBefore6PM
|
||||||
|
const isGuaranteedFlexBooking = booking.guaranteeInfo && isFlexBooking
|
||||||
|
|
||||||
|
const ancillaries: TrackingSDKAncillaries = rooms
|
||||||
|
.flatMap((r) => r.packages)
|
||||||
|
.filter(
|
||||||
|
(p) =>
|
||||||
|
p.code === RoomPackageCodeEnum.PET_ROOM ||
|
||||||
|
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST
|
||||||
|
)
|
||||||
|
.map((pkg) => mapAncillaryPackage(pkg, hotel.operaId))
|
||||||
|
|
||||||
|
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||||
|
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "").join("|"),
|
||||||
|
analyticsRateCode: rooms
|
||||||
|
.map((r) => getRate(r.rateDefinition.cancellationRule))
|
||||||
|
.join("|"),
|
||||||
|
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||||
|
bedType: rooms
|
||||||
|
.map((r) => r.bedType)
|
||||||
|
.join(",")
|
||||||
|
.toLowerCase(),
|
||||||
|
bnr: rooms.map((r) => r.confirmationNumber).join(","),
|
||||||
|
bookingCode: rooms.map((room) => room.bookingCode ?? "n/a").join(", "),
|
||||||
|
bookingCodeAvailability: booking.bookingCode
|
||||||
|
? rooms.map((room) => (room.bookingCode ? "true" : "false")).join(", ")
|
||||||
|
: undefined,
|
||||||
|
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||||
|
breakfastOption: rooms
|
||||||
|
.map((r) => {
|
||||||
|
if (r.breakfastIncluded || r.breakfast) {
|
||||||
|
return "breakfast buffet"
|
||||||
|
}
|
||||||
|
return "no breakfast"
|
||||||
|
})
|
||||||
|
.join(","),
|
||||||
|
childBedPreference: rooms
|
||||||
|
.map(
|
||||||
|
(r) =>
|
||||||
|
r.childBedPreferences
|
||||||
|
.map((cbp) =>
|
||||||
|
Array(cbp.quantity).fill(invertedBedTypeMap[cbp.bedType])
|
||||||
|
)
|
||||||
|
.join(",") ?? ""
|
||||||
|
)
|
||||||
|
.join("|"),
|
||||||
|
country: hotel?.address.country,
|
||||||
|
departureDate: format(departureDate, "yyyy-MM-dd"),
|
||||||
|
duration: differenceInCalendarDays(departureDate, arrivalDate),
|
||||||
|
hotelID: hotel.operaId,
|
||||||
|
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
|
||||||
|
noOfAdults,
|
||||||
|
noOfChildren,
|
||||||
|
noOfRooms,
|
||||||
|
rateCode: rooms.map((r) => r.rateDefinition.rateCode).join(","),
|
||||||
|
rateCodeCancellationRule: rooms
|
||||||
|
.map((r) => r.rateDefinition.cancellationRule)
|
||||||
|
.join(",")
|
||||||
|
.toLowerCase(),
|
||||||
|
rateCodeName: rooms.map(constructRateCodeName).join(","),
|
||||||
|
rateCodeType: rooms.map((r) => r.rateCodeType?.toLowerCase()).join(","),
|
||||||
|
region: hotel?.address.city,
|
||||||
|
revenueCurrencyCode: [...new Set(rooms.map((r) => r.currencyCode))].join(
|
||||||
|
","
|
||||||
|
),
|
||||||
|
rewardNight: booking.roomPoints > 0 ? "yes" : "no",
|
||||||
|
rewardNightAvailability: booking.roomPoints > 0 ? "true" : "false",
|
||||||
|
points: booking.roomPoints > 0 ? booking.roomPoints : undefined,
|
||||||
|
roomPrice: rooms.reduce((total, room) => total + room.roomPrice, 0),
|
||||||
|
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "").join(","),
|
||||||
|
searchTerm,
|
||||||
|
searchType: "hotel",
|
||||||
|
specialRoomType: rooms
|
||||||
|
.map((room) => getSpecialRoomType(room.packages))
|
||||||
|
.join(","),
|
||||||
|
totalPrice: rooms.reduce((total, room) => total + room.totalPrice, 0),
|
||||||
|
lateArrivalGuarantee: booking.rateDefinition.mustBeGuaranteed
|
||||||
|
? "mandatory"
|
||||||
|
: isFlexBooking
|
||||||
|
? booking.guaranteeInfo
|
||||||
|
? "yes"
|
||||||
|
: "no"
|
||||||
|
: "na",
|
||||||
|
guaranteedProduct: isGuaranteedFlexBooking ? "room" : "na",
|
||||||
|
emailId: getSHAHash(booking.guest.email),
|
||||||
|
mobileNumber: getSHAHash(booking.guest.phoneNumber),
|
||||||
|
}
|
||||||
|
|
||||||
|
const paymentInfo: TrackingSDKPaymentInfo = {
|
||||||
|
paymentStatus: isGuaranteedFlexBooking
|
||||||
|
? "glacardsaveconfirmed"
|
||||||
|
: "confirmed",
|
||||||
|
type:
|
||||||
|
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
hotelsTrackingData,
|
||||||
|
pageTrackingData,
|
||||||
|
paymentInfo,
|
||||||
|
ancillaries,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructRateCodeName(room: Room) {
|
||||||
|
if (room.cheques) {
|
||||||
|
return "corporate cheque"
|
||||||
|
} else if (room.vouchers) {
|
||||||
|
return "voucher"
|
||||||
|
} else if (room.roomPoints) {
|
||||||
|
return "redemption"
|
||||||
|
}
|
||||||
|
|
||||||
|
const rate = getRate(room.rateDefinition.cancellationRule)
|
||||||
|
|
||||||
|
const bookingCodeStr = room.bookingCode ? room.bookingCode.toUpperCase() : ""
|
||||||
|
|
||||||
|
const breakfastIncludedStr = room.breakfastIncluded
|
||||||
|
? "incl. breakfast"
|
||||||
|
: "excl. breakfast"
|
||||||
|
|
||||||
|
return [bookingCodeStr, rate, breakfastIncludedStr]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" - ")
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSHAHash(key: string) {
|
||||||
|
return createHash("sha256").update(key).digest("hex")
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ import { PaymentDetails } from "./PaymentDetails"
|
|||||||
import { Promos } from "./Promos"
|
import { Promos } from "./Promos"
|
||||||
import { Receipt } from "./Receipt"
|
import { Receipt } from "./Receipt"
|
||||||
import { Rooms } from "./Rooms"
|
import { Rooms } from "./Rooms"
|
||||||
|
import BookingConfirmationTracking from "./Tracking"
|
||||||
import { mapRoomState } from "./utils"
|
import { mapRoomState } from "./utils"
|
||||||
|
|
||||||
import styles from "./bookingConfirmation.module.css"
|
import styles from "./bookingConfirmation.module.css"
|
||||||
@@ -26,17 +27,12 @@ type BookingConfirmationProps = {
|
|||||||
intl: IntlShape
|
intl: IntlShape
|
||||||
refId: string
|
refId: string
|
||||||
membershipFailedError: boolean
|
membershipFailedError: boolean
|
||||||
renderTracking: (trackingProps: {
|
|
||||||
bookingConfirmation: BookingConfirmation
|
|
||||||
refId: string
|
|
||||||
}) => React.ReactNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function BookingConfirmation({
|
export async function BookingConfirmation({
|
||||||
intl,
|
intl,
|
||||||
refId,
|
refId,
|
||||||
membershipFailedError,
|
membershipFailedError,
|
||||||
renderTracking,
|
|
||||||
}: BookingConfirmationProps) {
|
}: BookingConfirmationProps) {
|
||||||
const bookingConfirmation = await getBookingConfirmation(refId)
|
const bookingConfirmation = await getBookingConfirmation(refId)
|
||||||
|
|
||||||
@@ -112,7 +108,10 @@ export async function BookingConfirmation({
|
|||||||
</aside>
|
</aside>
|
||||||
</Confirmation>
|
</Confirmation>
|
||||||
|
|
||||||
{renderTracking({ bookingConfirmation, refId })}
|
<BookingConfirmationTracking
|
||||||
|
bookingConfirmation={bookingConfirmation}
|
||||||
|
refId={refId}
|
||||||
|
/>
|
||||||
</BookingConfirmationProvider>
|
</BookingConfirmationProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { getBookingConfirmation } from "../trpc/memoizedRequests/getBookingConfi
|
|||||||
import { MEMBERSHIP_FAILED_ERROR } from "../types/membershipFailedError"
|
import { MEMBERSHIP_FAILED_ERROR } from "../types/membershipFailedError"
|
||||||
|
|
||||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
import type { BookingConfirmation as BookingConfirmationType } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
import type { IntlShape } from "react-intl"
|
import type { IntlShape } from "react-intl"
|
||||||
|
|
||||||
import type { NextSearchParams } from "../types"
|
import type { NextSearchParams } from "../types"
|
||||||
@@ -17,15 +16,10 @@ export async function BookingConfirmationPage({
|
|||||||
intl,
|
intl,
|
||||||
lang,
|
lang,
|
||||||
searchParams,
|
searchParams,
|
||||||
renderTracking,
|
|
||||||
}: {
|
}: {
|
||||||
intl: IntlShape
|
intl: IntlShape
|
||||||
lang: Lang
|
lang: Lang
|
||||||
searchParams: NextSearchParams
|
searchParams: NextSearchParams
|
||||||
renderTracking: (trackingProps: {
|
|
||||||
bookingConfirmation: BookingConfirmationType
|
|
||||||
refId: string
|
|
||||||
}) => React.ReactNode
|
|
||||||
}) {
|
}) {
|
||||||
const refId = searchParams.RefId?.toString()
|
const refId = searchParams.RefId?.toString()
|
||||||
|
|
||||||
@@ -56,7 +50,6 @@ export async function BookingConfirmationPage({
|
|||||||
intl={intl}
|
intl={intl}
|
||||||
refId={refId}
|
refId={refId}
|
||||||
membershipFailedError={membershipFailedError}
|
membershipFailedError={membershipFailedError}
|
||||||
renderTracking={renderTracking}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,19 +23,20 @@ type PaymentCallbackPageProps = {
|
|||||||
lang: Lang
|
lang: Lang
|
||||||
searchParams: NextSearchParams
|
searchParams: NextSearchParams
|
||||||
userAccessToken: string | null
|
userAccessToken: string | null
|
||||||
|
status: PaymentCallbackStatusEnum
|
||||||
}
|
}
|
||||||
export async function PaymentCallbackPage({
|
export async function PaymentCallbackPage({
|
||||||
lang,
|
lang,
|
||||||
userAccessToken,
|
userAccessToken,
|
||||||
searchParams,
|
searchParams,
|
||||||
|
status,
|
||||||
}: PaymentCallbackPageProps) {
|
}: PaymentCallbackPageProps) {
|
||||||
const { status, confirmationNumber } = searchParams
|
const { confirmationNumber } = searchParams
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!status ||
|
!status ||
|
||||||
!confirmationNumber ||
|
!confirmationNumber ||
|
||||||
typeof confirmationNumber !== "string" ||
|
typeof confirmationNumber !== "string"
|
||||||
typeof status !== "string"
|
|
||||||
) {
|
) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`[payment-callback] missing status or confirmationNumber in search params`
|
`[payment-callback] missing status or confirmationNumber in search params`
|
||||||
@@ -143,8 +144,7 @@ export async function PaymentCallbackPage({
|
|||||||
<HandleErrorCallback
|
<HandleErrorCallback
|
||||||
returnUrl={returnUrl.toString()}
|
returnUrl={returnUrl.toString()}
|
||||||
searchObject={searchObject}
|
searchObject={searchObject}
|
||||||
// TODO we should parse instead of cast
|
status={status}
|
||||||
status={status as PaymentCallbackStatusEnum}
|
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
"./stores/enter-details": "./lib/stores/enter-details/index.ts",
|
"./stores/enter-details": "./lib/stores/enter-details/index.ts",
|
||||||
"./stores/enter-details/types": "./lib/stores/enter-details/types.ts",
|
"./stores/enter-details/types": "./lib/stores/enter-details/types.ts",
|
||||||
"./stores/hotels-map": "./lib/stores/hotels-map.ts",
|
"./stores/hotels-map": "./lib/stores/hotels-map.ts",
|
||||||
|
"./stores/booking-confirmation": "./lib/stores/booking-confirmation/index.ts",
|
||||||
"./types/components/bookingConfirmation/bookingConfirmation": "./lib/types/components/bookingConfirmation/bookingConfirmation.ts",
|
"./types/components/bookingConfirmation/bookingConfirmation": "./lib/types/components/bookingConfirmation/bookingConfirmation.ts",
|
||||||
"./types/components/findMyBooking/additionalInfoCookieValue": "./lib/types/components/findMyBooking/additionalInfoCookieValue.ts",
|
"./types/components/findMyBooking/additionalInfoCookieValue": "./lib/types/components/findMyBooking/additionalInfoCookieValue.ts",
|
||||||
"./types/components/promo/promoProps": "./lib/types/components/promo/promoProps.ts",
|
"./types/components/promo/promoProps": "./lib/types/components/promo/promoProps.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user