@voyant-travel/bookings-react 0.155.2 → 0.156.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/booking-journey-host.js +5 -5
- package/dist/admin/journey-travel-credit-picker.d.ts +3 -0
- package/dist/admin/journey-travel-credit-picker.d.ts.map +1 -0
- package/dist/admin/{journey-voucher-picker.js → journey-travel-credit-picker.js} +19 -19
- package/dist/components/booking-create-sheet.d.ts +1 -1
- package/dist/components/booking-create-sheet.d.ts.map +1 -1
- package/dist/components/booking-create-sheet.js +16 -16
- package/dist/components/booking-payments-summary.d.ts +3 -3
- package/dist/components/booking-payments-summary.d.ts.map +1 -1
- package/dist/components/booking-payments-summary.js +2 -2
- package/dist/components/payment-schedule-section.js +1 -1
- package/dist/components/{voucher-picker-section.d.ts → travel-credit-picker-section.d.ts} +14 -15
- package/dist/components/travel-credit-picker-section.d.ts.map +1 -0
- package/dist/components/{voucher-picker-section.js → travel-credit-picker-section.js} +18 -19
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/use-booking-create-mutation.d.ts +6 -6
- package/dist/hooks/use-booking-create-mutation.d.ts.map +1 -1
- package/dist/hooks/use-booking-create-mutation.js +3 -3
- package/dist/hooks/use-booking-dual-create-mutation.d.ts +4 -4
- package/dist/hooks/use-booking-dual-create-mutation.js +2 -2
- package/dist/i18n/en-create-list.d.ts +7 -7
- package/dist/i18n/en-create-list.js +8 -8
- package/dist/i18n/en-sections.d.ts +1 -1
- package/dist/i18n/en-sections.js +13 -13
- package/dist/i18n/en.d.ts +8 -8
- package/dist/i18n/messages-create-list.d.ts +7 -7
- package/dist/i18n/messages-create-list.d.ts.map +1 -1
- package/dist/i18n/messages-sections.d.ts +1 -1
- package/dist/i18n/messages-sections.d.ts.map +1 -1
- package/dist/i18n/provider.d.ts +16 -16
- package/dist/i18n/ro-create-list.d.ts +7 -7
- package/dist/i18n/ro-create-list.js +8 -8
- package/dist/i18n/ro-sections.d.ts +1 -1
- package/dist/i18n/ro-sections.js +13 -13
- package/dist/i18n/ro.d.ts +8 -8
- package/dist/journey/components/booking-journey.js +2 -2
- package/dist/journey/components/journey-steps/payment-step.d.ts +4 -4
- package/dist/journey/components/journey-steps/payment-step.d.ts.map +1 -1
- package/dist/journey/components/journey-steps/payment-step.js +25 -25
- package/dist/journey/components/side-panel.d.ts +1 -1
- package/dist/journey/index.d.ts +1 -1
- package/dist/journey/index.d.ts.map +1 -1
- package/dist/journey/types.d.ts +10 -10
- package/dist/journey/types.d.ts.map +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +1 -1
- package/package.json +38 -38
- package/dist/admin/journey-voucher-picker.d.ts +0 -3
- package/dist/admin/journey-voucher-picker.d.ts.map +0 -1
- package/dist/components/voucher-picker-section.d.ts.map +0 -1
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* Packaged admin host for the unified `<BookingJourney />` wizard —
|
|
5
5
|
* supplies CRM-backed contact pickers, the B2B billing default, real
|
|
6
|
-
* departure/units/
|
|
6
|
+
* departure/units/Travel Credit pickers over operator inventory, and post-commit
|
|
7
7
|
* navigation to the new booking's detail page.
|
|
8
8
|
*
|
|
9
9
|
* Per booking-journey-architecture §8.1 + §10 Phase B, packaged per the
|
|
@@ -23,8 +23,8 @@ import { BookingJourney, } from "../journey/index.js";
|
|
|
23
23
|
import { useVoyantBookingsContext } from "../provider.js";
|
|
24
24
|
import { JourneyBillingDuplicateWarning } from "./journey-billing-duplicate-warning.js";
|
|
25
25
|
import { JourneyDeparturePicker } from "./journey-departure-picker.js";
|
|
26
|
+
import { JourneyTravelCreditPicker } from "./journey-travel-credit-picker.js";
|
|
26
27
|
import { JourneyUnitsPicker } from "./journey-units-picker.js";
|
|
27
|
-
import { JourneyVoucherPicker } from "./journey-voucher-picker.js";
|
|
28
28
|
/** The catalog browse surface the journey returns to when cancelled. */
|
|
29
29
|
function journeyReturnSurface(vertical) {
|
|
30
30
|
switch (vertical) {
|
|
@@ -60,9 +60,9 @@ export function BookingJourneyHost({ entityModule, entityId, sourceKind, sourceC
|
|
|
60
60
|
// Rooms/units for the picked option + departure (operator inventory).
|
|
61
61
|
return _jsx(JourneyUnitsPicker, { ...pickerProps });
|
|
62
62
|
},
|
|
63
|
-
|
|
64
|
-
// Admin searches
|
|
65
|
-
return _jsx(
|
|
63
|
+
renderTravelCreditPicker(pickerProps) {
|
|
64
|
+
// Admin searches and selects a Travel Credit without needing to know the code.
|
|
65
|
+
return _jsx(JourneyTravelCreditPicker, { ...pickerProps });
|
|
66
66
|
},
|
|
67
67
|
renderTravelerContactPicker({ apply, selectedPersonId }) {
|
|
68
68
|
// Travelers reuse the same picker (person-only). Adapt the picker's
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journey-travel-credit-picker.d.ts","sourceRoot":"","sources":["../../src/admin/journey-travel-credit-picker.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAclE,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,OAAO,GACR,EAAE,uBAAuB,GAAG,KAAK,CAAC,YAAY,CAkF9C"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
|
-
* Admin
|
|
5
|
-
* Staff search by code and pick a
|
|
4
|
+
* Admin Travel Credit picker: an async combobox over the admin Travel Credit list.
|
|
5
|
+
* Staff search by code and pick a Travel Credit (the full remaining balance is
|
|
6
6
|
* redeemed); they never need to know the exact code, unlike storefront
|
|
7
|
-
* customers. Wired into `<BookingJourneyHost />` via `
|
|
7
|
+
* customers. Wired into `<BookingJourneyHost />` via `renderTravelCreditPicker`.
|
|
8
8
|
*/
|
|
9
9
|
import { useOperatorAdminMessages } from "@voyant-travel/admin";
|
|
10
|
-
import {
|
|
10
|
+
import { useTravelCredits } from "@voyant-travel/finance-react";
|
|
11
11
|
import { Combobox, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList, } from "@voyant-travel/ui/components/combobox";
|
|
12
12
|
import { Label } from "@voyant-travel/ui/components/label";
|
|
13
13
|
import { useEffect, useState } from "react";
|
|
@@ -19,32 +19,32 @@ function formatMoney(cents, currency) {
|
|
|
19
19
|
return `${(cents / 100).toFixed(2)} ${currency}`;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
return `${
|
|
22
|
+
function travelCreditLabel(travelCredit) {
|
|
23
|
+
return `${travelCredit.code} · ${formatMoney(travelCredit.remainingAmountCents, travelCredit.currency)}`;
|
|
24
24
|
}
|
|
25
|
-
export function
|
|
25
|
+
export function JourneyTravelCreditPicker({ value, onApply, }) {
|
|
26
26
|
const t = useOperatorAdminMessages().bookings.detail.bookingJourney;
|
|
27
27
|
const [inputValue, setInputValue] = useState("");
|
|
28
28
|
const [search, setSearch] = useState("");
|
|
29
|
-
// Active
|
|
30
|
-
const query =
|
|
29
|
+
// Active Travel Credits with a remaining balance, filtered by the typed code.
|
|
30
|
+
const query = useTravelCredits({
|
|
31
31
|
status: "active",
|
|
32
32
|
hasBalance: true,
|
|
33
33
|
search: search || undefined,
|
|
34
34
|
limit: 20,
|
|
35
35
|
});
|
|
36
|
-
const
|
|
37
|
-
const byId = new Map(
|
|
38
|
-
const selectedId = value.
|
|
39
|
-
// Reflect a pre-selected
|
|
36
|
+
const travelCredits = query.data?.data ?? [];
|
|
37
|
+
const byId = new Map(travelCredits.map((travelCredit) => [travelCredit.id, travelCredit]));
|
|
38
|
+
const selectedId = value.travelCreditId ?? null;
|
|
39
|
+
// Reflect a pre-selected Travel Credit's label once its record loads.
|
|
40
40
|
useEffect(() => {
|
|
41
41
|
if (selectedId && byId.has(selectedId)) {
|
|
42
|
-
setInputValue(
|
|
42
|
+
setInputValue(travelCreditLabel(byId.get(selectedId)));
|
|
43
43
|
}
|
|
44
44
|
}, [selectedId, byId]);
|
|
45
|
-
return (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { children: t.
|
|
45
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { children: t.travelCreditPickerLabel }), _jsxs(Combobox, { items: travelCredits.map((travelCredit) => travelCredit.id), value: selectedId, inputValue: inputValue, autoHighlight: true, itemToStringLabel: (id) => {
|
|
46
46
|
const v = byId.get(id);
|
|
47
|
-
return v ?
|
|
47
|
+
return v ? travelCreditLabel(v) : id;
|
|
48
48
|
}, itemToStringValue: (id) => id, onInputValueChange: (next) => {
|
|
49
49
|
setInputValue(next);
|
|
50
50
|
setSearch(next);
|
|
@@ -59,10 +59,10 @@ export function JourneyVoucherPicker({ value, onApply }) {
|
|
|
59
59
|
}
|
|
60
60
|
const v = byId.get(id);
|
|
61
61
|
if (v) {
|
|
62
|
-
onApply({
|
|
63
|
-
setInputValue(
|
|
62
|
+
onApply({ travelCreditId: v.id, amountCents: v.remainingAmountCents });
|
|
63
|
+
setInputValue(travelCreditLabel(v));
|
|
64
64
|
}
|
|
65
|
-
}, children: [_jsx(ComboboxInput, { placeholder: t.
|
|
65
|
+
}, children: [_jsx(ComboboxInput, { placeholder: t.travelCreditSearchPlaceholder, showClear: !!selectedId }), _jsxs(ComboboxContent, { children: [_jsx(ComboboxEmpty, { children: t.travelCreditEmpty }), _jsx(ComboboxList, { children: _jsx(ComboboxCollection, { children: (id) => {
|
|
66
66
|
const v = byId.get(id);
|
|
67
67
|
if (!v)
|
|
68
68
|
return null;
|
|
@@ -22,7 +22,7 @@ export interface BookingCreateFormProps {
|
|
|
22
22
|
/**
|
|
23
23
|
* Operator booking-create sheet. Composes the booking-create picker
|
|
24
24
|
* sections — product, departure, rooms, person, shared-room, travelers,
|
|
25
|
-
* price breakdown,
|
|
25
|
+
* price breakdown, Travel Credit, payment schedule, and submits via the atomic
|
|
26
26
|
* `POST /v1/admin/bookings/create` endpoint so partial failures can't
|
|
27
27
|
* leave orphan state.
|
|
28
28
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booking-create-sheet.d.ts","sourceRoot":"","sources":["../../src/components/booking-create-sheet.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAIL,KAAK,aAAa,EAInB,MAAM,aAAa,CAAA;AAkEpB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,EAAE,uBAAuB,qBA8BzB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,OAAc,EACd,QAAQ,GACT,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"booking-create-sheet.d.ts","sourceRoot":"","sources":["../../src/components/booking-create-sheet.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAIL,KAAK,aAAa,EAInB,MAAM,aAAa,CAAA;AAkEpB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,EAAE,uBAAuB,qBA8BzB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,OAAc,EACd,QAAQ,GACT,EAAE,sBAAsB,qBAgnCxB"}
|
|
@@ -23,12 +23,12 @@ import { emptyPaymentScheduleValue, PaymentScheduleSection, } from "./payment-sc
|
|
|
23
23
|
import { emptyPersonPickerValue, PersonPickerSection, } from "./person-picker-section.js";
|
|
24
24
|
import { ProductPickerSection } from "./product-picker-section.js";
|
|
25
25
|
import { emptySharedRoomValue, SharedRoomSection, } from "./shared-room-section.js";
|
|
26
|
+
import { emptyTravelCreditPickerValue, TravelCreditPickerSection, } from "./travel-credit-picker-section.js";
|
|
26
27
|
import { emptyTravelerListValue, TravelersSection, } from "./travelers-section.js";
|
|
27
|
-
import { emptyVoucherPickerValue, VoucherPickerSection, } from "./voucher-picker-section.js";
|
|
28
28
|
/**
|
|
29
29
|
* Operator booking-create sheet. Composes the booking-create picker
|
|
30
30
|
* sections — product, departure, rooms, person, shared-room, travelers,
|
|
31
|
-
* price breakdown,
|
|
31
|
+
* price breakdown, Travel Credit, payment schedule, and submits via the atomic
|
|
32
32
|
* `POST /v1/admin/bookings/create` endpoint so partial failures can't
|
|
33
33
|
* leave orphan state.
|
|
34
34
|
*
|
|
@@ -55,7 +55,7 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
55
55
|
const [person, setPerson] = React.useState(emptyPersonPickerValue);
|
|
56
56
|
const [sharedRoom, setSharedRoom] = React.useState(emptySharedRoomValue);
|
|
57
57
|
const [travelers, setTravelers] = React.useState(emptyTravelerListValue);
|
|
58
|
-
const [
|
|
58
|
+
const [travelCredit, setTravelCredit] = React.useState(emptyTravelCreditPickerValue);
|
|
59
59
|
const [pricing, setPricing] = React.useState(null);
|
|
60
60
|
const [paymentSchedule, setPaymentScheduleState] = React.useState(emptyPaymentScheduleValue);
|
|
61
61
|
// Tracks whether the operator has manually touched the schedule. The
|
|
@@ -115,7 +115,7 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
115
115
|
setPerson(emptyPersonPickerValue);
|
|
116
116
|
setSharedRoom(emptySharedRoomValue);
|
|
117
117
|
setTravelers(emptyTravelerListValue);
|
|
118
|
-
|
|
118
|
+
setTravelCredit(emptyTravelCreditPickerValue);
|
|
119
119
|
setPricing(null);
|
|
120
120
|
setPaymentScheduleState(emptyPaymentScheduleValue);
|
|
121
121
|
paymentScheduleTouchedRef.current = false;
|
|
@@ -417,7 +417,7 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
417
417
|
extraLines,
|
|
418
418
|
travelerCount: travelers.travelers.length,
|
|
419
419
|
}), [extraLines, travelers.travelers.length]);
|
|
420
|
-
// Currency placeholder
|
|
420
|
+
// Currency placeholder used for Travel Credit and payment schedule display.
|
|
421
421
|
// Consumers hooking in real product data should override this by wrapping
|
|
422
422
|
// the component or swapping in their own currency-aware hook.
|
|
423
423
|
const currency = messages.bookingCreateDialog.labels.currency;
|
|
@@ -599,10 +599,10 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
599
599
|
travelerKeys: travelerKeys.length === redistributed.travelers.length ? travelerKeys : undefined,
|
|
600
600
|
});
|
|
601
601
|
const travelerRows = travelersToRows({ travelers: redistributed.travelers });
|
|
602
|
-
const
|
|
602
|
+
const travelCreditRedemption = travelCredit.picked && travelCredit.picked.remainingAmountCents != null
|
|
603
603
|
? {
|
|
604
|
-
|
|
605
|
-
amountCents:
|
|
604
|
+
travelCreditId: travelCredit.picked.id,
|
|
605
|
+
amountCents: travelCredit.picked.remainingAmountCents,
|
|
606
606
|
}
|
|
607
607
|
: undefined;
|
|
608
608
|
const selectedSharedRoomUnitId = getSelectedSharedRoomUnitId(rooms.quantities);
|
|
@@ -682,7 +682,7 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
682
682
|
extraLines: resolvedExtraLines.length > 0 ? resolvedExtraLines : undefined,
|
|
683
683
|
travelers: travelerRows.length > 0 ? travelerRows : undefined,
|
|
684
684
|
paymentSchedules: paymentSchedules.length > 0 ? paymentSchedules : undefined,
|
|
685
|
-
|
|
685
|
+
travelCreditRedemption,
|
|
686
686
|
groupMembership,
|
|
687
687
|
documentGeneration: generateProforma
|
|
688
688
|
? { contractDocument: false, invoiceDocument: true, invoiceType: "proforma" }
|
|
@@ -785,13 +785,13 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
|
|
|
785
785
|
: messages.bookingCreateDialog.actions.createAwaitingPaymentBooking] })] })] }), _jsxs("div", { className: "flex flex-col gap-4 lg:col-span-4", children: [_jsx(BookingPreviewCard, { productId: product.productId, optionId: product.optionId, slotId: slotId, slotLabel: (() => {
|
|
786
786
|
const slot = slots.find((s) => s.id === slotId);
|
|
787
787
|
return slot ? formatSlotLabel(slot) : null;
|
|
788
|
-
})(), unitQuantities: displayQuantities, unitLabels: roomUnitLabels, pricingCategoryQuantities: travelerPricingCategoryQuantities, pricingCategoryLabels: travelerPricingCategoryLabels, extraLines: displayExtraLines, travelers: travelers.travelers, messages: messages, onPricingChange: setPricing }), product.productId && slotId ? (_jsx(
|
|
789
|
-
heading: messages.bookingCreateDialog.labels.
|
|
790
|
-
codePlaceholder: messages.bookingCreateDialog.labels.
|
|
791
|
-
apply: messages.bookingCreateDialog.labels.
|
|
792
|
-
clear: messages.bookingCreateDialog.labels.
|
|
793
|
-
remainingLabel: messages.bookingCreateDialog.labels.
|
|
794
|
-
invalidLabel: messages.bookingCreateDialog.labels.
|
|
788
|
+
})(), unitQuantities: displayQuantities, unitLabels: roomUnitLabels, pricingCategoryQuantities: travelerPricingCategoryQuantities, pricingCategoryLabels: travelerPricingCategoryLabels, extraLines: displayExtraLines, travelers: travelers.travelers, messages: messages, onPricingChange: setPricing }), product.productId && slotId ? (_jsx(TravelCreditPickerSection, { value: travelCredit, onChange: setTravelCredit, currency: currency, labels: {
|
|
789
|
+
heading: messages.bookingCreateDialog.labels.travelCreditHeading,
|
|
790
|
+
codePlaceholder: messages.bookingCreateDialog.labels.travelCreditCodePlaceholder,
|
|
791
|
+
apply: messages.bookingCreateDialog.labels.travelCreditApply,
|
|
792
|
+
clear: messages.bookingCreateDialog.labels.travelCreditClear,
|
|
793
|
+
remainingLabel: messages.bookingCreateDialog.labels.travelCreditRemainingLabel,
|
|
794
|
+
invalidLabel: messages.bookingCreateDialog.labels.travelCreditInvalidLabel,
|
|
795
795
|
} })) : null, product.productId && slotId ? (_jsx(PaymentScheduleSection, { value: paymentSchedule, onChange: setPaymentSchedule, currency: pricingCurrency, totalAmountCents: pricingTotalAmountCents, departureDate: selectedSlot?.startsAt?.slice(0, 10) ?? null, labels: {
|
|
796
796
|
heading: messages.bookingCreateDialog.labels.paymentHeading,
|
|
797
797
|
modeUnpaid: messages.bookingCreateDialog.labels.paymentModeUnpaid,
|
|
@@ -17,13 +17,13 @@ export interface BookingPaymentSummaryPaymentRow {
|
|
|
17
17
|
referenceNumber: string | null;
|
|
18
18
|
notes: string | null;
|
|
19
19
|
}
|
|
20
|
-
export interface
|
|
21
|
-
source: "
|
|
20
|
+
export interface BookingPaymentSummaryTravelCreditRedemptionRow extends Omit<BookingPaymentSummaryPaymentRow, "source" | "invoiceId" | "invoiceNumber" | "invoiceType"> {
|
|
21
|
+
source: "travel_credit_redemption";
|
|
22
22
|
invoiceId: null;
|
|
23
23
|
invoiceNumber: null;
|
|
24
24
|
invoiceType: null;
|
|
25
25
|
}
|
|
26
|
-
export type BookingPaymentsSummaryRow = BookingPaymentSummaryPaymentRow |
|
|
26
|
+
export type BookingPaymentsSummaryRow = BookingPaymentSummaryPaymentRow | BookingPaymentSummaryTravelCreditRedemptionRow;
|
|
27
27
|
export interface BookingPaymentsSummaryProps {
|
|
28
28
|
bookingId: string;
|
|
29
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booking-payments-summary.d.ts","sourceRoot":"","sources":["../../src/components/booking-payments-summary.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAGnB,MAAM,8BAA8B,CAAA;AAarC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,aAAa,CAAA;IACrB,aAAa,EAAE,aAAa,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"booking-payments-summary.d.ts","sourceRoot":"","sources":["../../src/components/booking-payments-summary.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAGnB,MAAM,8BAA8B,CAAA;AAarC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,aAAa,CAAA;IACrB,aAAa,EAAE,aAAa,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,8CACf,SAAQ,IAAI,CACV,+BAA+B,EAC/B,QAAQ,GAAG,WAAW,GAAG,eAAe,GAAG,aAAa,CACzD;IACD,MAAM,EAAE,0BAA0B,CAAA;IAClC,SAAS,EAAE,IAAI,CAAA;IACf,aAAa,EAAE,IAAI,CAAA;IACnB,WAAW,EAAE,IAAI,CAAA;CAClB;AAED,MAAM,MAAM,yBAAyB,GACjC,+BAA+B,GAC/B,8CAA8C,CAAA;AAmBlD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,yBAAyB,KAAK,IAAI,CAAA;IAC3E;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,MAAM,CAAA;IAC3D;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,IAAI,CAAA;IACxD,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAClF,uEAAuE;IACvE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,IAAI,CAAA;IACxD;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1E;;;;OAIG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,OAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,YAAY,GACb,EAAE,2BAA2B,qBAqS7B"}
|
|
@@ -64,10 +64,10 @@ export function BookingPaymentsSummary({ bookingId, variant = "public", onInvoic
|
|
|
64
64
|
notes: payment.notes,
|
|
65
65
|
};
|
|
66
66
|
const source = payment.source ?? "payment";
|
|
67
|
-
if (source === "
|
|
67
|
+
if (source === "travel_credit_redemption") {
|
|
68
68
|
return {
|
|
69
69
|
...base,
|
|
70
|
-
source: "
|
|
70
|
+
source: "travel_credit_redemption",
|
|
71
71
|
invoiceId: null,
|
|
72
72
|
invoiceNumber: null,
|
|
73
73
|
invoiceType: null,
|
|
@@ -199,7 +199,7 @@ export function PaymentScheduleSection({ value, onChange, totalAmountCents, depa
|
|
|
199
199
|
const paymentMethodLabels = messages.bookingPaymentsSummary.paymentMethodLabels;
|
|
200
200
|
const renderPaidFields = (idx, installment) => {
|
|
201
201
|
const checkboxId = `payment-schedule-installment-${idx}-already-paid`;
|
|
202
|
-
return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border border-dashed p-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: checkboxId, checked: installment.alreadyPaid, onCheckedChange: (next) => updateInstallment(idx, { alreadyPaid: next === true }) }), _jsx(Label, { htmlFor: checkboxId, className: "cursor-pointer text-xs", children: merged.alreadyPaid })] }), installment.alreadyPaid ? (_jsxs("div", { className: "grid gap-2 sm:grid-cols-3", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.paymentDate }), _jsx(DatePicker, { value: installment.paymentDate ?? "", onChange: (nextValue) => updateInstallment(idx, { paymentDate: nextValue }) })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.paymentMethod }), _jsxs(Select, { value: installment.paymentMethod, onValueChange: (nextValue) => updateInstallment(idx, { paymentMethod: nextValue ?? "bank_transfer" }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: ["bank_transfer", "credit_card", "cash", "
|
|
202
|
+
return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border border-dashed p-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: checkboxId, checked: installment.alreadyPaid, onCheckedChange: (next) => updateInstallment(idx, { alreadyPaid: next === true }) }), _jsx(Label, { htmlFor: checkboxId, className: "cursor-pointer text-xs", children: merged.alreadyPaid })] }), installment.alreadyPaid ? (_jsxs("div", { className: "grid gap-2 sm:grid-cols-3", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.paymentDate }), _jsx(DatePicker, { value: installment.paymentDate ?? "", onChange: (nextValue) => updateInstallment(idx, { paymentDate: nextValue }) })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.paymentMethod }), _jsxs(Select, { value: installment.paymentMethod, onValueChange: (nextValue) => updateInstallment(idx, { paymentMethod: nextValue ?? "bank_transfer" }), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: ["bank_transfer", "credit_card", "cash", "travel_credit", "other"].map((method) => (_jsx(SelectItem, { value: method, children: paymentMethodLabels[method === "credit_card" ? "card" : method] }, method))) })] })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.paymentReference }), _jsx(Input, { value: installment.paymentReference, onChange: (event) => updateInstallment(idx, { paymentReference: event.target.value }) })] })] })) : null] }));
|
|
203
203
|
};
|
|
204
204
|
const fullInstallment = value.installments[0] ?? createInstallment({ dueDate: todayIso() });
|
|
205
205
|
return (_jsxs("div", { className: "flex flex-col gap-3 rounded-md border p-3", children: [_jsx(Label, { children: merged.heading }), _jsxs("div", { className: "grid gap-2 rounded-md bg-muted/40 p-2 text-xs sm:grid-cols-3", children: [_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground", children: merged.totalDue }), _jsx("span", { className: "font-medium tabular-nums", children: formatAmount(total) })] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground", children: merged.scheduledTotal }), _jsx("span", { className: "font-medium tabular-nums", children: formatAmount(scheduledTotal) })] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground", children: merged.remaining }), _jsx("span", { className: "font-medium tabular-nums", children: formatAmount(remaining) })] })] }), _jsx("div", { className: "flex flex-wrap items-center gap-2", children: modes.map((mode) => (_jsx(Button, { type: "button", size: "sm", variant: value.mode === mode.id ? "default" : "ghost", onClick: () => switchMode(mode.id), children: mode.label }, mode.id))) }), value.mode === "full" && (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs", children: merged.dueDate }), _jsx(DatePicker, { value: fullInstallment.dueDate ?? "", onChange: (nextValue) => updateInstallment(0, { dueDate: nextValue }) })] }), renderPaidFields(0, fullInstallment)] })), value.mode === "split" && (_jsxs("div", { className: "flex flex-col gap-3", children: [value.installments.map((installment, idx) => (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium", children: merged.firstInstallment.replace(/\b1\b|first|primul|1st/i, String(idx + 1)) }), value.installments.length > 2 ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": merged.removeInstallment, onClick: () => removeInstallment(idx), children: _jsx(X, { className: "h-3.5 w-3.5" }) })) : null] }), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [_jsx(CurrencyInput, { placeholder: merged.amount, value: installment.amountCents, onChange: (next) => updateInstallment(idx, { amountCents: next }), currency: currency }), _jsx(DatePicker, { value: installment.dueDate ?? "", onChange: (nextValue) => updateInstallment(idx, { dueDate: nextValue }) })] }), renderPaidFields(idx, installment)] }, installment.id))), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addInstallment, className: "self-start", children: [_jsx(Plus, { className: "mr-1 h-3.5 w-3.5" }), merged.addInstallment] })] }))] }));
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
/** Details of a successfully
|
|
2
|
-
export interface
|
|
1
|
+
/** Details of a successfully validated Travel Credit. */
|
|
2
|
+
export interface PickedTravelCredit {
|
|
3
3
|
id: string;
|
|
4
4
|
code: string;
|
|
5
|
-
label: string | null;
|
|
6
5
|
currency: string | null;
|
|
7
6
|
remainingAmountCents: number | null;
|
|
8
7
|
expiresAt: string | null;
|
|
9
8
|
}
|
|
10
|
-
export interface
|
|
9
|
+
export interface TravelCreditPickerValue {
|
|
11
10
|
/** Code typed by the operator. Not cleared on failure so they can correct a typo. */
|
|
12
11
|
code: string;
|
|
13
12
|
/** Populated only when the last validate call succeeded. */
|
|
14
|
-
picked:
|
|
13
|
+
picked: PickedTravelCredit | null;
|
|
15
14
|
/** Reason returned by the server when validate fails, or a client-side message. */
|
|
16
15
|
error: string | null;
|
|
17
16
|
}
|
|
18
|
-
export declare const
|
|
19
|
-
export interface
|
|
20
|
-
value:
|
|
21
|
-
onChange: (value:
|
|
17
|
+
export declare const emptyTravelCreditPickerValue: TravelCreditPickerValue;
|
|
18
|
+
export interface TravelCreditPickerSectionProps {
|
|
19
|
+
value: TravelCreditPickerValue;
|
|
20
|
+
onChange: (value: TravelCreditPickerValue) => void;
|
|
22
21
|
/**
|
|
23
|
-
* Context for the validate call
|
|
22
|
+
* Context for the validate call. When provided, the server rejects Travel Credits
|
|
24
23
|
* locked to a different booking / mismatched currency / insufficient balance.
|
|
25
24
|
*/
|
|
26
25
|
bookingId?: string;
|
|
@@ -36,15 +35,15 @@ export interface VoucherPickerSectionProps {
|
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
|
-
*
|
|
40
|
-
* Apply, and the server-side `/v1/public/
|
|
38
|
+
* Travel Credit picker for booking-create flows. The operator enters a code, clicks
|
|
39
|
+
* Apply, and the server-side `/v1/public/finance/travel-credits/validate` runs all the
|
|
41
40
|
* usual guards (status, expiry, currency, booking-assignment, balance).
|
|
42
41
|
*
|
|
43
42
|
* The section only *validates* — it doesn't redeem. Redemption happens when
|
|
44
|
-
* the parent calls `POST /v1/admin/finance/
|
|
43
|
+
* the parent calls `POST /v1/admin/finance/travel-credits/:id/redeem` at submit time,
|
|
45
44
|
* after the booking exists and the final amount is known. Validate being
|
|
46
45
|
* idempotent means the operator can try a code, correct a typo, and try
|
|
47
46
|
* again without leaving a trail.
|
|
48
47
|
*/
|
|
49
|
-
export declare function
|
|
50
|
-
//# sourceMappingURL=
|
|
48
|
+
export declare function TravelCreditPickerSection({ value, onChange, bookingId, currency, amountCents, labels, }: TravelCreditPickerSectionProps): import("react").JSX.Element;
|
|
49
|
+
//# sourceMappingURL=travel-credit-picker-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"travel-credit-picker-section.d.ts","sourceRoot":"","sources":["../../src/components/travel-credit-picker-section.tsx"],"names":[],"mappings":"AAOA,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACjC,mFAAmF;IACnF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,eAAO,MAAM,4BAA4B,EAAE,uBAI1C,CAAA;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,uBAAuB,CAAA;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAClD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,MAAM,GACP,EAAE,8BAA8B,+BAgHhC"}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { usePublicTravelCreditValidationMutation } from "@voyant-travel/finance-react";
|
|
4
4
|
import { Button, Input, Label } from "@voyant-travel/ui/components";
|
|
5
5
|
import { CheckCircle2, Loader2, XCircle } from "lucide-react";
|
|
6
6
|
import { useBookingsUiI18nOrDefault, useBookingsUiMessagesOrDefault } from "../i18n/provider.js";
|
|
7
|
-
export const
|
|
7
|
+
export const emptyTravelCreditPickerValue = {
|
|
8
8
|
code: "",
|
|
9
9
|
picked: null,
|
|
10
10
|
error: null,
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* Apply, and the server-side `/v1/public/
|
|
13
|
+
* Travel Credit picker for booking-create flows. The operator enters a code, clicks
|
|
14
|
+
* Apply, and the server-side `/v1/public/finance/travel-credits/validate` runs all the
|
|
15
15
|
* usual guards (status, expiry, currency, booking-assignment, balance).
|
|
16
16
|
*
|
|
17
17
|
* The section only *validates* — it doesn't redeem. Redemption happens when
|
|
18
|
-
* the parent calls `POST /v1/admin/finance/
|
|
18
|
+
* the parent calls `POST /v1/admin/finance/travel-credits/:id/redeem` at submit time,
|
|
19
19
|
* after the booking exists and the final amount is known. Validate being
|
|
20
20
|
* idempotent means the operator can try a code, correct a typo, and try
|
|
21
21
|
* again without leaving a trail.
|
|
22
22
|
*/
|
|
23
|
-
export function
|
|
23
|
+
export function TravelCreditPickerSection({ value, onChange, bookingId, currency, amountCents, labels, }) {
|
|
24
24
|
const { formatCurrency } = useBookingsUiI18nOrDefault();
|
|
25
25
|
const messages = useBookingsUiMessagesOrDefault();
|
|
26
|
-
const merged = { ...messages.
|
|
27
|
-
const validate =
|
|
26
|
+
const merged = { ...messages.travelCreditPickerSection.labels, ...labels };
|
|
27
|
+
const validate = usePublicTravelCreditValidationMutation();
|
|
28
28
|
const handleApply = async () => {
|
|
29
29
|
const code = value.code.trim();
|
|
30
30
|
if (!code)
|
|
@@ -36,16 +36,15 @@ export function VoucherPickerSection({ value, onChange, bookingId, currency, amo
|
|
|
36
36
|
currency: currency ?? undefined,
|
|
37
37
|
amountCents: amountCents ?? undefined,
|
|
38
38
|
});
|
|
39
|
-
if (data.valid && data.
|
|
39
|
+
if (data.valid && data.travelCredit) {
|
|
40
40
|
onChange({
|
|
41
41
|
code,
|
|
42
42
|
picked: {
|
|
43
|
-
id: data.
|
|
44
|
-
code: data.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expiresAt: data.voucher.expiresAt,
|
|
43
|
+
id: data.travelCredit.id,
|
|
44
|
+
code: data.travelCredit.code,
|
|
45
|
+
currency: data.travelCredit.currency,
|
|
46
|
+
remainingAmountCents: data.travelCredit.remainingAmountCents,
|
|
47
|
+
expiresAt: data.travelCredit.expiresAt,
|
|
49
48
|
},
|
|
50
49
|
error: null,
|
|
51
50
|
});
|
|
@@ -54,7 +53,7 @@ export function VoucherPickerSection({ value, onChange, bookingId, currency, amo
|
|
|
54
53
|
onChange({
|
|
55
54
|
code,
|
|
56
55
|
picked: null,
|
|
57
|
-
error: messages.
|
|
56
|
+
error: messages.travelCreditPickerSection.reasonMessages[data.reason] ?? messages.travelCreditPickerSection.validation.invalid,
|
|
58
57
|
});
|
|
59
58
|
}
|
|
60
59
|
catch (err) {
|
|
@@ -63,17 +62,17 @@ export function VoucherPickerSection({ value, onChange, bookingId, currency, amo
|
|
|
63
62
|
picked: null,
|
|
64
63
|
error: err instanceof Error
|
|
65
64
|
? err.message
|
|
66
|
-
: messages.
|
|
65
|
+
: messages.travelCreditPickerSection.validation.lookupFailed,
|
|
67
66
|
});
|
|
68
67
|
}
|
|
69
68
|
};
|
|
70
|
-
const handleClear = () => onChange(
|
|
69
|
+
const handleClear = () => onChange(emptyTravelCreditPickerValue);
|
|
71
70
|
return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsx(Label, { children: merged.heading }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { value: value.code, onChange: (e) => onChange({ ...value, code: e.target.value, error: null }), onKeyDown: (e) => {
|
|
72
71
|
if (e.key === "Enter") {
|
|
73
72
|
e.preventDefault();
|
|
74
73
|
void handleApply();
|
|
75
74
|
}
|
|
76
75
|
}, placeholder: merged.codePlaceholder, disabled: validate.isPending || Boolean(value.picked) }), value.picked ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleClear, children: merged.clear })) : (_jsxs(Button, { type: "button", size: "sm", onClick: () => void handleApply(), disabled: validate.isPending || !value.code.trim(), children: [validate.isPending && _jsx(Loader2, { className: "mr-1 h-3.5 w-3.5 animate-spin" }), merged.apply] }))] }), value.picked && (_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-600" }), _jsxs("span", { children: [merged.remainingLabel, " ", _jsx("strong", { children: value.picked.remainingAmountCents == null || !value.picked.currency
|
|
77
|
-
? messages.
|
|
76
|
+
? messages.travelCreditPickerSection.validation.amountUnavailable
|
|
78
77
|
: formatCurrency(value.picked.remainingAmountCents / 100, value.picked.currency) })] })] })), value.error && (_jsxs("div", { className: "flex items-start gap-2 text-sm text-destructive", children: [_jsx(XCircle, { className: "mt-0.5 h-4 w-4" }), _jsxs("span", { children: [merged.invalidLabel, " ", value.error] })] }))] }));
|
|
79
78
|
}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { type UseBookingActivityOptions, useBookingActivity } from "./use-bookin
|
|
|
4
4
|
export { type CancelBookingInput, useBookingCancelMutation, } from "./use-booking-cancel-mutation.js";
|
|
5
5
|
export { type GenerateBookingContractInput, useBookingContractGenerationMutation, } from "./use-booking-contract-generation.js";
|
|
6
6
|
export { type ConvertProductToBookingInput, useBookingConvertMutation, } from "./use-booking-convert-mutation.js";
|
|
7
|
-
export { type BookingCreateExtraLineInput, type BookingCreateGroupMembershipInput, type BookingCreateInput, type BookingCreateItemLineInput, type BookingCreatePaymentScheduleInput, type BookingCreateResult, type
|
|
7
|
+
export { type BookingCreateExtraLineInput, type BookingCreateGroupMembershipInput, type BookingCreateInput, type BookingCreateItemLineInput, type BookingCreatePaymentScheduleInput, type BookingCreateResult, type BookingCreateTravelCreditRedemptionInput, type BookingCreateTravelerInput, useBookingCreateMutation, } from "./use-booking-create-mutation.js";
|
|
8
8
|
export { type CreateBookingTravelerDocumentInput, type UseBookingTravelerDocumentsOptions, useBookingTravelerDocumentMutation, useBookingTravelerDocuments, } from "./use-booking-documents.js";
|
|
9
9
|
export { type DualCreateBookingInput, type DualCreateBookingResult, type DualCreateGroupInput, type DualCreateSubBookingInput, useBookingDualCreateMutation, } from "./use-booking-dual-create-mutation.js";
|
|
10
10
|
export { type UseBookingGroupOptions, useBookingGroup } from "./use-booking-group.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EACL,KAAK,6BAA6B,EAClC,sBAAsB,GACvB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,KAAK,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EACL,KAAK,kBAAkB,EACvB,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,KAAK,4BAA4B,EACjC,oCAAoC,GACrC,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EACL,KAAK,4BAA4B,EACjC,yBAAyB,GAC1B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,iCAAiC,EACtC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,iCAAiC,EACtC,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EACL,KAAK,6BAA6B,EAClC,sBAAsB,GACvB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,KAAK,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EACL,KAAK,kBAAkB,EACvB,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,KAAK,4BAA4B,EACjC,oCAAoC,GACrC,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EACL,KAAK,4BAA4B,EACjC,yBAAyB,GAC1B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,iCAAiC,EACtC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,iCAAiC,EACtC,KAAK,mBAAmB,EACxB,KAAK,wCAAwC,EAC7C,KAAK,0BAA0B,EAC/B,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,KAAK,kCAAkC,EACvC,KAAK,kCAAkC,EACvC,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,4BAA4B,GAC7B,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrF,OAAO,EACL,KAAK,gCAAgC,EACrC,yBAAyB,GAC1B,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACL,KAAK,0BAA0B,EAC/B,6BAA6B,GAC9B,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,KAAK,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,sBAAsB,GACvB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,kBAAkB,GACnB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,KAAK,sBAAsB,EAC3B,sBAAsB,GACvB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrF,OAAO,EACL,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC7B,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,KAAK,2BAA2B,EAChC,oBAAoB,GACrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,KAAK,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EACL,KAAK,8BAA8B,EACnC,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAA;AACnG,OAAO,EACL,KAAK,mCAAmC,EACxC,4BAA4B,GAC7B,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,KAAK,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,EACnC,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,yBAAyB,GAC1B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,KAAK,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AACjG,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,mBAAmB,GACpB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,KAAK,oCAAoC,EACzC,KAAK,oCAAoC,EACzC,oCAAoC,GACrC,MAAM,gDAAgD,CAAA;AACvD,OAAO,EAAE,KAAK,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -96,8 +96,8 @@ export interface BookingCreateExtraLineInput {
|
|
|
96
96
|
*/
|
|
97
97
|
travelerIndexes?: number[] | null;
|
|
98
98
|
}
|
|
99
|
-
export interface
|
|
100
|
-
|
|
99
|
+
export interface BookingCreateTravelCreditRedemptionInput {
|
|
100
|
+
travelCreditId: string;
|
|
101
101
|
amountCents: number;
|
|
102
102
|
}
|
|
103
103
|
export type BookingCreateGroupMembershipInput = {
|
|
@@ -126,7 +126,7 @@ export interface BookingCreateInput {
|
|
|
126
126
|
extraLines?: BookingCreateExtraLineInput[];
|
|
127
127
|
travelers?: BookingCreateTravelerInput[];
|
|
128
128
|
paymentSchedules?: BookingCreatePaymentScheduleInput[];
|
|
129
|
-
|
|
129
|
+
travelCreditRedemption?: BookingCreateTravelCreditRedemptionInput;
|
|
130
130
|
groupMembership?: BookingCreateGroupMembershipInput;
|
|
131
131
|
documentGeneration?: BookingCreateDocumentGenerationInput;
|
|
132
132
|
/**
|
|
@@ -249,7 +249,7 @@ declare const bookingCreateResultSchema: z.ZodObject<{
|
|
|
249
249
|
}, z.core.$strip>;
|
|
250
250
|
travelers: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
251
251
|
paymentSchedules: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
252
|
-
|
|
252
|
+
travelCreditRedemption: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
253
253
|
groupMembership: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
254
254
|
invoice: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
255
255
|
invoiceDocument: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -258,7 +258,7 @@ declare const bookingCreateResultSchema: z.ZodObject<{
|
|
|
258
258
|
export type BookingCreateResult = z.infer<typeof bookingCreateResultSchema>;
|
|
259
259
|
/**
|
|
260
260
|
* Atomic booking-create: calls `POST /v1/admin/bookings/create` which wraps
|
|
261
|
-
* convert-from-product + travelers + payment schedules +
|
|
261
|
+
* convert-from-product + travelers + payment schedules + Travel Credit redemption
|
|
262
262
|
* + group membership in one transaction. Prefer this over chaining the
|
|
263
263
|
* separate create mutations (convert, group, traveler) from a single submit
|
|
264
264
|
* handler — a mid-chain failure there leaves orphan state.
|
|
@@ -327,7 +327,7 @@ export declare function useBookingCreateMutation(): import("@tanstack/react-quer
|
|
|
327
327
|
};
|
|
328
328
|
travelers?: unknown[] | undefined;
|
|
329
329
|
paymentSchedules?: unknown[] | undefined;
|
|
330
|
-
|
|
330
|
+
travelCreditRedemption?: unknown;
|
|
331
331
|
groupMembership?: unknown;
|
|
332
332
|
invoice?: unknown;
|
|
333
333
|
invoiceDocument?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-booking-create-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-booking-create-mutation.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-booking-create-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-booking-create-mutation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,eAAe,CAAA;AAEvE,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAA;IACnD,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;IAC3E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,iCAAiC;IAChD,YAAY,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAA;IACvE,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAA;IACxE,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,oCAAoC;IACnD,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,sEAAsE;IACtE,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,wCAAwC;IACvD,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,MAAM,iCAAiC,GACzC;IACE,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAC5B,GACD;IACE,MAAM,EAAE,QAAQ,CAAA;IAChB,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAEL,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEnC,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAA;IACxC,UAAU,CAAC,EAAE,2BAA2B,EAAE,CAAA;IAC1C,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAA;IACxC,gBAAgB,CAAC,EAAE,iCAAiC,EAAE,CAAA;IACtD,sBAAsB,CAAC,EAAE,wCAAwC,CAAA;IACjE,eAAe,CAAC,EAAE,iCAAiC,CAAA;IACnD,kBAAkB,CAAC,EAAE,oCAAoC,CAAA;IACzD;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,gBAAgB,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAAA;IAClD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAOD,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAS7B,CAAA;AAIF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E;;;;;;GAMG;AACH,wBAAgB,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAkBvC"}
|
|
@@ -5,7 +5,7 @@ import { fetchWithValidation } from "../client.js";
|
|
|
5
5
|
import { useVoyantBookingsContext } from "../provider.js";
|
|
6
6
|
import { bookingsQueryKeys } from "../query-keys.js";
|
|
7
7
|
import { bookingRecordSchema } from "../schemas.js";
|
|
8
|
-
// Response envelope: route returns `{ data: { booking, travelers, paymentSchedules,
|
|
8
|
+
// Response envelope: route returns `{ data: { booking, travelers, paymentSchedules, travelCreditRedemption, groupMembership } }`.
|
|
9
9
|
// We validate only the booking shape (which drives cache invalidation) and
|
|
10
10
|
// pass the rest through as-is so the surface can evolve without breaking
|
|
11
11
|
// clients. Callers who want typed assertions on the extras can narrow on the
|
|
@@ -14,7 +14,7 @@ const bookingCreateResultSchema = z.object({
|
|
|
14
14
|
booking: bookingRecordSchema,
|
|
15
15
|
travelers: z.array(z.unknown()).optional(),
|
|
16
16
|
paymentSchedules: z.array(z.unknown()).optional(),
|
|
17
|
-
|
|
17
|
+
travelCreditRedemption: z.unknown().nullable().optional(),
|
|
18
18
|
groupMembership: z.unknown().nullable().optional(),
|
|
19
19
|
invoice: z.unknown().nullable().optional(),
|
|
20
20
|
invoiceDocument: z.unknown().optional(),
|
|
@@ -23,7 +23,7 @@ const bookingCreateResultSchema = z.object({
|
|
|
23
23
|
const bookingCreateResponseSchema = z.object({ data: bookingCreateResultSchema });
|
|
24
24
|
/**
|
|
25
25
|
* Atomic booking-create: calls `POST /v1/admin/bookings/create` which wraps
|
|
26
|
-
* convert-from-product + travelers + payment schedules +
|
|
26
|
+
* convert-from-product + travelers + payment schedules + Travel Credit redemption
|
|
27
27
|
* + group membership in one transaction. Prefer this over chaining the
|
|
28
28
|
* separate create mutations (convert, group, traveler) from a single submit
|
|
29
29
|
* handler — a mid-chain failure there leaves orphan state.
|
|
@@ -101,7 +101,7 @@ declare const dualCreateResultSchema: z.ZodObject<{
|
|
|
101
101
|
}, z.core.$strip>;
|
|
102
102
|
travelers: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
103
103
|
paymentSchedules: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
104
|
-
|
|
104
|
+
travelCreditRedemption: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
105
105
|
}, z.core.$strip>;
|
|
106
106
|
secondary: z.ZodObject<{
|
|
107
107
|
booking: z.ZodObject<{
|
|
@@ -183,7 +183,7 @@ declare const dualCreateResultSchema: z.ZodObject<{
|
|
|
183
183
|
}, z.core.$strip>;
|
|
184
184
|
travelers: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
185
185
|
paymentSchedules: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
186
|
-
|
|
186
|
+
travelCreditRedemption: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
187
187
|
}, z.core.$strip>;
|
|
188
188
|
group: z.ZodUnknown;
|
|
189
189
|
primaryMember: z.ZodUnknown;
|
|
@@ -262,7 +262,7 @@ export declare function useBookingDualCreateMutation(): import("@tanstack/react-
|
|
|
262
262
|
};
|
|
263
263
|
travelers?: unknown[] | undefined;
|
|
264
264
|
paymentSchedules?: unknown[] | undefined;
|
|
265
|
-
|
|
265
|
+
travelCreditRedemption?: unknown;
|
|
266
266
|
};
|
|
267
267
|
secondary: {
|
|
268
268
|
booking: {
|
|
@@ -328,7 +328,7 @@ export declare function useBookingDualCreateMutation(): import("@tanstack/react-
|
|
|
328
328
|
};
|
|
329
329
|
travelers?: unknown[] | undefined;
|
|
330
330
|
paymentSchedules?: unknown[] | undefined;
|
|
331
|
-
|
|
331
|
+
travelCreditRedemption?: unknown;
|
|
332
332
|
};
|
|
333
333
|
group: unknown;
|
|
334
334
|
primaryMember: unknown;
|