Files
web/apps/scandic-web/components/HotelReservation/utils/index.tsx
Joakim Jäderberg 2a9313362f Merged in feature/SW-3327-move-hotel-info-card-to-design-system (pull request #2730)
Feature/SW-3327 move hotel info card to design system

* wip

* wip

* wip

* wip moving hotelinfocard

* add controls for HotelInfoCard in storybook

* merge


Approved-by: Anton Gunnarsson
2025-08-29 10:09:48 +00:00

144 lines
3.9 KiB
TypeScript

import { type Dayjs, dt } from "@scandic-hotels/common/dt"
import {
MaterialIcon,
type MaterialIconSetIconProps,
} from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import type { Package, Packages } from "@scandic-hotels/trpc/types/packages"
import type { JSX } from "react"
import { type RoomPackageCodes } from "@/types/components/hotelReservation/selectRate/roomFilter"
interface IconForFeatureCodeProps {
featureCode: RoomPackageCodes
}
export function IconForFeatureCode({
featureCode,
...props
}: IconForFeatureCodeProps & MaterialIconSetIconProps): JSX.Element {
switch (featureCode) {
case RoomPackageCodeEnum.ACCESSIBILITY_ROOM:
return <MaterialIcon icon="accessible" {...props} />
case RoomPackageCodeEnum.ALLERGY_ROOM:
return <MaterialIcon icon="mode_fan" {...props} />
case RoomPackageCodeEnum.PET_ROOM:
default:
return <MaterialIcon icon="pets" {...props} />
}
}
export const invertedBedTypeMap: Record<ChildBedTypeEnum, string> = {
[ChildBedTypeEnum.ParentsBed]: ChildBedMapEnum[ChildBedMapEnum.IN_ADULTS_BED],
[ChildBedTypeEnum.Crib]: ChildBedMapEnum[ChildBedMapEnum.IN_CRIB],
[ChildBedTypeEnum.ExtraBed]: ChildBedMapEnum[ChildBedMapEnum.IN_EXTRA_BED],
[ChildBedTypeEnum.Unknown]: ChildBedMapEnum[ChildBedMapEnum.UNKNOWN],
}
export function sumPackages(
packages: Pick<Package, "localPrice">[] | undefined | null
) {
if (!packages || !packages.length) {
return {
currency: undefined,
price: 0,
}
}
return packages.reduce(
(total, pkg) => {
total.price = total.price + pkg.localPrice.totalPrice
return total
},
{
currency: packages[0].localPrice.currency,
price: 0,
}
)
}
export function sumPackagesRequestedPrice(packages: Packages | null) {
if (!packages || !packages.length) {
return {
currency: undefined,
price: 0,
}
}
return packages.reduce(
(total, pkg) => {
total.price = total.price + pkg.requestedPrice.totalPrice
return total
},
{
currency: packages[0].requestedPrice.currency,
price: 0,
}
)
}
export function calculateVat(priceInclVat: number, vat: number) {
const vatPercentage = vat / 100
const priceExclVat = priceInclVat / (1 + vatPercentage)
const vatAmount = priceInclVat - priceExclVat
return {
priceExclVat,
vatAmount,
}
}
export function filterOverlappingDates<
T extends {
startDate: Date | Dayjs | string | undefined | null
endDate: Date | Dayjs | string | undefined | null
},
>(dateRangeItems: T[], fromDate: Date | Dayjs, toDate: Date | Dayjs) {
const startDate = dt(fromDate)
const endDate = dt(toDate)
return dateRangeItems.filter((item) =>
hasOverlappingDates(item, startDate, endDate)
)
}
export function hasOverlappingDates(
dateRangeItem: {
startDate: Date | Dayjs | string | undefined | null
endDate: Date | Dayjs | string | undefined | null
},
fromDate: Date | Dayjs,
toDate: Date | Dayjs
) {
const startDate = dt(fromDate)
const endDate = dt(toDate)
if (dateRangeItem.endDate && dateRangeItem.startDate) {
const itemStartDate = dt(dateRangeItem.startDate)
const itemEndDate = dt(dateRangeItem.endDate)
const fromDateIsBetweenItemDates = startDate.isBetween(
itemStartDate,
itemEndDate,
"date",
"[]"
)
const toDateIsBetweenItemDates = endDate.isBetween(
itemStartDate,
itemEndDate,
"date",
"[]"
)
const itemFullyContained =
startDate.isSameOrBefore(itemStartDate, "date") &&
endDate.isSameOrAfter(itemEndDate, "date")
return (
fromDateIsBetweenItemDates ||
toDateIsBetweenItemDates ||
itemFullyContained
)
}
return true
}