feat(SW-718): Created store for selectRate

This commit is contained in:
Pontus Dreij
2025-01-22 10:44:51 +01:00
parent 98793c58e3
commit 2a6c88d897
13 changed files with 168 additions and 89 deletions

View File

@@ -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}

View File

@@ -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;