chore: Cleanup booking widget with types and other minor issues

This commit is contained in:
Christian Andolf
2025-04-02 10:06:28 +02:00
parent 3c810d67a2
commit 14f9b68365
9 changed files with 92 additions and 98 deletions

View File

@@ -15,7 +15,7 @@ import { GuestsRoom } from "./GuestsRoom"
import styles from "./guests-rooms-picker.module.css"
import type { BookingWidgetSchema } from "@/types/components/bookingWidget"
import type { TGuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
import type { GuestsRoom as TGuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
const MAX_ROOMS = 4

View File

@@ -12,14 +12,14 @@ import ChildSelector from "../ChildSelector"
import styles from "../guests-rooms-picker.module.css"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { TGuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
import type { GuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
export function GuestsRoom({
room,
index,
onRemove,
}: {
room: TGuestsRoom
room: GuestsRoom
index: number
onRemove: (index: number) => void
}) {
@@ -54,22 +54,18 @@ export function GuestsRoom({
childrenInAdultsBed={childrenInAdultsBed}
/>
{index !== 0 && (
<div className={styles.roomActions}>
<Button
intent="text"
variant="icon"
wrapping
theme="secondaryLight"
onPress={() => onRemove(index)}
size="small"
className={styles.roomActionsButton}
>
<MaterialIcon icon="delete" color="CurrentColor" />
<span className={styles.roomActionsLabel}>
{intl.formatMessage({ id: "Remove room" })}
</span>
</Button>
</div>
<Button
intent="text"
variant="icon"
wrapping
theme="secondaryLight"
onPress={() => onRemove(index)}
size="small"
className={styles.roomActionsButton}
>
<MaterialIcon icon="delete" color="CurrentColor" />
{intl.formatMessage({ id: "Remove room" })}
</Button>
)}
</section>
<Divider color="primaryLightSubtle" />

View File

@@ -1,6 +1,6 @@
"use client"
import { useCallback, useEffect, useState } from "react"
import { useCallback, useEffect, useId, useState } from "react"
import {
Button,
Dialog,
@@ -8,7 +8,7 @@ import {
Modal,
Popover,
} from "react-aria-components"
import { useFormContext } from "react-hook-form"
import { useFormContext, useWatch } from "react-hook-form"
import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"
@@ -18,23 +18,23 @@ import PickerForm from "./Form"
import styles from "./guests-rooms-picker.module.css"
import type { TGuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
import type { BookingWidgetSchema } from "@/types/components/bookingWidget"
import type { GuestsRoom } from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function GuestsRoomsPickerForm() {
const { watch, trigger } = useFormContext()
const rooms = watch("rooms") as TGuestsRoom[]
const { trigger } = useFormContext<BookingWidgetSchema>()
const rooms = useWatch<BookingWidgetSchema, "rooms">({ 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] && rooms[0].childrenInRoom ? rooms[0].childrenInRoom.length : 0 // ToDo Update for multiroom later
const childCount = 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) {
const htmlElement = document.body
if (htmlElement) {
if (isOpen) {
htmlElement.style.overflow = "visible"
@@ -57,34 +57,32 @@ export default function GuestsRoomsPickerForm() {
}, [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)
}
// 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])
}, [containerHeight, popoverId])
useEffect(() => {
if (typeof window !== undefined && isDesktop && rooms.length > 0) {
if (isDesktop && rooms.length > 0) {
updateHeight()
}
}, [childCount, isDesktop, updateHeight, rooms])
@@ -99,10 +97,10 @@ export default function GuestsRoomsPickerForm() {
}}
/>
<Popover
className="guests_picker_popover"
className={popoverId}
placement="bottom start"
offset={36}
style={containerHeight ? { overflow: "auto" } : {}}
style={containerHeight ? { overflow: "auto" } : undefined}
>
<Dialog className={styles.pickerContainerDesktop}>
{({ close }) => <PickerForm rooms={rooms} onClose={close} />}
@@ -132,7 +130,7 @@ function Trigger({
className,
triggerFn,
}: {
rooms: TGuestsRoom[]
rooms: GuestsRoom[]
className: string
triggerFn?: () => void
}) {