fix(SW-1043): added hook with the scroll logic
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { animate, motion, scroll, useAnimate } from "framer-motion"
|
import { useCallback, useEffect, useRef, useState } from "react"
|
||||||
import { useEffect, useRef, useState } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||||
@@ -14,6 +13,55 @@ import styles from "./sectionAccordion.module.css"
|
|||||||
import type { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion"
|
import type { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion"
|
||||||
import { StepEnum } from "@/types/enums/step"
|
import { StepEnum } from "@/types/enums/step"
|
||||||
|
|
||||||
|
function useScrollToActiveSection(
|
||||||
|
step: StepEnum,
|
||||||
|
steps: StepEnum[],
|
||||||
|
isActive: boolean
|
||||||
|
) {
|
||||||
|
const handleScroll = useCallback(() => {
|
||||||
|
const isMobile = window.matchMedia("(max-width: 768px)").matches
|
||||||
|
if (!isMobile) return
|
||||||
|
|
||||||
|
const currentElement = document.querySelector<HTMLElement>(
|
||||||
|
`[data-step="${step}"]`
|
||||||
|
)
|
||||||
|
const prevOpenElement =
|
||||||
|
document.querySelector<HTMLElement>(`[data-open="true"]`)
|
||||||
|
|
||||||
|
const currentStepIndex = steps.indexOf(step)
|
||||||
|
const prevStep = prevOpenElement?.dataset.step as StepEnum
|
||||||
|
const prevStepIndex = steps.indexOf(prevStep)
|
||||||
|
|
||||||
|
if (currentElement) {
|
||||||
|
const BOOKING_WIDGET_OFFSET = 71
|
||||||
|
|
||||||
|
const prevElementContent = prevOpenElement?.querySelector("header + div")
|
||||||
|
|
||||||
|
let collapsedSpace = 0
|
||||||
|
if (prevElementContent && prevStepIndex < currentStepIndex) {
|
||||||
|
collapsedSpace = prevElementContent.clientHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentElementTop =
|
||||||
|
currentElement.getBoundingClientRect().top + window.scrollY
|
||||||
|
|
||||||
|
const scrollTarget = Math.round(
|
||||||
|
currentElementTop - BOOKING_WIDGET_OFFSET - collapsedSpace
|
||||||
|
)
|
||||||
|
|
||||||
|
window.scrollTo({
|
||||||
|
top: scrollTarget,
|
||||||
|
behavior: "smooth",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [step, steps])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isActive) return
|
||||||
|
handleScroll()
|
||||||
|
}, [isActive, handleScroll])
|
||||||
|
}
|
||||||
|
|
||||||
export default function SectionAccordion({
|
export default function SectionAccordion({
|
||||||
children,
|
children,
|
||||||
header,
|
header,
|
||||||
@@ -22,6 +70,7 @@ export default function SectionAccordion({
|
|||||||
}: React.PropsWithChildren<SectionAccordionProps>) {
|
}: React.PropsWithChildren<SectionAccordionProps>) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const currentStep = useEnterDetailsStore((state) => state.currentStep)
|
const currentStep = useEnterDetailsStore((state) => state.currentStep)
|
||||||
|
const steps = useEnterDetailsStore((state) => state.steps)
|
||||||
const [isComplete, setIsComplete] = useState(false)
|
const [isComplete, setIsComplete] = useState(false)
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
const isValid = useEnterDetailsStore((state) => state.isValid[step])
|
const isValid = useEnterDetailsStore((state) => state.isValid[step])
|
||||||
@@ -35,6 +84,8 @@ export default function SectionAccordion({
|
|||||||
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
||||||
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
||||||
|
|
||||||
|
useScrollToActiveSection(step, steps, currentStep === step)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (step === StepEnum.selectBed && bedType) {
|
if (step === StepEnum.selectBed && bedType) {
|
||||||
setTitle(bedType.description)
|
setTitle(bedType.description)
|
||||||
|
|||||||
@@ -42,16 +42,6 @@ export function extractGuestFromUser(user: NonNullable<SafeUser>) {
|
|||||||
|
|
||||||
export function navigate(step: StepEnum, searchParams: string) {
|
export function navigate(step: StepEnum, searchParams: string) {
|
||||||
window.history.pushState({ step }, "", `${step}?${searchParams}`)
|
window.history.pushState({ step }, "", `${step}?${searchParams}`)
|
||||||
|
|
||||||
const element = document.querySelector(`[data-step='${step}']`)
|
|
||||||
const isMobile = window.matchMedia("(max-width: 768px)").matches
|
|
||||||
if (element && isMobile) {
|
|
||||||
element.addEventListener(
|
|
||||||
"transitionend",
|
|
||||||
() => element?.scrollIntoView({ behavior: "smooth" }),
|
|
||||||
{ once: true }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkIsSameBooking(prev: BookingData, next: BookingData) {
|
export function checkIsSameBooking(prev: BookingData, next: BookingData) {
|
||||||
|
|||||||
Reference in New Issue
Block a user