Files
web/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/Description/index.tsx
Christel Westerberg 6b08d5a113 Merged in fix/STAY-135 (pull request #3368)
Fix/STAY-135 & STAY-127

* fix: make quantity and delivery separate steps in mobile

* fix: update design for delivery step in ancillary flow

* fix: add error state for missing time

* fix: only allow points or cash payment for ancillaries

* fix: break out stepper to design system

* fix: update design of select quantity step in add ancillaries flow

* fix: add error states for quantity

* fix: handle insufficient points case

* fix: update stepper to include optional disabledMessage tooltip

* fix: handle validations

* fix: change name to camel case


Approved-by: Bianca Widstam
Approved-by: Chuma Mcphoy (We Ahead)
2025-12-18 13:31:43 +00:00

176 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useIntl } from "react-intl"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { Divider } from "@scandic-hotels/design-system/Divider"
import Image from "@scandic-hotels/design-system/Image"
import { Typography } from "@scandic-hotels/design-system/Typography"
import {
AncillaryStepEnum,
useAddAncillaryStore,
} from "@/stores/my-stay/add-ancillary-flow"
import styles from "./description.module.css"
export default function Description() {
const intl = useIntl()
const { selectedAncillary, isBreakfast, currentStep } = useAddAncillaryStore(
(state) => ({
selectedAncillary: state.selectedAncillary,
isBreakfast: state.isBreakfast,
currentStep: state.currentStep,
})
)
if (!selectedAncillary || currentStep === AncillaryStepEnum.confirmation) {
return null
}
return (
<div className={styles.contentContainer}>
<Image
src={selectedAncillary.imageUrl}
width={400}
height={200}
alt={selectedAncillary.title}
className={styles.image}
/>
<div className={styles.price}>
{isBreakfast ? (
<BreakfastPriceList />
) : (
<Typography variant="Body/Paragraph/mdBold">
<p>
{formatPrice(
intl,
selectedAncillary.price.total,
selectedAncillary.price.currency
)}
</p>
</Typography>
)}
{selectedAncillary.points && (
<Typography variant="Body/Paragraph/mdBold">
<p>
{intl.formatMessage(
{
id: "common.orNumberOfPoints",
defaultMessage:
"or {points, plural, one {# point} other {# points}}",
},
{
points: selectedAncillary.points,
}
)}
</p>
</Typography>
)}
{selectedAncillary.requiresQuantity && (
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage(
{
id: "addAncillaryFlowModal.perUnit",
defaultMessage: "/per {unit}",
},
{ unit: selectedAncillary.unitName }
)}
</p>
</Typography>
)}
</div>
<div className={styles.description}>
{selectedAncillary.description && (
<Typography variant="Body/Paragraph/mdRegular">
<p
dangerouslySetInnerHTML={{
__html: selectedAncillary.description,
}}
/>
</Typography>
)}
</div>
</div>
)
}
function BreakfastPriceList() {
const intl = useIntl()
const breakfastData = useAddAncillaryStore((state) => state.breakfastData)
if (!breakfastData) {
return intl.formatMessage({
id: "ancillaries.unableToDisplayBreakfastPrices",
defaultMessage: "Unable to display breakfast prices.",
})
}
return (
<div>
<div className={styles.breakfastPriceList}>
<Typography variant="Body/Paragraph/mdBold">
<span>
{intl.formatMessage(
{
id: "addAncillaryFlowModal.pricePerNightPerAdult",
defaultMessage: "{price}/night per adult",
},
{
price: formatPrice(
intl,
breakfastData.priceAdult,
breakfastData.currency
),
}
)}
</span>
</Typography>
{breakfastData.nrOfPayingChildren > 0 && (
<>
<div className={styles.divider}>
<Divider variant="vertical" color="Border/Divider/Subtle" />
</div>
<Typography variant="Body/Paragraph/mdBold">
<span>
{intl.formatMessage(
{
id: "addAncillaryFlowModal.pricePerNightPerKids",
defaultMessage: "{price}/night for kids (ages 412)",
},
{
price: formatPrice(
intl,
breakfastData.priceChild,
breakfastData.currency
),
}
)}
</span>
</Typography>
</>
)}
{breakfastData.nrOfFreeChildren > 0 && (
<>
<div className={styles.divider}>
<Divider variant="vertical" color="Border/Divider/Subtle" />
</div>
<Typography variant="Body/Paragraph/mdBold">
<span>
{intl.formatMessage({
id: "addAncillaryFlowModal.freeBreakfastForKids",
defaultMessage: "Free for kids (under 4)",
})}
</span>
</Typography>
</>
)}
</div>
</div>
)
}