Files
web/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx
Arvid Norlin 540402b969 Merged in feat/SW-1813 (pull request #1516)
Feat/SW-1813

* feat(SW-1652): handle linkedReservations fetching

* feat: add linkedReservation retry functionality

* chore: align naming

* feat(SW-1813): Add booking confirmation PriceDetailsModal


Approved-by: Simon.Emanuelsson
2025-03-14 13:49:22 +00:00

119 lines
3.8 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 BreakfastChoiceCard from "@/components/HotelReservation/EnterDetails/Breakfast/BreakfastChoiceCard"
import Body from "@/components/TempDesignSystem/Text/Body"
import { useRoomContext } from "@/contexts/Details/Room"
import { breakfastFormSchema } from "./schema"
import styles from "./breakfast.module.css"
import type { BreakfastFormSchema } from "@/types/components/hotelReservation/breakfast"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
export default function Breakfast() {
const intl = useIntl()
const packages = useEnterDetailsStore((state) => state.breakfastPackages)
const {
actions: { updateBreakfast },
room,
} = useRoomContext()
const breakfastSelection = room?.breakfast
? room.breakfast.code
: room?.breakfast === false
? "false"
: undefined
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 (methods.formState.isSubmitting) {
return
}
const subscription = methods.watch(() => methods.handleSubmit(onSubmit)())
return () => subscription.unsubscribe()
}, [methods, onSubmit])
return (
<FormProvider {...methods}>
<div className={styles.container}>
{room.childrenInRoom?.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>
)
}