@voyant-travel/bookings-react 0.201.1 → 0.203.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/README.md +8 -8
- package/dist/admin/bookings-host.d.ts +1 -2
- package/dist/admin/bookings-host.js +2 -3
- package/dist/admin/index.d.ts +6 -44
- package/dist/admin/index.js +2 -65
- package/dist/components/booking-create-utils.d.ts +1 -1
- package/dist/components/booking-create-utils.js +5 -17
- package/dist/components/booking-dialog.d.ts +4 -19
- package/dist/components/booking-dialog.js +3 -12
- package/dist/components/booking-list.d.ts +1 -2
- package/dist/components/booking-list.js +5 -13
- package/dist/components/bookings-page.d.ts +1 -2
- package/dist/components/bookings-page.js +2 -2
- package/dist/hooks/booking-create-types.d.ts +34 -0
- package/dist/hooks/booking-create-types.js +1 -0
- package/dist/hooks/index.d.ts +2 -4
- package/dist/hooks/index.js +1 -4
- package/dist/hooks/use-booking-mutation.d.ts +3 -65
- package/dist/hooks/use-booking-mutation.js +1 -10
- package/dist/i18n/en-create-list.d.ts +0 -1
- package/dist/i18n/en-create-list.js +0 -1
- package/dist/i18n/en.d.ts +0 -1
- package/dist/i18n/messages-create-list.d.ts +0 -1
- package/dist/i18n/provider.d.ts +0 -2
- package/dist/i18n/ro-create-list.d.ts +0 -1
- package/dist/i18n/ro-create-list.js +0 -1
- package/dist/i18n/ro.d.ts +0 -1
- package/dist/journey/components/booking-journey-rules.d.ts +0 -22
- package/dist/journey/components/booking-journey-rules.js +0 -54
- package/dist/journey/components/journey-steps/payment-step.js +1 -1
- package/dist/journey/components/journey-steps/shared.d.ts +3 -3
- package/dist/journey/components/journey-steps.d.ts +1 -1
- package/dist/journey/components/journey-steps.js +1 -1
- package/dist/journey/index.d.ts +2 -12
- package/dist/journey/index.js +1 -11
- package/dist/journey/types.d.ts +3 -208
- package/dist/journey/types.js +2 -6
- package/dist/storefront/index.d.ts +0 -2
- package/dist/storefront/index.js +0 -2
- package/dist/ui.d.ts +0 -2
- package/dist/ui.js +0 -2
- package/package.json +33 -33
- package/dist/admin/booking-journey-host.d.ts +0 -23
- package/dist/admin/booking-journey-host.js +0 -280
- package/dist/admin/journey-billing-duplicate-warning.d.ts +0 -2
- package/dist/admin/journey-billing-duplicate-warning.js +0 -26
- package/dist/admin/journey-departure-picker.d.ts +0 -6
- package/dist/admin/journey-departure-picker.js +0 -91
- package/dist/admin/journey-travel-credit-picker.d.ts +0 -2
- package/dist/admin/journey-travel-credit-picker.js +0 -72
- package/dist/admin/journey-units-picker.d.ts +0 -10
- package/dist/admin/journey-units-picker.js +0 -60
- package/dist/admin/pages/booking-journey-page.d.ts +0 -11
- package/dist/admin/pages/booking-journey-page.js +0 -26
- package/dist/admin/pages/booking-new-page.d.ts +0 -15
- package/dist/admin/pages/booking-new-page.js +0 -50
- package/dist/components/booking-create-page.d.ts +0 -13
- package/dist/components/booking-create-page.js +0 -11
- package/dist/components/booking-create-sheet.d.ts +0 -34
- package/dist/components/booking-create-sheet.js +0 -815
- package/dist/hooks/use-booking-convert-mutation.d.ts +0 -80
- package/dist/hooks/use-booking-convert-mutation.js +0 -24
- package/dist/hooks/use-booking-create-mutation.d.ts +0 -336
- package/dist/hooks/use-booking-create-mutation.js +0 -43
- package/dist/hooks/use-booking-dual-create-mutation.d.ts +0 -337
- package/dist/hooks/use-booking-dual-create-mutation.js +0 -45
- package/dist/journey/components/booking-journey.d.ts +0 -2
- package/dist/journey/components/booking-journey.js +0 -485
- package/dist/storefront/storefront-booking-errors.d.ts +0 -12
- package/dist/storefront/storefront-booking-errors.js +0 -50
- package/dist/storefront/storefront-booking-journey.d.ts +0 -71
- package/dist/storefront/storefront-booking-journey.js +0 -327
- package/dist/storefront/storefront-booking-page.d.ts +0 -35
- package/dist/storefront/storefront-booking-page.js +0 -215
- package/dist/storefront/storefront-checkout-bodies.d.ts +0 -36
- package/dist/storefront/storefront-checkout-bodies.js +0 -69
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useRef, useState } from "react";
|
|
4
|
-
import { emptyOptionUnitsStepperValue, OptionUnitsStepperSection, } from "../components/option-units-stepper-section.js";
|
|
5
|
-
/**
|
|
6
|
-
* Admin rooms/units picker for the booking journey's `"option-units"`
|
|
7
|
-
* sub-step. Wraps the shared `OptionUnitsStepperSection` (which loads the
|
|
8
|
-
* product's option units + per-slot availability) and mirrors the picked
|
|
9
|
-
* quantities into the journey draft's `configure.optionSelections`.
|
|
10
|
-
*
|
|
11
|
-
* Wired into `<BookingJourneyHost />` via the `renderUnitsPicker` slot.
|
|
12
|
-
*/
|
|
13
|
-
export function JourneyUnitsPicker({ productId, optionId, slotId, selections, onChange, }) {
|
|
14
|
-
// Seed the stepper from any selections already on the draft (refresh /
|
|
15
|
-
// step revisit). Local state mirrors the departure picker's approach.
|
|
16
|
-
const [value, setValue] = useState(() => {
|
|
17
|
-
const quantities = {};
|
|
18
|
-
for (const selection of selections) {
|
|
19
|
-
if (selection.optionUnitId)
|
|
20
|
-
quantities[selection.optionUnitId] = selection.quantity;
|
|
21
|
-
}
|
|
22
|
-
return Object.keys(quantities).length > 0 ? { quantities } : emptyOptionUnitsStepperValue;
|
|
23
|
-
});
|
|
24
|
-
// The loaded unit metadata (optionId + name per unit) needed to rebuild
|
|
25
|
-
// `optionSelections` from the quantity map.
|
|
26
|
-
// Loaded unit metadata is kept in a ref, NOT state: it's only read when
|
|
27
|
-
// the operator changes a quantity, never rendered. Using state here would
|
|
28
|
-
// make `onUnitsChange` (which fires as units load) re-render → the stepper
|
|
29
|
-
// re-emits → setDraft → re-quote → re-render … an infinite loop.
|
|
30
|
-
const unitsRef = useRef([]);
|
|
31
|
-
const emit = (quantities) => {
|
|
32
|
-
const next = [];
|
|
33
|
-
for (const unit of unitsRef.current) {
|
|
34
|
-
const quantity = quantities[unit.optionUnitId] ?? 0;
|
|
35
|
-
if (quantity <= 0)
|
|
36
|
-
continue;
|
|
37
|
-
const unitOptionId = unit.optionId ?? optionId;
|
|
38
|
-
if (!unitOptionId)
|
|
39
|
-
continue;
|
|
40
|
-
next.push({
|
|
41
|
-
optionId: unitOptionId,
|
|
42
|
-
optionUnitId: unit.optionUnitId,
|
|
43
|
-
optionUnitName: unit.unitName,
|
|
44
|
-
quantity,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
onChange(next);
|
|
48
|
-
};
|
|
49
|
-
return (_jsx(OptionUnitsStepperSection, { value: value, onChange: (nextValue) => {
|
|
50
|
-
setValue(nextValue);
|
|
51
|
-
emit(nextValue.quantities);
|
|
52
|
-
}, productId: productId, slotId: slotId ?? undefined, optionId: optionId,
|
|
53
|
-
// The journey nests rooms under the chosen option — show only that
|
|
54
|
-
// option's units (New having no rooms correctly shows none).
|
|
55
|
-
restrictToOption: true, enabled: true,
|
|
56
|
-
// Record loaded units without triggering a render (see unitsRef note).
|
|
57
|
-
onUnitsChange: (loadedUnits) => {
|
|
58
|
-
unitsRef.current = loadedUnits;
|
|
59
|
-
} }));
|
|
60
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { AdminRoutePageProps } from "@voyant-travel/admin";
|
|
2
|
-
/**
|
|
3
|
-
* Packaged unified booking journey page (packaged-admin RFC §4.8): binds the
|
|
4
|
-
* route's `$entityModule`/`$entityId` params and the journey search contract
|
|
5
|
-
* (`bookingJourneySearchSchema`) onto {@link BookingJourneyHost}. Mounted at
|
|
6
|
-
* `/catalog/journey/$entityModule/$entityId` — a flat path under the
|
|
7
|
-
* workspace layout, so the wizard renders with workspace chrome but OUTSIDE
|
|
8
|
-
* any catalog section nesting (the same semantics the old `catalog_.journey`
|
|
9
|
-
* escaped route file had).
|
|
10
|
-
*/
|
|
11
|
-
export default function BookingJourneyPage({ params, search }: AdminRoutePageProps): import("react").JSX.Element;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo } from "react";
|
|
4
|
-
import { BookingJourneyHost } from "../booking-journey-host.js";
|
|
5
|
-
/**
|
|
6
|
-
* Packaged unified booking journey page (packaged-admin RFC §4.8): binds the
|
|
7
|
-
* route's `$entityModule`/`$entityId` params and the journey search contract
|
|
8
|
-
* (`bookingJourneySearchSchema`) onto {@link BookingJourneyHost}. Mounted at
|
|
9
|
-
* `/catalog/journey/$entityModule/$entityId` — a flat path under the
|
|
10
|
-
* workspace layout, so the wizard renders with workspace chrome but OUTSIDE
|
|
11
|
-
* any catalog section nesting (the same semantics the old `catalog_.journey`
|
|
12
|
-
* escaped route file had).
|
|
13
|
-
*/
|
|
14
|
-
export default function BookingJourneyPage({ params, search }) {
|
|
15
|
-
const journeySearch = search;
|
|
16
|
-
// Stable draft id — refresh-safe when carried in the URL; generated once
|
|
17
|
-
// per mount otherwise.
|
|
18
|
-
const draftId = useMemo(() => journeySearch.draftId ?? generateDraftId(), [journeySearch.draftId]);
|
|
19
|
-
return (_jsx("div", { className: "mx-auto", children: _jsx(BookingJourneyHost, { entityModule: params.entityModule ?? "", entityId: params.entityId ?? "", sourceKind: journeySearch.sourceKind, sourceConnectionId: journeySearch.sourceConnectionId, sourceRef: journeySearch.sourceRef, departureId: journeySearch.departureId, departureDate: journeySearch.departureDate, optionId: journeySearch.optionId, roomTypeId: journeySearch.roomTypeId, ratePlanId: journeySearch.ratePlanId, board: journeySearch.board, entityName: journeySearch.entityName, entityImageUrl: journeySearch.entityImageUrl, draftId: draftId }) }));
|
|
20
|
-
}
|
|
21
|
-
function generateDraftId() {
|
|
22
|
-
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.randomUUID) {
|
|
23
|
-
return `bdrf_${globalThis.crypto.randomUUID().replace(/-/g, "")}`;
|
|
24
|
-
}
|
|
25
|
-
return `bdrf_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
26
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type AdminRoutePageProps } from "@voyant-travel/admin";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
/**
|
|
4
|
-
* Packaged "New booking" entry page (packaged-admin RFC §4.8): pick an owned
|
|
5
|
-
* product, then route into the unified booking journey so every booking goes
|
|
6
|
-
* through one flow. Owned products come straight off the products table —
|
|
7
|
-
* real names (including non-English), always browsable, with a proper
|
|
8
|
-
* loading state. Supplier-sourced products are booked from the catalog
|
|
9
|
-
* browse/detail pages (which carry the connect provenance), not here.
|
|
10
|
-
*
|
|
11
|
-
* Mounted at `/bookings/new` — a static path, so it outranks the
|
|
12
|
-
* `/bookings/$id` detail route for the `"new"` segment by the router's
|
|
13
|
-
* static-over-dynamic scoring.
|
|
14
|
-
*/
|
|
15
|
-
export default function BookingNewPage({ search }: AdminRoutePageProps): React.JSX.Element | null;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useAdminNavigate } from "@voyant-travel/admin";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
import { ProductPickerSection } from "../../components/product-picker-section.js";
|
|
6
|
-
import { useBookingsUiMessagesOrDefault } from "../../i18n/provider.js";
|
|
7
|
-
/**
|
|
8
|
-
* Packaged "New booking" entry page (packaged-admin RFC §4.8): pick an owned
|
|
9
|
-
* product, then route into the unified booking journey so every booking goes
|
|
10
|
-
* through one flow. Owned products come straight off the products table —
|
|
11
|
-
* real names (including non-English), always browsable, with a proper
|
|
12
|
-
* loading state. Supplier-sourced products are booked from the catalog
|
|
13
|
-
* browse/detail pages (which carry the connect provenance), not here.
|
|
14
|
-
*
|
|
15
|
-
* Mounted at `/bookings/new` — a static path, so it outranks the
|
|
16
|
-
* `/bookings/$id` detail route for the `"new"` segment by the router's
|
|
17
|
-
* static-over-dynamic scoring.
|
|
18
|
-
*/
|
|
19
|
-
export default function BookingNewPage({ search }) {
|
|
20
|
-
const { productId, slotId } = search;
|
|
21
|
-
const navigate = useAdminNavigate();
|
|
22
|
-
const messages = useBookingsUiMessagesOrDefault();
|
|
23
|
-
// Deep-link with a product already chosen (e.g. launched from a product
|
|
24
|
-
// page) → straight into the unified booking journey for that owned
|
|
25
|
-
// product. `replace` keeps route-redirect history semantics.
|
|
26
|
-
React.useEffect(() => {
|
|
27
|
-
if (!productId)
|
|
28
|
-
return;
|
|
29
|
-
navigate("bookingJourney.start", {
|
|
30
|
-
entityModule: "products",
|
|
31
|
-
entityId: productId,
|
|
32
|
-
sourceKind: "owned",
|
|
33
|
-
...(slotId ? { departureId: slotId } : {}),
|
|
34
|
-
}, { replace: true });
|
|
35
|
-
}, [productId, slotId, navigate]);
|
|
36
|
-
if (productId)
|
|
37
|
-
return null;
|
|
38
|
-
return (_jsxs("main", { className: "mx-auto flex w-full max-w-screen-md flex-col gap-6", children: [_jsxs("header", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "font-semibold text-2xl tracking-normal", children: messages.bookingCreatePage.title }), _jsx("p", { className: "text-muted-foreground text-sm", children: messages.bookingCreatePage.description })] }), _jsx(ProductPickerSection, { value: { productId: "", optionId: null }, enabled: true, lockProduct: false, showOptionPicker: false,
|
|
39
|
-
// Owned pick -> journey with `owned` provenance. Clearing the field
|
|
40
|
-
// yields an empty productId, which we ignore.
|
|
41
|
-
onChange: (value) => {
|
|
42
|
-
if (value.productId) {
|
|
43
|
-
navigate("bookingJourney.start", {
|
|
44
|
-
entityModule: "products",
|
|
45
|
-
entityId: value.productId,
|
|
46
|
-
sourceKind: "owned",
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
} })] }));
|
|
50
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { BookingRecord } from "../index.js";
|
|
2
|
-
export interface BookingCreatePageProps {
|
|
3
|
-
onCreated?: (booking: BookingRecord) => void;
|
|
4
|
-
onCancel?: () => void;
|
|
5
|
-
/** When provided, pre-selects this product and hides the product picker. */
|
|
6
|
-
defaultProductId?: string;
|
|
7
|
-
/** When provided, pre-selects and locks the departure slot. */
|
|
8
|
-
defaultSlotId?: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Full-page booking create surface for route-based booking creation.
|
|
12
|
-
*/
|
|
13
|
-
export declare function BookingCreatePage({ onCreated, onCancel, defaultProductId, defaultSlotId, }: BookingCreatePageProps): import("react").JSX.Element;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useBookingsUiMessagesOrDefault } from "../i18n/provider.js";
|
|
4
|
-
import { BookingCreateForm } from "./booking-create-sheet.js";
|
|
5
|
-
/**
|
|
6
|
-
* Full-page booking create surface for route-based booking creation.
|
|
7
|
-
*/
|
|
8
|
-
export function BookingCreatePage({ onCreated, onCancel, defaultProductId, defaultSlotId, }) {
|
|
9
|
-
const messages = useBookingsUiMessagesOrDefault();
|
|
10
|
-
return (_jsxs("main", { className: "mx-auto flex w-full max-w-screen-2xl flex-col gap-6", children: [_jsxs("header", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-2xl font-semibold tracking-normal", children: messages.bookingCreatePage.title }), _jsx("p", { className: "text-sm text-muted-foreground", children: messages.bookingCreatePage.description })] }), _jsx("section", { className: "flex flex-col gap-4", children: _jsx(BookingCreateForm, { onCreated: onCreated, onCancel: onCancel, defaultProductId: defaultProductId, defaultSlotId: defaultSlotId }) })] }));
|
|
11
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { type BookingRecord } from "../index.js";
|
|
3
|
-
export interface BookingCreateSheetProps {
|
|
4
|
-
open: boolean;
|
|
5
|
-
onOpenChange: (open: boolean) => void;
|
|
6
|
-
onCreated?: (booking: BookingRecord) => void;
|
|
7
|
-
/** When provided, pre-selects this product and hides the product picker. */
|
|
8
|
-
defaultProductId?: string;
|
|
9
|
-
/** When provided, pre-selects and locks the departure slot. */
|
|
10
|
-
defaultSlotId?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface BookingCreateFormProps {
|
|
13
|
-
onCreated?: (booking: BookingRecord) => void;
|
|
14
|
-
/** When provided, pre-selects this product and hides the product picker. */
|
|
15
|
-
defaultProductId?: string;
|
|
16
|
-
/** When provided, pre-selects and locks the departure slot. */
|
|
17
|
-
defaultSlotId?: string;
|
|
18
|
-
/** Gates data fetching and resets transient form state when false. */
|
|
19
|
-
enabled?: boolean;
|
|
20
|
-
onCancel?: () => void;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Operator booking-create sheet. Composes the booking-create picker
|
|
24
|
-
* sections — product, departure, rooms, person, shared-room, travelers,
|
|
25
|
-
* price breakdown, Travel Credit, payment schedule, and submits via the atomic
|
|
26
|
-
* `POST /v1/admin/bookings/create` endpoint so partial failures can't
|
|
27
|
-
* leave orphan state.
|
|
28
|
-
*
|
|
29
|
-
* Normally consumed via `BookingDialog` which delegates here when no
|
|
30
|
-
* `booking` prop is passed. Apps that need a bespoke flow can install the
|
|
31
|
-
* sections individually and assemble their own sheet instead of forking.
|
|
32
|
-
*/
|
|
33
|
-
export declare function BookingCreateSheet({ open, onOpenChange, onCreated, defaultProductId, defaultSlotId, }: BookingCreateSheetProps): React.JSX.Element;
|
|
34
|
-
export declare function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId, enabled, onCancel, }: BookingCreateFormProps): React.JSX.Element;
|