106 lines
2.9 KiB
TypeScript
106 lines
2.9 KiB
TypeScript
import { useRouter } from "next/navigation"
|
|
import { useCallback, useEffect, useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { useHandleBookingStatus } from "@scandic-hotels/booking-flow/hooks/useHandleBookingStatus"
|
|
import { toast } from "@scandic-hotels/design-system/Toast"
|
|
import { trackEvent } from "@scandic-hotels/tracking/base"
|
|
import { trpc } from "@scandic-hotels/trpc/client"
|
|
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
|
|
|
|
const maxRetries = 15
|
|
const retryInterval = 2000
|
|
|
|
export function useGuaranteeBooking(
|
|
refId: string,
|
|
isAncillaryFlow = false,
|
|
hotelId: string
|
|
) {
|
|
const intl = useIntl()
|
|
const router = useRouter()
|
|
const [isPollingForBookingStatus, setIsPollingForBookingStatus] =
|
|
useState(false)
|
|
|
|
const handleGuaranteeError = useCallback(
|
|
(errorMessage?: string) => {
|
|
trackEvent({
|
|
event: "glaCardSaveFailed",
|
|
hotelInfo: {
|
|
hotelId,
|
|
lateArrivalGuarantee: "yes",
|
|
guaranteedProduct: isAncillaryFlow ? "room + ancillary" : "room",
|
|
},
|
|
paymentInfo: {
|
|
status: "glacardsavefailed",
|
|
errorMessage,
|
|
},
|
|
})
|
|
toast.error(
|
|
intl.formatMessage({
|
|
defaultMessage:
|
|
"We had an issue guaranteeing your booking. Please try again.",
|
|
})
|
|
)
|
|
},
|
|
[intl, isAncillaryFlow, hotelId]
|
|
)
|
|
|
|
const utils = trpc.useUtils()
|
|
const guaranteeBooking = trpc.booking.guarantee.useMutation({
|
|
onSuccess: (result) => {
|
|
if (result) {
|
|
const mainRoom = result.rooms[0]
|
|
if (result.reservationStatus == BookingStatusEnum.BookingCompleted) {
|
|
utils.booking.get.invalidate({ refId: mainRoom.refId })
|
|
} else {
|
|
setIsPollingForBookingStatus(true)
|
|
utils.booking.status.invalidate({ refId: mainRoom.refId })
|
|
}
|
|
} else {
|
|
handleGuaranteeError()
|
|
}
|
|
},
|
|
onError: (error) => {
|
|
handleGuaranteeError(error.message)
|
|
},
|
|
})
|
|
|
|
const bookingStatus = useHandleBookingStatus({
|
|
refId,
|
|
expectedStatuses: [BookingStatusEnum.BookingCompleted],
|
|
maxRetries,
|
|
retryInterval,
|
|
enabled: isPollingForBookingStatus,
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (bookingStatus?.data?.booking.paymentUrl && isPollingForBookingStatus) {
|
|
router.push(bookingStatus.data.booking.paymentUrl)
|
|
utils.booking.get.invalidate({ refId })
|
|
setIsPollingForBookingStatus(false)
|
|
} else if (bookingStatus.isTimeout) {
|
|
handleGuaranteeError("Timeout")
|
|
}
|
|
}, [
|
|
bookingStatus,
|
|
router,
|
|
handleGuaranteeError,
|
|
setIsPollingForBookingStatus,
|
|
isPollingForBookingStatus,
|
|
refId,
|
|
utils.booking.get,
|
|
])
|
|
|
|
const isLoading =
|
|
guaranteeBooking.isPending ||
|
|
(isPollingForBookingStatus &&
|
|
!bookingStatus.data?.booking.paymentUrl &&
|
|
!bookingStatus.isTimeout)
|
|
|
|
return {
|
|
guaranteeBooking,
|
|
isLoading,
|
|
handleGuaranteeError,
|
|
}
|
|
}
|