diff --git a/components/Forms/BookingWidget/schema.ts b/components/Forms/BookingWidget/schema.ts
index 9541abd42..cfa3cb03f 100644
--- a/components/Forms/BookingWidget/schema.ts
+++ b/components/Forms/BookingWidget/schema.ts
@@ -2,17 +2,17 @@ import { z } from "zod"
import type { Location } from "@/types/trpc/routers/hotel/locations"
-export const guestRoomsSchema = z.array(
- z.object({
- adults: z.number().default(1),
- children: z.array(
- z.object({
- age: z.number().nonnegative(),
- bed: z.number(),
- })
- ),
- })
-)
+export const guestRoomSchema = z.object({
+ adults: z.number().default(1),
+ children: z.array(
+ z.object({
+ age: z.number().nonnegative(),
+ bed: z.number(),
+ })
+ ),
+})
+
+export const guestRoomsSchema = z.array(guestRoomSchema)
export const bookingWidgetSchema = z.object({
bookingCode: z.string(), // Update this as required when working with booking codes component
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/AdultSelector/adult-selector.module.css b/components/GuestsRoomsPicker/AdultSelector/adult-selector.module.css
similarity index 100%
rename from components/GuestsRoomsPicker/GuestsRoomPicker/AdultSelector/adult-selector.module.css
rename to components/GuestsRoomsPicker/AdultSelector/adult-selector.module.css
diff --git a/components/GuestsRoomsPicker/AdultSelector/index.tsx b/components/GuestsRoomsPicker/AdultSelector/index.tsx
new file mode 100644
index 000000000..b591e7eb0
--- /dev/null
+++ b/components/GuestsRoomsPicker/AdultSelector/index.tsx
@@ -0,0 +1,75 @@
+"use client"
+
+import { useFormContext } from "react-hook-form"
+import { useIntl } from "react-intl"
+
+import { guestsRoomsStore } from "@/stores/guests-rooms"
+
+import Button from "@/components/TempDesignSystem/Button"
+import Caption from "@/components/TempDesignSystem/Text/Caption"
+
+import styles from "./adult-selector.module.css"
+
+import { BedTypeEnum } from "@/types/components/bookingWidget/enums"
+import { AdultSelectorProps } from "@/types/components/bookingWidget/guestsRoomsPicker"
+
+export default function AdultSelector({ roomIndex = 0 }: AdultSelectorProps) {
+ const intl = useIntl()
+ const adultsLabel = intl.formatMessage({ id: "Adults" })
+ const { setValue } = useFormContext()
+ const { adults, children } = guestsRoomsStore().rooms[roomIndex]
+ const { increaseAdults, decreaseAdults } = guestsRoomsStore()
+
+ function increaseAdultsCount(roomIndex: number) {
+ if (adults < 6) {
+ increaseAdults(roomIndex)
+ setValue(`rooms.${roomIndex}.adults`, adults + 1)
+ }
+ }
+
+ function decreaseAdultsCount(roomIndex: number) {
+ if (adults > 1) {
+ decreaseAdults(roomIndex)
+ setValue(`rooms.${roomIndex}.adults`, adults - 1)
+ let inAdultsBed = 0
+ let toUpdateIndex = -1
+ children.forEach((child, index) => {
+ if (child.bed == BedTypeEnum["In adults bed"]) {
+ inAdultsBed = inAdultsBed + 1
+ if (inAdultsBed > adults - 1) toUpdateIndex = index
+ }
+ })
+ if (toUpdateIndex != -1) {
+ setValue(
+ `rooms.${roomIndex}.children.${toUpdateIndex}.bed`,
+ children[toUpdateIndex].age < 3 ? 1 : 2
+ )
+ }
+ }
+ }
+
+ return (
+
+ {adultsLabel}
+
+ {adults}
+
+
+ )
+}
diff --git a/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx
new file mode 100644
index 000000000..85f37f9ce
--- /dev/null
+++ b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx
@@ -0,0 +1,131 @@
+import { useFormContext } from "react-hook-form"
+import { useIntl } from "react-intl"
+
+import { guestsRoomsStore } from "@/stores/guests-rooms"
+
+import Select from "@/components/TempDesignSystem/Select"
+
+import { BedTypeEnum } from "@/types/components/bookingWidget/enums"
+import {
+ ChildBed,
+ ChildInfoSelectorProps,
+} from "@/types/components/bookingWidget/guestsRoomsPicker"
+
+export default function ChildInfoSelector({
+ child = { age: -1, bed: -1 },
+ index = 0,
+ roomIndex = 0,
+}: ChildInfoSelectorProps) {
+ const intl = useIntl()
+ const ageLabel = intl.formatMessage({ id: "Age" })
+ const ageReqdErrMsg = intl.formatMessage({ id: "Child age is required" })
+ const bedLabel = intl.formatMessage({ id: "Bed" })
+ const { setValue } = useFormContext()
+ const { adults, childrenInAdultsBed } = guestsRoomsStore().rooms[roomIndex]
+ const {
+ isValidated,
+ updateChildAge,
+ updateChildBed,
+ increaseChildInAdultsBed,
+ decreaseChildInAdultsBed,
+ } = guestsRoomsStore()
+
+ const ageList = [
+ { label: "0", value: 0 },
+ { label: "1", value: 1 },
+ { label: "2", value: 2 },
+ { label: "3", value: 3 },
+ { label: "4", value: 4 },
+ { label: "5", value: 5 },
+ { label: "6", value: 6 },
+ { label: "7", value: 7 },
+ { label: "8", value: 8 },
+ { label: "9", value: 9 },
+ { label: "10", value: 10 },
+ { label: "11", value: 11 },
+ { label: "12", value: 12 },
+ ]
+
+ function updateSelectedAge(age: number) {
+ updateChildAge(age, roomIndex, index)
+ setValue(`rooms.${roomIndex}.children.${index}.age`, age, {
+ shouldTouch: true,
+ })
+ const availableBedTypes = getAvailableBeds(age)
+ updateSelectedBed(availableBedTypes[0].value)
+ }
+
+ function updateSelectedBed(bed: number) {
+ if (bed == BedTypeEnum["In adults bed"] && childrenInAdultsBed < adults) {
+ increaseChildInAdultsBed(roomIndex)
+ } else if (child.bed == BedTypeEnum["In adults bed"]) {
+ decreaseChildInAdultsBed(roomIndex)
+ }
+ updateChildBed(bed, roomIndex, index)
+ setValue(`rooms.${roomIndex}.children.${index}.bed`, bed)
+ }
+
+ const allBedTypes: ChildBed[] = [
+ {
+ label: intl.formatMessage({ id: "In adults bed" }),
+ value: BedTypeEnum["In adults bed"],
+ },
+ {
+ label: intl.formatMessage({ id: "In crib" }),
+ value: BedTypeEnum["In crib"],
+ },
+ {
+ label: intl.formatMessage({ id: "In extra bed" }),
+ value: BedTypeEnum["In extra bed"],
+ },
+ ]
+
+ function getAvailableBeds(age: number) {
+ let availableBedTypes: ChildBed[] = []
+ if (age <= 5 && (adults > childrenInAdultsBed || child.bed === 0)) {
+ availableBedTypes.push(allBedTypes[0])
+ }
+ if (age < 3) {
+ availableBedTypes.push(allBedTypes[1])
+ }
+ if (age > 2) {
+ availableBedTypes.push(allBedTypes[2])
+ }
+ return availableBedTypes
+ }
+
+ return (
+ <>
+
+
+
+ {child.age !== -1 ? (
+
+ >
+ )
+}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/child-selector.module.css b/components/GuestsRoomsPicker/ChildSelector/child-selector.module.css
similarity index 100%
rename from components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/child-selector.module.css
rename to components/GuestsRoomsPicker/ChildSelector/child-selector.module.css
diff --git a/components/GuestsRoomsPicker/ChildSelector/index.tsx b/components/GuestsRoomsPicker/ChildSelector/index.tsx
new file mode 100644
index 000000000..e9d8ff625
--- /dev/null
+++ b/components/GuestsRoomsPicker/ChildSelector/index.tsx
@@ -0,0 +1,68 @@
+import { useFormContext } from "react-hook-form"
+import { useIntl } from "react-intl"
+
+import { guestsRoomsStore } from "@/stores/guests-rooms"
+
+import Button from "@/components/TempDesignSystem/Button"
+import Caption from "@/components/TempDesignSystem/Text/Caption"
+
+import ChildInfoSelector from "./ChildInfoSelector"
+
+import styles from "./child-selector.module.css"
+
+import { ChildSelectorProps } from "@/types/components/bookingWidget/guestsRoomsPicker"
+
+export default function ChildSelector({ roomIndex = 0 }: ChildSelectorProps) {
+ const intl = useIntl()
+ const childrenLabel = intl.formatMessage({ id: "Children" })
+ const { setValue } = useFormContext()
+ const children = guestsRoomsStore().rooms[roomIndex].children
+ const { increaseChildren, decreaseChildren, childCount } = guestsRoomsStore()
+
+ function updateChildrenCount(direction: string, roomIndex: number) {
+ if (direction == "up" && children.length < 5) {
+ increaseChildren(roomIndex)
+ setValue(`rooms.${roomIndex}.children.${children.length}`, {
+ age: -1,
+ bed: -1,
+ })
+ } else if (children.length > 0) {
+ decreaseChildren(roomIndex)
+ let newChildrenList = JSON.parse(JSON.stringify(children))
+ newChildrenList.pop()
+ setValue(`rooms.${roomIndex}.children`, newChildrenList)
+ }
+ }
+
+ return (
+ <>
+
+ {childrenLabel}
+
+ {children.length}
+
+
+ {children.map((child, index) => (
+
+
+
+ ))}
+ >
+ )
+}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/AdultSelector/index.tsx b/components/GuestsRoomsPicker/GuestsRoomPicker/AdultSelector/index.tsx
deleted file mode 100644
index f4bf255b5..000000000
--- a/components/GuestsRoomsPicker/GuestsRoomPicker/AdultSelector/index.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { useIntl } from "react-intl"
-
-import Button from "@/components/TempDesignSystem/Button"
-import Caption from "@/components/TempDesignSystem/Text/Caption"
-
-import styles from "./adult-selector.module.css"
-
-import { AdultSelectorProps } from "@/types/components/bookingWidget/guestsRoomsPicker"
-
-export default function AdultSelector({
- adults = 1,
- updateAdults = (count: number) => {},
-}: AdultSelectorProps) {
- const intl = useIntl()
- const adultsLabel = intl.formatMessage({ id: "Adults" })
-
- function decreaseAdults() {
- if (adults > 1) {
- updateAdults(adults - 1)
- }
- }
- function increaseAdults() {
- if (adults < 6) {
- updateAdults(adults + 1)
- }
- }
-
- return (
-
- {adultsLabel}
-
- {adults}
-
-
- )
-}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/ChildInfoSelector.tsx b/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/ChildInfoSelector.tsx
deleted file mode 100644
index 698d74756..000000000
--- a/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/ChildInfoSelector.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { useIntl } from "react-intl"
-
-import Select from "@/components/TempDesignSystem/Select"
-
-import {
- Child,
- ChildInfoSelectorProps,
-} from "@/types/components/bookingWidget/guestsRoomsPicker"
-
-export default function ChildInfoSelector({
- child = { age: -1, bed: -1 },
- index = 0,
- availableBedTypes = [
- { label: "In adults bed", value: 0 },
- { label: "In crib", value: 1 },
- { label: "In extra bed", value: 2 },
- ],
- updateChild = (child: Child, index: number) => {},
- isValid,
-}: ChildInfoSelectorProps) {
- const intl = useIntl()
- const ageLabel = intl.formatMessage({ id: "Age" })
- const ageReqdErrMsg = intl.formatMessage({ id: "Child age is required" })
- const bedLabel = intl.formatMessage({ id: "Bed" })
-
- const ageList = [
- { label: "0", value: 0 },
- { label: "1", value: 1 },
- { label: "2", value: 2 },
- { label: "3", value: 3 },
- { label: "4", value: 4 },
- { label: "5", value: 5 },
- { label: "6", value: 6 },
- { label: "7", value: 7 },
- { label: "8", value: 8 },
- { label: "9", value: 9 },
- { label: "10", value: 10 },
- { label: "11", value: 11 },
- { label: "12", value: 12 },
- ]
-
- function handleOnSelect(selectedKey: number, childInfo: string) {
- if (childInfo == "age") {
- child.age = selectedKey
- } else if (childInfo == "bed") {
- child.bed = selectedKey
- }
- updateChild(child, index)
- }
-
- return (
- <>
-
-
-
- {child.age !== -1 ? (
-
- >
- )
-}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/index.tsx b/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/index.tsx
deleted file mode 100644
index 58e79c876..000000000
--- a/components/GuestsRoomsPicker/GuestsRoomPicker/ChildSelector/index.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import { useIntl } from "react-intl"
-
-import Button from "@/components/TempDesignSystem/Button"
-import Caption from "@/components/TempDesignSystem/Text/Caption"
-
-import ChildInfoSelector from "./ChildInfoSelector"
-
-import styles from "./child-selector.module.css"
-
-import {
- Child,
- ChildBed,
- ChildSelectorProps,
-} from "@/types/components/bookingWidget/guestsRoomsPicker"
-
-export default function ChildSelector({
- roomChildren = [],
- adultCount = 1,
- updateChildren = (children: Child[]) => {},
- isValid,
-}: ChildSelectorProps) {
- const intl = useIntl()
- const childrenLabel = intl.formatMessage({ id: "Children" })
-
- function decreaseChildren() {
- if (roomChildren.length > 0) {
- roomChildren.pop()
- updateChildren(roomChildren)
- }
- }
-
- function increaseChildren() {
- if (roomChildren.length < 5) {
- roomChildren.push({ age: -1, bed: -1 })
- updateChildren(roomChildren)
- }
- }
-
- function updateChildInfo(child: Child, index: number) {
- roomChildren[index] = child
- updateChildren(roomChildren)
- }
-
- const childInAdultsBedIndices: number[] = []
- let availableInAdultsBed = adultCount
- const availableBedTypes: ChildBed[] = [
- { label: intl.formatMessage({ id: "In adults bed" }), value: 0 },
- { label: intl.formatMessage({ id: "In crib" }), value: 1 },
- { label: intl.formatMessage({ id: "In extra bed" }), value: 2 },
- ]
-
- const childBedTypes: ChildBed[][] = []
- for (let i = 0; i < roomChildren.length; i++) {
- if (roomChildren[i].bed == 0 && availableInAdultsBed > 0) {
- childInAdultsBedIndices.push(i)
- availableInAdultsBed = availableInAdultsBed - 1
- }
- }
- roomChildren.forEach((child, index) => {
- let types: typeof availableBedTypes = []
- let selectedBed: boolean = false
- if (
- child.age <= 5 &&
- (availableInAdultsBed > 0 || childInAdultsBedIndices.indexOf(index) != -1)
- ) {
- types.push(availableBedTypes[0])
- if (child.bed == 0) {
- selectedBed = true
- }
- }
- if (child.age < 3) {
- types.push(availableBedTypes[1])
- if (child.bed == 1) {
- selectedBed = true
- }
- }
- if (child.age > 2) {
- types.push(availableBedTypes[2])
- if (child.bed == 2) {
- selectedBed = true
- }
- }
- childBedTypes[index] = types
- if (!selectedBed) {
- child.bed = types[0].value
- }
- })
-
- return (
- <>
-
- {childrenLabel}
-
- {roomChildren.length}
-
-
- {roomChildren.map((child, index) => (
-
-
-
- ))}
- >
- )
-}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/guests-room-picker.module.css b/components/GuestsRoomsPicker/GuestsRoomPicker/guests-room-picker.module.css
deleted file mode 100644
index 59ab72488..000000000
--- a/components/GuestsRoomsPicker/GuestsRoomPicker/guests-room-picker.module.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.container {
- display: grid;
- gap: var(--Spacing-x2);
- padding-bottom: var(--Spacing-x1);
-}
diff --git a/components/GuestsRoomsPicker/GuestsRoomPicker/index.tsx b/components/GuestsRoomsPicker/GuestsRoomPicker/index.tsx
deleted file mode 100644
index 4cf4ba766..000000000
--- a/components/GuestsRoomsPicker/GuestsRoomPicker/index.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-"use client"
-
-import { useIntl } from "react-intl"
-
-import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
-
-import AdultSelector from "./AdultSelector"
-import ChildSelector from "./ChildSelector"
-
-import styles from "./guests-room-picker.module.css"
-
-import {
- Child,
- GuestsRoom,
- GuestsRoomPickerProps,
-} from "@/types/components/bookingWidget/guestsRoomsPicker"
-
-export default function GuestsRoomPicker({
- handleOnSelect = (selected: GuestsRoom, index: number) => {},
- room = { adults: 1, children: [] },
- index = 1,
- isValid,
-}: GuestsRoomPickerProps) {
- const intl = useIntl()
- const roomLabel = intl.formatMessage({ id: "Room" })
-
- function updateAdults(count: number) {
- room.adults = count
- handleOnSelect(room, index)
- }
-
- function updateChildren(children: Child[]) {
- room.children = children
- handleOnSelect(room, index)
- }
-
- return (
-
-
- {roomLabel} {index + 1}
-
-
-
-
- )
-}
diff --git a/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx b/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx
index 7e8f4cabf..6eb6022b4 100644
--- a/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx
+++ b/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx
@@ -1,83 +1,47 @@
"use client"
-import { useState } from "react"
import { useIntl } from "react-intl"
-import useLang from "@/hooks/useLang"
+import { guestsRoomsStore } from "@/stores/guests-rooms"
+import { guestRoomsSchema } from "../Forms/BookingWidget/schema"
import Button from "../TempDesignSystem/Button"
import Divider from "../TempDesignSystem/Divider"
-import GuestsRoomPicker from "./GuestsRoomPicker"
+import Subtitle from "../TempDesignSystem/Text/Subtitle"
+import AdultSelector from "./AdultSelector"
+import ChildSelector from "./ChildSelector"
import styles from "./guests-rooms-picker.module.css"
-import {
- GuestsRoom,
- GuestsRoomsPickerProps,
-} from "@/types/components/bookingWidget/guestsRoomsPicker"
+import { GuestsRoomsPickerProps } from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function GuestsRoomsPicker({
- handleOnSelect,
- initialSelected = [
- {
- adults: 1,
- children: [],
- },
- ],
closePicker,
- isValid,
}: GuestsRoomsPickerProps) {
- const lang = useLang()
const intl = useIntl()
const doneLabel = intl.formatMessage({ id: "Done" })
- const [selectedGuests, setSelectedGuests] =
- useState(initialSelected)
- function handleSelectRoomGuests(
- selectedGuestsRoom: GuestsRoom,
- index: number
- ) {
- let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
- updatedSelectedGuests[index] = selectedGuestsRoom
- handleOnSelect(updatedSelectedGuests)
- setSelectedGuests(updatedSelectedGuests)
- }
+ const guestsData = guestsRoomsStore().rooms
+ const guestRoomsValidData = guestRoomsSchema.safeParse(guestsData)
+ const isInValid = !guestRoomsValidData.success
+ const roomLabel = intl.formatMessage({ id: "Room" })
- // Not in MVP scope
- function addRoom() {
- if (selectedGuests.length < 4) {
- let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
- updatedSelectedGuests.push({
- adults: 1,
- children: [],
- })
- setSelectedGuests(updatedSelectedGuests)
- handleOnSelect(updatedSelectedGuests)
- }
- }
-
- // Not in MVP scope
- function removeRoom(index: number) {
- if (selectedGuests.length > 1) {
- let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
- updatedSelectedGuests.splice(index, 1)
- setSelectedGuests(updatedSelectedGuests)
- handleOnSelect(updatedSelectedGuests)
- }
- }
+ // Not in MVP
+ // const { increaseRoom, decreaseRoom } = guestsRoomsStore()
return (
<>
- {selectedGuests.map((room, index) => (
+ {guestsData.map((room, index) => (
-
+
+
+ {roomLabel} {index + 1}
+
+
+
+
{/* Not in MVP
{index > 0 ? (
-