Fix: refactor booking flow search params * wip: apply codemod and upgrade swc plugin * wip: design-system to react 19, fix issues from async (search)params * Prepare new parse function for booking flow search params * Prepare serialize function for booking flow search params * Improve handling of comma separated arrays * Slightly refactor for readability * Next abstracts URLSearchParams so handle the abstraction instead * Refactor booking widget to use new search params parsing * Rename search param functions * Refactor select-hotel to use new search param parser * Use new search params parser in select-rate and details * Fix hotelId type * Avoid passing down search params into BookingWidget components * More updates to use new types instead of SearchParams<T> * Remove types SelectHotelSearchParams and AlternativeSelectHotelSearchParams * Fix parseBookingWidgetSearchParams return type * Add error handling to booking search param parsers * Fix modifyRateIndex handling in details page * Clean up * Refactor booking widget search param serializing to util function * Move start page booking widget search param parsing to page * Use new search param serializer in HandleErrorCallback * Delete convertSearchParamsToObj & convertObjToSearchParams Approved-by: Michael Zetterberg
100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
"use client"
|
|
|
|
import { useRouter } from "next/navigation"
|
|
import { useEffect } from "react"
|
|
|
|
import { PaymentCallbackStatusEnum } from "@/constants/booking"
|
|
import { detailsStorageName } from "@/stores/enter-details"
|
|
|
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
|
import { trackPaymentEvent } from "@/utils/tracking"
|
|
import { trackEvent } from "@/utils/tracking/base"
|
|
import { serializeBookingSearchParams } from "@/utils/url"
|
|
|
|
import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers"
|
|
|
|
import type { PersistedState } from "@/types/stores/enter-details"
|
|
|
|
export default function HandleErrorCallback({
|
|
returnUrl,
|
|
searchObject,
|
|
status,
|
|
errorMessage,
|
|
}: {
|
|
returnUrl: string
|
|
searchObject: URLSearchParams
|
|
status: PaymentCallbackStatusEnum
|
|
errorMessage?: string
|
|
}) {
|
|
const router = useRouter()
|
|
|
|
useEffect(() => {
|
|
const bookingData = window.sessionStorage.getItem(detailsStorageName)
|
|
|
|
if (bookingData) {
|
|
const detailsStorage: PersistedState = JSON.parse(bookingData)
|
|
const searchParams = serializeBookingSearchParams(
|
|
detailsStorage.booking,
|
|
{
|
|
initialSearchParams: searchObject,
|
|
}
|
|
)
|
|
|
|
const glaSessionData = readGlaFromSessionStorage()
|
|
|
|
if (status === PaymentCallbackStatusEnum.Cancel) {
|
|
if (glaSessionData) {
|
|
trackEvent({
|
|
event: "glaCardSaveCancelled",
|
|
hotelInfo: {
|
|
hotelId: glaSessionData.hotelId,
|
|
lateArrivalGuarantee: glaSessionData.lateArrivalGuarantee,
|
|
guaranteedProduct: "room",
|
|
},
|
|
paymentInfo: {
|
|
hotelId: glaSessionData.hotelId,
|
|
status: "glacardsavecancelled",
|
|
},
|
|
})
|
|
} else {
|
|
trackPaymentEvent({
|
|
event: "paymentCancel",
|
|
hotelId: detailsStorage.booking.hotelId,
|
|
status: "cancelled",
|
|
})
|
|
}
|
|
}
|
|
if (status === PaymentCallbackStatusEnum.Error) {
|
|
if (glaSessionData) {
|
|
trackEvent({
|
|
event: "glaCardSaveFailed",
|
|
hotelInfo: {
|
|
hotelId: glaSessionData.hotelId,
|
|
lateArrivalGuarantee: glaSessionData.lateArrivalGuarantee,
|
|
guaranteedProduct: "room",
|
|
},
|
|
paymentInfo: {
|
|
hotelId: glaSessionData.hotelId,
|
|
status: "glacardsavefailed",
|
|
},
|
|
})
|
|
} else {
|
|
trackPaymentEvent({
|
|
event: "paymentFail",
|
|
hotelId: detailsStorage.booking.hotelId,
|
|
errorMessage,
|
|
status: "failed",
|
|
})
|
|
}
|
|
}
|
|
clearGlaSessionStorage()
|
|
|
|
if (searchParams.size > 0) {
|
|
router.replace(`${returnUrl}?${searchParams.toString()}`)
|
|
}
|
|
}
|
|
}, [returnUrl, router, searchObject, status, errorMessage])
|
|
|
|
return <LoadingSpinner fullPage />
|
|
}
|