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 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 } } }