feat(SW-718): Created store for selectRate
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
"use client"
|
||||
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import { useCallback, useEffect, useMemo } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
import { useRateSelectionStore } from "@/stores/rate-selection"
|
||||
|
||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
import { useRateSummary } from "@/hooks/selectRate/useRateSummary"
|
||||
import { useRoomFiltering } from "@/hooks/selectRate/useRoomFiltering"
|
||||
@@ -23,14 +24,9 @@ import {
|
||||
RoomPackageCodeEnum,
|
||||
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import type { SelectRateProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
|
||||
import type {
|
||||
Rate,
|
||||
RateCode,
|
||||
} from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
import type { RoomConfiguration } from "@/server/routers/hotels/output"
|
||||
|
||||
type SelectedRates = (RateCode | undefined)[]
|
||||
|
||||
export default function Rooms({
|
||||
roomsAvailability,
|
||||
roomCategories = [],
|
||||
@@ -46,19 +42,22 @@ export default function Rooms({
|
||||
const arrivalDate = searchParams.get("fromDate")
|
||||
const departureDate = searchParams.get("toDate")
|
||||
|
||||
const { modifyRate, selectedRates, setSelectedRates } =
|
||||
useRateSelectionStore()
|
||||
|
||||
const searchedRoomsAndGuests = useMemo(
|
||||
() => parseRoomParams(searchParams),
|
||||
[searchParams]
|
||||
)
|
||||
|
||||
const [selectedRates, setSelectedRates] = useState<SelectedRates>(
|
||||
new Array(searchedRoomsAndGuests.length).fill(undefined)
|
||||
)
|
||||
|
||||
const isMultipleRooms = searchedRoomsAndGuests.length > 1
|
||||
|
||||
const intl = useIntl()
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedRates(new Array(searchedRoomsAndGuests.length).fill(undefined))
|
||||
}, [setSelectedRates, searchedRoomsAndGuests.length])
|
||||
|
||||
const visibleRooms: RoomConfiguration[] = useMemo(() => {
|
||||
const deduped = filterDuplicateRoomTypesByLowestPrice(
|
||||
roomsAvailability.roomConfigurations
|
||||
@@ -173,16 +172,11 @@ export default function Rooms({
|
||||
router.push(`select-bed?${queryParams}`)
|
||||
}
|
||||
|
||||
const setSelectedRateForRoom = useCallback(
|
||||
(index: number) => (value: React.SetStateAction<RateCode | undefined>) => {
|
||||
setSelectedRates((prev) => {
|
||||
const newRates = [...prev]
|
||||
newRates[index] =
|
||||
typeof value === "function" ? value(prev[index]) : value
|
||||
return newRates
|
||||
})
|
||||
const handleModify = useCallback(
|
||||
(index: number) => () => {
|
||||
modifyRate(index)
|
||||
},
|
||||
[]
|
||||
[modifyRate]
|
||||
)
|
||||
|
||||
const handleFilterForRoom = useCallback(
|
||||
@@ -193,6 +187,25 @@ export default function Rooms({
|
||||
[handleFilter]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
const SCROLL_OFFSET = 100
|
||||
const roomElements = document.querySelectorAll(`.${styles.roomContainer}`)
|
||||
const index = selectedRates.findIndex((rate) => rate === undefined)
|
||||
const selectedRoom = roomElements[index - 1]
|
||||
|
||||
if (selectedRoom) {
|
||||
const elementPosition = selectedRoom.getBoundingClientRect().top
|
||||
const offsetPosition = elementPosition + window.scrollY - SCROLL_OFFSET
|
||||
|
||||
window.scrollTo({
|
||||
top: offsetPosition,
|
||||
behavior: "smooth",
|
||||
})
|
||||
}
|
||||
}, 0)
|
||||
}, [selectedRates])
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
{isMultipleRooms ? (
|
||||
@@ -232,6 +245,7 @@ export default function Rooms({
|
||||
room={room}
|
||||
selectedRate={rateSummary[index]}
|
||||
roomCategories={roomCategories}
|
||||
handleModify={handleModify(index)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.roomSelectionPanel}>
|
||||
@@ -240,7 +254,6 @@ export default function Rooms({
|
||||
roomCategories={roomCategories}
|
||||
availablePackages={availablePackages}
|
||||
selectedPackages={selectedPackagesByRoom[index]}
|
||||
setSelectedRate={setSelectedRateForRoom(index)}
|
||||
hotelType={hotelType}
|
||||
handleFilter={handleFilterForRoom(index)}
|
||||
defaultPackages={defaultPackages}
|
||||
@@ -256,7 +269,6 @@ export default function Rooms({
|
||||
roomCategories={roomCategories}
|
||||
availablePackages={availablePackages}
|
||||
selectedPackages={selectedPackagesByRoom[0]}
|
||||
setSelectedRate={setSelectedRateForRoom(0)}
|
||||
hotelType={hotelType}
|
||||
handleFilter={handleFilterForRoom(0)}
|
||||
defaultPackages={defaultPackages}
|
||||
|
||||
@@ -10,10 +10,9 @@
|
||||
.roomContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x2);
|
||||
border: 1px solid var(--Base-Border-Subtle);
|
||||
border-radius: var(--Corner-radius-Large);
|
||||
padding: var(--Spacing-x2) var(--Spacing-x2) 0 var(--Spacing-x2);
|
||||
padding: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.roomSelectionPanel {
|
||||
@@ -24,6 +23,7 @@
|
||||
opacity 0.3s ease,
|
||||
grid-template-rows 0.5s ease;
|
||||
height: 0;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.roomSelectionPanel > * {
|
||||
@@ -48,9 +48,11 @@
|
||||
grid-template-rows: 1fr;
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
padding-bottom: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.roomSelectionPanelContainer[data-selected="true"] .roomSelectionPanel {
|
||||
display: none;
|
||||
}
|
||||
.roomSelectionPanelContainer[data-active-panel="true"] .roomSelectionPanel {
|
||||
grid-template-rows: 1fr;
|
||||
opacity: 1;
|
||||
|
||||
Reference in New Issue
Block a user