Files
web/components/HotelReservation/SelectRate/RoomList/FlexibilityOption/index.tsx
2025-01-30 11:19:22 +01:00

179 lines
5.2 KiB
TypeScript

"use client"
import { useSearchParams } from "next/navigation"
import { useEffect, useRef } from "react"
import { useIntl } from "react-intl"
import { CheckIcon, InfoCircleIcon } from "@/components/Icons"
import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
import Label from "@/components/TempDesignSystem/Form/Label"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import PriceTable from "./PriceList"
import styles from "./flexibilityOption.module.css"
import type { FlexibilityOptionProps } from "@/types/components/hotelReservation/selectRate/flexibilityOption"
export default function FlexibilityOption({
product,
name,
paymentTerm,
priceInformation,
roomTypeCode,
petRoomPackage,
handleSelectRate,
roomListIndex,
}: FlexibilityOptionProps) {
const intl = useIntl()
const inputElementRef = useRef<HTMLInputElement>(null)
const handleSelectRateRef = useRef(handleSelectRate)
useEffect(() => {
handleSelectRateRef.current = handleSelectRate
}, [handleSelectRate])
const searchParams = useSearchParams()
// When entering the page with a room and rate selection already in the URL we
// want to preselect the selection. This happens e.g. when you do a selection,
// go to the enter details page and then want to change the room.
useEffect(() => {
const ratecodeSearchParam = searchParams.get(
`room[${roomListIndex}].ratecode`
)
const roomtypeSearchParam = searchParams.get(
`room[${roomListIndex}].roomtype`
)
// If this is not the room and rate we want to preselect, abort
if (
!product ||
ratecodeSearchParam !== product.productType.public.rateCode ||
roomtypeSearchParam !== roomTypeCode
) {
return
}
handleSelectRateRef.current((prev) => {
// If the user already has made a new selection we respect that and don't do anything else
if (prev) {
return prev
}
if (inputElementRef.current) {
inputElementRef.current.checked = true
}
return {
publicRateCode: product.productType.public.rateCode,
roomTypeCode: roomTypeCode,
name: name,
paymentTerm: paymentTerm,
}
})
}, [searchParams, roomListIndex, product, roomTypeCode, name, paymentTerm])
if (!product) {
return (
<div className={styles.noPricesCard}>
<div className={styles.header}>
<InfoCircleIcon width={16} height={16} color="uiTextMediumContrast" />
<div className={styles.priceType}>
<Caption>{name}</Caption>
<Caption color="uiTextPlaceholder">({paymentTerm})</Caption>
</div>
</div>
<Label size="regular" className={styles.noPricesLabel}>
<Caption color="uiTextHighContrast" type="bold">
{intl.formatMessage({ id: "No prices available" })}
</Caption>
</Label>
</div>
)
}
const { public: publicPrice, member: memberPrice } = product.productType
const onClick: React.MouseEventHandler<HTMLInputElement> = (e) => {
handleSelectRateRef.current((prev) => {
if (
prev &&
prev.publicRateCode === publicPrice.rateCode &&
prev.roomTypeCode === roomTypeCode
) {
if (e.currentTarget?.checked) e.currentTarget.checked = false
return undefined
} else
return {
publicRateCode: publicPrice.rateCode,
roomTypeCode: roomTypeCode,
name: name,
paymentTerm: paymentTerm,
}
})
}
return (
<label>
<input
type="radio"
name={`rateCode-${roomListIndex}`}
value={publicPrice?.rateCode}
onClick={onClick}
ref={inputElementRef}
/>
<div className={styles.card}>
<div className={styles.header}>
<Modal
trigger={
<Button intent="text">
<InfoCircleIcon
width={16}
height={16}
color="uiTextMediumContrast"
/>
</Button>
}
title={name}
subtitle={paymentTerm}
>
<div className={styles.terms}>
{priceInformation?.map((info) => (
<Body
key={info}
color="uiTextHighContrast"
className={styles.termsText}
>
<CheckIcon
color="uiSemanticSuccess"
width={20}
height={20}
className={styles.termsIcon}
></CheckIcon>
{info}
</Body>
))}
</div>
</Modal>
<div className={styles.priceType}>
<Caption color="uiTextHighContrast">{name}</Caption>
<Caption color="uiTextPlaceholder">({paymentTerm})</Caption>
</div>
</div>
<PriceTable
publicPrice={publicPrice}
memberPrice={memberPrice}
petRoomPackage={petRoomPackage}
/>
<div className={styles.checkIcon}>
<CheckIcon color="white" height="16" width="16" />
</div>
</div>
</label>
)
}