Feat/SW-1077 enter details edit room * feat(SW-1077): persist state when changing rooms * fix: issue with step state when closing accordion and transition to correct room when modifying step Approved-by: Pontus Dreij
142 lines
4.1 KiB
TypeScript
142 lines
4.1 KiB
TypeScript
"use client"
|
|
import { useEffect, useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
import {
|
|
selectBookingProgress,
|
|
selectNextStep,
|
|
selectRoom,
|
|
selectRoomStatus,
|
|
} from "@/stores/enter-details/helpers"
|
|
|
|
import { CheckIcon, ChevronDownIcon } from "@/components/Icons"
|
|
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
|
|
import styles from "./sectionAccordion.module.css"
|
|
|
|
import type { SectionAccordionProps } from "@/types/components/hotelReservation/selectRate/sectionAccordion"
|
|
import { StepEnum } from "@/types/enums/step"
|
|
|
|
export default function SectionAccordion({
|
|
children,
|
|
header,
|
|
label,
|
|
step,
|
|
roomIndex,
|
|
}: React.PropsWithChildren<SectionAccordionProps>) {
|
|
const intl = useIntl()
|
|
const roomStatus = useEnterDetailsStore((state) =>
|
|
selectRoomStatus(state, roomIndex)
|
|
)
|
|
|
|
const setStep = useEnterDetailsStore((state) => state.actions.setStep)
|
|
const { bedType, breakfast } = useEnterDetailsStore((state) =>
|
|
selectRoom(state, roomIndex)
|
|
)
|
|
const { roomStatuses, currentRoomIndex } = useEnterDetailsStore((state) =>
|
|
selectBookingProgress(state)
|
|
)
|
|
|
|
const [isComplete, setIsComplete] = useState(false)
|
|
const [isOpen, setIsOpen] = useState(false)
|
|
const isValid = roomStatus.steps[step]?.isValid ?? false
|
|
|
|
const [title, setTitle] = useState(label)
|
|
|
|
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
|
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
|
|
|
// useScrollToActiveSection(step, steps, roomStatus.currentStep === step)
|
|
|
|
useEffect(() => {
|
|
if (step === StepEnum.selectBed && bedType) {
|
|
setTitle(bedType.description)
|
|
}
|
|
// If breakfast step, check if an option has been selected
|
|
if (step === StepEnum.breakfast && breakfast !== undefined) {
|
|
if (breakfast === false) {
|
|
setTitle(noBreakfastTitle)
|
|
} else {
|
|
setTitle(breakfastTitle)
|
|
}
|
|
}
|
|
}, [bedType, breakfast, setTitle, step, breakfastTitle, noBreakfastTitle])
|
|
|
|
useEffect(() => {
|
|
setIsComplete(isValid)
|
|
}, [isValid, setIsComplete])
|
|
|
|
useEffect(() => {
|
|
setIsOpen(roomStatus.currentStep === step && currentRoomIndex === roomIndex)
|
|
}, [currentRoomIndex, roomIndex, roomStatus.currentStep, setIsOpen, step])
|
|
|
|
function onModify() {
|
|
setStep(step, roomIndex)
|
|
}
|
|
|
|
function close() {
|
|
setIsOpen(false)
|
|
|
|
const nextRoom = roomStatuses.find((room) => !room.isComplete)
|
|
const nextStep = nextRoom
|
|
? Object.values(nextRoom.steps).find((step) => !step.isValid)?.step
|
|
: null
|
|
|
|
if (nextRoom !== undefined && nextStep !== undefined) {
|
|
setStep(nextStep, roomStatuses.indexOf(nextRoom))
|
|
} else {
|
|
// Time for payment, collapse any open step
|
|
setStep(null)
|
|
}
|
|
}
|
|
|
|
const textColor =
|
|
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
|
return (
|
|
<div
|
|
className={styles.accordion}
|
|
data-section-open={isOpen}
|
|
data-step={step}
|
|
>
|
|
<div className={styles.iconWrapper}>
|
|
<div className={styles.circle} data-checked={isComplete}>
|
|
{isComplete ? (
|
|
<CheckIcon color="white" height="16" width="16" />
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
<header className={styles.header}>
|
|
<button
|
|
onClick={isOpen ? close : onModify}
|
|
disabled={!isComplete}
|
|
className={styles.modifyButton}
|
|
>
|
|
<Footnote
|
|
className={styles.title}
|
|
asChild
|
|
textTransform="uppercase"
|
|
type="label"
|
|
color={textColor}
|
|
>
|
|
<h2>{header}</h2>
|
|
</Footnote>
|
|
<Subtitle className={styles.selection} type="two" color={textColor}>
|
|
{title}
|
|
</Subtitle>
|
|
{isComplete && (
|
|
<ChevronDownIcon
|
|
className={`${styles.button} ${isOpen ? styles.buttonOpen : ""}`}
|
|
color="burgundy"
|
|
/>
|
|
)}
|
|
</button>
|
|
</header>
|
|
<div className={styles.content}>
|
|
<div className={styles.contentWrapper}>{children}</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|