"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 { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" import { customerService } from "@scandic-hotels/common/constants/routes/customerService" import { myStay } from "@scandic-hotels/common/constants/routes/myStay" import { logger } from "@scandic-hotels/common/logger" import { Alert } from "@scandic-hotels/design-system/Alert" import { Button } from "@scandic-hotels/design-system/Button" import { FormInput } from "@scandic-hotels/design-system/Form/FormInput" import { TextLink } from "@scandic-hotels/design-system/TextLink" import { toast } from "@scandic-hotels/design-system/Toast" import { Typography } from "@scandic-hotels/design-system/Typography" import { trpc } from "@scandic-hotels/trpc/client" import useLang from "@/hooks/useLang" import { formatFormErrorMessage } from "@/utils/getErrorMessage" import { type FindMyBookingFormSchema, findMyBookingFormSchema } from "./schema" import { Title } from "./Title" import { type FindMyBookingErrorEnum, getErrorMessage } from "./utils" import styles from "./findMyBooking.module.css" import type { AdditionalInfoCookieValue } from "@scandic-hotels/booking-flow/types/components/findMyBooking/additionalInfoCookieValue" const DEFAULT_VALUES: FindMyBookingFormSchema = { confirmationNumber: "", firstName: "", lastName: "", email: "", } export default function FindMyBooking({ error, defaultValues = DEFAULT_VALUES, }: { error?: FindMyBookingErrorEnum defaultValues: AdditionalInfoCookieValue | undefined }) { const router = useRouter() const intl = useIntl() const lang = useLang() const form = useForm({ defaultValues, resolver: zodResolver(findMyBookingFormSchema), mode: "all", criteriaMode: "all", reValidateMode: "onChange", }) const update = trpc.booking.createRefId.useMutation({ onSuccess: (result) => { const values = form.getValues() const value: AdditionalInfoCookieValue = { ...values, } document.cookie = `bv=${JSON.stringify(value)}; Path=/; Max-Age=600; Secure; SameSite=Strict` router.push(`${myStay[lang]}?RefId=${encodeURIComponent(result.refId)}`) }, onError: (error) => { logger.error("Failed to create ref id", error) toast.error( intl.formatMessage({ id: "findMyBooking.failedToSubmit", defaultMessage: "Failed to submit form, please try again later.", }) ) }, }) async function onSubmit(data: FindMyBookingFormSchema) { update.mutate({ confirmationNumber: data.confirmationNumber, lastName: data.lastName, }) } const errorMessage = getErrorMessage(intl, error) return (
{errorMessage ? ( <Alert type={AlertTypeEnum.Alarm} heading={errorMessage.heading} text={errorMessage.text} className={styles.alert} /> ) : null} <div className={[styles.inputs, styles.grid].join(" ")}> <FormInput label={intl.formatMessage({ id: "common.bookingNumber", defaultMessage: "Booking number", })} name="confirmationNumber" registerOptions={{ required: true }} errorFormatter={formatFormErrorMessage} /> <FormInput label={intl.formatMessage({ id: "common.firstName", defaultMessage: "First name", })} name="firstName" registerOptions={{ required: true }} errorFormatter={formatFormErrorMessage} /> <FormInput label={intl.formatMessage({ id: "common.lastName", defaultMessage: "Last name", })} name="lastName" registerOptions={{ required: true }} errorFormatter={formatFormErrorMessage} /> <FormInput label={intl.formatMessage({ id: "common.email", defaultMessage: "Email", })} name="email" type="email" registerOptions={{ required: true }} errorFormatter={formatFormErrorMessage} /> </div> <div className={styles.buttons}> <div className={styles.footnote}> <Typography variant="Body/Supporting text (caption)/smBold"> <p> {intl.formatMessage({ id: "findMyBooking.cantFindYourStay", defaultMessage: "Can't find your stay?", })} </p> </Typography> <Typography variant="Body/Supporting text (caption)/smRegular"> <p> {intl.formatMessage( { id: "findMyBooking.customerService", defaultMessage: "Please contact <link>customer service</link>.", }, { link: (str) => ( <TextLink isInline href={customerService[lang]} typography="Link/sm" target="_blank" > {str} </TextLink> ), } )} </p> </Typography> </div> <Button type="submit" variant="Primary" size="lg" isDisabled={form.formState.isSubmitting || update.isPending} > {intl.formatMessage({ id: "common.find", defaultMessage: "Find", })} </Button> </div> </form> </FormProvider> ) }