@qite/tide-booking-component
Version:
React Booking wizard & Booking product component for Tide
155 lines (138 loc) • 5.59 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 =
(option.isOnRequest && availability.count == 99) || // Tide sets count to 99 if an option falls back to on request.
(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;
}
})
};
});
};