@ticketboothapp/booking 1.2.123 → 1.2.125

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 (112) hide show
  1. package/CHANGE_BOOKING_BE_HANDOFF.md +15 -4
  2. package/package.json +1 -1
  3. package/src/components/booking/AdminChangeBookingContent.tsx +276 -0
  4. package/src/components/booking/AdminChangeBookingFlow.tsx +651 -6202
  5. package/src/components/booking/AdminChangeCheckoutDialogs.tsx +105 -0
  6. package/src/components/booking/AdminChangeCheckoutPanel.tsx +307 -0
  7. package/src/components/booking/AdminChangePricingPanel.tsx +244 -0
  8. package/src/components/booking/AdminChangeProductSwitcher.tsx +50 -0
  9. package/src/components/booking/AdminChangeReceiptComparison.tsx +167 -0
  10. package/src/components/booking/ChangeBookingCalendarPanel.tsx +126 -0
  11. package/src/components/booking/ChangeBookingCheckoutPanel.tsx +204 -0
  12. package/src/components/booking/ChangeBookingFlow.tsx +576 -4648
  13. package/src/components/booking/ChangeBookingItineraryPanel.tsx +115 -0
  14. package/src/components/booking/ChangeBookingQuoteStatusPlaceholder.tsx +57 -0
  15. package/src/components/booking/ChangeBookingSelectionControlsPanel.tsx +157 -0
  16. package/src/components/booking/ChangeBookingTicketsAndAddOnsPanel.tsx +102 -0
  17. package/src/components/booking/CheckoutModal.tsx +68 -49
  18. package/src/components/booking/NewBookingFlow.tsx +485 -3505
  19. package/src/components/booking/PriceBreakdown.tsx +17 -3
  20. package/src/components/booking/PriceSummary.tsx +21 -3
  21. package/src/components/booking/PrivateShuttleAddOnsSection.tsx +102 -0
  22. package/src/components/booking/PrivateShuttleBookingFlow.tsx +407 -2788
  23. package/src/components/booking/PrivateShuttleCheckoutDialogs.tsx +106 -0
  24. package/src/components/booking/PrivateShuttleCheckoutSection.tsx +333 -0
  25. package/src/components/booking/PrivateShuttleItinerarySection.tsx +95 -0
  26. package/src/components/booking/PrivateShuttleMediaIntro.tsx +62 -0
  27. package/src/components/booking/PrivateShuttleOptionSection.tsx +81 -0
  28. package/src/components/booking/PrivateShuttlePassengerSection.tsx +148 -0
  29. package/src/components/booking/PrivateShuttlePickupSection.tsx +91 -0
  30. package/src/components/booking/PrivateShuttlePreferencesSection.tsx +75 -0
  31. package/src/components/booking/PrivateShuttleStartTimeSection.tsx +88 -0
  32. package/src/components/booking/StandardBookingCheckoutDialogs.tsx +106 -0
  33. package/src/components/booking/StandardBookingCheckoutSection.tsx +185 -0
  34. package/src/components/booking/StandardBookingItineraryPanel.tsx +125 -0
  35. package/src/components/booking/StandardBookingMediaIntro.tsx +69 -0
  36. package/src/components/booking/StandardBookingSelectionControlsPanel.tsx +236 -0
  37. package/src/components/booking/admin-change-customer-quote-runner.ts +119 -0
  38. package/src/components/booking/admin-change-flow-state-helpers.ts +124 -0
  39. package/src/components/booking/admin-change-payment-choice-runner.ts +172 -0
  40. package/src/components/booking/admin-change-provider-payload.ts +101 -0
  41. package/src/components/booking/change-booking-checkout-builders.ts +185 -0
  42. package/src/components/booking/change-booking-checkout-quote-runner.ts +207 -0
  43. package/src/components/booking/change-booking-flow-helpers.ts +706 -0
  44. package/src/components/booking/change-booking-payment-modal-builders.ts +151 -0
  45. package/src/components/booking/change-booking-quote-guards.ts +223 -0
  46. package/src/components/booking/change-booking-quote-state.ts +64 -0
  47. package/src/components/booking/pricing-v2-checkout-summary.ts +144 -0
  48. package/src/components/booking/private-shuttle-availability.ts +111 -0
  49. package/src/components/booking/private-shuttle-checkout-builders.ts +264 -0
  50. package/src/components/booking/private-shuttle-checkout-controller.ts +744 -0
  51. package/src/components/booking/private-shuttle-payment-choice-runner.ts +271 -0
  52. package/src/components/booking/private-shuttle-provider-change-runner.ts +73 -0
  53. package/src/components/booking/private-shuttle-reservation-runner.ts +260 -0
  54. package/src/components/booking/standard-booking-availability.ts +305 -0
  55. package/src/components/booking/standard-booking-checkout-builders.ts +289 -0
  56. package/src/components/booking/standard-booking-checkout-controller.ts +659 -0
  57. package/src/components/booking/standard-booking-payment-choice-runner.ts +274 -0
  58. package/src/components/booking/standard-booking-reservation-runner.ts +229 -0
  59. package/src/components/booking/use-private-shuttle-availability.ts +602 -0
  60. package/src/components/booking/use-standard-booking-availability.ts +806 -0
  61. package/src/components/booking/useActiveProductOptions.ts +26 -0
  62. package/src/components/booking/useAdminChangeCheckoutController.ts +806 -0
  63. package/src/components/booking/useAdminChangeOrderSummaryModel.ts +246 -0
  64. package/src/components/booking/useAdminChangePriceSummary.ts +416 -0
  65. package/src/components/booking/useAdminChangePricingDebugPanel.tsx +178 -0
  66. package/src/components/booking/useAdminChangeProductReset.ts +60 -0
  67. package/src/components/booking/useAdminChangeProducts.ts +102 -0
  68. package/src/components/booking/useAdminChangePromoDiscount.ts +235 -0
  69. package/src/components/booking/useAdminChangeProtectedPricing.ts +280 -0
  70. package/src/components/booking/useAdminChangeQuoteDisplayState.tsx +437 -0
  71. package/src/components/booking/useAdminChangeQuotePreview.ts +506 -0
  72. package/src/components/booking/useAdminChangeReceiptDerivation.ts +203 -0
  73. package/src/components/booking/useAdminCustomReceiptLines.ts +57 -0
  74. package/src/components/booking/useAdminProviderPricingAdjustments.ts +146 -0
  75. package/src/components/booking/useBookingAvailabilityAddOns.ts +54 -0
  76. package/src/components/booking/useBookingPromoAndQuantityController.ts +163 -0
  77. package/src/components/booking/useBookingQuantityCapTrim.ts +56 -0
  78. package/src/components/booking/useBookingViewItemAnalytics.ts +30 -0
  79. package/src/components/booking/useChangeBookingAddOnFloorController.ts +109 -0
  80. package/src/components/booking/useChangeBookingAutoSelections.ts +148 -0
  81. package/src/components/booking/useChangeBookingAvailabilities.ts +692 -0
  82. package/src/components/booking/useChangeBookingCheckoutController.ts +461 -0
  83. package/src/components/booking/useChangeBookingInitialHydration.ts +204 -0
  84. package/src/components/booking/useChangeBookingItineraryUiState.ts +133 -0
  85. package/src/components/booking/useChangeBookingPickupItinerary.ts +472 -0
  86. package/src/components/booking/useChangeBookingPriceSummary.ts +199 -0
  87. package/src/components/booking/useChangeBookingPromoDiscount.ts +218 -0
  88. package/src/components/booking/useChangeBookingProtectedPricing.ts +256 -0
  89. package/src/components/booking/useChangeBookingQuotePreview.ts +442 -0
  90. package/src/components/booking/useChangeBookingReceiptDerivation.ts +128 -0
  91. package/src/components/booking/useChangeBookingReceiptFloorController.ts +449 -0
  92. package/src/components/booking/useChangeBookingSelection.ts +362 -0
  93. package/src/components/booking/useChangeBookingSelectionDetails.ts +200 -0
  94. package/src/components/booking/useChangeBookingSummaryLines.ts +169 -0
  95. package/src/components/booking/usePrivateShuttlePriceSummary.ts +513 -0
  96. package/src/components/booking/usePrivateShuttlePromoController.ts +143 -0
  97. package/src/components/booking/usePrivateShuttlePromoDiscount.ts +124 -0
  98. package/src/components/booking/useSeedPromoCodeInput.ts +13 -0
  99. package/src/components/booking/useStandardBookingAutoSelections.ts +224 -0
  100. package/src/components/booking/useStandardBookingPickupItinerary.ts +473 -0
  101. package/src/components/booking/useStandardBookingPriceSummary.ts +438 -0
  102. package/src/components/booking/useStandardBookingPromoController.ts +258 -0
  103. package/src/components/booking/useStandardBookingPromoDiscount.ts +203 -0
  104. package/src/data/products-config.json +1 -1
  105. package/src/lib/booking/change-booking-server-preview.ts +134 -20
  106. package/src/lib/booking/change-flow-pricing.ts +31 -11
  107. package/src/lib/booking/checkout-breakdown.ts +66 -1
  108. package/src/lib/booking/pricing-config.ts +10 -0
  109. package/src/lib/booking/source-metadata.ts +58 -0
  110. package/src/lib/booking-api.ts +155 -3
  111. package/src/lib/pricing-v2-shadow.ts +272 -0
  112. package/test/change-booking-helpers.test.ts +206 -0
@@ -0,0 +1,206 @@
1
+ import assert from 'node:assert/strict';
2
+ import {
3
+ buildChangeBookingPaidCheckoutModalData,
4
+ buildChangeBookingPaymentSuccessUrl,
5
+ } from '../src/components/booking/change-booking-payment-modal-builders';
6
+ import { evaluateChangeBookingQuoteForCheckout } from '../src/components/booking/change-booking-quote-guards';
7
+ import type { ChangeQuoteUiSlice } from '../src/lib/booking/change-flow-pricing';
8
+ import type { ChangeBookingQuoteResponse } from '../src/lib/booking-api';
9
+
10
+ function quote(overrides: Partial<ChangeBookingQuoteResponse>): ChangeBookingQuoteResponse {
11
+ return {
12
+ priceDiff: 0,
13
+ canProceed: true,
14
+ ...overrides,
15
+ };
16
+ }
17
+
18
+ function quoteSlice(overrides: Partial<ChangeQuoteUiSlice>): ChangeQuoteUiSlice {
19
+ return {
20
+ priceDiff: 0,
21
+ currency: 'CAD',
22
+ canProceed: true,
23
+ ...overrides,
24
+ };
25
+ }
26
+
27
+ function test(name: string, fn: () => void): void {
28
+ try {
29
+ fn();
30
+ console.log(`ok - ${name}`);
31
+ } catch (error) {
32
+ console.error(`not ok - ${name}`);
33
+ throw error;
34
+ }
35
+ }
36
+
37
+ test('routes customer change quote to paid checkout when amount is due', () => {
38
+ const decision = evaluateChangeBookingQuoteForCheckout({
39
+ quote: quote({
40
+ changeIntentId: 'ci_paid',
41
+ amountToCharge: 42,
42
+ proposed: { total: 142 },
43
+ original: { total: 100 },
44
+ }),
45
+ quoteSlice: quoteSlice({
46
+ changeIntentId: 'ci_paid',
47
+ quotedTotal: 142,
48
+ }),
49
+ fallbackNewBookingTotal: 142,
50
+ originalReceiptTotal: 100,
51
+ audience: 'customer',
52
+ });
53
+
54
+ assert.deepEqual(decision, {
55
+ kind: 'paid',
56
+ changeIntentId: 'ci_paid',
57
+ amountDueForCheckout: 42,
58
+ });
59
+ });
60
+
61
+ test('routes customer no-pay quote to free confirmation with the quote intent', () => {
62
+ const decision = evaluateChangeBookingQuoteForCheckout({
63
+ quote: quote({
64
+ changeIntentId: 'ci_free',
65
+ amountToCharge: 0,
66
+ proposed: { total: 100 },
67
+ original: { total: 100 },
68
+ }),
69
+ quoteSlice: quoteSlice({
70
+ changeIntentId: 'ci_free',
71
+ quotedTotal: 100,
72
+ }),
73
+ fallbackNewBookingTotal: 100,
74
+ originalReceiptTotal: 100,
75
+ audience: 'customer',
76
+ });
77
+
78
+ assert.deepEqual(decision, {
79
+ kind: 'free',
80
+ changeIntentId: 'ci_free',
81
+ amountDueForCheckout: 0,
82
+ });
83
+ });
84
+
85
+ test('blocks customer upgrade when server confirms no charge but totals increased', () => {
86
+ assert.throws(
87
+ () =>
88
+ evaluateChangeBookingQuoteForCheckout({
89
+ quote: quote({
90
+ changeIntentId: 'ci_conflict',
91
+ amountToCharge: 0,
92
+ proposed: { total: 150 },
93
+ original: { total: 100 },
94
+ }),
95
+ quoteSlice: quoteSlice({
96
+ changeIntentId: 'ci_conflict',
97
+ quotedTotal: 150,
98
+ }),
99
+ fallbackNewBookingTotal: 150,
100
+ originalReceiptTotal: 100,
101
+ audience: 'customer',
102
+ }),
103
+ /requires payment/,
104
+ );
105
+ });
106
+
107
+ test('uses admin frontend-authoritative amount when staff manual quote is active', () => {
108
+ const decision = evaluateChangeBookingQuoteForCheckout({
109
+ quote: quote({
110
+ changeIntentId: 'ci_admin',
111
+ amountToCharge: 0,
112
+ previousTotalCents: 10000,
113
+ newTotalCents: 10000,
114
+ }),
115
+ quoteSlice: quoteSlice({
116
+ changeIntentId: 'ci_admin',
117
+ quotedTotal: 100,
118
+ }),
119
+ fallbackNewBookingTotal: 100,
120
+ originalReceiptTotal: 100,
121
+ audience: 'admin',
122
+ useAdminFeAuthoritativeQuote: true,
123
+ adminFeAmountDueMajorUnits: 33.33,
124
+ });
125
+
126
+ assert.deepEqual(decision, {
127
+ kind: 'paid',
128
+ changeIntentId: 'ci_admin',
129
+ amountDueForCheckout: 33.33,
130
+ });
131
+ });
132
+
133
+ test('builds manage-booking success URL for public paid change checkout', () => {
134
+ const globalWithWindow = globalThis as typeof globalThis & {
135
+ window?: { location: { origin: string } };
136
+ };
137
+ globalWithWindow.window = { location: { origin: 'https://book.example.test' } };
138
+ try {
139
+ const url = buildChangeBookingPaymentSuccessUrl({
140
+ enabled: true,
141
+ bookingReference: 'bookRef_ABC-123',
142
+ lastName: " O'Neil ",
143
+ datePart: '2026-07-08',
144
+ changeIntentId: 'ci_123',
145
+ });
146
+
147
+ assert.equal(
148
+ url,
149
+ "https://book.example.test/manage-booking?ref=ABC-123&lastName=O'Neil&from=change_payment&changeIntentId=ci_123",
150
+ );
151
+ } finally {
152
+ delete globalWithWindow.window;
153
+ }
154
+ });
155
+
156
+ test('delegates success URL construction to host when provider dashboard asks for it', () => {
157
+ const url = buildChangeBookingPaymentSuccessUrl({
158
+ enabled: true,
159
+ bookingReference: 'bookRef_ABC-123',
160
+ lastName: ' Smith ',
161
+ datePart: '2026-07-08',
162
+ preferHostSuccessUrl: true,
163
+ getSuccessUrl: ({ reservationRef, lastName, focusDate }) =>
164
+ `provider://${reservationRef}/${lastName}/${focusDate}`,
165
+ });
166
+
167
+ assert.equal(url, 'provider://ABC-123/Smith/2026-07-08');
168
+ });
169
+
170
+ test('builds paid checkout modal data with trimmed customer and change totals', () => {
171
+ const modalData = buildChangeBookingPaidCheckoutModalData({
172
+ bookingReference: 'bookRef_ABC-123',
173
+ lastName: ' Smith ',
174
+ datePart: '2026-07-08',
175
+ ticketLines: [],
176
+ feeLineItems: [],
177
+ returnPriceAdjustment: 0,
178
+ cancellationPolicyFee: 0,
179
+ subtotal: 112,
180
+ tax: 0,
181
+ total: 12,
182
+ totalQuantity: 2,
183
+ isTaxIncludedInPrice: false,
184
+ taxRate: 0,
185
+ promoDiscountAmount: 0,
186
+ discountLabel: null,
187
+ previousTotal: 100,
188
+ newTotal: 112,
189
+ successUrl: {
190
+ enabled: false,
191
+ bookingReference: 'bookRef_ABC-123',
192
+ lastName: ' Smith ',
193
+ datePart: '2026-07-08',
194
+ changeIntentId: 'ci_paid',
195
+ },
196
+ });
197
+
198
+ assert.equal(modalData.reservationReference, 'bookRef_ABC-123');
199
+ assert.equal(modalData.customerLastName, 'Smith');
200
+ assert.equal(modalData.successUrlOverride, undefined);
201
+ assert.deepEqual(modalData.changeTotals, {
202
+ previousTotal: 100,
203
+ newTotal: 112,
204
+ differenceTotal: 12,
205
+ });
206
+ });