@ticketboothapp/booking 1.2.54 → 1.2.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export interface BookingData {
|
|
2
2
|
bookingReference: string;
|
|
3
|
-
reservationReference?: string;
|
|
4
|
-
dateTime?: string;
|
|
5
|
-
totalAmount?: number;
|
|
6
|
-
currency?: string;
|
|
7
|
-
productId?: string;
|
|
8
|
-
optionId?: string;
|
|
9
|
-
bookingItems?: Array<{ category: string; count: number }
|
|
3
|
+
reservationReference?: string | null;
|
|
4
|
+
dateTime?: string | null;
|
|
5
|
+
totalAmount?: number | null;
|
|
6
|
+
currency?: string | null;
|
|
7
|
+
productId?: string | null;
|
|
8
|
+
optionId?: string | null;
|
|
9
|
+
bookingItems?: Array<{ category: string; count: number }> | null;
|
|
10
10
|
pickupLocationId?: string | null;
|
|
11
11
|
travelerHotel?: string | null;
|
|
12
12
|
startTime?: string | null;
|
|
@@ -14,5 +14,4 @@ export interface BookingData {
|
|
|
14
14
|
cancellationPolicyId?: string | null;
|
|
15
15
|
promoCode?: string | null;
|
|
16
16
|
addOnSelections?: Array<{ addOnId: string; variantId?: string; quantity?: number }> | null;
|
|
17
|
-
[key: string]: unknown;
|
|
18
17
|
}
|
|
@@ -673,6 +673,8 @@ export function BookingFlow({
|
|
|
673
673
|
const [precomputedPricesByOption, setPrecomputedPricesByOption] = useState<Record<string, PrecomputedPricesByCategory> | null>(null);
|
|
674
674
|
const pricingConfigSetRef = useRef(false); // Track if pricingConfig has been set (optimize: only set once)
|
|
675
675
|
const fetchingRef = useRef(false); // Prevent concurrent fetches
|
|
676
|
+
const hasLoadedAvailabilitiesRef = useRef(false); // First successful availability paint completed
|
|
677
|
+
const inFlightRangeRef = useRef<{ start: Date; end: Date } | null>(null); // Range currently being fetched
|
|
676
678
|
const fetchedRangesRef = useRef<Array<{ start: Date; end: Date }>>([]); // Track fetched date ranges
|
|
677
679
|
const pendingRangeRef = useRef<{ start: Date; end: Date } | null>(null); // Range to fetch when current fetch completes (user navigated during fetch)
|
|
678
680
|
const [visibleRange, setVisibleRange] = useState<{ start: Date; end: Date } | null>(null);
|
|
@@ -1068,6 +1070,14 @@ export function BookingFlow({
|
|
|
1068
1070
|
async function fetchAvailabilities() {
|
|
1069
1071
|
// Prevent concurrent fetches - store range to fetch when current one completes
|
|
1070
1072
|
if (fetchingRef.current && visibleRange) {
|
|
1073
|
+
const inFlight = inFlightRangeRef.current;
|
|
1074
|
+
if (
|
|
1075
|
+
inFlight &&
|
|
1076
|
+
inFlight.start.getTime() === visibleRange.start.getTime() &&
|
|
1077
|
+
inFlight.end.getTime() === visibleRange.end.getTime()
|
|
1078
|
+
) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1071
1081
|
pendingRangeRef.current = { start: visibleRange.start, end: visibleRange.end };
|
|
1072
1082
|
return;
|
|
1073
1083
|
}
|
|
@@ -1119,6 +1129,9 @@ export function BookingFlow({
|
|
|
1119
1129
|
const isStale = availabilitiesCache?.isStale(cached) ?? false;
|
|
1120
1130
|
if (cacheCoversRange) {
|
|
1121
1131
|
setAvailabilities(cached.availabilities);
|
|
1132
|
+
if (cached.availabilities.length > 0) {
|
|
1133
|
+
hasLoadedAvailabilitiesRef.current = true;
|
|
1134
|
+
}
|
|
1122
1135
|
if (cached.pricingConfig) {
|
|
1123
1136
|
setPricingConfig(cached.pricingConfig);
|
|
1124
1137
|
pricingConfigSetRef.current = true;
|
|
@@ -1137,6 +1150,9 @@ export function BookingFlow({
|
|
|
1137
1150
|
}
|
|
1138
1151
|
// Partial cache: show cached data immediately, then fetch missing range below
|
|
1139
1152
|
setAvailabilities(cached.availabilities);
|
|
1153
|
+
if (cached.availabilities.length > 0) {
|
|
1154
|
+
hasLoadedAvailabilitiesRef.current = true;
|
|
1155
|
+
}
|
|
1140
1156
|
if (cached.pricingConfig) {
|
|
1141
1157
|
setPricingConfig(cached.pricingConfig);
|
|
1142
1158
|
pricingConfigSetRef.current = true;
|
|
@@ -1160,8 +1176,14 @@ export function BookingFlow({
|
|
|
1160
1176
|
}
|
|
1161
1177
|
|
|
1162
1178
|
const hasPartialCache = cached && cached.availabilities.length > 0;
|
|
1179
|
+
const shouldUsePrimaryLoader =
|
|
1180
|
+
!hasPartialCache && !hasLoadedAvailabilitiesRef.current;
|
|
1163
1181
|
fetchingRef.current = true;
|
|
1164
|
-
|
|
1182
|
+
inFlightRangeRef.current = {
|
|
1183
|
+
start: new Date(clampedStart),
|
|
1184
|
+
end: new Date(clampedEnd),
|
|
1185
|
+
};
|
|
1186
|
+
if (shouldUsePrimaryLoader) setLoadingAvailabilities(true);
|
|
1165
1187
|
else setIsFetchingMoreAvailabilities(true);
|
|
1166
1188
|
|
|
1167
1189
|
try {
|
|
@@ -1218,6 +1240,9 @@ export function BookingFlow({
|
|
|
1218
1240
|
|
|
1219
1241
|
const results = await Promise.all(availabilityPromises);
|
|
1220
1242
|
const allFetchedAvailabilities = results.flatMap(r => r.availabilities);
|
|
1243
|
+
if (allFetchedAvailabilities.length > 0) {
|
|
1244
|
+
hasLoadedAvailabilitiesRef.current = true;
|
|
1245
|
+
}
|
|
1221
1246
|
setPrecomputedPricesByOption(prev => {
|
|
1222
1247
|
const next = { ...(prev || {}) };
|
|
1223
1248
|
results.forEach(r => {
|
|
@@ -1298,6 +1323,7 @@ export function BookingFlow({
|
|
|
1298
1323
|
setLoadingAvailabilities(false);
|
|
1299
1324
|
setIsFetchingMoreAvailabilities(false);
|
|
1300
1325
|
fetchingRef.current = false;
|
|
1326
|
+
inFlightRangeRef.current = null;
|
|
1301
1327
|
// If user navigated during fetch, trigger fetch for the pending range
|
|
1302
1328
|
const pending = pendingRangeRef.current;
|
|
1303
1329
|
if (pending) {
|
|
@@ -252,7 +252,7 @@ export function ItineraryBox({
|
|
|
252
252
|
<button
|
|
253
253
|
type="button"
|
|
254
254
|
onClick={handlePickupLocationClick}
|
|
255
|
-
className={styles.placeLink}
|
|
255
|
+
className={`${styles.placeLink} text-emerald-600`}
|
|
256
256
|
>
|
|
257
257
|
{getDisplayLabel(locationOnlyDisplay)}
|
|
258
258
|
</button>
|
|
@@ -284,7 +284,7 @@ export function ItineraryBox({
|
|
|
284
284
|
<button
|
|
285
285
|
type="button"
|
|
286
286
|
onClick={handlePickupLocationClick}
|
|
287
|
-
className={styles.placeLink}
|
|
287
|
+
className={`${styles.placeLink} text-emerald-600`}
|
|
288
288
|
>
|
|
289
289
|
{getDisplayLabel(locationOnlyDisplay)}
|
|
290
290
|
</button>
|
|
@@ -301,13 +301,16 @@
|
|
|
301
301
|
color: #b91c1c !important;
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
/* Clickable "your pickup location" etc.
|
|
304
|
+
/* Clickable "your pickup location" etc. should stay booking green */
|
|
305
305
|
.booking-flow-preflight button.text-stone-400.underline,
|
|
306
306
|
.booking-flow-preflight button.text-stone-400.underline:hover {
|
|
307
|
-
color: var(--booking-
|
|
307
|
+
color: var(--booking-emerald-600, #059669) !important;
|
|
308
308
|
background: none;
|
|
309
309
|
border: none;
|
|
310
310
|
}
|
|
311
|
+
.booking-flow-preflight button.text-stone-400.underline:hover {
|
|
312
|
+
color: var(--booking-emerald-700, #047857) !important;
|
|
313
|
+
}
|
|
311
314
|
|
|
312
315
|
/* ========== Itinerary section - orange bg, Poppins, lowercase (match TourDescription) ========== */
|
|
313
316
|
.booking-flow-preflight [class*="ItineraryBox_box"],
|