chore: Cleanup unused vars, exports, types * Cleanup some unused exports * Remove more * Readd CampaignPageIncludedHotelsRef * Add alias comment to procedure exports * Remove unused exports Approved-by: Linus Flood
221 lines
5.8 KiB
TypeScript
221 lines
5.8 KiB
TypeScript
import { use } from "react"
|
|
import { type IntlShape, useIntl } from "react-intl"
|
|
|
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
|
|
|
import { useMyStayStore } from "@/stores/my-stay"
|
|
|
|
import type { User } from "@scandic-hotels/trpc/types/user"
|
|
|
|
import type {
|
|
Ancillaries,
|
|
Ancillary,
|
|
Packages,
|
|
SelectedAncillary,
|
|
} from "@/types/components/myPages/myStay/ancillaries"
|
|
|
|
export function useAncillaries(
|
|
ancillariesPromise: Promise<Ancillaries | null>,
|
|
packages: Packages | null,
|
|
user: User | null,
|
|
alreadyAcquiredAncillaryCodes: string[]
|
|
) {
|
|
const intl = useIntl()
|
|
const bookedRoom = useMyStayStore((state) => state.bookedRoom)
|
|
|
|
if (!bookedRoom || bookedRoom.isCancelled || !bookedRoom.showAncillaries) {
|
|
return null
|
|
}
|
|
|
|
const ancillaries = use(ancillariesPromise)
|
|
|
|
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",
|
|
}),
|
|
requiresQuantity: false,
|
|
unitName: intl.formatMessage({
|
|
id: "common.person",
|
|
defaultMessage: "person",
|
|
}),
|
|
}
|
|
: undefined
|
|
|
|
const allAncillaries = mapAncillaries(
|
|
intl,
|
|
ancillaries,
|
|
breakfastAncillary,
|
|
user
|
|
)
|
|
|
|
if (!allAncillaries.length) {
|
|
return null
|
|
}
|
|
|
|
const allUniqueAncillaries = generateUniqueAncillaries(allAncillaries)
|
|
|
|
const availableByCategory = alreadyAcquiredAncillaryCodes.length
|
|
? filterOutAlreadyAcquiredAncillaries(
|
|
allAncillaries,
|
|
alreadyAcquiredAncillaryCodes
|
|
)
|
|
: allAncillaries
|
|
|
|
const availableUniqueAncillaries =
|
|
generateUniqueAncillaries(availableByCategory)
|
|
|
|
return {
|
|
availableByCategory,
|
|
allUnique: allUniqueAncillaries,
|
|
availableUnique: availableUniqueAncillaries,
|
|
}
|
|
}
|
|
|
|
function mapAncillaries(
|
|
intl: IntlShape,
|
|
ancillaries: Ancillaries | null,
|
|
breakfastAncillary: SelectedAncillary | undefined,
|
|
user: User | null
|
|
) {
|
|
const withBreakfastPopular = addBreakfastPackage(
|
|
ancillaries ?? [],
|
|
breakfastAncillary,
|
|
"Popular",
|
|
intl.formatMessage({
|
|
defaultMessage: "Popular",
|
|
id: "myStay.ancillaries.popularCategory",
|
|
})
|
|
)
|
|
const withBreakfastFood = addBreakfastPackage(
|
|
withBreakfastPopular,
|
|
breakfastAncillary,
|
|
"Food",
|
|
intl.formatMessage({
|
|
id: "common.food",
|
|
defaultMessage: "Food",
|
|
})
|
|
)
|
|
|
|
return filterPoints(withBreakfastFood, user)
|
|
}
|
|
|
|
function filterPoints(ancillaries: Ancillaries, user: User | null) {
|
|
return ancillaries.map((ancillary) => {
|
|
return {
|
|
...ancillary,
|
|
ancillaryContent: ancillary.ancillaryContent.map(
|
|
({ points, ...ancillary }) => ({
|
|
...ancillary,
|
|
points: user ? points : undefined,
|
|
})
|
|
),
|
|
}
|
|
})
|
|
}
|
|
|
|
function generateUniqueAncillaries(
|
|
ancillaries: Ancillaries
|
|
): Ancillary["ancillaryContent"] {
|
|
const uniqueAncillaries = new Map(
|
|
ancillaries.flatMap((a) => {
|
|
return a.ancillaryContent.map((ancillary) => [ancillary.id, ancillary])
|
|
})
|
|
)
|
|
return [...uniqueAncillaries.values()]
|
|
}
|
|
|
|
/**
|
|
* Adds the breakfast package to the ancillaries
|
|
*
|
|
* Returns the ancillaries array with the breakfast package added to the
|
|
* specified category. If the category doesn't exist it's created.
|
|
*/
|
|
function addBreakfastPackage(
|
|
ancillaries: Ancillaries,
|
|
breakfast: SelectedAncillary | undefined,
|
|
internalCategoryName: string,
|
|
translatedCategoryName: string
|
|
): Ancillaries {
|
|
if (!breakfast) return ancillaries
|
|
|
|
const category = ancillaries.find(
|
|
(a) => a.internalCategoryName === internalCategoryName
|
|
)
|
|
if (category) {
|
|
const newCategory = {
|
|
...category,
|
|
ancillaryContent: [breakfast, ...category.ancillaryContent],
|
|
}
|
|
|
|
return ancillaries.map((ancillary) =>
|
|
ancillary.internalCategoryName === internalCategoryName
|
|
? newCategory
|
|
: ancillary
|
|
)
|
|
}
|
|
|
|
return [
|
|
{
|
|
internalCategoryName,
|
|
translatedCategoryName,
|
|
ancillaryContent: [breakfast],
|
|
},
|
|
...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
|
|
)
|
|
),
|
|
}))
|
|
}
|