139 lines
4.4 KiB
TypeScript
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>
|
|
)
|
|
}
|