@ticketboothapp/booking 1.2.25-rc.0 → 1.2.27

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 (142) hide show
  1. package/package.json +11 -29
  2. package/src/components/booking/AddOnsSection.tsx +2 -2
  3. package/src/components/booking/AdminPaymentChoiceModal.tsx +1 -1
  4. package/src/components/booking/BookingDialog.tsx +31 -13
  5. package/src/components/booking/BookingFlow.tsx +32 -27
  6. package/src/components/booking/BookingFlowCollage.tsx +10 -6
  7. package/src/components/booking/BookingFlowPlaceholder.tsx +1 -1
  8. package/src/components/booking/BookingFlowPreview.tsx +18 -9
  9. package/src/components/booking/BookingProductGrid.tsx +55 -19
  10. package/src/components/booking/Calendar.module.css +19 -4
  11. package/src/components/booking/Calendar.tsx +13 -8
  12. package/src/components/booking/CancellationPolicySelector.tsx +2 -2
  13. package/src/components/booking/ChangeBookingDialog.tsx +22 -12
  14. package/src/components/booking/CheckoutForm.module.css +10 -0
  15. package/src/components/booking/CheckoutForm.tsx +10 -2
  16. package/src/components/booking/CheckoutModal.tsx +16 -14
  17. package/src/components/booking/DapFlowCollage.tsx +5 -2
  18. package/src/components/booking/DapTourDescription.tsx +4 -4
  19. package/src/components/booking/DependentAddOnBookingDialog.tsx +23 -16
  20. package/src/components/booking/DependentAddOnPaymentForm.tsx +10 -7
  21. package/src/components/booking/ItineraryBox.tsx +6 -6
  22. package/src/components/booking/ItineraryBuilder.tsx +1 -1
  23. package/src/components/booking/MealDrinkAddOnSelector.tsx +3 -3
  24. package/src/components/booking/PickupLocationSelector.tsx +20 -18
  25. package/src/components/booking/PickupTimeSelector.tsx +3 -3
  26. package/src/components/booking/PriceBreakdown.tsx +5 -5
  27. package/src/components/booking/PriceSummary.module.css +7 -0
  28. package/src/components/booking/PriceSummary.tsx +8 -7
  29. package/src/components/booking/PrivateShuttleBookingFlow.tsx +28 -19
  30. package/src/components/booking/PromoCodeInput.module.css +31 -25
  31. package/src/components/booking/PromoCodeInput.tsx +36 -24
  32. package/src/components/booking/ReturnTimeSelector.tsx +3 -3
  33. package/src/components/booking/TermsAcceptance.tsx +7 -2
  34. package/src/components/booking/TicketSelector.tsx +1 -1
  35. package/src/components/booking/TourDescription.tsx +11 -6
  36. package/src/components/booking/booking-flow.css +65 -4
  37. package/src/hooks/useBookingSourceMetadataFromLocation.ts +1 -1
  38. package/src/hooks/useIsBookingLaunchLive.ts +1 -1
  39. package/src/index.ts +26 -64
  40. package/src/providers/booking-dialog-provider.tsx +62 -53
  41. package/src/runtime/BookingHostContext.tsx +39 -0
  42. package/src/runtime/index.ts +13 -0
  43. package/src/runtime/types.ts +86 -0
  44. package/tsconfig.json +3 -5
  45. package/src/assets/icons/minus.svg +0 -7
  46. package/src/assets/icons/partner-logos/getyourguide.svg +0 -8
  47. package/src/assets/icons/plus.svg +0 -3
  48. package/src/colours.css +0 -23
  49. package/src/components/BookingDetails.module.css +0 -1591
  50. package/src/components/BookingDetails.tsx +0 -2264
  51. package/src/components/BookingWidget.tsx +0 -302
  52. package/src/components/ManageBookingView.tsx +0 -437
  53. package/src/components/PhoneInputWithCountry.module.css +0 -131
  54. package/src/components/PhoneInputWithCountry.tsx +0 -44
  55. package/src/components/PickupLocationDialog.module.css +0 -360
  56. package/src/components/PickupLocationDialog.tsx +0 -357
  57. package/src/components/PostBookingDependentAddOnUpsell.module.css +0 -174
  58. package/src/components/PostBookingDependentAddOnUpsell.tsx +0 -407
  59. package/src/components/button.css +0 -245
  60. package/src/components/button.tsx +0 -152
  61. package/src/components/colorable-svg.tsx +0 -29
  62. package/src/components/image.css +0 -29
  63. package/src/components/image.tsx +0 -113
  64. package/src/components/partner/PartnerBookingPage.module.css +0 -130
  65. package/src/components/partner/PartnerBookingPage.tsx +0 -390
  66. package/src/components/partner/PartnerBookingPageWithBrowserMetadata.tsx +0 -45
  67. package/src/components/product-tag.module.css +0 -30
  68. package/src/components/product-tag.tsx +0 -34
  69. package/src/components/product-theme-pages/image-modal.tsx +0 -248
  70. package/src/components/product-theme-pages/photo-gallery.module.css +0 -200
  71. package/src/components/terms/TermsContent.tsx +0 -178
  72. package/src/components/value-pill.module.css +0 -59
  73. package/src/components/value-pill.tsx +0 -46
  74. package/src/constants/images.ts +0 -556
  75. package/src/constants/pill-values.ts +0 -210
  76. package/src/constants/products.ts +0 -155
  77. package/src/contexts/AvailabilitiesCacheContext.tsx +0 -125
  78. package/src/contexts/CompanyContext.tsx +0 -70
  79. package/src/data/dap-descriptions/session-couples-families-friends.en.json +0 -61
  80. package/src/data/dap-descriptions/session-elopements.en.json +0 -60
  81. package/src/data/dap-descriptions/session-proposals.en.json +0 -60
  82. package/src/data/product-descriptions/afternoon-delight.en.json +0 -35
  83. package/src/data/product-descriptions/emerald-lake-escape.en.json +0 -68
  84. package/src/data/product-descriptions/lake-louise-adventure.en.json +0 -74
  85. package/src/data/product-descriptions/moraine-lake-adventure.en.json +0 -78
  86. package/src/data/product-descriptions/moraine-lake-sunrise-lake-louise-golden-hour.en.json +0 -65
  87. package/src/data/product-descriptions/moraine-lake-sunrise.en.json +0 -64
  88. package/src/data/product-descriptions/private-tour.en.json +0 -80
  89. package/src/data/product-descriptions/two-lakes-combo.en.json +0 -65
  90. package/src/data/products-config.json +0 -101
  91. package/src/lib/analytics.ts +0 -197
  92. package/src/lib/booking/booking-source.ts +0 -51
  93. package/src/lib/booking/checkout-breakdown.ts +0 -69
  94. package/src/lib/booking/correlation-id.ts +0 -46
  95. package/src/lib/booking/i18n/config.ts +0 -21
  96. package/src/lib/booking/i18n/index.tsx +0 -144
  97. package/src/lib/booking/i18n/messages/en.json +0 -236
  98. package/src/lib/booking/i18n/messages/fr.json +0 -236
  99. package/src/lib/booking/itinerary-display.ts +0 -36
  100. package/src/lib/booking/itinerary-labels.ts +0 -70
  101. package/src/lib/booking/location-calculations.ts +0 -43
  102. package/src/lib/booking/location-utils.ts +0 -165
  103. package/src/lib/booking/map-utils.ts +0 -153
  104. package/src/lib/booking/marker-icons.ts +0 -113
  105. package/src/lib/booking/normalize-booking-product-id.ts +0 -21
  106. package/src/lib/booking/pickup-location-types.ts +0 -25
  107. package/src/lib/booking/places-api.ts +0 -154
  108. package/src/lib/booking/pricing.ts +0 -466
  109. package/src/lib/booking/product-option-id.ts +0 -35
  110. package/src/lib/booking/source-metadata.ts +0 -226
  111. package/src/lib/booking/sunday-week.ts +0 -14
  112. package/src/lib/booking/theme.ts +0 -83
  113. package/src/lib/booking/trace-context.ts +0 -62
  114. package/src/lib/booking/utils.ts +0 -9
  115. package/src/lib/booking-api.ts +0 -1793
  116. package/src/lib/booking-constants.ts +0 -23
  117. package/src/lib/booking-ref.ts +0 -13
  118. package/src/lib/booking-types.ts +0 -36
  119. package/src/lib/currency.ts +0 -81
  120. package/src/lib/dap-descriptions.ts +0 -50
  121. package/src/lib/dap-itinerary-preview.ts +0 -315
  122. package/src/lib/dependent-add-on-api.ts +0 -434
  123. package/src/lib/env.ts +0 -96
  124. package/src/lib/firebase.ts +0 -20
  125. package/src/lib/job-application-api.ts +0 -83
  126. package/src/lib/manage-booking-embed-print.ts +0 -16
  127. package/src/lib/manage-booking-post-checkout.ts +0 -68
  128. package/src/lib/photo-dap-config.ts +0 -228
  129. package/src/lib/photo-packages.ts +0 -75
  130. package/src/lib/pickup/map-utils.ts +0 -56
  131. package/src/lib/pickup/marker-icons.ts +0 -19
  132. package/src/lib/product-descriptions.ts +0 -66
  133. package/src/lib/products-config.ts +0 -73
  134. package/src/providers/dependent-add-on-dialog-provider.tsx +0 -105
  135. package/src/radius.css +0 -5
  136. package/src/spacing.css +0 -7
  137. package/src/strings/en.json +0 -1774
  138. package/src/strings/es.json +0 -1573
  139. package/src/strings/fr.json +0 -1573
  140. package/src/strings/index.js +0 -23
  141. package/src/text-style.css +0 -56
  142. package/src/utils/currency-converter.ts +0 -101
@@ -1,302 +0,0 @@
1
- 'use client';
2
-
3
- import { useState, useEffect, useCallback } from 'react';
4
- import { CompanyProvider } from '@/contexts/CompanyContext';
5
- import {
6
- BookingAppProvider,
7
- type BookingAppMode,
8
- type BookingAppPermissions,
9
- type ManageParams,
10
- } from '@/contexts/BookingAppContext';
11
- import { BookingFlow } from '@/components/booking/BookingFlow';
12
- import { PrivateShuttleBookingFlow } from '@/components/booking/PrivateShuttleBookingFlow';
13
- import { CurrencySwitcher, useCurrency, type Currency } from '@/components/booking/CurrencySwitcher';
14
- import { ErrorBoundary } from '@/components/booking/ErrorBoundary';
15
- import { getProduct, setPartnerPortalBookingJwtGetter, type Product } from '@/lib/booking-api';
16
- import { getProductByIdOrSlug } from '@/lib/products-config';
17
- import { ENV } from '@/lib/env';
18
- import BookingProductGrid from '@/components/booking/BookingProductGrid';
19
- import { BookingDialogProvider } from '@/providers/booking-dialog-provider';
20
-
21
- type Step = 'products' | 'booking';
22
-
23
- interface NavState {
24
- step: Step;
25
- selectedProduct: Product | null;
26
- }
27
-
28
- export interface BookingWidgetProps {
29
- initialProductId?: string;
30
- initialCurrency?: Currency;
31
- showHeader?: boolean;
32
- authToken?: string | null;
33
- onProductSelect?: (product: Product) => void;
34
- onBookingSuccess?: (data: { reservationReference: string; sessionId?: string }) => void;
35
- onBack?: () => void;
36
- className?: string;
37
- mode?: BookingAppMode;
38
- permissions?: Partial<BookingAppPermissions>;
39
- googleMapsApiKey?: string;
40
- onShowManage?: (params: ManageParams) => void;
41
- getSuccessUrl?: (params: { reservationRef: string; lastName: string; focusDate?: string }) => string;
42
- showLanguageSelector?: boolean;
43
- initialProduct?: Product;
44
- products?: Product[];
45
- companyId?: string;
46
- initialBooking?: {
47
- bookingReference: string;
48
- productId: string;
49
- availabilityId?: string;
50
- dateTime: string;
51
- originalTotalAmount?: number;
52
- originalCurrency?: string;
53
- bookingItems: Array<{ category: string; count: number }>;
54
- returnAvailabilityId?: string | null;
55
- pickupLocationId?: string | null;
56
- travelerHotel?: string | null;
57
- startTime?: string | null;
58
- privateShuttleDetails?: { passengerCount?: number };
59
- cancellationPolicyId?: string | null;
60
- promoCode?: string | null;
61
- additionalHoursCount?: number | null;
62
- addOnSelections?: Array<{ addOnId: string; variantId?: string; quantity?: number }> | null;
63
- };
64
- /** Last name on the booking — required for public change-quote APIs inside the flow. */
65
- changeFlowLastName?: string;
66
- }
67
-
68
- /**
69
- * Embeddable booking UI (product grid + flow). Used by provider-dashboard change-booking in “change mode”.
70
- */
71
- export function BookingWidget({
72
- initialProductId,
73
- initialProduct,
74
- initialBooking,
75
- changeFlowLastName = '',
76
- products: productsProp,
77
- companyId: _companyId,
78
- initialCurrency = 'CAD',
79
- showHeader = true,
80
- authToken,
81
- onProductSelect,
82
- onBookingSuccess,
83
- onBack,
84
- className = '',
85
- mode = 'standalone',
86
- permissions = {},
87
- googleMapsApiKey,
88
- onShowManage,
89
- getSuccessUrl,
90
- showLanguageSelector = true,
91
- }: BookingWidgetProps) {
92
- const { currency, setCurrency } = useCurrency();
93
-
94
- useEffect(() => {
95
- setPartnerPortalBookingJwtGetter(() => authToken ?? null);
96
- return () => setPartnerPortalBookingJwtGetter(() => null);
97
- }, [authToken]);
98
-
99
- useEffect(() => {
100
- if (initialCurrency) setCurrency(initialCurrency);
101
- // eslint-disable-next-line react-hooks/exhaustive-deps
102
- }, []);
103
-
104
- const isChangeMode = !!(initialProduct && initialBooking);
105
-
106
- const flowInitialValues = initialBooking
107
- ? {
108
- bookingReference: initialBooking.bookingReference,
109
- dateTime: initialBooking.dateTime,
110
- availabilityId: initialBooking.availabilityId ?? null,
111
- productOptionId: initialBooking.productId,
112
- pickupLocationId: initialBooking.pickupLocationId ?? null,
113
- returnAvailabilityId: initialBooking.returnAvailabilityId ?? null,
114
- bookingItems: initialBooking.bookingItems,
115
- addOnSelections: initialBooking.addOnSelections ?? null,
116
- promoCode: initialBooking.promoCode ?? null,
117
- cancellationPolicyId: initialBooking.cancellationPolicyId ?? null,
118
- customer: changeFlowLastName ? { lastName: changeFlowLastName } : null,
119
- }
120
- : undefined;
121
-
122
- const privateShuttleInitialValues = initialBooking
123
- ? {
124
- bookingReference: initialBooking.bookingReference,
125
- dateTime: initialBooking.dateTime,
126
- pickupLocationId: initialBooking.pickupLocationId ?? null,
127
- customPickupAddress: initialBooking.travelerHotel ?? null,
128
- passengers: initialBooking.privateShuttleDetails?.passengerCount ?? null,
129
- additionalHoursCount: initialBooking.additionalHoursCount ?? null,
130
- notes: null,
131
- specialRequest: null,
132
- }
133
- : undefined;
134
-
135
- const bookingSourceAttribution: import('@/lib/booking/source-metadata').BookingSourceMetadata = {
136
- pagePath: '/provider-dashboard',
137
- };
138
-
139
- const [navState, setNavState] = useState<NavState>(() => {
140
- if (isChangeMode && initialProduct) {
141
- return { step: 'booking', selectedProduct: initialProduct };
142
- }
143
- return { step: 'products', selectedProduct: null };
144
- });
145
-
146
- const [error, setError] = useState('');
147
-
148
- useEffect(() => {
149
- if (!isChangeMode || !productsProp?.length || !initialProductId) return;
150
- const product = productsProp.find(
151
- (p) => p.productId === initialProductId || p.options?.some((o) => o.optionId === initialProductId)
152
- );
153
- if (product) setNavState({ step: 'booking', selectedProduct: product });
154
- }, [isChangeMode, initialProductId, productsProp]);
155
-
156
- useEffect(() => {
157
- if (isChangeMode || !initialProductId) return;
158
- let cancelled = false;
159
- (async () => {
160
- const config = getProductByIdOrSlug(initialProductId);
161
- const apiProductId = config?.productId ?? initialProductId;
162
- try {
163
- const p = await getProduct(apiProductId, ENV.COMPANY_ID);
164
- if (!cancelled && p) setNavState({ step: 'booking', selectedProduct: p });
165
- } catch (e) {
166
- if (!cancelled) setError(e instanceof Error ? e.message : 'Failed to load product');
167
- }
168
- })();
169
- return () => {
170
- cancelled = true;
171
- };
172
- }, [isChangeMode, initialProductId]);
173
-
174
- const handleSelectProduct = useCallback(
175
- (product: Product) => {
176
- setNavState({ step: 'booking', selectedProduct: product });
177
- onProductSelect?.(product);
178
- },
179
- [onProductSelect]
180
- );
181
-
182
- const handleBookProductId = useCallback(
183
- async (productSlugOrId: string) => {
184
- const config = getProductByIdOrSlug(productSlugOrId);
185
- const apiProductId = config?.productId ?? productSlugOrId;
186
- try {
187
- const p = await getProduct(apiProductId, ENV.COMPANY_ID);
188
- if (p) handleSelectProduct(p);
189
- } catch (e) {
190
- setError(e instanceof Error ? e.message : 'Failed to load product');
191
- }
192
- },
193
- [handleSelectProduct]
194
- );
195
-
196
- const handleBack = useCallback(() => {
197
- setNavState({ step: 'products', selectedProduct: null });
198
- onBack?.();
199
- }, [onBack]);
200
-
201
- const handleBookingSuccess = useCallback(
202
- (data: { reservationReference: string; sessionId?: string }) => {
203
- onBookingSuccess?.(data);
204
- },
205
- [onBookingSuccess]
206
- );
207
-
208
- return (
209
- <CompanyProvider>
210
- <BookingAppProvider
211
- mode={mode}
212
- permissions={permissions}
213
- googleMapsApiKey={googleMapsApiKey}
214
- onShowManage={onShowManage}
215
- getSuccessUrl={getSuccessUrl}
216
- showLanguageSelector={showLanguageSelector}
217
- >
218
- <BookingDialogProvider>
219
- <div className={`min-h-0 overflow-x-hidden ${className}`}>
220
- {showHeader && (
221
- <header className="py-4 w-full overflow-hidden" style={{ backgroundColor: 'var(--booking-header-bg)', color: 'var(--booking-header-text)' }}>
222
- <div className="max-w-4xl mx-auto px-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 min-w-0">
223
- <h1 className="text-xl font-semibold shrink-0" style={{ fontFamily: 'var(--booking-font-sans)' }}>
224
- Via Via Moraine Lake
225
- </h1>
226
- <div className="flex flex-wrap items-center gap-2 sm:gap-4 min-w-0">
227
- <CurrencySwitcher currency={currency} onCurrencyChange={setCurrency} />
228
- </div>
229
- </div>
230
- </header>
231
- )}
232
-
233
- {!showHeader && (
234
- <div
235
- className="border-b px-4 py-2 flex flex-wrap items-center justify-end gap-2 min-w-0"
236
- style={{ borderColor: 'var(--booking-border)', backgroundColor: 'var(--booking-surface)' }}
237
- >
238
- <CurrencySwitcher currency={currency} onCurrencyChange={setCurrency} />
239
- </div>
240
- )}
241
-
242
- <main className={`max-w-4xl mx-auto px-4 py-8 ${!showHeader ? 'pt-4' : ''}`} style={{ fontFamily: 'var(--booking-font-sans)' }}>
243
- <div
244
- className="overflow-visible p-8"
245
- style={{
246
- backgroundColor: 'var(--booking-surface)',
247
- borderRadius: 'var(--booking-radius)',
248
- boxShadow: '0 25px 50px -12px rgba(0,0,0,0.25)',
249
- }}
250
- >
251
- {error ? (
252
- <div
253
- className="p-4 rounded-lg"
254
- style={{
255
- backgroundColor: 'var(--booking-error-bg)',
256
- borderWidth: '1px',
257
- borderStyle: 'solid',
258
- borderColor: 'var(--booking-error-border)',
259
- color: 'var(--booking-error-text)',
260
- }}
261
- >
262
- {error}
263
- </div>
264
- ) : navState.step === 'products' ? (
265
- <BookingProductGrid
266
- initialFilterId="all"
267
- bookOnTileClick
268
- onBookProduct={handleBookProductId}
269
- />
270
- ) : navState.selectedProduct ? (
271
- <ErrorBoundary>
272
- {navState.selectedProduct.productType === 'PRIVATE_SHUTTLE' ? (
273
- <PrivateShuttleBookingFlow
274
- product={navState.selectedProduct}
275
- onBack={handleBack}
276
- currency={currency}
277
- onSuccess={handleBookingSuccess}
278
- mode={isChangeMode ? 'change' : 'standard'}
279
- initialValues={isChangeMode ? privateShuttleInitialValues : undefined}
280
- bookingSourceAttribution={bookingSourceAttribution}
281
- />
282
- ) : (
283
- <BookingFlow
284
- product={navState.selectedProduct}
285
- onBack={handleBack}
286
- currency={currency}
287
- onSuccess={handleBookingSuccess}
288
- mode={isChangeMode ? 'change' : 'standard'}
289
- initialValues={isChangeMode ? flowInitialValues : undefined}
290
- bookingSourceAttribution={bookingSourceAttribution}
291
- />
292
- )}
293
- </ErrorBoundary>
294
- ) : null}
295
- </div>
296
- </main>
297
- </div>
298
- </BookingDialogProvider>
299
- </BookingAppProvider>
300
- </CompanyProvider>
301
- );
302
- }