"use client" import { useCallback, useEffect, useState } from "react" import { Button, Dialog, DialogTrigger, Modal, Popover, } from "react-aria-components" import { useFormContext } from "react-hook-form" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import Body from "@/components/TempDesignSystem/Text/Body" import PickerForm from "./Form" import styles from "./guests-rooms-picker.module.css" import type { TGuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker" export default function GuestsRoomsPickerForm() { const { watch, trigger } = useFormContext() const rooms = watch("rooms") as TGuestsRoom[] const checkIsDesktop = useMediaQuery("(min-width: 1367px)") const [isDesktop, setIsDesktop] = useState(true) const [isOpen, setIsOpen] = useState(false) const [containerHeight, setContainerHeight] = useState(0) const childCount = rooms[0] && rooms[0].childrenInRoom ? rooms[0].childrenInRoom.length : 0 // ToDo Update for multiroom later const htmlElement = typeof window !== "undefined" ? document.querySelector("body") : null //isOpen is the 'old state', so isOpen === true means "The modal is open and WILL be closed". async function setOverflowClip(isOpen: boolean) { if (htmlElement) { if (isOpen) { htmlElement.style.overflow = "visible" } else { // !important needed to override 'overflow: hidden' set by react-aria. // 'overflow: hidden' does not work in combination with other sticky positioned elements, which clip does. htmlElement.style.overflow = "clip !important" } } if (!isOpen) { const state = await trigger("rooms") if (state) { setIsOpen(isOpen) } } } useEffect(() => { setIsDesktop(checkIsDesktop) }, [checkIsDesktop]) const updateHeight = useCallback(() => { if (typeof window !== undefined) { // Get available space for picker to show without going beyond screen let maxHeight = window.innerHeight - (document.querySelector("#booking-widget")?.getBoundingClientRect() .bottom ?? 0) - 50 const innerContainerHeight = document .querySelector(".guests_picker_popover") ?.getBoundingClientRect().height if ( maxHeight != containerHeight && innerContainerHeight && maxHeight <= innerContainerHeight ) { setContainerHeight(maxHeight) } else if ( containerHeight && innerContainerHeight && maxHeight > innerContainerHeight ) { setContainerHeight(0) } } }, [containerHeight]) useEffect(() => { if (typeof window !== undefined && isDesktop && rooms.length > 0) { updateHeight() } }, [childCount, isDesktop, updateHeight, rooms]) return isDesktop ? ( { setIsOpen(true) }} /> {({ close }) => } ) : ( { setIsOpen(true) }} /> {({ close }) => } ) } function Trigger({ rooms, className, triggerFn, }: { rooms: TGuestsRoom[] className: string triggerFn?: () => void }) { const intl = useIntl() const parts = [ intl.formatMessage( { id: "{totalRooms, plural, one {# room} other {# rooms}}" }, { totalRooms: rooms.length } ), intl.formatMessage( { id: "{totalAdults, plural, one {# adult} other {# adults}}" }, { totalAdults: rooms.reduce((acc, room) => acc + room.adults, 0) } ), ] if (rooms.some((room) => room.childrenInRoom.length > 0)) { parts.push( intl.formatMessage( { id: "{totalChildren, plural, one {# child} other {# children}}", }, { totalChildren: rooms.reduce( (acc, room) => acc + room.childrenInRoom.length, 0 ), } ) ) } return ( ) }