Files
web/components/HotelReservation/SelectRate/Rooms/utils.ts
2025-01-30 11:19:22 +01:00

158 lines
4.5 KiB
TypeScript

import type { RoomParam } from "@/types/components/hotelReservation/selectRate/section"
import type { RoomConfiguration } from "@/server/routers/hotels/output"
/**
* Get the lowest priced room for each room type that appears more than once.
*/
export function filterDuplicateRoomTypesByLowestPrice(
roomConfigurations: RoomConfiguration[]
): RoomConfiguration[] {
const roomTypeCount = roomConfigurations.reduce(
(acc, room) => {
acc[room.roomType] = (acc[room.roomType] || 0) + 1
return acc
},
{} as Record<string, number>
)
const duplicateRoomTypes = new Set(
Object.keys(roomTypeCount).filter((roomType) => roomTypeCount[roomType] > 1)
)
const roomMap = new Map()
roomConfigurations.forEach((room) => {
const { roomType, products } = room
if (!duplicateRoomTypes.has(roomType)) {
roomMap.set(roomType, room)
return
}
products.forEach((product) => {
const { productType } = product
const publicProduct = productType.public || {
requestedPrice: null,
localPrice: null,
}
const memberProduct = productType.member || {
requestedPrice: null,
localPrice: null,
}
const {
requestedPrice: publicRequestedPrice,
localPrice: publicLocalPrice,
} = publicProduct
const {
requestedPrice: memberRequestedPrice,
localPrice: memberLocalPrice,
} = memberProduct
const previousLowest = roomMap.get(roomType)
const currentRequestedPrice = Math.min(
Number(publicRequestedPrice?.pricePerNight) ?? Infinity,
Number(memberRequestedPrice?.pricePerNight) ?? Infinity
)
const currentLocalPrice = Math.min(
Number(publicLocalPrice?.pricePerNight) ?? Infinity,
Number(memberLocalPrice?.pricePerNight) ?? Infinity
)
if (
!previousLowest ||
currentRequestedPrice <
Math.min(
Number(
previousLowest.products[0].productType.public.requestedPrice
?.pricePerNight
) ?? Infinity,
Number(
previousLowest.products[0].productType.member?.requestedPrice
?.pricePerNight
) ?? Infinity
) ||
(currentRequestedPrice ===
Math.min(
Number(
previousLowest.products[0].productType.public.requestedPrice
?.pricePerNight
) ?? Infinity,
Number(
previousLowest.products[0].productType.member?.requestedPrice
?.pricePerNight
) ?? Infinity
) &&
currentLocalPrice <
Math.min(
Number(
previousLowest.products[0].productType.public.localPrice
?.pricePerNight
) ?? Infinity,
Number(
previousLowest.products[0].productType.member?.localPrice
?.pricePerNight
) ?? Infinity
))
) {
roomMap.set(roomType, room)
}
})
})
return Array.from(roomMap.values())
}
/**
* Parse the room params from the search params.
*/
export function parseRoomParams(searchParams: URLSearchParams): RoomParam[] {
const rooms: RoomParam[] = []
// Collect all param keys and sort them to ensure correct order
const paramKeys = Array.from(searchParams.keys()).sort()
for (const key of paramKeys) {
const roomRegex = /^room\[(\d+)\]\.(.+)/
const roomMatch = roomRegex.exec(key)
if (!roomMatch) continue
const [, roomIndex, param] = roomMatch
const value = searchParams.get(key)
if (!value) continue
// Initialize room if it doesn't exist
if (!rooms[Number(roomIndex)]) rooms[Number(roomIndex)] = { adults: 1 }
// Handle adults
if (param === "adults") {
rooms[Number(roomIndex)].adults = Number(value)
continue
}
// Handle children
const childRegex = /child\[(\d+)\]\.(.+)/
const childMatch = childRegex.exec(param)
if (childMatch) {
const [, childIndex, childParam] = childMatch
const room = rooms[Number(roomIndex)]
if (!room.children) room.children = []
// Set child properties
if (childParam === "age" && room.children) {
room.children[Number(childIndex)] = {
age: Number(value),
bed: Number(value),
}
} else if (childParam === "bed" && room.children?.[Number(childIndex)])
room.children[Number(childIndex)].bed = Number(value)
}
}
return rooms
}