@ticketboothapp/booking 1.2.24 → 1.2.25-rc.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/package.json +29 -2
- package/src/assets/icons/minus.svg +7 -0
- package/src/assets/icons/partner-logos/getyourguide.svg +8 -0
- package/src/assets/icons/plus.svg +3 -0
- package/src/colours.css +23 -0
- package/src/components/BookingDetails.module.css +1591 -0
- package/src/components/BookingDetails.tsx +2264 -0
- package/src/components/BookingWidget.tsx +302 -0
- package/src/components/ManageBookingView.tsx +437 -0
- package/src/components/PhoneInputWithCountry.module.css +131 -0
- package/src/components/PhoneInputWithCountry.tsx +44 -0
- package/src/components/PickupLocationDialog.module.css +360 -0
- package/src/components/PickupLocationDialog.tsx +357 -0
- package/src/components/PostBookingDependentAddOnUpsell.module.css +174 -0
- package/src/components/PostBookingDependentAddOnUpsell.tsx +407 -0
- package/src/components/booking/AddOnsSection.module.css +10 -0
- package/src/components/booking/AddOnsSection.tsx +184 -0
- package/src/components/booking/AdminPaymentChoiceModal.tsx +98 -0
- package/src/components/booking/BookingDialog.module.css +643 -0
- package/src/components/booking/BookingDialog.tsx +356 -0
- package/src/components/booking/BookingFlow.tsx +4385 -0
- package/src/components/booking/BookingFlowCollage.module.css +148 -0
- package/src/components/booking/BookingFlowCollage.tsx +184 -0
- package/src/components/booking/BookingFlowPlaceholder.module.css +27 -0
- package/src/components/booking/BookingFlowPlaceholder.tsx +25 -0
- package/src/components/booking/BookingFlowPreview.tsx +51 -0
- package/src/components/booking/BookingProductGrid.module.css +359 -0
- package/src/components/booking/BookingProductGrid.tsx +497 -0
- package/src/components/booking/Calendar.module.css +616 -0
- package/src/components/booking/Calendar.tsx +1123 -0
- package/src/components/booking/CancellationPolicySelector.module.css +124 -0
- package/src/components/booking/CancellationPolicySelector.tsx +142 -0
- package/src/components/booking/ChangeBookingDialog.tsx +562 -0
- package/src/components/booking/CheckoutForm.module.css +244 -0
- package/src/components/booking/CheckoutForm.tsx +364 -0
- package/src/components/booking/CheckoutModal.tsx +451 -0
- package/src/components/booking/CurrencySwitcher.tsx +81 -0
- package/src/components/booking/DapFlowCollage.tsx +88 -0
- package/src/components/booking/DapTourDescription.tsx +35 -0
- package/src/components/booking/DependentAddOnBookingDialog.tsx +1350 -0
- package/src/components/booking/DependentAddOnPaymentForm.tsx +124 -0
- package/src/components/booking/ErrorBoundary.tsx +63 -0
- package/src/components/booking/InfoTooltip.tsx +108 -0
- package/src/components/booking/ItineraryBox.module.css +258 -0
- package/src/components/booking/ItineraryBox.tsx +550 -0
- package/src/components/booking/ItineraryBuilder.tsx +82 -0
- package/src/components/booking/ItineraryPlaceholder.module.css +45 -0
- package/src/components/booking/ItineraryPlaceholder.tsx +26 -0
- package/src/components/booking/MealDrinkAddOnSelector.tsx +338 -0
- package/src/components/booking/PickupLocationSelector.module.css +124 -0
- package/src/components/booking/PickupLocationSelector.tsx +1566 -0
- package/src/components/booking/PickupTimeSelector.module.css +134 -0
- package/src/components/booking/PickupTimeSelector.tsx +112 -0
- package/src/components/booking/PriceBreakdown.tsx +154 -0
- package/src/components/booking/PriceSummary.tsx +234 -0
- package/src/components/booking/PrivateShuttleBookingFlow.module.css +357 -0
- package/src/components/booking/PrivateShuttleBookingFlow.tsx +2662 -0
- package/src/components/booking/PromoCodeInput.module.css +166 -0
- package/src/components/booking/PromoCodeInput.tsx +99 -0
- package/src/components/booking/ReturnTimeSelector.module.css +173 -0
- package/src/components/booking/ReturnTimeSelector.tsx +145 -0
- package/src/components/booking/TermsAcceptance.tsx +111 -0
- package/src/components/booking/TicketSelector.module.css +164 -0
- package/src/components/booking/TicketSelector.tsx +199 -0
- package/src/components/booking/TourDescription.module.css +304 -0
- package/src/components/booking/TourDescription.tsx +273 -0
- package/src/components/booking/booking-flow-ui.ts +38 -0
- package/src/components/booking/booking-flow.css +944 -0
- package/src/components/button.css +245 -0
- package/src/components/button.tsx +152 -0
- package/src/components/colorable-svg.tsx +29 -0
- package/src/components/image.css +29 -0
- package/src/components/image.tsx +113 -0
- package/src/components/partner/PartnerBookingPage.module.css +130 -0
- package/src/components/partner/PartnerBookingPage.tsx +390 -0
- package/src/components/partner/PartnerBookingPageWithBrowserMetadata.tsx +45 -0
- package/src/components/product-tag.module.css +30 -0
- package/src/components/product-tag.tsx +34 -0
- package/src/components/product-theme-pages/image-modal.tsx +248 -0
- package/src/components/product-theme-pages/photo-gallery.module.css +200 -0
- package/src/components/terms/TermsContent.tsx +178 -0
- package/src/components/value-pill.module.css +59 -0
- package/src/components/value-pill.tsx +46 -0
- package/src/constants/images.ts +556 -0
- package/src/constants/pill-values.ts +210 -0
- package/src/constants/products.ts +155 -0
- package/src/contexts/AvailabilitiesCacheContext.tsx +125 -0
- package/src/contexts/BookingAppContext.tsx +134 -0
- package/src/contexts/CompanyContext.tsx +70 -0
- package/src/data/dap-descriptions/session-couples-families-friends.en.json +61 -0
- package/src/data/dap-descriptions/session-elopements.en.json +60 -0
- package/src/data/dap-descriptions/session-proposals.en.json +60 -0
- package/src/data/product-descriptions/afternoon-delight.en.json +35 -0
- package/src/data/product-descriptions/emerald-lake-escape.en.json +68 -0
- package/src/data/product-descriptions/lake-louise-adventure.en.json +74 -0
- package/src/data/product-descriptions/moraine-lake-adventure.en.json +78 -0
- package/src/data/product-descriptions/moraine-lake-sunrise-lake-louise-golden-hour.en.json +65 -0
- package/src/data/product-descriptions/moraine-lake-sunrise.en.json +64 -0
- package/src/data/product-descriptions/private-tour.en.json +80 -0
- package/src/data/product-descriptions/two-lakes-combo.en.json +65 -0
- package/src/data/products-config.json +101 -0
- package/src/hooks/useBookingSourceMetadataFromLocation.ts +21 -0
- package/src/hooks/useIsBookingLaunchLive.ts +49 -0
- package/src/index.ts +79 -0
- package/src/lib/analytics.ts +197 -0
- package/src/lib/booking/booking-source.ts +51 -0
- package/src/lib/booking/checkout-breakdown.ts +69 -0
- package/src/lib/booking/correlation-id.ts +46 -0
- package/src/lib/booking/i18n/config.ts +21 -0
- package/src/lib/booking/i18n/index.tsx +144 -0
- package/src/lib/booking/i18n/messages/en.json +236 -0
- package/src/lib/booking/i18n/messages/fr.json +236 -0
- package/src/lib/booking/itinerary-display.ts +36 -0
- package/src/lib/booking/itinerary-labels.ts +70 -0
- package/src/lib/booking/location-calculations.ts +43 -0
- package/src/lib/booking/location-utils.ts +165 -0
- package/src/lib/booking/map-utils.ts +153 -0
- package/src/lib/booking/marker-icons.ts +113 -0
- package/src/lib/booking/normalize-booking-product-id.ts +21 -0
- package/src/lib/booking/pickup-location-types.ts +25 -0
- package/src/lib/booking/places-api.ts +154 -0
- package/src/lib/booking/pricing.ts +466 -0
- package/src/lib/booking/product-option-id.ts +35 -0
- package/src/lib/booking/source-metadata.ts +226 -0
- package/src/lib/booking/sunday-week.ts +14 -0
- package/src/lib/booking/theme.ts +83 -0
- package/src/lib/booking/trace-context.ts +62 -0
- package/src/lib/booking/utils.ts +9 -0
- package/src/lib/booking-api.ts +1793 -0
- package/src/lib/booking-constants.ts +23 -0
- package/src/lib/booking-ref.ts +13 -0
- package/src/lib/booking-types.ts +36 -0
- package/src/lib/currency.ts +81 -0
- package/src/lib/dap-descriptions.ts +50 -0
- package/src/lib/dap-itinerary-preview.ts +315 -0
- package/src/lib/dependent-add-on-api.ts +434 -0
- package/src/lib/env.ts +96 -0
- package/src/lib/firebase.ts +20 -0
- package/src/lib/job-application-api.ts +83 -0
- package/src/lib/manage-booking-embed-print.ts +16 -0
- package/src/lib/manage-booking-post-checkout.ts +68 -0
- package/src/lib/photo-dap-config.ts +228 -0
- package/src/lib/photo-packages.ts +75 -0
- package/src/lib/pickup/map-utils.ts +56 -0
- package/src/lib/pickup/marker-icons.ts +19 -0
- package/src/lib/product-descriptions.ts +66 -0
- package/src/lib/products-config.ts +73 -0
- package/src/providers/booking-dialog-provider.tsx +282 -0
- package/src/providers/dependent-add-on-dialog-provider.tsx +105 -0
- package/src/radius.css +5 -0
- package/src/spacing.css +7 -0
- package/src/strings/en.json +1774 -0
- package/src/strings/es.json +1573 -0
- package/src/strings/fr.json +1573 -0
- package/src/strings/index.js +23 -0
- package/src/text-style.css +56 -0
- package/src/utils/currency-converter.ts +101 -0
- package/tsconfig.json +8 -2
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState, useMemo } from 'react';
|
|
4
|
+
import { useTranslations, useLocale } from '@/lib/booking/i18n';
|
|
5
|
+
import { getProductDescription } from '@/lib/product-descriptions';
|
|
6
|
+
import PlusIcon from '@/assets/icons/plus.svg';
|
|
7
|
+
import MinusIcon from '@/assets/icons/minus.svg';
|
|
8
|
+
import styles from './TourDescription.module.css';
|
|
9
|
+
|
|
10
|
+
export interface TourDescriptionReview {
|
|
11
|
+
text: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Grouped bullets under a bold subheading inside an expandable section */
|
|
16
|
+
export interface TourDescriptionSubsection {
|
|
17
|
+
title: string;
|
|
18
|
+
items: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TourDescriptionSection {
|
|
22
|
+
title: string;
|
|
23
|
+
/** String for paragraph; string[] for bullet list or line-by-line HTML; subsection[] for titled bullet groups */
|
|
24
|
+
content:
|
|
25
|
+
| string
|
|
26
|
+
| string[]
|
|
27
|
+
| TourDescriptionSubsection[]
|
|
28
|
+
| React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TourDescriptionProps {
|
|
32
|
+
/** Product slug (e.g. moraine-lake-sunrise) - loads content from product-descriptions/{slug}.{locale}.json */
|
|
33
|
+
productSlug?: string;
|
|
34
|
+
/** Locale for loading translated content (defaults to useLocale) */
|
|
35
|
+
locale?: string;
|
|
36
|
+
/** Override main toggle label (default: “See full tour description”) */
|
|
37
|
+
toggleLabel?: string;
|
|
38
|
+
/** Override: main description paragraphs (if provided, skips file load) */
|
|
39
|
+
paragraphs?: string[];
|
|
40
|
+
/** Override: highlighted review (if provided, skips file load for review) */
|
|
41
|
+
review?: TourDescriptionReview;
|
|
42
|
+
/** Override: nested expandable sections (if provided, skips file load) */
|
|
43
|
+
sections?: TourDescriptionSection[];
|
|
44
|
+
/** Start expanded (e.g. when in partial/pre-launch state) */
|
|
45
|
+
defaultExpanded?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Items starting with • - * are bullet list; otherwise join as HTML (multi-line format) */
|
|
49
|
+
function isBulletList(items: string[]): boolean {
|
|
50
|
+
const bulletChars = ['•', '-', '*'];
|
|
51
|
+
return items.length > 0 && items.every((item) => bulletChars.some((c) => item.trim().startsWith(c)));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Single item is a bullet (starts with •, -, or *) */
|
|
55
|
+
function isBulletItem(item: string): boolean {
|
|
56
|
+
const bulletChars = ['•', '-', '*'];
|
|
57
|
+
return bulletChars.some((c) => item.trim().startsWith(c));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** True if the entire line is just a single tag (e.g. <strong>Heading</strong>), not mixed content */
|
|
61
|
+
function isHeadingLine(line: string): boolean {
|
|
62
|
+
const trimmed = line.trim();
|
|
63
|
+
return /^<[a-zA-Z]+>[^<]*<\/[a-zA-Z]+>$/.test(trimmed);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isSubsectionGroups(
|
|
67
|
+
content: TourDescriptionSection['content']
|
|
68
|
+
): content is TourDescriptionSubsection[] {
|
|
69
|
+
if (!Array.isArray(content) || content.length === 0) return false;
|
|
70
|
+
const first = content[0];
|
|
71
|
+
return (
|
|
72
|
+
typeof first === 'object' &&
|
|
73
|
+
first !== null &&
|
|
74
|
+
'title' in first &&
|
|
75
|
+
'items' in first &&
|
|
76
|
+
typeof (first as TourDescriptionSubsection).title === 'string' &&
|
|
77
|
+
Array.isArray((first as TourDescriptionSubsection).items)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ExpandableSection({
|
|
82
|
+
title,
|
|
83
|
+
children,
|
|
84
|
+
isOpen,
|
|
85
|
+
onToggle,
|
|
86
|
+
}: {
|
|
87
|
+
title: string;
|
|
88
|
+
children: React.ReactNode;
|
|
89
|
+
isOpen: boolean;
|
|
90
|
+
onToggle: () => void;
|
|
91
|
+
}) {
|
|
92
|
+
return (
|
|
93
|
+
<div className={styles.nestedSection}>
|
|
94
|
+
<button
|
|
95
|
+
type="button"
|
|
96
|
+
className={styles.nestedToggle}
|
|
97
|
+
onClick={onToggle}
|
|
98
|
+
aria-expanded={isOpen}
|
|
99
|
+
>
|
|
100
|
+
<span>{title}</span>
|
|
101
|
+
<svg
|
|
102
|
+
className={styles.chevron}
|
|
103
|
+
width="16"
|
|
104
|
+
height="16"
|
|
105
|
+
viewBox="0 0 24 24"
|
|
106
|
+
fill="none"
|
|
107
|
+
stroke="currentColor"
|
|
108
|
+
strokeWidth="2"
|
|
109
|
+
>
|
|
110
|
+
<path d="M9 6l6 6-6 6" />
|
|
111
|
+
</svg>
|
|
112
|
+
</button>
|
|
113
|
+
<div className={`${styles.nestedContentWrapper} ${isOpen ? styles.nestedContentOpen : ''}`}>
|
|
114
|
+
<div className={styles.nestedContent}>{children}</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function TourDescription({
|
|
121
|
+
productSlug,
|
|
122
|
+
locale: localeProp,
|
|
123
|
+
toggleLabel,
|
|
124
|
+
paragraphs: paragraphsProp,
|
|
125
|
+
review: reviewProp,
|
|
126
|
+
sections: sectionsProp,
|
|
127
|
+
defaultExpanded = false,
|
|
128
|
+
}: TourDescriptionProps) {
|
|
129
|
+
const { t } = useTranslations();
|
|
130
|
+
const { locale: contextLocale } = useLocale();
|
|
131
|
+
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
132
|
+
const [openSectionIndex, setOpenSectionIndex] = useState<number | null>(null);
|
|
133
|
+
|
|
134
|
+
const locale = localeProp ?? contextLocale;
|
|
135
|
+
|
|
136
|
+
const loadedContent = useMemo(() => {
|
|
137
|
+
if (productSlug && locale) {
|
|
138
|
+
return getProductDescription(productSlug, locale);
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}, [productSlug, locale]);
|
|
142
|
+
|
|
143
|
+
const paragraphs = paragraphsProp ?? loadedContent?.paragraphs ?? [];
|
|
144
|
+
const review = reviewProp ?? loadedContent?.review;
|
|
145
|
+
const sections = sectionsProp ?? loadedContent?.sections ?? [];
|
|
146
|
+
|
|
147
|
+
const displayParagraphs =
|
|
148
|
+
paragraphs.length > 0 ? paragraphs : [];
|
|
149
|
+
const displayReview = review ?? null;
|
|
150
|
+
const displaySections =
|
|
151
|
+
sections.length > 0 ? sections : [];
|
|
152
|
+
|
|
153
|
+
/** Group paragraphs: consecutive bullet items become a single <ul> block */
|
|
154
|
+
const paragraphBlocks = useMemo(() => {
|
|
155
|
+
const blocks: ({ type: 'paragraph'; text: string } | { type: 'bulletList'; items: string[] })[] = [];
|
|
156
|
+
let i = 0;
|
|
157
|
+
while (i < displayParagraphs.length) {
|
|
158
|
+
const p = displayParagraphs[i];
|
|
159
|
+
if (isBulletItem(p)) {
|
|
160
|
+
const items: string[] = [];
|
|
161
|
+
while (i < displayParagraphs.length && isBulletItem(displayParagraphs[i])) {
|
|
162
|
+
items.push(displayParagraphs[i]);
|
|
163
|
+
i++;
|
|
164
|
+
}
|
|
165
|
+
blocks.push({ type: 'bulletList', items });
|
|
166
|
+
} else {
|
|
167
|
+
blocks.push({ type: 'paragraph', text: p });
|
|
168
|
+
i++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return blocks;
|
|
172
|
+
}, [displayParagraphs]);
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<div className={styles.root}>
|
|
176
|
+
<button
|
|
177
|
+
type="button"
|
|
178
|
+
className={styles.mainToggle}
|
|
179
|
+
onClick={() => setIsExpanded((e) => !e)}
|
|
180
|
+
aria-expanded={isExpanded}
|
|
181
|
+
>
|
|
182
|
+
<span>{toggleLabel ?? t('booking.seeFullTourDescription')}</span>
|
|
183
|
+
<span className={`${styles.toggleIcon} ${isExpanded ? styles.toggleIconExpanded : ''}`} aria-hidden>
|
|
184
|
+
{isExpanded ? (
|
|
185
|
+
<MinusIcon />
|
|
186
|
+
) : (
|
|
187
|
+
<PlusIcon />
|
|
188
|
+
)}
|
|
189
|
+
</span>
|
|
190
|
+
</button>
|
|
191
|
+
|
|
192
|
+
<div className={`${styles.contentWrapper} ${isExpanded ? styles.contentExpanded : ''}`}>
|
|
193
|
+
<div className={styles.content}>
|
|
194
|
+
{paragraphBlocks.map((block, i) =>
|
|
195
|
+
block.type === 'paragraph' ? (
|
|
196
|
+
<p key={i} className={styles.paragraph} dangerouslySetInnerHTML={{ __html: block.text }} />
|
|
197
|
+
) : (
|
|
198
|
+
<ul key={i} className={styles.bulletList}>
|
|
199
|
+
{block.items.map((item, j) => (
|
|
200
|
+
<li key={j} className={styles.bulletItem} dangerouslySetInnerHTML={{ __html: item }} />
|
|
201
|
+
))}
|
|
202
|
+
</ul>
|
|
203
|
+
)
|
|
204
|
+
)}
|
|
205
|
+
{displayReview && (
|
|
206
|
+
<blockquote className={styles.review}>
|
|
207
|
+
<p className={styles.reviewText} dangerouslySetInnerHTML={{ __html: displayReview.text }} />
|
|
208
|
+
<cite className={styles.reviewName} dangerouslySetInnerHTML={{ __html: displayReview.name }} />
|
|
209
|
+
</blockquote>
|
|
210
|
+
)}
|
|
211
|
+
{displaySections.map((section, i) => (
|
|
212
|
+
<ExpandableSection
|
|
213
|
+
key={i}
|
|
214
|
+
title={section.title}
|
|
215
|
+
isOpen={openSectionIndex === i}
|
|
216
|
+
onToggle={() => setOpenSectionIndex((prev) => (prev === i ? null : i))}
|
|
217
|
+
>
|
|
218
|
+
{isSubsectionGroups(section.content) ? (
|
|
219
|
+
<div className={styles.sectionSubsections}>
|
|
220
|
+
{section.content.map((sub, k) => (
|
|
221
|
+
<div key={k} className={styles.sectionSubsection}>
|
|
222
|
+
<div
|
|
223
|
+
className={styles.sectionSubsectionTitle}
|
|
224
|
+
dangerouslySetInnerHTML={{ __html: sub.title }}
|
|
225
|
+
/>
|
|
226
|
+
{sub.items.length > 0 && (
|
|
227
|
+
<ul className={styles.bulletList}>
|
|
228
|
+
{sub.items.map((item, j) => (
|
|
229
|
+
<li
|
|
230
|
+
key={j}
|
|
231
|
+
className={styles.bulletItem}
|
|
232
|
+
dangerouslySetInnerHTML={{ __html: item }}
|
|
233
|
+
/>
|
|
234
|
+
))}
|
|
235
|
+
</ul>
|
|
236
|
+
)}
|
|
237
|
+
</div>
|
|
238
|
+
))}
|
|
239
|
+
</div>
|
|
240
|
+
) : Array.isArray(section.content) ? (
|
|
241
|
+
isBulletList(section.content) ? (
|
|
242
|
+
<ul className={styles.bulletList}>
|
|
243
|
+
{section.content.map((item, j) => (
|
|
244
|
+
<li key={j} className={styles.bulletItem} dangerouslySetInnerHTML={{ __html: item }} />
|
|
245
|
+
))}
|
|
246
|
+
</ul>
|
|
247
|
+
) : (
|
|
248
|
+
<div className={styles.sectionHtmlLines}>
|
|
249
|
+
{section.content.map((item, j) => (
|
|
250
|
+
<div
|
|
251
|
+
key={j}
|
|
252
|
+
className={
|
|
253
|
+
isHeadingLine(item)
|
|
254
|
+
? styles.sectionLineHeading
|
|
255
|
+
: styles.sectionLineIndented
|
|
256
|
+
}
|
|
257
|
+
dangerouslySetInnerHTML={{ __html: item }}
|
|
258
|
+
/>
|
|
259
|
+
))}
|
|
260
|
+
</div>
|
|
261
|
+
)
|
|
262
|
+
) : typeof section.content === 'string' ? (
|
|
263
|
+
<div className={styles.sectionHtml} dangerouslySetInnerHTML={{ __html: section.content }} />
|
|
264
|
+
) : (
|
|
265
|
+
section.content
|
|
266
|
+
)}
|
|
267
|
+
</ExpandableSection>
|
|
268
|
+
))}
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional UI/behavior overrides for booking flows.
|
|
3
|
+
* Omitted fields keep main-site / change-booking defaults.
|
|
4
|
+
*/
|
|
5
|
+
export interface BookingFlowUiOptions {
|
|
6
|
+
showCollage?: boolean;
|
|
7
|
+
showTourDescription?: boolean;
|
|
8
|
+
autoSelectFirstAvailableDate?: boolean;
|
|
9
|
+
autoSelectFirstHighlightedPickup?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Partner portal: org has DEFERRED_INVOICE — confirm via `/1/partner/confirm-booking-without-payment`
|
|
12
|
+
* (Bearer from [setPartnerPortalBookingJwtGetter]) instead of Stripe checkout.
|
|
13
|
+
*/
|
|
14
|
+
partnerDeferredInvoice?: boolean;
|
|
15
|
+
/** Optional submit label override when `partnerDeferredInvoice` is enabled. */
|
|
16
|
+
partnerDeferredInvoiceSubmitLabel?: string;
|
|
17
|
+
/** Optional attribution summary shown at checkout (e.g. partner + agent). */
|
|
18
|
+
partnerAttributionSummary?: string;
|
|
19
|
+
/** Optional required confirmation checkbox label for attribution summary. */
|
|
20
|
+
partnerAttributionConfirmLabel?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Extra inset (px) from the top of the viewport for itinerary “sticky” detection and CSS `top`
|
|
23
|
+
* when a host page has its own sticky chrome (e.g. partner portal header + tabs).
|
|
24
|
+
*/
|
|
25
|
+
itineraryStickyTopOffsetPx?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Baseline UX for embedded partner-style surfaces (partner portal Book tab, TicketBooth provider dashboard):
|
|
30
|
+
* skip collage + tour description, auto-pick the earliest bookable calendar day and first time slot,
|
|
31
|
+
* optionally auto-select a highlighted pickup when `highlightedPickupLocationIds` is set on the page.
|
|
32
|
+
*/
|
|
33
|
+
export const PARTNER_EMBEDDED_BOOKING_FLOW_UI_BASE: BookingFlowUiOptions = {
|
|
34
|
+
showCollage: false,
|
|
35
|
+
showTourDescription: false,
|
|
36
|
+
autoSelectFirstAvailableDate: true,
|
|
37
|
+
autoSelectFirstHighlightedPickup: true,
|
|
38
|
+
};
|