Files
web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
2025-01-13 13:35:03 +01:00

139 lines
4.4 KiB
TypeScript

"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useCallback, useEffect } from "react"
import { FormProvider, useForm } from "react-hook-form"
import { useIntl } from "react-intl"
import { useEnterDetailsStore } from "@/stores/enter-details"
import { Highlight } from "@/components/TempDesignSystem/Form/ChoiceCard/_Card"
import RadioCard from "@/components/TempDesignSystem/Form/ChoiceCard/Radio"
import Body from "@/components/TempDesignSystem/Text/Body"
import { formatPrice } from "@/utils/numberFormatting"
import { breakfastFormSchema } from "./schema"
import styles from "./breakfast.module.css"
import type {
BreakfastFormSchema,
BreakfastProps,
} from "@/types/components/hotelReservation/enterDetails/breakfast"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
export default function Breakfast({ packages }: BreakfastProps) {
const intl = useIntl()
const formValuesBreakfast = useEnterDetailsStore(({ formValues }) =>
formValues?.breakfast
? formValues.breakfast.code
: formValues?.breakfast === false
? "false"
: undefined
)
const updateBreakfast = useEnterDetailsStore(
(state) => state.actions.updateBreakfast
)
const children = useEnterDetailsStore(
(state) => state.booking.rooms[0].children
)
const methods = useForm<BreakfastFormSchema>({
defaultValues: formValuesBreakfast
? { breakfast: formValuesBreakfast }
: undefined,
criteriaMode: "all",
mode: "all",
resolver: zodResolver(breakfastFormSchema),
reValidateMode: "onChange",
})
const onSubmit = useCallback(
(values: BreakfastFormSchema) => {
const pkg = packages?.find((p) => p.code === values.breakfast)
if (pkg) {
updateBreakfast(pkg)
} else {
updateBreakfast(false)
}
},
[packages, updateBreakfast]
)
useEffect(() => {
if (methods.formState.isSubmitting) {
return
}
const subscription = methods.watch(() => methods.handleSubmit(onSubmit)())
return () => subscription.unsubscribe()
}, [methods, onSubmit])
return (
<FormProvider {...methods}>
<div className={styles.container}>
{children?.length ? (
<Body>
{intl.formatMessage({
id: "Children's breakfast is always free as part of the adult's breakfast.",
})}
</Body>
) : null}
<form className={styles.form} onSubmit={methods.handleSubmit(onSubmit)}>
{packages.map((pkg) => (
<RadioCard
key={pkg.code}
id={pkg.code}
name="breakfast"
subtitle={
pkg.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST
? intl.formatMessage<React.ReactNode>(
{
id: "<strikethrough>{amount}</strikethrough> <free>0 {currency}</free>/night per adult",
},
{
amount: formatPrice(
intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
currency: pkg.localPrice.currency,
free: (str) => <Highlight>{str}</Highlight>,
strikethrough: (str) => <s>{str}</s>,
}
)
: intl.formatMessage(
{ id: "{amount}/night per adult" },
{
amount: formatPrice(
intl,
parseInt(pkg.localPrice.price),
pkg.localPrice.currency
),
}
)
}
text={intl.formatMessage({
id: "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.",
})}
title={intl.formatMessage({ id: "Breakfast buffet" })}
value={pkg.code}
/>
))}
<RadioCard
name="breakfast"
subtitle={formatPrice(intl, 0, packages[0].localPrice.currency)}
text={intl.formatMessage({
id: "You can always change your mind later and add breakfast at the hotel.",
})}
title={intl.formatMessage({ id: "No breakfast" })}
value="false"
/>
</form>
</div>
</FormProvider>
)
}