108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
"use client"
|
|
import { useEffect, useState } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
|
|
import { CheckIcon, ChevronDownIcon } from "@/components/Icons"
|
|
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
import useScrollToActiveSection from "@/hooks/booking/useScrollToActiveSection"
|
|
|
|
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,
|
|
}: React.PropsWithChildren<SectionAccordionProps>) {
|
|
const intl = useIntl()
|
|
const currentStep = useEnterDetailsStore((state) => state.currentStep)
|
|
const steps = useEnterDetailsStore((state) => state.steps)
|
|
const [isComplete, setIsComplete] = useState(false)
|
|
const [isOpen, setIsOpen] = useState(false)
|
|
const isValid = useEnterDetailsStore((state) => state.isValid[step])
|
|
const navigate = useEnterDetailsStore((state) => state.actions.navigate)
|
|
const { bedType, breakfast } = useEnterDetailsStore((state) => ({
|
|
bedType: state.bedType,
|
|
breakfast: state.breakfast,
|
|
}))
|
|
const [title, setTitle] = useState(label)
|
|
|
|
const noBreakfastTitle = intl.formatMessage({ id: "No breakfast" })
|
|
const breakfastTitle = intl.formatMessage({ id: "Breakfast buffet" })
|
|
|
|
useScrollToActiveSection(step, steps, 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(currentStep === step)
|
|
}, [currentStep, setIsOpen, step])
|
|
|
|
function onModify() {
|
|
navigate(step)
|
|
}
|
|
|
|
const textColor =
|
|
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
|
return (
|
|
<div className={styles.accordion} data-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={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 && !isOpen && (
|
|
<ChevronDownIcon className={styles.button} color="burgundy" />
|
|
)}
|
|
</button>
|
|
</header>
|
|
<div className={styles.content}>
|
|
<div className={styles.contentWrapper}>{children}</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|