import { useCallback, useEffect, useRef, useState } from "react" import { Dialog, DialogTrigger, Popover } from "react-aria-components" import { useFormContext } from "react-hook-form" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { ErrorCircleIcon, InfoCircleIcon } from "@/components/Icons" import Modal from "@/components/Modal" import Button from "@/components/TempDesignSystem/Button" import Checkbox from "@/components/TempDesignSystem/Form/Checkbox" import Switch from "@/components/TempDesignSystem/Form/Switch" import Body from "@/components/TempDesignSystem/Text/Body" import Caption from "@/components/TempDesignSystem/Text/Caption" import Input from "../Input" import TabletCodeInput from "./TabletCodeInput" import styles from "./booking-code.module.css" import type { BookingCodeSchema, BookingWidgetSchema, } from "@/types/components/bookingWidget" export default function BookingCode() { const intl = useIntl() const checkIsTablet = useMediaQuery( "(min-width: 768px) and (max-width: 1367px)" ) const checkIsDesktop = useMediaQuery("(min-width: 1367px)") const [isTablet, setIsTablet] = useState(false) const [isDesktop, setIsDesktop] = useState(false) const { setValue, formState: { errors }, getValues, register, } = useFormContext() const bookingCode: BookingCodeSchema = getValues("bookingCode") const [isOpen, setIsOpen] = useState(!!bookingCode?.value) const [showRemember, setShowRemember] = useState(false) const [showRememberMobile, setShowRememberMobile] = useState(false) const codeError = errors["bookingCode"]?.value const codeVoucher = intl.formatMessage({ id: "Code / Voucher" }) const addCode = intl.formatMessage({ id: "Add code" }) const ref = useRef(null) function updateBookingCodeFormValue(value: string) { setValue("bookingCode.value", value, { shouldValidate: true }) } function toggleModal(isOpen: boolean) { if (!isOpen && !bookingCode?.value) { setValue("bookingCode.flag", false) setIsOpen(isOpen) } else if (!codeError || isOpen) { setIsOpen(isOpen) if (isOpen || bookingCode?.value) { setValue("bookingCode.flag", true) } } } const closeIfOutside = useCallback( (target: HTMLElement) => { if (ref.current && target && !ref.current.contains(target)) { setShowRemember(false) } }, [setShowRemember, ref] ) function showRememberCheck() { setShowRemember(true) } useEffect(() => { setIsTablet(checkIsTablet) }, [checkIsTablet]) useEffect(() => { setIsDesktop(checkIsDesktop) }, [checkIsDesktop]) const isRememberMobileVisible = !isDesktop && (showRemember || !!bookingCode?.remember) useEffect(() => { setShowRememberMobile(isRememberMobileVisible) }, [isRememberMobileVisible]) useEffect(() => { function handleClickOutside(evt: Event) { if (showRemember) { const target = evt.target as HTMLElement closeIfOutside(target) } } document.body.addEventListener("click", handleClickOutside) return () => { document.body.removeEventListener("click", handleClickOutside) } }, [closeIfOutside, showRemember]) return isTablet ? (
{({ close }) => (
)}
) : (
closeIfOutside(e.nativeEvent.relatedTarget as HTMLElement)} >
{codeVoucher}
updateBookingCodeFormValue(event.target.value)} defaultValue={bookingCode?.value} /> {codeError?.message ? ( {intl.formatMessage({ id: codeError.message })} ) : null} {isDesktop ? (
setShowRemember(false)} />
) : (
{intl.formatMessage({ id: "Remember code" })}
)}
) } type CodeRememberProps = { bookingCodeValue: string | undefined onApplyClick: () => void } function CodeRulesModal() { const intl = useIntl() const codeVoucher = intl.formatMessage({ id: "Code / Voucher" }) const bookingCodeTooltipText = intl.formatMessage({ id: "If you're booking a promotional offer or a Corporate negotiated rate you'll need a special booking code. Don't use any special characters such as (.) (,) (-) (:). If you would like to make a booking with code VOF, please call us +46 8 517 517 20.Save your booking code for the next time you visit the page by ticking the box “Remember”. Don't tick the box if you're using a public computer to avoid unauthorized access to your booking code.", }) return ( } title={codeVoucher} > {bookingCodeTooltipText} ) } function CodeRemember({ bookingCodeValue, onApplyClick }: CodeRememberProps) { const intl = useIntl() return ( <> {intl.formatMessage({ id: "Remember code" })} {bookingCodeValue ? ( ) : null} ) }