"use client" import { useCallback, useEffect, useId, useState } from "react" import { Button, Dialog, DialogTrigger, Modal, Popover, } from "react-aria-components" import { useFormContext, useWatch } 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 { BookingWidgetSchema } from "@/types/components/bookingWidget" import type { GuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker" export default function GuestsRoomsPickerForm() { const { trigger } = useFormContext() const rooms = useWatch({ name: "rooms" }) const popoverId = useId() 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]?.childrenInRoom.length ?? 0 // ToDo Update for multiroom later //isOpen is the 'old state', so isOpen === true means "The modal is open and WILL be closed". async function setOverflowClip(isOpen: boolean) { const htmlElement = document.body 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(() => { // Get available space for picker to show without going beyond screen const bookingWidget = document.getElementById("booking-widget") let maxHeight = window.innerHeight - (bookingWidget?.getBoundingClientRect().bottom ?? 0) - 50 const innerContainerHeight = document .getElementsByClassName(popoverId)[0] ?.getBoundingClientRect().height if ( maxHeight != containerHeight && innerContainerHeight && maxHeight <= innerContainerHeight ) { setContainerHeight(maxHeight) } else if ( containerHeight && innerContainerHeight && maxHeight > innerContainerHeight ) { setContainerHeight(0) } }, [containerHeight, popoverId]) useEffect(() => { if (isDesktop && rooms.length > 0) { updateHeight() } }, [childCount, isDesktop, updateHeight, rooms]) return isDesktop ? ( { setIsOpen(true) }} /> {({ close }) => } ) : ( { setIsOpen(true) }} /> {({ close }) => } ) } function Trigger({ rooms, className, triggerFn, }: { rooms: GuestsRoom[] 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 ( ) }