Merged in fix/STAY-131-hide-ancillaries (pull request #3299)

fix: fix logic for identifying single use ancillaries

* fix: fix logic for identifying single use ancillaries

* fix: filter out empty categories of ancillaries


Approved-by: Erik Tiekstra
This commit is contained in:
Christel Westerberg
2025-12-05 12:25:12 +00:00
parent 3bd23bf56e
commit 001000a56d
7 changed files with 125 additions and 73 deletions

View File

@@ -1,6 +1,6 @@
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
import { useAddAncillaryStore } from "@/stores/my-stay/add-ancillary-flow"
@@ -30,22 +30,20 @@ export default function SelectAncillaryStep({
<div className={styles.container}>
<div className={styles.tabs}>
{categories.map((categoryName) => (
<button
<ChipButton
onPress={() => selectCategory(categoryName)}
key={categoryName}
className={`${styles.chip} ${categoryName === selectedCategory ? styles.selected : ""}`}
onClick={() => selectCategory(categoryName)}
selected={categoryName === selectedCategory}
variant="FilterRounded"
size="Large"
>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{categoryName
? categoryName
: intl.formatMessage({
id: "common.other",
defaultMessage: "Other",
})}
</p>
</Typography>
</button>
{categoryName
? categoryName
: intl.formatMessage({
id: "common.other",
defaultMessage: "Other",
})}
</ChipButton>
))}
</div>

View File

@@ -11,8 +11,8 @@ import { AddAncillaryProvider } from "@/providers/AddAncillaryProvider"
import AddAncillaryFlowModal from "./AddAncillaryFlow/AddAncillaryFlowModal"
import AncillaryFlowModalWrapper from "./AddAncillaryFlow/AncillaryFlowModalWrapper"
import AllAncillariesModal from "./AllAncillariesModal/input"
import { AddedAncillaries } from "./AddedAncillaries"
import AllAncillariesModal from "./AllAncillariesModal"
import WrappedAncillaryCard from "./Card"
import styles from "./ancillaries.module.css"
@@ -28,60 +28,69 @@ export function Ancillaries({
const intl = useIntl()
const bookedRoom = useMyStayStore((state) => state.bookedRoom)
const ancillaries = useAncillaries(ancillariesPromise, packages, user)
const ancillaries = useAncillaries(
ancillariesPromise,
packages,
user,
bookedRoom.ancillaries.map((a) => a.code)
)
if (!ancillaries || !bookedRoom) {
return null
}
return (
<AddAncillaryProvider booking={bookedRoom} ancillaries={ancillaries.all}>
<AddAncillaryProvider
booking={bookedRoom}
ancillaries={ancillaries.availableByCategory}
>
<div className={styles.container}>
{ancillaries.unique.length > 0 && bookedRoom.canModifyAncillaries && (
<>
<div className={styles.title}>
<Typography variant="Title/Subtitle/lg">
<h2>
{intl.formatMessage({
id: "ancillaries.upgradeYourStay",
defaultMessage: "Upgrade your stay",
})}
</h2>
</Typography>
<div className={styles.viewAllLink}>
<AllAncillariesModal />
{ancillaries.availableUnique.length > 0 &&
bookedRoom.canModifyAncillaries && (
<>
<div className={styles.title}>
<Typography variant="Title/Subtitle/lg">
<h2>
{intl.formatMessage({
id: "ancillaries.upgradeYourStay",
defaultMessage: "Upgrade your stay",
})}
</h2>
</Typography>
<div className={styles.viewAllLink}>
<AllAncillariesModal />
</div>
</div>
</div>
<div className={styles.ancillaries}>
{ancillaries.unique.slice(0, 4).map((ancillary) => (
<WrappedAncillaryCard
ancillary={ancillary}
key={ancillary.id}
/>
))}
</div>
<div className={styles.ancillaries}>
{ancillaries.availableUnique.slice(0, 4).map((ancillary) => (
<WrappedAncillaryCard
ancillary={ancillary}
key={ancillary.id}
/>
))}
</div>
<div className={styles.mobileAncillaries}>
<Carousel>
<Carousel.Content>
{ancillaries.unique.map((ancillary) => {
return (
<Carousel.Item key={ancillary.id}>
<WrappedAncillaryCard ancillary={ancillary} />
</Carousel.Item>
)
})}
</Carousel.Content>
<Carousel.Dots />
</Carousel>
</div>
</>
)}
<div className={styles.mobileAncillaries}>
<Carousel>
<Carousel.Content>
{ancillaries.availableUnique.map((ancillary) => {
return (
<Carousel.Item key={ancillary.id}>
<WrappedAncillaryCard ancillary={ancillary} />
</Carousel.Item>
)
})}
</Carousel.Content>
<Carousel.Dots />
</Carousel>
</div>
</>
)}
<AddedAncillaries
booking={bookedRoom}
ancillaries={ancillaries.unique}
ancillaries={ancillaries.allUnique}
/>
<AncillaryFlowModalWrapper>

View File

@@ -17,7 +17,8 @@ import type {
export function useAncillaries(
ancillariesPromise: Promise<Ancillaries | null>,
packages: Packages | null,
user: User | null
user: User | null,
alreadyAcquiredAncillaryCodes: string[]
) {
const intl = useIntl()
const bookedRoom = useMyStayStore((state) => state.bookedRoom)
@@ -86,9 +87,23 @@ export function useAncillaries(
return null
}
const uniqueAncillaries = generateUniqueAncillaries(allAncillaries)
const allUniqueAncillaries = generateUniqueAncillaries(allAncillaries)
return { all: allAncillaries, unique: uniqueAncillaries }
const availableByCategory = alreadyAcquiredAncillaryCodes.length
? filterOutAlreadyAcquiredAncillaries(
allAncillaries,
alreadyAcquiredAncillaryCodes
)
: allAncillaries
const availableUniqueAncillaries =
generateUniqueAncillaries(availableByCategory)
return {
availableByCategory,
allUnique: allUniqueAncillaries,
availableUnique: availableUniqueAncillaries,
}
}
function mapAncillaries(
@@ -183,3 +198,19 @@ function addBreakfastPackage(
...ancillaries,
]
}
function filterOutAlreadyAcquiredAncillaries(
ancillaries: Ancillaries,
alreadyAcquiredAncillaryCodes: string[]
): Ancillaries {
return ancillaries.map((cat) => ({
...cat,
ancillaryContent: cat.ancillaryContent.filter((ancillary) =>
ancillary.requiresQuantity
? true
: !alreadyAcquiredAncillaryCodes.includes(
ancillary.loyaltyCode || ancillary.id
)
),
}))
}

View File

@@ -83,9 +83,9 @@ export const createAddAncillaryStore = (
ancillaries,
selectedCategory
)
const categories = ancillaries.map(
(ancillary) => ancillary.translatedCategoryName
)
const categories = ancillaries
.filter((anc) => !!anc.ancillaryContent.length)
.map((ancillary) => ancillary.translatedCategoryName)
const steps = {
[AncillaryStepEnum.selectQuantity]: {
step: AncillaryStepEnum.selectQuantity,