"use client" import { zodResolver } from "@hookform/resolvers/zod" import { useRouter } from "next/navigation" import { FormProvider, useForm } from "react-hook-form" import { useIntl } from "react-intl" import { PaymentMethodEnum } from "@/constants/booking" import { bookingTermsAndConditions, privacyPolicy, } from "@/constants/currentWebHrefs" import { guaranteeCallback } from "@/constants/routes/hotelReservation" import { env } from "@/env/client" import { useManageStayStore } from "@/stores/my-stay/manageStayStore" import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore" import LoadingSpinner from "@/components/LoadingSpinner" import { ModalContentWithActions } from "@/components/Modal/ModalContentWithActions" import Divider from "@/components/TempDesignSystem/Divider" import Checkbox from "@/components/TempDesignSystem/Form/Checkbox" import Link from "@/components/TempDesignSystem/Link" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import { toast } from "@/components/TempDesignSystem/Toasts" import { useGuaranteeBooking } from "@/hooks/booking/useGuaranteeBooking" import useLang from "@/hooks/useLang" import { formatPrice } from "@/utils/numberFormatting" import MySavedCards from "../../EnterDetails/Payment/MySavedCards" import PaymentOption from "../../EnterDetails/Payment/PaymentOption" import { type GuaranteeFormData, paymentSchema } from "./schema" import styles from "./guaranteeLateArrival.module.css" import type { CreditCard } from "@/types/user" export interface GuaranteeLateArrivalProps { savedCreditCards: CreditCard[] | null refId: string } export default function GuaranteeLateArrival({ savedCreditCards, refId, }: GuaranteeLateArrivalProps) { const intl = useIntl() const lang = useLang() const router = useRouter() const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom) const { actions: { handleCloseView, handleCloseModal }, } = useManageStayStore() const methods = useForm({ defaultValues: { paymentMethod: savedCreditCards?.length ? savedCreditCards[0].id : PaymentMethodEnum.card, termsAndConditions: false, }, mode: "all", reValidateMode: "onChange", resolver: zodResolver(paymentSchema), }) const guaranteeRedirectUrl = `${env.NEXT_PUBLIC_NODE_ENV === "development" ? `http://localhost:${env.NEXT_PUBLIC_PORT}` : ""}${guaranteeCallback(lang)}` const { guaranteeBooking, isLoading } = useGuaranteeBooking({ confirmationNumber: bookedRoom.confirmationNumber, handleBookingCompleted: router.refresh, }) if (isLoading) { return (
) } const handleGuaranteeLateArrival = (data: GuaranteeFormData) => { const savedCreditCard = savedCreditCards?.find( (card) => card.id === data.paymentMethod ) if (bookedRoom.confirmationNumber) { const card = savedCreditCard ? { alias: savedCreditCard.alias, expiryDate: savedCreditCard.expirationDate, cardType: savedCreditCard.cardType, } : undefined guaranteeBooking.mutate({ confirmationNumber: bookedRoom.confirmationNumber, language: lang, ...(card !== undefined && { card }), success: `${guaranteeRedirectUrl}?status=success&RefId=${encodeURIComponent(refId)}`, error: `${guaranteeRedirectUrl}?status=error&RefId=${encodeURIComponent(refId)}`, cancel: `${guaranteeRedirectUrl}?status=cancel&RefId=${encodeURIComponent(refId)}`, }) } else { toast.error( intl.formatMessage({ id: "Something went wrong!", }) ) } } return ( {intl.formatMessage({ id: "Planning to arrive after 18.00? Secure your room by guaranteeing it with a credit card. Without the guarantee and in case of no-show, the room might be reallocated after 18:00.", })} {intl.formatMessage({ id: "In case of no-show you will be charged for the first night.", })} {savedCreditCards?.length ? ( <> {intl.formatMessage({ id: "OTHER" })} ) : null}
{intl.formatMessage( { id: "By guaranteeing with any of the payment methods available, I accept the terms for this stay and the general Terms & Conditions, and understand Scandic will process my personal data for this stay in accordance with Scandic’s Privacy Policy. I accept Scandic requiring a valid credit card during my visit in case anything is left unpaid.", }, { termsAndConditionsLink: (str) => ( {str} ), privacyPolicyLink: (str) => ( {str} ), } )}
{intl.formatMessage({ id: "Guarantee cost" })} {intl.formatMessage({ id: "Your card will only be used for authorisation", })}
{formatPrice(intl, 0, bookedRoom.currencyCode)}
} primaryAction={{ label: intl.formatMessage({ id: "Guarantee" }), onClick: methods.handleSubmit(handleGuaranteeLateArrival), intent: "primary", }} secondaryAction={{ label: intl.formatMessage({ id: "Back" }), onClick: handleCloseView, intent: "text", }} />
) }