@voyantjs/bookings-ui 0.81.14 → 0.81.16

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.
Files changed (54) hide show
  1. package/dist/components/booking-billing-dialog.d.ts.map +1 -1
  2. package/dist/components/booking-billing-dialog.js +2 -2
  3. package/dist/components/booking-create-dialog.d.ts.map +1 -1
  4. package/dist/components/booking-create-dialog.js +53 -67
  5. package/dist/components/booking-detail-page.d.ts +44 -6
  6. package/dist/components/booking-detail-page.d.ts.map +1 -1
  7. package/dist/components/booking-detail-page.js +117 -42
  8. package/dist/components/booking-guarantee-list.d.ts.map +1 -1
  9. package/dist/components/booking-guarantee-list.js +66 -28
  10. package/dist/components/booking-item-list.d.ts +8 -1
  11. package/dist/components/booking-item-list.d.ts.map +1 -1
  12. package/dist/components/booking-item-list.js +157 -96
  13. package/dist/components/booking-list-filters.d.ts +3 -1
  14. package/dist/components/booking-list-filters.d.ts.map +1 -1
  15. package/dist/components/booking-list-filters.js +5 -3
  16. package/dist/components/booking-list.d.ts.map +1 -1
  17. package/dist/components/booking-list.js +12 -8
  18. package/dist/components/booking-payment-schedule-dialog.d.ts.map +1 -1
  19. package/dist/components/booking-payment-schedule-dialog.js +23 -8
  20. package/dist/components/booking-payment-schedule-list.d.ts +6 -1
  21. package/dist/components/booking-payment-schedule-list.d.ts.map +1 -1
  22. package/dist/components/booking-payment-schedule-list.js +131 -27
  23. package/dist/components/booking-payments-summary.d.ts +15 -7
  24. package/dist/components/booking-payments-summary.d.ts.map +1 -1
  25. package/dist/components/booking-payments-summary.js +99 -74
  26. package/dist/components/icon-action-button.d.ts +18 -0
  27. package/dist/components/icon-action-button.d.ts.map +1 -0
  28. package/dist/components/icon-action-button.js +13 -0
  29. package/dist/components/payment-schedule-section.d.ts +41 -46
  30. package/dist/components/payment-schedule-section.d.ts.map +1 -1
  31. package/dist/components/payment-schedule-section.js +150 -58
  32. package/dist/components/status-badge.d.ts +24 -0
  33. package/dist/components/status-badge.d.ts.map +1 -0
  34. package/dist/components/status-badge.js +65 -0
  35. package/dist/components/supplier-status-list.d.ts.map +1 -1
  36. package/dist/components/supplier-status-list.js +64 -27
  37. package/dist/components/traveler-dialog.d.ts.map +1 -1
  38. package/dist/components/traveler-dialog.js +10 -5
  39. package/dist/components/traveler-list.d.ts.map +1 -1
  40. package/dist/components/traveler-list.js +194 -80
  41. package/dist/i18n/en.d.ts +98 -5
  42. package/dist/i18n/en.d.ts.map +1 -1
  43. package/dist/i18n/en.js +101 -8
  44. package/dist/i18n/messages.d.ts +108 -5
  45. package/dist/i18n/messages.d.ts.map +1 -1
  46. package/dist/i18n/provider.d.ts +196 -10
  47. package/dist/i18n/provider.d.ts.map +1 -1
  48. package/dist/i18n/ro.d.ts +98 -5
  49. package/dist/i18n/ro.d.ts.map +1 -1
  50. package/dist/i18n/ro.js +101 -8
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +2 -0
  54. package/package.json +34 -32
@@ -1 +1 @@
1
- {"version":3,"file":"booking-billing-dialog.d.ts","sourceRoot":"","sources":["../../src/components/booking-billing-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,0BAA0B,CAAA;AAuCjF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,OAAO,EAAE,aAAa,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,SAAS,GACV,EAAE,yBAAyB,2CA2J3B"}
1
+ {"version":3,"file":"booking-billing-dialog.d.ts","sourceRoot":"","sources":["../../src/components/booking-billing-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,0BAA0B,CAAA;AAsCjF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,OAAO,EAAE,aAAa,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,SAAS,GACV,EAAE,yBAAyB,2CA2J3B"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useBookingMutation } from "@voyantjs/bookings-react";
4
- import { Button, Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, Textarea, } from "@voyantjs/ui/components";
4
+ import { Button, Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, } from "@voyantjs/ui/components";
5
5
  import { CountryCombobox } from "@voyantjs/ui/components/country-combobox";
6
6
  import { PhoneInput } from "@voyantjs/ui/components/phone-input";
7
7
  import { zodResolver } from "@voyantjs/ui/lib/zod-resolver";
@@ -87,7 +87,7 @@ export function BookingBillingDialog({ open, onOpenChange, booking, onSuccess, }
87
87
  onOpenChange(false);
88
88
  onSuccess?.();
89
89
  };
90
- return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { size: "lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: messages.title }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-1 flex-col overflow-hidden", children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.firstName }), _jsx(Input, { ...form.register("contactFirstName") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.lastName }), _jsx(Input, { ...form.register("contactLastName") })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.email }), _jsx(Input, { type: "email", ...form.register("contactEmail") }), form.formState.errors.contactEmail ? (_jsx("p", { className: "text-xs text-destructive", children: form.formState.errors.contactEmail.message })) : null] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.phone }), _jsx(PhoneInput, { value: form.watch("contactPhone") ?? "", onChange: (next) => form.setValue("contactPhone", next, { shouldDirty: true }) })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.addressLine1 }), _jsx(Textarea, { rows: 2, ...form.register("contactAddressLine1") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.addressLine2 }), _jsx(Textarea, { rows: 2, ...form.register("contactAddressLine2") })] })] }), _jsxs("div", { className: "grid grid-cols-3 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.city }), _jsx(Input, { ...form.register("contactCity") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.region }), _jsx(Input, { ...form.register("contactRegion") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.postalCode }), _jsx(Input, { ...form.register("contactPostalCode") })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.country }), _jsx(CountryCombobox, { value: form.watch("contactCountry") || null, onChange: (next) => form.setValue("contactCountry", next ?? "", {
90
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { size: "lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: messages.title }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-1 flex-col overflow-hidden", children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.firstName }), _jsx(Input, { ...form.register("contactFirstName") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.lastName }), _jsx(Input, { ...form.register("contactLastName") })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.email }), _jsx(Input, { type: "email", ...form.register("contactEmail") }), form.formState.errors.contactEmail ? (_jsx("p", { className: "text-xs text-destructive", children: form.formState.errors.contactEmail.message })) : null] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.phone }), _jsx(PhoneInput, { value: form.watch("contactPhone") ?? "", onChange: (next) => form.setValue("contactPhone", next, { shouldDirty: true }) })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.addressLine1 }), _jsx(Input, { ...form.register("contactAddressLine1") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.addressLine2 }), _jsx(Input, { ...form.register("contactAddressLine2") })] })] }), _jsxs("div", { className: "grid grid-cols-3 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.city }), _jsx(Input, { ...form.register("contactCity") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.region }), _jsx(Input, { ...form.register("contactRegion") })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.postalCode }), _jsx(Input, { ...form.register("contactPostalCode") })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.fields.country }), _jsx(CountryCombobox, { value: form.watch("contactCountry") || null, onChange: (next) => form.setValue("contactCountry", next ?? "", {
91
91
  shouldDirty: true,
92
92
  shouldValidate: true,
93
93
  }) })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onOpenChange(false), children: messages.actions.cancel }), _jsxs(Button, { type: "submit", size: "sm", disabled: update.isPending, children: [update.isPending ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null, messages.actions.save] })] })] })] }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"booking-create-dialog.d.ts","sourceRoot":"","sources":["../../src/components/booking-create-dialog.tsx"],"names":[],"mappings":"AAeA,OAAO,EAKL,KAAK,aAAa,EAInB,MAAM,0BAA0B,CAAA;AAkQjC,MAAM,WAAW,wBAAwB;IACvC,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,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,EAAE,wBAAwB,2CAsB1B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,OAAc,EACd,QAAQ,GACT,EAAE,sBAAsB,2CAg+BxB"}
1
+ {"version":3,"file":"booking-create-dialog.d.ts","sourceRoot":"","sources":["../../src/components/booking-create-dialog.tsx"],"names":[],"mappings":"AAeA,OAAO,EAKL,KAAK,aAAa,EAInB,MAAM,0BAA0B,CAAA;AAiPjC,MAAM,WAAW,wBAAwB;IACvC,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,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,EAAE,wBAAwB,2CAsB1B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,OAAc,EACd,QAAQ,GACT,EAAE,sBAAsB,2CAg8BxB"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useQueries, useQuery } from "@tanstack/react-query";
4
4
  import { getSlotQueryOptions, useSlots, useSlotUnitAvailability, useVoyantAvailabilityContext, } from "@voyantjs/availability-react";
5
5
  import { resolveBookingDraft, resolveBookingExtraLines, travelersToRows, } from "@voyantjs/bookings/pricing-assignment";
@@ -32,39 +32,35 @@ function generateBookingNumber() {
32
32
  }
33
33
  function paymentScheduleToRows(value, currency, totalAmountCents) {
34
34
  if (value.mode === "full") {
35
- if (!value.fullDueDate || totalAmountCents === null)
35
+ const installment = value.installments[0];
36
+ if (!installment?.dueDate || totalAmountCents === null)
36
37
  return [];
37
38
  return [
38
39
  {
39
40
  scheduleType: "balance",
40
- status: value.fullAlreadyPaid ? "paid" : "due",
41
- dueDate: value.fullDueDate,
41
+ status: installment.alreadyPaid ? "paid" : "due",
42
+ dueDate: installment.dueDate,
42
43
  currency,
43
44
  amountCents: totalAmountCents,
44
- notes: paidScheduleNotes(value.fullAlreadyPaid, value.fullPaymentDate, value.fullPaymentMethod, value.fullPaymentReference),
45
+ notes: paidScheduleNotes(installment.alreadyPaid, installment.paymentDate, installment.paymentMethod, installment.paymentReference),
45
46
  },
46
47
  ];
47
48
  }
48
- // split
49
+ // split — N installments
49
50
  const rows = [];
50
- if (value.splitFirstDueDate && value.splitFirstAmountCents != null) {
51
+ for (const [idx, installment] of value.installments.entries()) {
52
+ if (!installment.dueDate || installment.amountCents == null)
53
+ continue;
51
54
  rows.push({
52
55
  scheduleType: "installment",
53
- status: value.splitFirstAlreadyPaid ? "paid" : "due",
54
- dueDate: value.splitFirstDueDate,
56
+ // First installment defaults to `due` (immediately collectable),
57
+ // subsequent ones to `pending` so the dashboard's "next due" picker
58
+ // doesn't flag them all at once.
59
+ status: installment.alreadyPaid ? "paid" : idx === 0 ? "due" : "pending",
60
+ dueDate: installment.dueDate,
55
61
  currency,
56
- amountCents: value.splitFirstAmountCents,
57
- notes: paidScheduleNotes(value.splitFirstAlreadyPaid, value.splitFirstPaymentDate, value.splitFirstPaymentMethod, value.splitFirstPaymentReference),
58
- });
59
- }
60
- if (value.splitSecondDueDate && value.splitSecondAmountCents != null) {
61
- rows.push({
62
- scheduleType: "installment",
63
- status: value.splitSecondAlreadyPaid ? "paid" : "pending",
64
- dueDate: value.splitSecondDueDate,
65
- currency,
66
- amountCents: value.splitSecondAmountCents,
67
- notes: paidScheduleNotes(value.splitSecondAlreadyPaid, value.splitSecondPaymentDate, value.splitSecondPaymentMethod, value.splitSecondPaymentReference),
62
+ amountCents: installment.amountCents,
63
+ notes: paidScheduleNotes(installment.alreadyPaid, installment.paymentDate, installment.paymentMethod, installment.paymentReference),
68
64
  });
69
65
  }
70
66
  return rows;
@@ -101,14 +97,7 @@ function stripUnitSuffix(name) {
101
97
  * `confirmed`; otherwise it lands in `awaiting_payment`.
102
98
  */
103
99
  function hasAnyPaidPayment(schedule) {
104
- switch (schedule.mode) {
105
- case "full":
106
- return schedule.fullAlreadyPaid;
107
- case "split":
108
- return schedule.splitFirstAlreadyPaid || schedule.splitSecondAlreadyPaid;
109
- default:
110
- return false;
111
- }
100
+ return schedule.installments.some((installment) => installment.alreadyPaid);
112
101
  }
113
102
  /**
114
103
  * Inverse of stripUnitSuffix — strip the leading "Option name - " so
@@ -195,18 +184,24 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
195
184
  const [voucher, setVoucher] = React.useState(emptyVoucherPickerValue);
196
185
  const [pricing, setPricing] = React.useState(null);
197
186
  const [paymentSchedule, setPaymentSchedule] = React.useState(emptyPaymentScheduleValue);
198
- const [generateContractDocument, setGenerateContractDocument] = React.useState(false);
199
- const [generateInvoiceDocument, setGenerateInvoiceDocument] = React.useState(false);
200
- const [notes, setNotes] = React.useState("");
201
187
  /**
202
- * Operator override that forces the booking to land in `draft`
203
- * regardless of payment state. Off by default the dialog
204
- * smart-defaults to `confirmed` (when any payment is marked paid)
205
- * or `awaiting_payment` (when nothing is paid yet). The override
206
- * exists so an operator can still capture a half-configured
207
- * booking without committing it to the lifecycle.
188
+ * Mutually-exclusive document toggles. "Proforma" issues a single
189
+ * placeholder invoice; "Invoice + contract" issues a final invoice
190
+ * alongside the customer contract. Either off no documents.
208
191
  */
209
- const [createAsDraft, setCreateAsDraft] = React.useState(false);
192
+ const [generateProforma, setGenerateProformaState] = React.useState(false);
193
+ const [generateInvoiceAndContract, setGenerateInvoiceAndContractState] = React.useState(false);
194
+ const setGenerateProforma = (next) => {
195
+ setGenerateProformaState(next);
196
+ if (next)
197
+ setGenerateInvoiceAndContractState(false);
198
+ };
199
+ const setGenerateInvoiceAndContract = (next) => {
200
+ setGenerateInvoiceAndContractState(next);
201
+ if (next)
202
+ setGenerateProformaState(false);
203
+ };
204
+ const [notes, setNotes] = React.useState("");
210
205
  // Only relevant when the derived status is `confirmed`: when off,
211
206
  // the status transition carries `suppressNotifications: true` so
212
207
  // the auto-dispatch subscriber skips the customer email + document
@@ -239,10 +234,9 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
239
234
  setVoucher(emptyVoucherPickerValue);
240
235
  setPricing(null);
241
236
  setPaymentSchedule(emptyPaymentScheduleValue);
242
- setGenerateContractDocument(false);
243
- setGenerateInvoiceDocument(false);
237
+ setGenerateProformaState(false);
238
+ setGenerateInvoiceAndContractState(false);
244
239
  setNotes("");
245
- setCreateAsDraft(false);
246
240
  setNotifyTraveler(true);
247
241
  setError(null);
248
242
  setPayloadMismatchUnitIds([]);
@@ -610,15 +604,12 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
610
604
  // Smart-default status from payment state — any payment marked
611
605
  // "Already paid" implies the booking is effectively confirmed,
612
606
  // otherwise it lands in `awaiting_payment` so the operator can
613
- // dispatch a payment link. Override available via the explicit
614
- // "Create as draft" checkbox. The server commits this status in
607
+ // dispatch a payment link. The server commits this status in
615
608
  // the create transaction and emits `booking.confirmed`
616
609
  // post-commit when applicable — no second roundtrip.
617
- const initialStatus = createAsDraft
618
- ? undefined
619
- : hasAnyPaidPayment(paymentSchedule)
620
- ? "confirmed"
621
- : "awaiting_payment";
610
+ const initialStatus = hasAnyPaidPayment(paymentSchedule)
611
+ ? "confirmed"
612
+ : "awaiting_payment";
622
613
  // Build the billing-contact snapshot from whichever CRM record
623
614
  // the operator picked, plus the primary identity address when
624
615
  // present. Falls back to nulls when a record is missing — the
@@ -670,10 +661,15 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
670
661
  paymentSchedules: paymentSchedules.length > 0 ? paymentSchedules : undefined,
671
662
  voucherRedemption,
672
663
  groupMembership,
673
- documentGeneration: {
674
- contractDocument: generateContractDocument,
675
- invoiceDocument: generateInvoiceDocument,
676
- },
664
+ documentGeneration: generateProforma
665
+ ? { contractDocument: false, invoiceDocument: true, invoiceType: "proforma" }
666
+ : generateInvoiceAndContract
667
+ ? {
668
+ contractDocument: true,
669
+ invoiceDocument: true,
670
+ invoiceType: "invoice",
671
+ }
672
+ : { contractDocument: false, invoiceDocument: false },
677
673
  initialStatus,
678
674
  // Suppression only matters when transitioning to `confirmed` —
679
675
  // `awaiting_payment` doesn't trigger the auto-dispatch
@@ -749,19 +745,9 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
749
745
  noRoom: messages.bookingCreateDialog.labels.travelerNoRoom,
750
746
  remove: messages.bookingCreateDialog.labels.travelerRemove,
751
747
  empty: messages.bookingCreateDialog.labels.travelerEmpty,
752
- } })) : null, product.productId && slotId ? (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.bookingCreateDialog.fields.internalNotes }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: messages.bookingCreateDialog.placeholders.internalNotes })] })) : null, product.productId && slotId ? (_jsxs("div", { className: "flex flex-col gap-3 rounded-md border p-3", children: [_jsx(Label, { children: messages.bookingCreateDialog.labels.documentGenerationHeading }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { id: "new-booking-generate-contract-document", checked: generateContractDocument, onCheckedChange: (value) => setGenerateContractDocument(value === true) }), _jsx(Label, { htmlFor: "new-booking-generate-contract-document", className: "cursor-pointer", children: messages.bookingCreateDialog.labels.generateContractDocument })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { id: "new-booking-generate-invoice-document", checked: generateInvoiceDocument, onCheckedChange: (value) => setGenerateInvoiceDocument(value === true) }), _jsx(Label, { htmlFor: "new-booking-generate-invoice-document", className: "cursor-pointer", children: messages.bookingCreateDialog.labels.generateInvoiceDocument })] }), _jsx("div", { className: "flex flex-col gap-2 border-t pt-2 text-sm", children: (() => {
753
- const wouldBeConfirmed = hasAnyPaidPayment(paymentSchedule);
754
- const derivedStatusLabel = createAsDraft
755
- ? messages.common.bookingStatusLabels.draft
756
- : wouldBeConfirmed
757
- ? messages.common.bookingStatusLabels.confirmed
758
- : messages.common.bookingStatusLabels.awaiting_payment;
759
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Checkbox, { id: "new-booking-create-as-draft", checked: createAsDraft, onCheckedChange: (v) => setCreateAsDraft(v === true), className: "mt-0.5" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { htmlFor: "new-booking-create-as-draft", className: "cursor-pointer text-sm", children: messages.bookingCreateDialog.fields.createAsDraft }), _jsx("p", { className: "text-xs text-muted-foreground", children: formatMessage(messages.bookingCreateDialog.fields.createAsDraftHint, { status: derivedStatusLabel }) })] })] }), !createAsDraft && wouldBeConfirmed ? (_jsxs("div", { className: "flex items-start gap-2 pl-6", children: [_jsx(Checkbox, { id: "new-booking-notify-traveler", checked: notifyTraveler, onCheckedChange: (v) => setNotifyTraveler(v === true), className: "mt-0.5" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { htmlFor: "new-booking-notify-traveler", className: "cursor-pointer text-sm", children: messages.bookingCreateDialog.fields.notifyTraveler }), _jsx("p", { className: "text-xs text-muted-foreground", children: messages.bookingCreateDialog.fields.notifyTravelerHint })] })] })) : null] }));
760
- })() })] })] })) : null] }), error ? (_jsx("div", { role: "alert", className: "mt-3 rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error })) : null, _jsxs("div", { className: "mt-4 flex items-center justify-end gap-2 border-t px-1 pt-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancel, disabled: isSubmitting, children: messages.common.cancel }), _jsxs(Button, { type: "button", size: "sm", onClick: handleSubmit, disabled: isSubmitting || !product.productId || !slotId || !hasSelectedUnits, children: [isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), createAsDraft
761
- ? messages.bookingCreateDialog.actions.createDraftBooking
762
- : hasAnyPaidPayment(paymentSchedule)
763
- ? messages.bookingCreateDialog.actions.createConfirmedBooking
764
- : 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: (() => {
748
+ } })) : null, product.productId && slotId ? (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.bookingCreateDialog.fields.internalNotes }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: messages.bookingCreateDialog.placeholders.internalNotes })] })) : null, product.productId && slotId ? (_jsxs("div", { className: "flex flex-col gap-3 rounded-md border p-3", children: [_jsx(Label, { children: messages.bookingCreateDialog.labels.documentGenerationHeading }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { id: "new-booking-generate-proforma", checked: generateProforma, onCheckedChange: (value) => setGenerateProforma(value === true) }), _jsx(Label, { htmlFor: "new-booking-generate-proforma", className: "cursor-pointer", children: messages.bookingCreateDialog.labels.generateProforma })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { id: "new-booking-generate-invoice-and-contract", checked: generateInvoiceAndContract, onCheckedChange: (value) => setGenerateInvoiceAndContract(value === true) }), _jsx(Label, { htmlFor: "new-booking-generate-invoice-and-contract", className: "cursor-pointer", children: messages.bookingCreateDialog.labels.generateInvoiceAndContract })] }), hasAnyPaidPayment(paymentSchedule) ? (_jsxs("div", { className: "flex items-start gap-2 border-t pt-2 text-sm", children: [_jsx(Checkbox, { id: "new-booking-notify-traveler", checked: notifyTraveler, onCheckedChange: (v) => setNotifyTraveler(v === true), className: "mt-0.5" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Label, { htmlFor: "new-booking-notify-traveler", className: "cursor-pointer text-sm", children: messages.bookingCreateDialog.fields.notifyTraveler }), _jsx("p", { className: "text-xs text-muted-foreground", children: messages.bookingCreateDialog.fields.notifyTravelerHint })] })] })) : null] })] })) : null] }), error ? (_jsx("div", { role: "alert", className: "mt-3 rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error })) : null, _jsxs("div", { className: "mt-4 flex items-center justify-end gap-2 border-t px-1 pt-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancel, disabled: isSubmitting, children: messages.common.cancel }), _jsxs(Button, { type: "button", size: "sm", onClick: handleSubmit, disabled: isSubmitting || !product.productId || !slotId || !hasSelectedUnits, children: [isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), hasAnyPaidPayment(paymentSchedule)
749
+ ? messages.bookingCreateDialog.actions.createConfirmedBooking
750
+ : 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: (() => {
765
751
  const slot = slots.find((s) => s.id === slotId);
766
752
  return slot ? formatSlotLabel(slot) : null;
767
753
  })(), unitQuantities: displayQuantities, unitLabels: roomUnitLabels, extraLines: displayExtraLines, travelers: travelers.travelers, messages: messages, onPricingChange: setPricing }), product.productId && slotId ? (_jsx(VoucherPickerSection, { value: voucher, onChange: setVoucher, currency: currency, labels: {
@@ -771,7 +757,7 @@ export function BookingCreateForm({ onCreated, defaultProductId, defaultSlotId,
771
757
  clear: messages.bookingCreateDialog.labels.voucherClear,
772
758
  remainingLabel: messages.bookingCreateDialog.labels.voucherRemainingLabel,
773
759
  invalidLabel: messages.bookingCreateDialog.labels.voucherInvalidLabel,
774
- } })) : null, product.productId && slotId ? (_jsx(PaymentScheduleSection, { value: paymentSchedule, onChange: setPaymentSchedule, currency: pricingCurrency, totalAmountCents: pricingTotalAmountCents, labels: {
760
+ } })) : null, product.productId && slotId ? (_jsx(PaymentScheduleSection, { value: paymentSchedule, onChange: setPaymentSchedule, currency: pricingCurrency, totalAmountCents: pricingTotalAmountCents, departureDate: selectedSlot?.startsAt?.slice(0, 10) ?? null, labels: {
775
761
  heading: messages.bookingCreateDialog.labels.paymentHeading,
776
762
  modeUnpaid: messages.bookingCreateDialog.labels.paymentModeUnpaid,
777
763
  modeFull: messages.bookingCreateDialog.labels.paymentModeFull,
@@ -1,5 +1,6 @@
1
1
  import { type BookingRecord } from "@voyantjs/bookings-react";
2
2
  import { type ReactNode } from "react";
3
+ import { type BookingItemResourceKind } from "./booking-item-list.js";
3
4
  import { type BookingPaymentsSummaryRow } from "./booking-payments-summary.js";
4
5
  /**
5
6
  * Optional extra tab. When provided, the canonical layout renders a
@@ -40,12 +41,45 @@ export interface BookingDetailPageProps {
40
41
  * (use when the host shell already renders breadcrumbs). */
41
42
  hideBreadcrumb?: boolean;
42
43
  onBack?: () => void;
44
+ /**
45
+ * Forwarded to the finance-tab `BookingPaymentsSummary` header as a
46
+ * `Record payment` action button.
47
+ */
48
+ onRecordPayment?: (booking: BookingRecord) => void;
49
+ /**
50
+ * When set, the Record payment header button renders disabled and its
51
+ * tooltip shows this reason. Use for "nothing left to pay" states.
52
+ */
53
+ recordPaymentDisabledReason?: string | null;
54
+ /**
55
+ * When set, the Add schedule button in the payment-schedule section
56
+ * renders disabled and its tooltip shows this reason.
57
+ */
58
+ addScheduleDisabledReason?: string | null;
59
+ /**
60
+ * Amount the customer has paid so far against this booking, in cents
61
+ * of `booking.sellCurrency`. When provided, a `Paid` stat is shown
62
+ * next to `Total`. Resolution (invoices vs. raw payments) is left to
63
+ * the host template — `bookings-ui` doesn't fetch finance data.
64
+ */
65
+ paidAmountCents?: number | null;
66
+ /**
67
+ * Open a linked resource referenced by a booking item (product or
68
+ * availability slot) in the host app. When omitted, the item-snapshot
69
+ * sheet renders the names as plain text.
70
+ */
71
+ onItemResourceOpen?: (kind: BookingItemResourceKind, id: string) => void;
72
+ /** Open the linked CRM person's detail page (used by the Payer card). */
43
73
  onPersonOpen?: (personId: string) => void;
74
+ /** Open the linked CRM organization's detail page (used by the Payer card). */
44
75
  onOrganizationOpen?: (organizationId: string) => void;
45
- /** Wired to a primary `Generate payment link` button on the Payments tab. */
46
- onCollectPayment?: (booking: BookingRecord) => void;
47
- /** Wired to a secondary `Record payment` button on the Payments tab. */
48
- onRecordPayment?: (booking: BookingRecord) => void;
76
+ /**
77
+ * Open an invoice in-place when the operator clicks the invoice
78
+ * number in the Payments row. Typically wired to a `Sheet` that
79
+ * renders the invoice-detail view so the admin doesn't leave the
80
+ * booking screen.
81
+ */
82
+ onInvoiceOpen?: (invoiceId: string, row: BookingPaymentsSummaryRow) => void;
49
83
  /** Forwarded to the finance-tab `BookingPaymentsSummary` row menu. */
50
84
  onViewPayment?: (row: BookingPaymentsSummaryRow) => void;
51
85
  /** Forwarded to the finance-tab `BookingPaymentsSummary` row menu. */
@@ -54,7 +88,7 @@ export interface BookingDetailPageProps {
54
88
  onDeletePayment?: (row: BookingPaymentsSummaryRow) => Promise<void> | void;
55
89
  slots?: BookingDetailPageSlots;
56
90
  }
57
- export declare function BookingDetailPage({ id, className, locale, hideBreadcrumb, onBack, onPersonOpen, onOrganizationOpen, onCollectPayment, onRecordPayment, onViewPayment, onEditPayment, onDeletePayment, slots, }: BookingDetailPageProps): import("react/jsx-runtime").JSX.Element;
91
+ export declare function BookingDetailPage({ id, className, locale, hideBreadcrumb, onBack, onRecordPayment, recordPaymentDisabledReason, addScheduleDisabledReason, paidAmountCents, onItemResourceOpen, onPersonOpen, onOrganizationOpen, onInvoiceOpen, onViewPayment, onEditPayment, onDeletePayment, slots, }: BookingDetailPageProps): import("react/jsx-runtime").JSX.Element;
58
92
  /**
59
93
  * Billing/contact card for the Travelers tab. Snapshot fields on the
60
94
  * booking row are the source of truth (they capture contact info at
@@ -63,7 +97,11 @@ export declare function BookingDetailPage({ id, className, locale, hideBreadcrum
63
97
  * person / organization so the operator still sees who they're
64
98
  * billing.
65
99
  */
66
- export declare function BookingBillingContextCard({ booking }: {
100
+ export declare function BookingBillingContextCard({ booking, onPersonOpen, onOrganizationOpen, }: {
67
101
  booking: BookingRecord;
102
+ /** Open the linked CRM person's detail page. */
103
+ onPersonOpen?: (personId: string) => void;
104
+ /** Open the linked CRM organization's detail page. */
105
+ onOrganizationOpen?: (organizationId: string) => void;
68
106
  }): import("react/jsx-runtime").JSX.Element;
69
107
  //# sourceMappingURL=booking-detail-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"booking-detail-page.d.ts","sourceRoot":"","sources":["../../src/components/booking-detail-page.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"booking-detail-page.d.ts","sourceRoot":"","sources":["../../src/components/booking-detail-page.tsx"],"names":[],"mappings":"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"}