Feat/lokalise rebuild * chore(lokalise): update translation ids * chore(lokalise): easier to switch between projects * chore(lokalise): update translation ids * . * . * . * . * . * . * chore(lokalise): update translation ids * chore(lokalise): update translation ids * . * . * . * chore(lokalise): update translation ids * chore(lokalise): update translation ids * . * . * chore(lokalise): update translation ids * chore(lokalise): update translation ids * chore(lokalise): new translations * merge * switch to errors for missing id's * merge * sync translations Approved-by: Linus Flood
160 lines
4.9 KiB
TypeScript
160 lines
4.9 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({
|
|
id: "common.buffet",
|
|
defaultMessage: "Buffet",
|
|
}),
|
|
id: breakfastPackageAdults.code,
|
|
title: intl.formatMessage({
|
|
id: "common.breakfast",
|
|
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),
|
|
internalCategoryName: "Food",
|
|
translatedCategoryName: intl.formatMessage({
|
|
id: "common.food",
|
|
defaultMessage: "Food",
|
|
}),
|
|
}
|
|
: undefined
|
|
|
|
const allAncillaries = mapAncillaries(
|
|
intl,
|
|
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({
|
|
id: "ancillaries.upgradeYourStay",
|
|
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>
|
|
)
|
|
}
|