diff --git a/components/GuestsRoomsPicker/AdultSelector/index.tsx b/components/GuestsRoomsPicker/AdultSelector/index.tsx index fc408befb..d95258c5e 100644 --- a/components/GuestsRoomsPicker/AdultSelector/index.tsx +++ b/components/GuestsRoomsPicker/AdultSelector/index.tsx @@ -21,11 +21,12 @@ import { export default function AdultSelector({ roomIndex = 0 }: AdultSelectorProps) { const intl = useIntl() const adultsLabel = intl.formatMessage({ id: "Adults" }) - const { trigger, setValue } = useFormContext() + const { setValue } = useFormContext() const { adults, children, childrenInAdultsBed } = useGuestsRoomsStore( - (state) => state.rooms[roomIndex] + (state) => ({ ...state.rooms[roomIndex] }) ) - const { increaseAdults, decreaseAdults } = useGuestsRoomsStore() + const increaseAdults = useGuestsRoomsStore.use.increaseAdults() + const decreaseAdults = useGuestsRoomsStore.use.decreaseAdults() function increaseAdultsCount(roomIndex: number) { if (adults < 6) { @@ -45,9 +46,10 @@ export default function AdultSelector({ roomIndex = 0 }: AdultSelectorProps) { if (toUpdateIndex != -1) { setValue( `rooms.${roomIndex}.children.${toUpdateIndex}.bed`, - children[toUpdateIndex].age < 3 ? 1 : 2 + children[toUpdateIndex].age < 3 + ? BedTypeEnum.IN_CRIB + : BedTypeEnum.IN_EXTRA_BED ) - trigger() } } } diff --git a/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx index 8106e4b4a..5dd75c64a 100644 --- a/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx +++ b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx @@ -30,13 +30,13 @@ export default function ChildInfoSelector({ const { adults, childrenInAdultsBed } = useGuestsRoomsStore( (state) => state.rooms[roomIndex] ) - const { - isValidated, - updateChildAge, - updateChildBed, - increaseChildInAdultsBed, - decreaseChildInAdultsBed, - } = useGuestsRoomsStore() + const isValidated = useGuestsRoomsStore.use.isValidated() + const updateChildAge = useGuestsRoomsStore.use.updateChildAge() + const updateChildBed = useGuestsRoomsStore.use.updateChildBed() + const increaseChildInAdultsBed = + useGuestsRoomsStore.use.increaseChildInAdultsBed() + const decreaseChildInAdultsBed = + useGuestsRoomsStore.use.decreaseChildInAdultsBed() const ageList = Array.from(Array(13).keys()).map((age) => ({ label: `${age}`, @@ -48,6 +48,7 @@ export default function ChildInfoSelector({ setValue(`rooms.${roomIndex}.children.${index}.age`, age) const availableBedTypes = getAvailableBeds(age) updateSelectedBed(availableBedTypes[0].value) + trigger("rooms") } function updateSelectedBed(bed: number) { @@ -58,7 +59,6 @@ export default function ChildInfoSelector({ } updateChildBed(bed, roomIndex, index) setValue(`rooms.${roomIndex}.children.${index}.bed`, bed) - trigger() } const allBedTypes: ChildBed[] = [ @@ -101,7 +101,7 @@ export default function ChildInfoSelector({ aria-label={ageLabel} value={child.age} onSelect={(key) => { - updateSelectedAge(parseInt(key.toString())) + updateSelectedAge(key as number) }} name={`rooms.${roomIndex}.children.${index}.age`} placeholder={ageLabel} @@ -115,7 +115,7 @@ export default function ChildInfoSelector({ aria-label={bedLabel} value={child.bed} onSelect={(key) => { - updateSelectedBed(parseInt(key.toString())) + updateSelectedBed(key as number) }} name={`rooms.${roomIndex}.children.${index}.age`} placeholder={bedLabel} diff --git a/components/GuestsRoomsPicker/ChildSelector/index.tsx b/components/GuestsRoomsPicker/ChildSelector/index.tsx index 04dd449af..eee62bcd0 100644 --- a/components/GuestsRoomsPicker/ChildSelector/index.tsx +++ b/components/GuestsRoomsPicker/ChildSelector/index.tsx @@ -21,8 +21,11 @@ export default function ChildSelector({ roomIndex = 0 }: ChildSelectorProps) { const intl = useIntl() const childrenLabel = intl.formatMessage({ id: "Children" }) const { setValue, trigger } = useFormContext() - const { children } = useGuestsRoomsStore((state) => state.rooms[roomIndex]) - const { increaseChildren, decreaseChildren } = useGuestsRoomsStore() + const children = useGuestsRoomsStore( + (state) => state.rooms[roomIndex].children + ) + const increaseChildren = useGuestsRoomsStore.use.increaseChildren() + const decreaseChildren = useGuestsRoomsStore.use.decreaseChildren() function increaseChildrenCount(roomIndex: number) { if (children.length < 5) { @@ -36,11 +39,9 @@ export default function ChildSelector({ roomIndex = 0 }: ChildSelectorProps) { } function decreaseChildrenCount(roomIndex: number) { if (children.length > 0) { - decreaseChildren(roomIndex) - let newChildrenList = JSON.parse(JSON.stringify(children)) - newChildrenList.pop() + const newChildrenList = decreaseChildren(roomIndex) setValue(`rooms.${roomIndex}.children`, newChildrenList) - trigger() + trigger("rooms") } } diff --git a/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx b/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx index 7d952049e..78e67704b 100644 --- a/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx +++ b/components/GuestsRoomsPicker/GuestsRoomsPicker.tsx @@ -4,7 +4,6 @@ import { useIntl } from "react-intl" import { useGuestsRoomsStore } from "@/stores/guests-rooms" -import { guestRoomsSchema } from "../Forms/BookingWidget/schema" import { CloseLarge } from "../Icons" import Button from "../TempDesignSystem/Button" import Divider from "../TempDesignSystem/Divider" @@ -26,7 +25,7 @@ export default function GuestsRoomsPicker({ const { getFieldState } = useFormContext() - const rooms = useGuestsRoomsStore((state) => state.rooms) + const rooms = useGuestsRoomsStore.use.rooms() // Not in MVP // const { increaseRoom, decreaseRoom } = guestsRoomsStore() diff --git a/components/GuestsRoomsPicker/index.tsx b/components/GuestsRoomsPicker/index.tsx index 8a1b4361d..5819ac11b 100644 --- a/components/GuestsRoomsPicker/index.tsx +++ b/components/GuestsRoomsPicker/index.tsx @@ -15,8 +15,10 @@ import styles from "./guests-rooms-picker.module.css" export default function GuestsRoomsPickerForm() { const intl = useIntl() const [isOpen, setIsOpen] = useState(false) - const { rooms, adultCount, childCount, setIsValidated } = - useGuestsRoomsStore() + const rooms = useGuestsRoomsStore.use.rooms() + const adultCount = useGuestsRoomsStore.use.adultCount() + const childCount = useGuestsRoomsStore.use.childCount() + const setIsValidated = useGuestsRoomsStore.use.setIsValidated() const ref = useRef(null) function handleOnClick() { setIsOpen((prevIsOpen) => !prevIsOpen) diff --git a/stores/guests-rooms.ts b/stores/guests-rooms.ts index 909e2f08c..617060dfe 100644 --- a/stores/guests-rooms.ts +++ b/stores/guests-rooms.ts @@ -3,6 +3,8 @@ import { produce } from "immer" import { create } from "zustand" +import { createSelectors } from "./utils" + import { BedTypeEnum } from "@/types/components/bookingWidget/enums" import { Child } from "@/types/components/bookingWidget/guestsRoomsPicker" @@ -20,17 +22,17 @@ interface GuestsRooms { increaseAdults: (roomIndex: number) => void decreaseAdults: (roomIndex: number) => void increaseChildren: (roomIndex: number) => void - decreaseChildren: (roomIndex: number) => void + decreaseChildren: (roomIndex: number) => Child[] updateChildAge: (age: number, roomIndex: number, childIndex: number) => void updateChildBed: (bed: number, roomIndex: number, childIndex: number) => void increaseChildInAdultsBed: (roomIndex: number) => void decreaseChildInAdultsBed: (roomIndex: number) => void increaseRoom: () => void decreaseRoom: (roomIndex: number) => void - setIsValidated: (status: boolean) => void + setIsValidated: (isValidated: boolean) => void } -export const useGuestsRoomsStore = create((set, get) => ({ +export const useGuestsRoomsStoreBase = create((set, get) => ({ rooms: [ { adults: 1, @@ -81,7 +83,7 @@ export const useGuestsRoomsStore = create((set, get) => ({ state.childCount = state.childCount + 1 }) ), - decreaseChildren: (roomIndex) => + decreaseChildren: (roomIndex) => { set( produce((state: GuestsRooms) => { const roomChildren = state.rooms[roomIndex].children @@ -95,7 +97,9 @@ export const useGuestsRoomsStore = create((set, get) => ({ state.rooms[roomIndex].children.pop() state.childCount = state.childCount - 1 }) - ), + ) + return get().rooms[roomIndex].children + }, updateChildAge: (age, roomIndex, childIndex) => set( produce((state: GuestsRooms) => { @@ -138,5 +142,7 @@ export const useGuestsRoomsStore = create((set, get) => ({ state.rooms.splice(roomIndex, 1) }) ), - setIsValidated: (status) => set(() => ({ isValidated: status })), + setIsValidated: (isValidated) => set(() => ({ isValidated })), })) + +export const useGuestsRoomsStore = createSelectors(useGuestsRoomsStoreBase) diff --git a/stores/utils.ts b/stores/utils.ts new file mode 100644 index 000000000..317ca8e91 --- /dev/null +++ b/stores/utils.ts @@ -0,0 +1,17 @@ +import { StoreApi, UseBoundStore } from "zustand" + +type WithSelectors = S extends { getState: () => infer T } + ? S & { use: { [K in keyof T]: () => T[K] } } + : never + +export const createSelectors = >>( + _store: S +) => { + let store = _store as WithSelectors + store.use = {} + for (let k of Object.keys(store.getState())) { + ;(store.use as any)[k] = () => store((s) => s[k as keyof typeof s]) + } + + return store +}