Files
web/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx
2024-12-12 11:47:44 +01:00

136 lines
3.8 KiB
TypeScript

"use client"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { ErrorCircleIcon } from "@/components/Icons"
import Select from "@/components/TempDesignSystem/Select"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import styles from "./child-selector.module.css"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type {
ChildBed,
ChildInfoSelectorProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
const ageList = [...Array(13)].map((_, i) => ({
label: i.toString(),
value: i,
}))
export default function ChildInfoSelector({
child = { age: -1, bed: -1 },
childrenInAdultsBed,
adults,
index = 0,
roomIndex = 0,
}: ChildInfoSelectorProps) {
const ageFieldName = `rooms.${roomIndex}.child.${index}.age`
const bedFieldName = `rooms.${roomIndex}.child.${index}.bed`
const intl = useIntl()
const ageLabel = intl.formatMessage({ id: "Age" })
const bedLabel = intl.formatMessage({ id: "Bed" })
const errorMessage = intl.formatMessage({ id: "Child age is required" })
const { setValue, formState } = useFormContext()
function updateSelectedBed(bed: number) {
setValue(`rooms.${roomIndex}.child.${index}.bed`, bed)
}
function updateSelectedAge(age: number) {
setValue(`rooms.${roomIndex}.child.${index}.age`, age)
const availableBedTypes = getAvailableBeds(age)
updateSelectedBed(availableBedTypes[0].value)
}
const allBedTypes: ChildBed[] = [
{
label: intl.formatMessage({ id: "In adults bed" }),
value: ChildBedMapEnum.IN_ADULTS_BED,
},
{
label: intl.formatMessage({ id: "In crib" }),
value: ChildBedMapEnum.IN_CRIB,
},
{
label: intl.formatMessage({ id: "In extra bed" }),
value: ChildBedMapEnum.IN_EXTRA_BED,
},
]
function getAvailableBeds(age: number) {
let availableBedTypes: ChildBed[] = []
if (age <= 5 && (adults > childrenInAdultsBed || child.bed === 0)) {
availableBedTypes.push(allBedTypes[0])
}
if (age < 3) {
availableBedTypes.push(allBedTypes[1])
}
if (age > 2) {
availableBedTypes.push(allBedTypes[2])
}
return availableBedTypes
}
//@ts-expect-error: formState is typed with FormValues
const roomErrors = formState.errors.rooms?.[roomIndex]?.child?.[index]
const ageError = roomErrors?.age
const bedError = roomErrors?.bed
return (
<>
<div key={index} className={styles.childInfoContainer}>
<div>
<Select
required={true}
items={ageList}
label={ageLabel}
aria-label={ageLabel}
value={child.age}
onSelect={(key) => {
updateSelectedAge(key as number)
}}
placeholder={ageLabel}
maxHeight={180}
name={ageFieldName}
isNestedInModal={true}
/>
</div>
<div>
{child.age >= 0 ? (
<Select
items={getAvailableBeds(child.age)}
label={bedLabel}
aria-label={bedLabel}
value={child.bed}
onSelect={(key) => {
updateSelectedBed(key as number)
}}
placeholder={bedLabel}
name={bedFieldName}
isNestedInModal={true}
/>
) : null}
</div>
</div>
{roomErrors && roomErrors.message ? (
<Caption color="red" className={styles.error}>
<ErrorCircleIcon color="red" />
{roomErrors.message}
</Caption>
) : null}
{ageError || bedError ? (
<Caption color="red" className={styles.error}>
<ErrorCircleIcon color="red" />
{errorMessage}
</Caption>
) : null}
</>
)
}