Files
web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
Pontus Dreij ed9dbded5d Merged in feat/SW-1504-UI-update-breakfast-component (pull request #1284)
feat(SW-1504): Used AncillaryCard and added to breakfast choice

* feat(SW-1504): Craeted AncillaryCard and added to breakfast choice

* feat(SW-1504): Using of AncillaryCard

* feat(SW-1504) Removed unused imports

* feat(SW-1504): Added price text

* feat(SW-1504): added /night per adult

* feat(SW-1504) Removed type prop


Approved-by: Arvid Norlin
2025-02-14 15:43:14 +00:00

136 lines
4.2 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 { selectRoom } from "@/stores/enter-details/helpers"
import BreakfastChoiceCard from "@/components/HotelReservation/EnterDetails/Breakfast/BreakfastChoiceCard"
import Body from "@/components/TempDesignSystem/Text/Body"
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,
roomIndex,
}: BreakfastProps & { roomIndex: number }) {
const intl = useIntl()
const room = useEnterDetailsStore((state) => selectRoom(state, roomIndex))
const breakfastSelection = room?.breakfast
? room.breakfast.code
: room?.breakfast === false
? "false"
: undefined
const updateBreakfast = useEnterDetailsStore(
(state) => state.actions.updateBreakfast
)
const children = useEnterDetailsStore(
(state) => state.booking.rooms[0].childrenInRoom
)
const methods = useForm<BreakfastFormSchema>({
defaultValues: breakfastSelection
? { breakfast: breakfastSelection }
: 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 (breakfastSelection) {
methods.setValue("breakfast", breakfastSelection)
}
}, [breakfastSelection, methods])
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) => (
<BreakfastChoiceCard
key={pkg.code}
name="breakfast"
ancillary={{
title: intl.formatMessage({ id: "Breakfast buffet" }),
price: {
total: parseInt(pkg.localPrice.price),
currency: pkg.localPrice.currency,
included:
pkg.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST,
text: intl.formatMessage({ id: "/night per adult" }),
},
description: intl.formatMessage({
id: "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.",
}),
imageUrl: "/_static/img/enter-details/breakfast.png", // TODO: Add dynamic image
}}
value={pkg.code}
id={pkg.code}
/>
))}
<BreakfastChoiceCard
name="breakfast"
ancillary={{
title: intl.formatMessage({ id: "No breakfast" }),
price: {
total: 0,
currency: packages[0].localPrice.currency,
},
description: intl.formatMessage({
id: "You can always change your mind later and add breakfast at the hotel.",
}),
imageUrl: "/_static/img/enter-details/breakfast.png", // TODO: Add dynamic image
imageOpacity: 0.1,
}}
value="false"
/>
</form>
</div>
</FormProvider>
)
}