@voyant-travel/bookings-react 0.157.0 → 0.159.0
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/dist/admin/index.d.ts +2 -5
- package/dist/admin/index.js +21 -6
- package/dist/hooks/use-public-booking-session-flow-mutation.d.ts +1 -1
- package/dist/hooks/use-public-booking-session.d.ts +1 -1
- package/dist/journey/components/booking-journey.js +42 -24
- package/dist/query-options.d.ts +4 -4
- package/dist/storefront/storefront-booking-journey.d.ts +2 -2
- package/dist/storefront/storefront-booking-journey.js +10 -63
- package/dist/storefront/storefront-checkout-bodies.d.ts +36 -0
- package/dist/storefront/storefront-checkout-bodies.js +69 -0
- package/package.json +40 -40
package/dist/admin/index.d.ts
CHANGED
|
@@ -213,11 +213,8 @@ export interface CreateBookingsAdminExtensionOptions {
|
|
|
213
213
|
* The bookings admin contribution (packaged-admin RFC Phase 3,
|
|
214
214
|
* `@voyant-travel/<domain>-ui/admin` convention).
|
|
215
215
|
*
|
|
216
|
-
* NAVIGATION:
|
|
217
|
-
*
|
|
218
|
-
* `@voyant-travel/admin` — so contributing nav entries here would duplicate it.
|
|
219
|
-
* If the base nav ever drops the bookings item, this extension is where the
|
|
220
|
-
* entry moves.
|
|
216
|
+
* NAVIGATION: the general-purpose factory remains neutral. The graph-selected
|
|
217
|
+
* factory below adds the standard operator Bookings item.
|
|
221
218
|
*
|
|
222
219
|
* ROUTES: full implementations (packaged-admin RFC §4.8) — the package-owned
|
|
223
220
|
* search contracts ({@link bookingsIndexSearchSchema} for the list,
|
package/dist/admin/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { defineAdminExtension, withAdminRouteMessagesProvider, } from "@voyant-t
|
|
|
5
5
|
// augmentation (`person.list`, `organization.list`, ...) into this program;
|
|
6
6
|
// this package already peer-depends on `@voyant-travel/relationships-react/ui`.
|
|
7
7
|
import { personDetailBookingsTabSlot } from "@voyant-travel/relationships-react/admin";
|
|
8
|
+
import { CalendarCheck } from "lucide-react";
|
|
8
9
|
import * as React from "react";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
// Lean statics only: the client module (fetcher), query-key types, and the
|
|
@@ -173,11 +174,8 @@ function PersonBookingsWidgetLoader(props) {
|
|
|
173
174
|
* The bookings admin contribution (packaged-admin RFC Phase 3,
|
|
174
175
|
* `@voyant-travel/<domain>-ui/admin` convention).
|
|
175
176
|
*
|
|
176
|
-
* NAVIGATION:
|
|
177
|
-
*
|
|
178
|
-
* `@voyant-travel/admin` — so contributing nav entries here would duplicate it.
|
|
179
|
-
* If the base nav ever drops the bookings item, this extension is where the
|
|
180
|
-
* entry moves.
|
|
177
|
+
* NAVIGATION: the general-purpose factory remains neutral. The graph-selected
|
|
178
|
+
* factory below adds the standard operator Bookings item.
|
|
181
179
|
*
|
|
182
180
|
* ROUTES: full implementations (packaged-admin RFC §4.8) — the package-owned
|
|
183
181
|
* search contracts ({@link bookingsIndexSearchSchema} for the list,
|
|
@@ -314,7 +312,24 @@ export function createBookingsAdminExtension(options = {}) {
|
|
|
314
312
|
});
|
|
315
313
|
}
|
|
316
314
|
export function createSelectedBookingsAdminExtension({ navMessages, }) {
|
|
317
|
-
|
|
315
|
+
const bookingsLabel = navMessages.bookings ?? "Bookings";
|
|
316
|
+
const extension = withAdminRouteMessagesProvider(createBookingsAdminExtension({ labels: { bookings: bookingsLabel } }), () => import("../i18n/index.js").then((module) => ({
|
|
318
317
|
default: module.BookingsUiMessagesProvider,
|
|
319
318
|
})));
|
|
319
|
+
return {
|
|
320
|
+
...extension,
|
|
321
|
+
navigation: [
|
|
322
|
+
{
|
|
323
|
+
order: -100,
|
|
324
|
+
items: [
|
|
325
|
+
{
|
|
326
|
+
id: "bookings",
|
|
327
|
+
title: bookingsLabel,
|
|
328
|
+
url: "/bookings",
|
|
329
|
+
icon: CalendarCheck,
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
};
|
|
320
335
|
}
|
|
@@ -105,7 +105,7 @@ export declare function usePublicBookingSessionFlowMutation(sessionId: string):
|
|
|
105
105
|
availabilitySlotId: string | null;
|
|
106
106
|
quantity: number;
|
|
107
107
|
allocationType: "resource" | "unit" | "pickup";
|
|
108
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
108
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
109
109
|
holdExpiresAt: string | null;
|
|
110
110
|
confirmedAt: string | null;
|
|
111
111
|
releasedAt: string | null;
|
|
@@ -69,7 +69,7 @@ export declare function usePublicBookingSession(sessionId: string | null | undef
|
|
|
69
69
|
availabilitySlotId: string | null;
|
|
70
70
|
quantity: number;
|
|
71
71
|
allocationType: "resource" | "unit" | "pickup";
|
|
72
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
72
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
73
73
|
holdExpiresAt: string | null;
|
|
74
74
|
confirmedAt: string | null;
|
|
75
75
|
releasedAt: string | null;
|
|
@@ -125,7 +125,7 @@ export function BookingJourney(props) {
|
|
|
125
125
|
// want to silently let two shoppers race past Configure with one
|
|
126
126
|
// capacity unit between them.
|
|
127
127
|
const holdApi = useBookingHold({ surface });
|
|
128
|
-
const holdState = useRef({});
|
|
128
|
+
const holdState = useRef({ transition: Promise.resolve() });
|
|
129
129
|
const holdSignature = makeHoldSignature(draft, props.entityModule, props.entityId);
|
|
130
130
|
// biome-ignore lint/correctness/useExhaustiveDependencies: signature change is the only trigger; refs + closure read latest values -- owner: bookings-react; existing suppression is intentional pending typed cleanup.
|
|
131
131
|
useEffect(() => {
|
|
@@ -143,30 +143,48 @@ export function BookingJourney(props) {
|
|
|
143
143
|
// is touched.
|
|
144
144
|
if (draft.payment.intent === "inquiry")
|
|
145
145
|
return;
|
|
146
|
-
|
|
147
|
-
holdState.current =
|
|
148
|
-
|
|
149
|
-
.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
holdState.current
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
146
|
+
holdState.current.signature = holdSignature;
|
|
147
|
+
holdState.current.transition = holdState.current.transition.then(async () => {
|
|
148
|
+
// A newer selection can arrive while this transition is queued. Skip
|
|
149
|
+
// stale work before it reaches inventory.
|
|
150
|
+
if (holdState.current.signature !== holdSignature)
|
|
151
|
+
return;
|
|
152
|
+
const previousToken = holdState.current.holdToken;
|
|
153
|
+
if (previousToken) {
|
|
154
|
+
holdState.current.holdToken = undefined;
|
|
155
|
+
await holdApi
|
|
156
|
+
.release({ entityModule: props.entityModule, holdToken: previousToken })
|
|
157
|
+
.catch(() => { });
|
|
158
|
+
}
|
|
159
|
+
// Re-check after the release: a newer transition may now be waiting.
|
|
160
|
+
if (holdState.current.signature !== holdSignature)
|
|
161
|
+
return;
|
|
162
|
+
try {
|
|
163
|
+
const result = await holdApi.place({
|
|
164
|
+
entityModule: props.entityModule,
|
|
165
|
+
entityId: props.entityId,
|
|
166
|
+
draftId: props.draftId,
|
|
167
|
+
parameters: {
|
|
168
|
+
slotId: draft.configure.departureSlotId,
|
|
169
|
+
paxCount: totalPax(draft),
|
|
170
|
+
productId: props.entityId,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
if (holdState.current.signature === holdSignature) {
|
|
174
|
+
holdState.current.holdToken = result.holdToken;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// The placement completed after the selection changed. Release it
|
|
178
|
+
// before the queued replacement starts so token-wide release cannot
|
|
179
|
+
// delete that replacement.
|
|
180
|
+
await holdApi
|
|
181
|
+
.release({ entityModule: props.entityModule, holdToken: result.holdToken })
|
|
182
|
+
.catch(() => { });
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Non-blocking — see comment above.
|
|
186
|
+
}
|
|
164
187
|
});
|
|
165
|
-
if (previousToken) {
|
|
166
|
-
void holdApi
|
|
167
|
-
.release({ entityModule: props.entityModule, holdToken: previousToken })
|
|
168
|
-
.catch(() => { });
|
|
169
|
-
}
|
|
170
188
|
}, [holdSignature, currentStep]);
|
|
171
189
|
const available = quote.data?.available !== false;
|
|
172
190
|
// A failed quote (e.g. the connector adapter 500s) leaves `quote.data` null,
|
package/dist/query-options.d.ts
CHANGED
|
@@ -1739,7 +1739,7 @@ export declare function getPublicBookingSessionQueryOptions(client: FetchWithVal
|
|
|
1739
1739
|
availabilitySlotId: string | null;
|
|
1740
1740
|
quantity: number;
|
|
1741
1741
|
allocationType: "resource" | "unit" | "pickup";
|
|
1742
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
1742
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
1743
1743
|
holdExpiresAt: string | null;
|
|
1744
1744
|
confirmedAt: string | null;
|
|
1745
1745
|
releasedAt: string | null;
|
|
@@ -1835,7 +1835,7 @@ export declare function getPublicBookingSessionQueryOptions(client: FetchWithVal
|
|
|
1835
1835
|
availabilitySlotId: string | null;
|
|
1836
1836
|
quantity: number;
|
|
1837
1837
|
allocationType: "resource" | "unit" | "pickup";
|
|
1838
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
1838
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
1839
1839
|
holdExpiresAt: string | null;
|
|
1840
1840
|
confirmedAt: string | null;
|
|
1841
1841
|
releasedAt: string | null;
|
|
@@ -1932,7 +1932,7 @@ export declare function getPublicBookingSessionQueryOptions(client: FetchWithVal
|
|
|
1932
1932
|
availabilitySlotId: string | null;
|
|
1933
1933
|
quantity: number;
|
|
1934
1934
|
allocationType: "resource" | "unit" | "pickup";
|
|
1935
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
1935
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
1936
1936
|
holdExpiresAt: string | null;
|
|
1937
1937
|
confirmedAt: string | null;
|
|
1938
1938
|
releasedAt: string | null;
|
|
@@ -2031,7 +2031,7 @@ export declare function getPublicBookingSessionQueryOptions(client: FetchWithVal
|
|
|
2031
2031
|
availabilitySlotId: string | null;
|
|
2032
2032
|
quantity: number;
|
|
2033
2033
|
allocationType: "resource" | "unit" | "pickup";
|
|
2034
|
-
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "
|
|
2034
|
+
status: "cancelled" | "fulfilled" | "confirmed" | "expired" | "released" | "held";
|
|
2035
2035
|
holdExpiresAt: string | null;
|
|
2036
2036
|
confirmedAt: string | null;
|
|
2037
2037
|
releasedAt: string | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type BookingEntitySummary, type BookingJourneyCheckoutContext, type ContractAcceptanceEvent
|
|
1
|
+
import { type BookingEntitySummary, type BookingJourneyCheckoutContext, type ContractAcceptanceEvent } from "../journey/index.js";
|
|
2
2
|
import { type ContractSourceContext } from "./resolve-contract-variables.js";
|
|
3
|
+
export { buildStorefrontBookBody, buildStorefrontCheckoutStartBody, buildStorefrontCommitParty, } from "./storefront-checkout-bodies.js";
|
|
3
4
|
export interface StorefrontBookingJourneyMessages {
|
|
4
5
|
checkoutFailed: string;
|
|
5
6
|
requestReference: string;
|
|
@@ -68,4 +69,3 @@ export interface StorefrontBookingJourneyProps {
|
|
|
68
69
|
className?: string;
|
|
69
70
|
}
|
|
70
71
|
export declare function StorefrontBookingJourney({ entityModule, entityId, sourceKind, sourceConnectionId, sourceRef, draftId, initialConfigure, initialAccommodation, entitySummary, entitySource, contractTemplateSlug, contractMarketingLabel, onContractAccepted, messages, scope, onNavigateToShop, onNavigateToConfirmation, onRedirectToPayment, className, }: StorefrontBookingJourneyProps): React.ReactElement;
|
|
71
|
-
export declare function buildStorefrontCommitParty(draft: Draft): Record<string, unknown>;
|
|
@@ -17,6 +17,8 @@ import { useVoyantReactContext } from "@voyant-travel/react";
|
|
|
17
17
|
import { BookingJourney, } from "../journey/index.js";
|
|
18
18
|
import { resolveContractVariables, } from "./resolve-contract-variables.js";
|
|
19
19
|
import { buildStorefrontBookFailureMessage, } from "./storefront-booking-errors.js";
|
|
20
|
+
import { buildStorefrontBookBody, buildStorefrontCheckoutStartBody, } from "./storefront-checkout-bodies.js";
|
|
21
|
+
export { buildStorefrontBookBody, buildStorefrontCheckoutStartBody, buildStorefrontCommitParty, } from "./storefront-checkout-bodies.js";
|
|
20
22
|
/**
|
|
21
23
|
* Marker for checkout failures we've already turned into a localized,
|
|
22
24
|
* customer-facing message. Native errors (a `fetch` network drop, a
|
|
@@ -72,10 +74,6 @@ export function StorefrontBookingJourney({ entityModule, entityId, sourceKind, s
|
|
|
72
74
|
//
|
|
73
75
|
const defaultCheckoutHandler = async (acceptance, context) => {
|
|
74
76
|
try {
|
|
75
|
-
const intent = checkoutIntentFromDraft(context.draft.payment.intent);
|
|
76
|
-
const contact = context.draft.billing?.contact;
|
|
77
|
-
const payerName = [contact?.firstName, contact?.lastName].filter(Boolean).join(" ").trim();
|
|
78
|
-
const idempotencyKey = `bj-${draftId}-${acceptance?.acceptedAt ?? "noaccept"}`;
|
|
79
77
|
// Step 1 — book the entity. Send the live scoped quote id explicitly
|
|
80
78
|
// (the server prefers `quoteId` over resolving the draft's stored
|
|
81
79
|
// `currentQuoteId`), so a market/currency change made mid-journey books
|
|
@@ -85,13 +83,12 @@ export function StorefrontBookingJourney({ entityModule, entityId, sourceKind, s
|
|
|
85
83
|
method: "POST",
|
|
86
84
|
credentials: "include",
|
|
87
85
|
headers: { "content-type": "application/json" },
|
|
88
|
-
body: JSON.stringify({
|
|
86
|
+
body: JSON.stringify(buildStorefrontBookBody({
|
|
89
87
|
draftId,
|
|
90
88
|
quoteId: context.quoteId,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}),
|
|
89
|
+
draft: context.draft,
|
|
90
|
+
acceptedAt: acceptance?.acceptedAt,
|
|
91
|
+
})),
|
|
95
92
|
});
|
|
96
93
|
if (!bookRes.ok) {
|
|
97
94
|
const errBody = (await bookRes.json().catch(() => ({})));
|
|
@@ -124,25 +121,12 @@ export function StorefrontBookingJourney({ entityModule, entityId, sourceKind, s
|
|
|
124
121
|
method: "POST",
|
|
125
122
|
credentials: "include",
|
|
126
123
|
headers: { "content-type": "application/json" },
|
|
127
|
-
body: JSON.stringify({
|
|
124
|
+
body: JSON.stringify(buildStorefrontCheckoutStartBody({
|
|
128
125
|
bookingId,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
? {
|
|
132
|
-
contractAcceptance: {
|
|
133
|
-
templateId: acceptance.templateId,
|
|
134
|
-
templateSlug: acceptance.templateSlug,
|
|
135
|
-
acceptedTerms: true,
|
|
136
|
-
acceptedMarketing: acceptance.acceptedMarketing,
|
|
137
|
-
acceptedAt: acceptance.acceptedAt,
|
|
138
|
-
renderedHtml: acceptance.renderedHtml,
|
|
139
|
-
},
|
|
140
|
-
}
|
|
141
|
-
: {}),
|
|
142
|
-
...(contact?.email ? { payerEmail: contact.email } : {}),
|
|
143
|
-
...(payerName ? { payerName } : {}),
|
|
126
|
+
draft: context.draft,
|
|
127
|
+
acceptance,
|
|
144
128
|
returnOrigin: window.location.origin,
|
|
145
|
-
}),
|
|
129
|
+
})),
|
|
146
130
|
});
|
|
147
131
|
const json = (await startRes.json());
|
|
148
132
|
if ("error" in json) {
|
|
@@ -241,43 +225,6 @@ export function StorefrontBookingJourney({ entityModule, entityId, sourceKind, s
|
|
|
241
225
|
acceptsInquiry: true,
|
|
242
226
|
}, className: className, ...slots }));
|
|
243
227
|
}
|
|
244
|
-
function checkoutIntentFromDraft(intent) {
|
|
245
|
-
if (intent === "card" || intent === "bank_transfer" || intent === "inquiry")
|
|
246
|
-
return intent;
|
|
247
|
-
return "hold";
|
|
248
|
-
}
|
|
249
|
-
export function buildStorefrontCommitParty(draft) {
|
|
250
|
-
const contact = draft.billing.contact;
|
|
251
|
-
const personId = draft.billing.buyerType === "B2C" ? contact.personId : undefined;
|
|
252
|
-
const organizationId = draft.billing.buyerType === "B2B" ? draft.billing.organizationId : undefined;
|
|
253
|
-
return {
|
|
254
|
-
personId,
|
|
255
|
-
organizationId,
|
|
256
|
-
billing: {
|
|
257
|
-
personId,
|
|
258
|
-
organizationId,
|
|
259
|
-
contact: {
|
|
260
|
-
firstName: contact.firstName,
|
|
261
|
-
lastName: contact.lastName,
|
|
262
|
-
email: contact.email,
|
|
263
|
-
phone: contact.phone,
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
travelerParty: {
|
|
267
|
-
travelers: draft.travelers.map((traveler) => ({
|
|
268
|
-
personId: traveler.personId,
|
|
269
|
-
firstName: traveler.firstName,
|
|
270
|
-
lastName: traveler.lastName,
|
|
271
|
-
email: traveler.email,
|
|
272
|
-
phone: traveler.phone,
|
|
273
|
-
dateOfBirth: traveler.dateOfBirth,
|
|
274
|
-
band: traveler.band,
|
|
275
|
-
documents: traveler.documents,
|
|
276
|
-
isPrimary: traveler.isPrimary,
|
|
277
|
-
})),
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
228
|
/**
|
|
282
229
|
* Resolve which contract template to preview at the Review step.
|
|
283
230
|
*
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ContractAcceptanceEvent, Draft } from "../journey/index.js";
|
|
2
|
+
export declare function buildStorefrontBookBody(input: {
|
|
3
|
+
draftId: string;
|
|
4
|
+
quoteId?: string;
|
|
5
|
+
draft: Draft;
|
|
6
|
+
acceptedAt?: string;
|
|
7
|
+
}): {
|
|
8
|
+
draftId: string;
|
|
9
|
+
quoteId: string | undefined;
|
|
10
|
+
party: Record<string, unknown>;
|
|
11
|
+
paymentIntent: {
|
|
12
|
+
type: "hold";
|
|
13
|
+
};
|
|
14
|
+
idempotencyKey: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function buildStorefrontCheckoutStartBody(input: {
|
|
17
|
+
bookingId: string;
|
|
18
|
+
draft: Draft;
|
|
19
|
+
acceptance: ContractAcceptanceEvent | null;
|
|
20
|
+
returnOrigin: string;
|
|
21
|
+
}): {
|
|
22
|
+
returnOrigin: string;
|
|
23
|
+
payerName?: string | undefined;
|
|
24
|
+
payerEmail?: string | undefined;
|
|
25
|
+
contractAcceptance?: {
|
|
26
|
+
templateId: string;
|
|
27
|
+
templateSlug: string;
|
|
28
|
+
acceptedTerms: true;
|
|
29
|
+
acceptedMarketing: boolean;
|
|
30
|
+
acceptedAt: string;
|
|
31
|
+
renderedHtml: string;
|
|
32
|
+
} | undefined;
|
|
33
|
+
bookingId: string;
|
|
34
|
+
paymentIntent: "hold" | "card" | "bank_transfer" | "inquiry";
|
|
35
|
+
};
|
|
36
|
+
export declare function buildStorefrontCommitParty(draft: Draft): Record<string, unknown>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function buildStorefrontBookBody(input) {
|
|
2
|
+
return {
|
|
3
|
+
draftId: input.draftId,
|
|
4
|
+
quoteId: input.quoteId,
|
|
5
|
+
party: buildStorefrontCommitParty(input.draft),
|
|
6
|
+
paymentIntent: { type: "hold" },
|
|
7
|
+
idempotencyKey: `bj-${input.draftId}-${input.acceptedAt ?? "noaccept"}`,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function buildStorefrontCheckoutStartBody(input) {
|
|
11
|
+
const contact = input.draft.billing?.contact;
|
|
12
|
+
const payerName = [contact?.firstName, contact?.lastName].filter(Boolean).join(" ").trim();
|
|
13
|
+
return {
|
|
14
|
+
bookingId: input.bookingId,
|
|
15
|
+
paymentIntent: checkoutIntentFromDraft(input.draft.payment.intent),
|
|
16
|
+
...(input.acceptance
|
|
17
|
+
? {
|
|
18
|
+
contractAcceptance: {
|
|
19
|
+
templateId: input.acceptance.templateId,
|
|
20
|
+
templateSlug: input.acceptance.templateSlug,
|
|
21
|
+
acceptedTerms: true,
|
|
22
|
+
acceptedMarketing: input.acceptance.acceptedMarketing,
|
|
23
|
+
acceptedAt: input.acceptance.acceptedAt,
|
|
24
|
+
renderedHtml: input.acceptance.renderedHtml,
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
: {}),
|
|
28
|
+
...(contact?.email ? { payerEmail: contact.email } : {}),
|
|
29
|
+
...(payerName ? { payerName } : {}),
|
|
30
|
+
returnOrigin: input.returnOrigin,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function checkoutIntentFromDraft(intent) {
|
|
34
|
+
if (intent === "card" || intent === "bank_transfer" || intent === "inquiry")
|
|
35
|
+
return intent;
|
|
36
|
+
return "hold";
|
|
37
|
+
}
|
|
38
|
+
export function buildStorefrontCommitParty(draft) {
|
|
39
|
+
const contact = draft.billing.contact;
|
|
40
|
+
const personId = draft.billing.buyerType === "B2C" ? contact.personId : undefined;
|
|
41
|
+
const organizationId = draft.billing.buyerType === "B2B" ? draft.billing.organizationId : undefined;
|
|
42
|
+
return {
|
|
43
|
+
personId,
|
|
44
|
+
organizationId,
|
|
45
|
+
billing: {
|
|
46
|
+
personId,
|
|
47
|
+
organizationId,
|
|
48
|
+
contact: {
|
|
49
|
+
firstName: contact.firstName,
|
|
50
|
+
lastName: contact.lastName,
|
|
51
|
+
email: contact.email,
|
|
52
|
+
phone: contact.phone,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
travelerParty: {
|
|
56
|
+
travelers: draft.travelers.map((traveler) => ({
|
|
57
|
+
personId: traveler.personId,
|
|
58
|
+
firstName: traveler.firstName,
|
|
59
|
+
lastName: traveler.lastName,
|
|
60
|
+
email: traveler.email,
|
|
61
|
+
phone: traveler.phone,
|
|
62
|
+
dateOfBirth: traveler.dateOfBirth,
|
|
63
|
+
band: traveler.band,
|
|
64
|
+
documents: traveler.documents,
|
|
65
|
+
isPrimary: traveler.isPrimary,
|
|
66
|
+
})),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/bookings-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.159.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -145,29 +145,29 @@
|
|
|
145
145
|
"peerDependencies": {
|
|
146
146
|
"@tanstack/react-query": "^5.0.0",
|
|
147
147
|
"@tanstack/react-table": "^8.0.0",
|
|
148
|
-
"lucide-react": "^1.
|
|
148
|
+
"lucide-react": "^0.475.0 || ^1.0.0",
|
|
149
149
|
"react": "^19.0.0",
|
|
150
150
|
"react-dom": "^19.0.0",
|
|
151
151
|
"react-hook-form": "^7.80.0",
|
|
152
152
|
"zod": "^4.0.0",
|
|
153
|
-
"@voyant-travel/accommodations": "^0.
|
|
154
|
-
"@voyant-travel/admin": "^0.
|
|
155
|
-
"@voyant-travel/bookings": "^0.
|
|
156
|
-
"@voyant-travel/catalog": "^0.
|
|
157
|
-
"@voyant-travel/catalog-react": "^0.
|
|
158
|
-
"@voyant-travel/distribution-react": "^0.
|
|
159
|
-
"@voyant-travel/relationships-react": "^0.
|
|
160
|
-
"@voyant-travel/finance": "^0.
|
|
161
|
-
"@voyant-travel/finance-react": "^0.
|
|
162
|
-
"@voyant-travel/identity-react": "^0.
|
|
163
|
-
"@voyant-travel/legal-react": "^0.
|
|
164
|
-
"@voyant-travel/commerce-react": "^0.
|
|
165
|
-
"@voyant-travel/cruises": "^0.
|
|
166
|
-
"@voyant-travel/inventory-react": "^0.
|
|
167
|
-
"@voyant-travel/inventory": "^0.10.
|
|
168
|
-
"@voyant-travel/storefront-react": "^0.
|
|
169
|
-
"@voyant-travel/ui": "^0.109.
|
|
170
|
-
"@voyant-travel/operations-react": "^0.
|
|
153
|
+
"@voyant-travel/accommodations": "^0.119.0",
|
|
154
|
+
"@voyant-travel/admin": "^0.125.0",
|
|
155
|
+
"@voyant-travel/bookings": "^0.159.0",
|
|
156
|
+
"@voyant-travel/catalog": "^0.157.0",
|
|
157
|
+
"@voyant-travel/catalog-react": "^0.157.0",
|
|
158
|
+
"@voyant-travel/distribution-react": "^0.149.0",
|
|
159
|
+
"@voyant-travel/relationships-react": "^0.159.0",
|
|
160
|
+
"@voyant-travel/finance": "^0.159.0",
|
|
161
|
+
"@voyant-travel/finance-react": "^0.159.0",
|
|
162
|
+
"@voyant-travel/identity-react": "^0.159.0",
|
|
163
|
+
"@voyant-travel/legal-react": "^0.159.0",
|
|
164
|
+
"@voyant-travel/commerce-react": "^0.41.0",
|
|
165
|
+
"@voyant-travel/cruises": "^0.158.0",
|
|
166
|
+
"@voyant-travel/inventory-react": "^0.41.0",
|
|
167
|
+
"@voyant-travel/inventory": "^0.10.4",
|
|
168
|
+
"@voyant-travel/storefront-react": "^0.161.0",
|
|
169
|
+
"@voyant-travel/ui": "^0.109.2",
|
|
170
|
+
"@voyant-travel/operations-react": "^0.40.0"
|
|
171
171
|
},
|
|
172
172
|
"peerDependenciesMeta": {
|
|
173
173
|
"@tanstack/react-table": {
|
|
@@ -233,10 +233,10 @@
|
|
|
233
233
|
},
|
|
234
234
|
"dependencies": {
|
|
235
235
|
"sonner": "^2.0.7",
|
|
236
|
-
"@voyant-travel/catalog-contracts": "^0.111.
|
|
236
|
+
"@voyant-travel/catalog-contracts": "^0.111.1",
|
|
237
237
|
"@voyant-travel/i18n": "^0.111.1",
|
|
238
238
|
"@voyant-travel/react": "^0.104.2",
|
|
239
|
-
"@voyant-travel/types": "^0.109.
|
|
239
|
+
"@voyant-travel/types": "^0.109.2"
|
|
240
240
|
},
|
|
241
241
|
"devDependencies": {
|
|
242
242
|
"@tanstack/react-query": "^5.101.2",
|
|
@@ -251,26 +251,26 @@
|
|
|
251
251
|
"typescript": "^6.0.3",
|
|
252
252
|
"vitest": "^4.1.9",
|
|
253
253
|
"zod": "^4.4.3",
|
|
254
|
-
"@voyant-travel/accommodations": "^0.
|
|
255
|
-
"@voyant-travel/admin": "^0.
|
|
256
|
-
"@voyant-travel/bookings": "^0.
|
|
257
|
-
"@voyant-travel/catalog": "^0.
|
|
258
|
-
"@voyant-travel/catalog-react": "^0.
|
|
259
|
-
"@voyant-travel/distribution-react": "^0.
|
|
260
|
-
"@voyant-travel/relationships-react": "^0.
|
|
261
|
-
"@voyant-travel/finance": "^0.
|
|
262
|
-
"@voyant-travel/finance-react": "^0.
|
|
263
|
-
"@voyant-travel/identity-react": "^0.
|
|
264
|
-
"@voyant-travel/legal-react": "^0.
|
|
265
|
-
"@voyant-travel/commerce-react": "^0.
|
|
266
|
-
"@voyant-travel/cruises": "^0.
|
|
267
|
-
"@voyant-travel/inventory-react": "^0.
|
|
268
|
-
"@voyant-travel/inventory": "^0.10.
|
|
254
|
+
"@voyant-travel/accommodations": "^0.119.0",
|
|
255
|
+
"@voyant-travel/admin": "^0.125.0",
|
|
256
|
+
"@voyant-travel/bookings": "^0.159.0",
|
|
257
|
+
"@voyant-travel/catalog": "^0.157.0",
|
|
258
|
+
"@voyant-travel/catalog-react": "^0.157.0",
|
|
259
|
+
"@voyant-travel/distribution-react": "^0.149.0",
|
|
260
|
+
"@voyant-travel/relationships-react": "^0.159.0",
|
|
261
|
+
"@voyant-travel/finance": "^0.159.0",
|
|
262
|
+
"@voyant-travel/finance-react": "^0.159.0",
|
|
263
|
+
"@voyant-travel/identity-react": "^0.159.0",
|
|
264
|
+
"@voyant-travel/legal-react": "^0.159.0",
|
|
265
|
+
"@voyant-travel/commerce-react": "^0.41.0",
|
|
266
|
+
"@voyant-travel/cruises": "^0.158.0",
|
|
267
|
+
"@voyant-travel/inventory-react": "^0.41.0",
|
|
268
|
+
"@voyant-travel/inventory": "^0.10.4",
|
|
269
269
|
"@voyant-travel/react": "^0.104.2",
|
|
270
|
-
"@voyant-travel/storefront-react": "^0.
|
|
271
|
-
"@voyant-travel/ui": "^0.109.
|
|
270
|
+
"@voyant-travel/storefront-react": "^0.161.0",
|
|
271
|
+
"@voyant-travel/ui": "^0.109.2",
|
|
272
272
|
"@voyant-travel/voyant-typescript-config": "^0.1.0",
|
|
273
|
-
"@voyant-travel/operations-react": "^0.
|
|
273
|
+
"@voyant-travel/operations-react": "^0.40.0"
|
|
274
274
|
},
|
|
275
275
|
"files": [
|
|
276
276
|
"dist",
|