Files
web/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/index.tsx
Anton Gunnarsson 923206ee4c Merged in chore/sw-3145-move-subtitle (pull request #2516)
chore(SW-3145): Move Title and Subtitle to design-system

* Move Title and Subtitle to design-system

* Fix export


Approved-by: Linus Flood
2025-07-04 06:22:28 +00:00

148 lines
4.6 KiB
TypeScript

"use client"
import { use } from "react"
import { useIntl } from "react-intl"
import Title from "@scandic-hotels/design-system/Title"
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
import { useMyStayStore } from "@/stores/my-stay"
import { Carousel } from "@/components/Carousel"
import { AddAncillaryProvider } from "@/providers/AddAncillaryProvider"
import AddAncillaryFlowModal from "./AddAncillaryFlow/AddAncillaryFlowModal"
import AncillaryFlowModalWrapper from "./AddAncillaryFlow/AncillaryFlowModalWrapper"
import WrappedAncillaryCard from "./AddAncillaryFlow/WrappedAncillaryCard"
import { AddedAncillaries } from "./AddedAncillaries"
import { generateUniqueAncillaries, mapAncillaries } from "./utils"
import ViewAllAncillaries from "./ViewAllAncillaries"
import styles from "./ancillaries.module.css"
import type {
AncillariesProps,
SelectedAncillary,
} from "@/types/components/myPages/myStay/ancillaries"
export function Ancillaries({
ancillariesPromise,
packages,
savedCreditCards,
user,
}: AncillariesProps) {
const intl = useIntl()
const ancillaries = use(ancillariesPromise)
const bookedRoom = useMyStayStore((state) => state.bookedRoom)
if (!bookedRoom || bookedRoom.isCancelled || !bookedRoom.showAncillaries) {
return null
}
const alreadyHasBreakfast =
bookedRoom.rateDefinition.breakfastIncluded || bookedRoom.breakfast
const breakfastPackageAdults = alreadyHasBreakfast
? undefined
: packages?.find(
(p) => p.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
)
/**
* A constructed ancillary for breakfast
*
* This is a "fake" ancillary for breakfast, since breakfast isn't really an
* ancillary in the system. This makes it play nicely with the add ancillary
* flow. If the user shouldn't be able to add breakfast this will be `undefined`.
*/
const breakfastAncillary: SelectedAncillary | undefined =
breakfastPackageAdults
? {
description: intl.formatMessage({
defaultMessage: "Buffet",
}),
id: breakfastPackageAdults.code,
title: intl.formatMessage({
defaultMessage: "Breakfast",
}),
price: {
currency: breakfastPackageAdults.localPrice.currency,
total: breakfastPackageAdults.localPrice.totalPrice,
},
imageUrl:
"https://images.scandichotels.com/publishedmedia/inyre69evkpzgtygjnvp/Breakfast_-_Scandic_Sweden_-_Free_to_use.jpg",
requiresDeliveryTime: false,
loyaltyCode: undefined,
points: undefined,
hotelId: Number(bookedRoom.hotelId),
categoryName: "Food",
}
: undefined
const allAncillaries = mapAncillaries(ancillaries, breakfastAncillary, user)
if (!allAncillaries.length) {
return null
}
const uniqueAncillaries = generateUniqueAncillaries(allAncillaries)
return (
<AddAncillaryProvider booking={bookedRoom} ancillaries={allAncillaries}>
<div className={styles.container}>
{uniqueAncillaries.length > 0 && bookedRoom.canModifyAncillaries && (
<>
<div className={styles.title}>
<Title as="h5">
{intl.formatMessage({
defaultMessage: "Upgrade your stay",
})}
</Title>
<div className={styles.viewAllLink}>
<ViewAllAncillaries />
</div>
</div>
<div className={styles.ancillaries}>
{uniqueAncillaries.slice(0, 4).map((ancillary) => (
<WrappedAncillaryCard
ancillary={ancillary}
key={ancillary.id}
/>
))}
</div>
<div className={styles.mobileAncillaries}>
<Carousel>
<Carousel.Content>
{uniqueAncillaries.map((ancillary) => {
return (
<Carousel.Item key={ancillary.id}>
<WrappedAncillaryCard ancillary={ancillary} />
</Carousel.Item>
)
})}
</Carousel.Content>
<Carousel.Dots />
</Carousel>
</div>
</>
)}
<AddedAncillaries
booking={bookedRoom}
ancillaries={uniqueAncillaries}
/>
<AncillaryFlowModalWrapper>
<AddAncillaryFlowModal
user={user}
booking={bookedRoom}
packages={packages}
savedCreditCards={savedCreditCards}
/>
</AncillaryFlowModalWrapper>
</div>
</AddAncillaryProvider>
)
}