"use client" import { useCallback, useEffect } from "react" import { useFormContext, useWatch } from "react-hook-form" import { useIntl } from "react-intl" import { Button } from "@scandic-hotels/design-system/Button" import { IconButton } from "@scandic-hotels/design-system/IconButton" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { useBookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfigContext" import { useIsDesktop } from "../../../hooks/useBreakpoint" import { GuestsRoom } from "./GuestsRoom" import styles from "./guests-rooms-picker.module.css" import type { GuestsRoom as TGuestsRoom } from ".." import type { BookingWidgetSchema } from "../Client" const MAX_ROOMS = 4 interface GuestsRoomsPickerDialogProps { rooms: TGuestsRoom[] onClose: () => void containerRef?: React.RefObject } export default function GuestsRoomsPickerDialog({ rooms, onClose, containerRef, }: GuestsRoomsPickerDialogProps) { const intl = useIntl() const isDesktop = useIsDesktop() const config = useBookingFlowConfig() const { getFieldState, trigger, setValue, getValues } = useFormContext() const roomsValue = useWatch({ name: "rooms" }) const addRoomLabel = intl.formatMessage({ id: "bookingWidget.roomsPicker.addRoom", defaultMessage: "Add room", }) const doneLabel = intl.formatMessage({ id: "bookingWidget.roomsPicker.done", defaultMessage: "Done", }) // Disable add room if booking code is either voucher or corporate cheque, or reward night is enabled const addRoomDisabledTextForSpecialRate = getValues(SEARCH_TYPE_REDEMPTION) ? config.variant === "partner-sas" ? intl.formatMessage({ id: "partnerSas.bookingWidget.roomsPicker.disabled", defaultMessage: "Multi-room booking is not available with EuroBonus points.", }) : intl.formatMessage({ id: "error.multiroomRewardNightUnavailable", defaultMessage: "Multi-room booking is not available with reward night.", }) : getValues("bookingCode.value")?.toLowerCase().startsWith("vo") && intl.formatMessage({ id: "error.multiroomBookingCodeUnavailable", defaultMessage: "Multi-room booking is not available with this booking code.", }) const isInvalid = getFieldState("rooms").invalid || roomsValue.some((room) => room.childrenInRoom.some((child) => child.age === undefined) ) const handleClose = useCallback(async () => { const isValid = await trigger("rooms") if (isValid) onClose() }, [trigger, onClose]) const handleAddRoom = useCallback(() => { setValue("rooms", [...roomsValue, { adults: 1, childrenInRoom: [] }], { shouldValidate: true, shouldDirty: true, }) }, [roomsValue, setValue]) const handleRemoveRoom = useCallback( (index: number) => { const updatedRooms = roomsValue.filter((_, i) => i !== index) setValue("rooms", updatedRooms, { shouldValidate: true, shouldDirty: true, }) if (updatedRooms.length === 1) { trigger("bookingCode.value") trigger(SEARCH_TYPE_REDEMPTION) } }, [roomsValue, trigger, setValue] ) // Validate rooms when they change useEffect(() => { const fieldState = getFieldState("rooms") if (fieldState.invalid) trigger("rooms") }, [roomsValue, getFieldState, trigger]) const canAddRooms = rooms.length < MAX_ROOMS const addRoomButtonDisabled = !!addRoomDisabledTextForSpecialRate || !canAddRooms return ( <>
{rooms.map((room, index) => ( ))} {!isDesktop && ( <>
{addRoomDisabledTextForSpecialRate && (
{addRoomDisabledTextForSpecialRate}
)} )}
) }