fix(SW-3702): Show correct point currencies in interactive map * Show correct point currencies in interactive map Approved-by: Matilda Haneling
143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import { PointType } from "@scandic-hotels/common/constants/pointType"
|
|
|
|
import type { imageSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/image"
|
|
import type { ProductTypeCheque } from "@scandic-hotels/trpc/types/availability"
|
|
import type { Amenities } from "@scandic-hotels/trpc/types/hotel"
|
|
import type { IntlShape } from "react-intl"
|
|
import type { z } from "zod"
|
|
|
|
import type { HotelResponse } from "../SelectHotel/helpers"
|
|
|
|
type ApiImage = z.infer<typeof imageSchema>
|
|
interface Coordinates {
|
|
lat: number
|
|
lng: number
|
|
}
|
|
|
|
export type HotelPin = {
|
|
bookingCode?: string | null
|
|
name: string
|
|
coordinates: Coordinates
|
|
chequePrice: ProductTypeCheque["localPrice"] | null
|
|
publicPrice: number | null
|
|
memberPrice: number | null
|
|
redemptionPrice: number | null
|
|
pointsType: PointType | null
|
|
voucherPrice: number | null
|
|
rateType: string | null
|
|
currency: string
|
|
images: ApiImage[]
|
|
amenities: Amenities
|
|
ratings: number | null
|
|
operaId: string
|
|
facilityIds: number[]
|
|
hasEnoughPoints: boolean
|
|
}
|
|
|
|
export function getHotelPins(
|
|
hotels: HotelResponse[],
|
|
intl: IntlShape,
|
|
currencyValue?: string
|
|
): HotelPin[] {
|
|
if (!hotels.length) {
|
|
return []
|
|
}
|
|
|
|
return hotels.map(({ availability, hotel, additionalData }) => {
|
|
const productType = availability.productType
|
|
const redemptionRate = productType?.redemptions?.find(
|
|
(r) => r?.localPrice.pointsPerStay
|
|
)
|
|
const chequePrice = productType?.bonusCheque?.localPrice
|
|
const voucherPrice = productType?.voucher?.numberOfVouchers
|
|
if (chequePrice || voucherPrice) {
|
|
currencyValue = chequePrice ? "CC" : "Voucher"
|
|
}
|
|
|
|
const redemptionPrice = redemptionRate?.localPrice.pointsPerStay ?? null
|
|
const redemptionCurrency = getRedemptionCurrencyText(
|
|
redemptionPrice,
|
|
redemptionRate?.localPrice.pointsType ?? null,
|
|
intl
|
|
)
|
|
|
|
return {
|
|
bookingCode: availability.bookingCode,
|
|
coordinates: {
|
|
lat: hotel.location.latitude,
|
|
lng: hotel.location.longitude,
|
|
},
|
|
name: hotel.name,
|
|
chequePrice: chequePrice ?? null,
|
|
publicPrice: productType?.public?.localPrice.pricePerNight ?? null,
|
|
memberPrice: productType?.member?.localPrice.pricePerNight ?? null,
|
|
redemptionPrice,
|
|
pointsType: redemptionRate?.localPrice.pointsType ?? null,
|
|
voucherPrice: voucherPrice ?? null,
|
|
rateType:
|
|
productType?.public?.rateType ?? productType?.member?.rateType ?? null,
|
|
currency:
|
|
productType?.public?.localPrice.currency ||
|
|
productType?.member?.localPrice.currency ||
|
|
redemptionCurrency ||
|
|
currencyValue ||
|
|
"N/A",
|
|
images: [
|
|
hotel.hotelContent.images,
|
|
...(additionalData.gallery?.heroImages ?? []),
|
|
],
|
|
amenities: hotel.detailedFacilities
|
|
.map((facility) => ({
|
|
...facility,
|
|
icon: facility.icon ?? "None",
|
|
}))
|
|
.slice(0, 5),
|
|
ratings: hotel.ratings?.tripAdvisor.rating ?? null,
|
|
operaId: hotel.operaId,
|
|
facilityIds: hotel.detailedFacilities.map((facility) => facility.id),
|
|
hasEnoughPoints: !!availability.productType?.redemptions?.some(
|
|
(r) => r.hasEnoughPoints
|
|
),
|
|
}
|
|
})
|
|
}
|
|
|
|
function getRedemptionCurrencyText(
|
|
points: number | null,
|
|
pointsType: PointType | null,
|
|
intl: IntlShape
|
|
) {
|
|
if (points === null || pointsType === null) return null
|
|
|
|
switch (pointsType) {
|
|
case PointType.SCANDIC: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfScandicPoints",
|
|
defaultMessage:
|
|
"{numberOfScandicPoints, plural, one {Point} other {Points}}",
|
|
},
|
|
{
|
|
numberOfScandicPoints: points,
|
|
}
|
|
)
|
|
}
|
|
case PointType.EUROBONUS: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfEuroBonusPoints",
|
|
defaultMessage:
|
|
"{numberOfEuroBonusPoints, plural, one {EB Point} other {EB Points}}",
|
|
},
|
|
{
|
|
numberOfEuroBonusPoints: points,
|
|
}
|
|
)
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck: never = pointsType
|
|
return null
|
|
}
|
|
}
|
|
}
|