UNPKG

@qite/tide-booking-component

Version:

React Booking wizard & Booking product component for Tide

191 lines (174 loc) 5.8 kB
import { BookingPackageAvailability, BookingPackageRoom, } from "@qite/tide-client/build/types"; import { AccommodationContent, RegimeContent, SelectableRoom, SelectableRoomAccommodation, } from "../../types"; export const buildSelectableRooms = ( packageRooms: BookingPackageRoom[], accommodations: AccommodationContent[] | undefined, regimes: RegimeContent[] | undefined, accommodationViews: { [key: string]: string } | undefined ) => { return packageRooms.map((x) => { const selectedOption = x.options.find((x) => x.isSelected)!; const alternativeOptions = x.options .filter( (x) => x.accommodationCode !== selectedOption.accommodationCode && !x.isLocked ) .sort((a, b) => a.price - b.price); const alternativeAccommodations: SelectableRoomAccommodation[] = []; alternativeOptions.forEach((x) => { const alternativeAccommodation = alternativeAccommodations.find( (y) => y.code === x.accommodationCode ); if (alternativeAccommodation) { const regime = regimes?.find((y) => y.code === x.regimeCode); alternativeAccommodation.regimes.push({ code: x.regimeCode, title: regime?.title ?? x.regimeName, price: x.price, }); } else { const accommodation = accommodations?.find( (y) => y.code === x.accommodationCode ); const regime = regimes?.find((y) => y.code === x.regimeCode); alternativeAccommodations.push({ code: x.accommodationCode, regimeCode: x.regimeCode, from: x.from, to: x.to, price: x.price, regimes: [ { code: x.regimeCode, title: regime?.title ?? x.regimeName, price: x.price, }, ], title: accommodation?.title ?? x.accommodationName, image: accommodation?.imageUrl, usps: accommodation?.usps ?? [], description: accommodation?.description, viewHtml: accommodationViews?.[x.accommodationCode], }); } }); const accommodation = accommodations?.find( (y) => y.code === selectedOption.accommodationCode ); return { index: x.index, selected: { code: selectedOption.accommodationCode, regimeCode: selectedOption.regimeCode, price: selectedOption.price, from: selectedOption.from, to: selectedOption.to, regimes: x.options .filter( (x) => x.accommodationCode === selectedOption.accommodationCode ) .sort((a, b) => a.price - b.price) .map((o) => { const regime = regimes?.find((y) => y.code === o.regimeCode); return { code: o.regimeCode, title: regime?.title ?? o.regimeName, price: o.price, }; }), title: accommodation?.title ?? selectedOption.accommodationName, image: accommodation?.imageUrl, usps: accommodation?.usps ?? [], description: accommodation?.description, viewHtml: accommodationViews?.[selectedOption.accommodationCode], }, showAlternatives: false, alternatives: alternativeAccommodations, } as SelectableRoom; }); }; export const updatePackageRooms = ( rooms: BookingPackageRoom[], index: number, accommodationCode: string, regimeCode: string | null, availabilities: BookingPackageAvailability[] ) => { const updatedRooms = rooms.map((room) => { if (room.index !== index) return room; return { ...room, options: room.options.map((option) => { return { ...option, isSelected: option.accommodationCode === accommodationCode && (option.regimeCode === regimeCode || (option.regimeCode === null && regimeCode === "")), }; }), }; }); const selectedAccommodations = new Map<string, number>(); updatedRooms .map((x) => x.options.find((x) => x.isSelected)!) .forEach((x) => { if (selectedAccommodations.has(x.accommodationCode)) { selectedAccommodations.set( x.accommodationCode, selectedAccommodations.get(x.accommodationCode)! + 1 ); } else { selectedAccommodations.set(x.accommodationCode, 1); } }); const accoCounter = availabilities.map((x) => ({ code: x.code, count: x.count, })); return updatedRooms.map((room) => { const selectedOption = room.options.find((x) => x.isSelected)!; return { ...room, options: room.options.map((option) => { const isCurrentOption = selectedOption.accommodationCode === option.accommodationCode; const usedCount = selectedAccommodations.get(option.accommodationCode) ?? 0; const availability = availabilities.find( (x) => x.code === option.accommodationCode ); if (availability) { const accoCount = accoCounter.find( (x) => x.code === option.accommodationCode )!; const roomsLeft = availability.count - usedCount; let isOnRequest = isCurrentOption ? accoCount.count < 0 && (availability?.onRequestPossible ?? false) : roomsLeft < 0 && (availability?.onRequestPossible ?? false); if (isCurrentOption) accoCount.count--; return { ...option, isLocked: !option.isSelected && !isOnRequest && roomsLeft < 0 && !availability.isExternal, isOnRequest: isOnRequest, }; } else { return option; } }), }; }); };