@qite/tide-booking-component
Version:
React Booking wizard & Booking product component for Tide
143 lines (127 loc) • 5.52 kB
text/typescript
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;
}
})
}
});
}