@ticketboothapp/booking 0.1.23 → 1.2.24

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 (158) hide show
  1. package/package.json +2 -29
  2. package/src/index.ts +0 -79
  3. package/tsconfig.json +2 -8
  4. package/src/assets/icons/minus.svg +0 -7
  5. package/src/assets/icons/partner-logos/getyourguide.svg +0 -8
  6. package/src/assets/icons/plus.svg +0 -3
  7. package/src/colours.css +0 -23
  8. package/src/components/BookingDetails.module.css +0 -1591
  9. package/src/components/BookingDetails.tsx +0 -2264
  10. package/src/components/BookingWidget.tsx +0 -302
  11. package/src/components/ManageBookingView.tsx +0 -437
  12. package/src/components/PhoneInputWithCountry.module.css +0 -131
  13. package/src/components/PhoneInputWithCountry.tsx +0 -44
  14. package/src/components/PickupLocationDialog.module.css +0 -360
  15. package/src/components/PickupLocationDialog.tsx +0 -357
  16. package/src/components/PostBookingDependentAddOnUpsell.module.css +0 -174
  17. package/src/components/PostBookingDependentAddOnUpsell.tsx +0 -407
  18. package/src/components/booking/AddOnsSection.module.css +0 -10
  19. package/src/components/booking/AddOnsSection.tsx +0 -184
  20. package/src/components/booking/AdminPaymentChoiceModal.tsx +0 -98
  21. package/src/components/booking/BookingDialog.module.css +0 -643
  22. package/src/components/booking/BookingDialog.tsx +0 -356
  23. package/src/components/booking/BookingFlow.tsx +0 -4385
  24. package/src/components/booking/BookingFlowCollage.module.css +0 -148
  25. package/src/components/booking/BookingFlowCollage.tsx +0 -184
  26. package/src/components/booking/BookingFlowPlaceholder.module.css +0 -27
  27. package/src/components/booking/BookingFlowPlaceholder.tsx +0 -25
  28. package/src/components/booking/BookingFlowPreview.tsx +0 -51
  29. package/src/components/booking/BookingProductGrid.module.css +0 -359
  30. package/src/components/booking/BookingProductGrid.tsx +0 -497
  31. package/src/components/booking/Calendar.module.css +0 -616
  32. package/src/components/booking/Calendar.tsx +0 -1123
  33. package/src/components/booking/CancellationPolicySelector.module.css +0 -124
  34. package/src/components/booking/CancellationPolicySelector.tsx +0 -142
  35. package/src/components/booking/ChangeBookingDialog.tsx +0 -562
  36. package/src/components/booking/CheckoutForm.module.css +0 -244
  37. package/src/components/booking/CheckoutForm.tsx +0 -364
  38. package/src/components/booking/CheckoutModal.tsx +0 -451
  39. package/src/components/booking/CurrencySwitcher.tsx +0 -81
  40. package/src/components/booking/DapFlowCollage.tsx +0 -88
  41. package/src/components/booking/DapTourDescription.tsx +0 -35
  42. package/src/components/booking/DependentAddOnBookingDialog.tsx +0 -1350
  43. package/src/components/booking/DependentAddOnPaymentForm.tsx +0 -124
  44. package/src/components/booking/ErrorBoundary.tsx +0 -63
  45. package/src/components/booking/InfoTooltip.tsx +0 -108
  46. package/src/components/booking/ItineraryBox.module.css +0 -258
  47. package/src/components/booking/ItineraryBox.tsx +0 -550
  48. package/src/components/booking/ItineraryBuilder.tsx +0 -82
  49. package/src/components/booking/ItineraryPlaceholder.module.css +0 -45
  50. package/src/components/booking/ItineraryPlaceholder.tsx +0 -26
  51. package/src/components/booking/MealDrinkAddOnSelector.tsx +0 -338
  52. package/src/components/booking/PickupLocationSelector.module.css +0 -124
  53. package/src/components/booking/PickupLocationSelector.tsx +0 -1566
  54. package/src/components/booking/PickupTimeSelector.module.css +0 -134
  55. package/src/components/booking/PickupTimeSelector.tsx +0 -112
  56. package/src/components/booking/PriceBreakdown.tsx +0 -154
  57. package/src/components/booking/PriceSummary.tsx +0 -234
  58. package/src/components/booking/PrivateShuttleBookingFlow.module.css +0 -357
  59. package/src/components/booking/PrivateShuttleBookingFlow.tsx +0 -2662
  60. package/src/components/booking/PromoCodeInput.module.css +0 -166
  61. package/src/components/booking/PromoCodeInput.tsx +0 -99
  62. package/src/components/booking/ReturnTimeSelector.module.css +0 -173
  63. package/src/components/booking/ReturnTimeSelector.tsx +0 -145
  64. package/src/components/booking/TermsAcceptance.tsx +0 -111
  65. package/src/components/booking/TicketSelector.module.css +0 -164
  66. package/src/components/booking/TicketSelector.tsx +0 -199
  67. package/src/components/booking/TourDescription.module.css +0 -304
  68. package/src/components/booking/TourDescription.tsx +0 -273
  69. package/src/components/booking/booking-flow-ui.ts +0 -38
  70. package/src/components/booking/booking-flow.css +0 -944
  71. package/src/components/button.css +0 -245
  72. package/src/components/button.tsx +0 -152
  73. package/src/components/colorable-svg.tsx +0 -29
  74. package/src/components/image.css +0 -29
  75. package/src/components/image.tsx +0 -113
  76. package/src/components/partner/PartnerBookingPage.module.css +0 -130
  77. package/src/components/partner/PartnerBookingPage.tsx +0 -390
  78. package/src/components/partner/PartnerBookingPageWithBrowserMetadata.tsx +0 -45
  79. package/src/components/product-tag.module.css +0 -30
  80. package/src/components/product-tag.tsx +0 -34
  81. package/src/components/product-theme-pages/image-modal.tsx +0 -248
  82. package/src/components/product-theme-pages/photo-gallery.module.css +0 -200
  83. package/src/components/terms/TermsContent.tsx +0 -178
  84. package/src/components/value-pill.module.css +0 -59
  85. package/src/components/value-pill.tsx +0 -46
  86. package/src/constants/images.ts +0 -556
  87. package/src/constants/pill-values.ts +0 -210
  88. package/src/constants/products.ts +0 -155
  89. package/src/contexts/AvailabilitiesCacheContext.tsx +0 -125
  90. package/src/contexts/BookingAppContext.tsx +0 -134
  91. package/src/contexts/CompanyContext.tsx +0 -70
  92. package/src/data/dap-descriptions/session-couples-families-friends.en.json +0 -61
  93. package/src/data/dap-descriptions/session-elopements.en.json +0 -60
  94. package/src/data/dap-descriptions/session-proposals.en.json +0 -60
  95. package/src/data/product-descriptions/afternoon-delight.en.json +0 -35
  96. package/src/data/product-descriptions/emerald-lake-escape.en.json +0 -68
  97. package/src/data/product-descriptions/lake-louise-adventure.en.json +0 -74
  98. package/src/data/product-descriptions/moraine-lake-adventure.en.json +0 -78
  99. package/src/data/product-descriptions/moraine-lake-sunrise-lake-louise-golden-hour.en.json +0 -65
  100. package/src/data/product-descriptions/moraine-lake-sunrise.en.json +0 -64
  101. package/src/data/product-descriptions/private-tour.en.json +0 -80
  102. package/src/data/product-descriptions/two-lakes-combo.en.json +0 -65
  103. package/src/data/products-config.json +0 -101
  104. package/src/hooks/useBookingSourceMetadataFromLocation.ts +0 -21
  105. package/src/hooks/useIsBookingLaunchLive.ts +0 -49
  106. package/src/lib/analytics.ts +0 -197
  107. package/src/lib/booking/booking-source.ts +0 -51
  108. package/src/lib/booking/checkout-breakdown.ts +0 -69
  109. package/src/lib/booking/correlation-id.ts +0 -46
  110. package/src/lib/booking/i18n/config.ts +0 -21
  111. package/src/lib/booking/i18n/index.tsx +0 -144
  112. package/src/lib/booking/i18n/messages/en.json +0 -236
  113. package/src/lib/booking/i18n/messages/fr.json +0 -236
  114. package/src/lib/booking/itinerary-display.ts +0 -36
  115. package/src/lib/booking/itinerary-labels.ts +0 -70
  116. package/src/lib/booking/location-calculations.ts +0 -43
  117. package/src/lib/booking/location-utils.ts +0 -165
  118. package/src/lib/booking/map-utils.ts +0 -153
  119. package/src/lib/booking/marker-icons.ts +0 -113
  120. package/src/lib/booking/normalize-booking-product-id.ts +0 -21
  121. package/src/lib/booking/pickup-location-types.ts +0 -25
  122. package/src/lib/booking/places-api.ts +0 -154
  123. package/src/lib/booking/pricing.ts +0 -466
  124. package/src/lib/booking/product-option-id.ts +0 -35
  125. package/src/lib/booking/source-metadata.ts +0 -226
  126. package/src/lib/booking/sunday-week.ts +0 -14
  127. package/src/lib/booking/theme.ts +0 -83
  128. package/src/lib/booking/trace-context.ts +0 -62
  129. package/src/lib/booking/utils.ts +0 -9
  130. package/src/lib/booking-api.ts +0 -1793
  131. package/src/lib/booking-constants.ts +0 -23
  132. package/src/lib/booking-ref.ts +0 -13
  133. package/src/lib/booking-types.ts +0 -36
  134. package/src/lib/currency.ts +0 -81
  135. package/src/lib/dap-descriptions.ts +0 -50
  136. package/src/lib/dap-itinerary-preview.ts +0 -315
  137. package/src/lib/dependent-add-on-api.ts +0 -434
  138. package/src/lib/env.ts +0 -96
  139. package/src/lib/firebase.ts +0 -20
  140. package/src/lib/job-application-api.ts +0 -83
  141. package/src/lib/manage-booking-embed-print.ts +0 -16
  142. package/src/lib/manage-booking-post-checkout.ts +0 -68
  143. package/src/lib/photo-dap-config.ts +0 -228
  144. package/src/lib/photo-packages.ts +0 -75
  145. package/src/lib/pickup/map-utils.ts +0 -56
  146. package/src/lib/pickup/marker-icons.ts +0 -19
  147. package/src/lib/product-descriptions.ts +0 -66
  148. package/src/lib/products-config.ts +0 -73
  149. package/src/providers/booking-dialog-provider.tsx +0 -282
  150. package/src/providers/dependent-add-on-dialog-provider.tsx +0 -105
  151. package/src/radius.css +0 -5
  152. package/src/spacing.css +0 -7
  153. package/src/strings/en.json +0 -1774
  154. package/src/strings/es.json +0 -1573
  155. package/src/strings/fr.json +0 -1573
  156. package/src/strings/index.js +0 -23
  157. package/src/text-style.css +0 -56
  158. package/src/utils/currency-converter.ts +0 -101
@@ -1,69 +0,0 @@
1
- import type { CheckoutBreakdown, CheckoutReceiptLine } from '@/lib/booking-api';
2
-
3
- /**
4
- * Round to 2 decimal places. Used so breakdown amounts and totals are stable
5
- * and pass backend validation (sum of line items ≈ totalAmount within 0.02).
6
- */
7
- export function round2(n: number): number {
8
- return Math.round(n * 100) / 100;
9
- }
10
-
11
- export interface CheckoutLineInput {
12
- label: string;
13
- amount: number;
14
- type: string;
15
- quantity?: number;
16
- }
17
-
18
- /** Line types for checkout breakdown. ADDITIONAL_HOURS reserved for future private shuttle extra hours. */
19
- export const CheckoutLineType = {
20
- TICKET: 'TICKET',
21
- DEPOSIT: 'DEPOSIT',
22
- FEE: 'FEE',
23
- RETURN_OPTION: 'return',
24
- CANCELLATION_UPGRADE: 'cancellation',
25
- TAX: 'TAX',
26
- PROMO_CODE: 'PROMO_CODE',
27
- ROUNDING: 'ROUNDING',
28
- ADDITIONAL_HOURS: 'ADDITIONAL_HOURS', // Future: private shuttle extra hours line
29
- } as const;
30
-
31
- export interface BuildCheckoutBreakdownParams {
32
- /** Line items in display order (tickets, return, cancellation, fees, tax, promo, etc.) */
33
- lines: CheckoutLineInput[];
34
- /** Total amount to charge (will be rounded to 2 decimals). */
35
- totalAmount: number;
36
- currency: string;
37
- /** Label for rounding line when added (e.g. "Rounding"). */
38
- roundingLabel: string;
39
- }
40
-
41
- /**
42
- * Builds a CheckoutBreakdown from the given lines and total.
43
- * Rounds each line amount to 2 decimals; if the sum differs from total by more than 0.02,
44
- * adds a rounding line so the backend validator accepts it.
45
- * Reused by BookingFlow and PrivateShuttleBookingFlow so Stripe and /manage match the UI.
46
- */
47
- export function buildCheckoutBreakdown(params: BuildCheckoutBreakdownParams): CheckoutBreakdown {
48
- const { lines, totalAmount, currency, roundingLabel } = params;
49
- const totalRounded = round2(totalAmount);
50
- const lineItems: CheckoutReceiptLine[] = lines.map((line) => ({
51
- label: line.label,
52
- amount: round2(line.amount),
53
- type: line.type,
54
- quantity: line.quantity,
55
- }));
56
- const sumLines = lineItems.reduce((s, l) => s + l.amount, 0);
57
- if (Math.abs(sumLines - totalRounded) > 0.02) {
58
- lineItems.push({
59
- label: roundingLabel,
60
- amount: round2(totalRounded - sumLines),
61
- type: 'ROUNDING',
62
- });
63
- }
64
- return {
65
- lineItems,
66
- totalAmount: totalRounded,
67
- currency,
68
- };
69
- }
@@ -1,46 +0,0 @@
1
- /**
2
- * One opaque id per browser tab/session for joining client telemetry → TicketBooth Lambda logs.
3
- */
4
-
5
- export const BOOKING_CORRELATION_HEADER = 'X-Correlation-Id';
6
-
7
- const STORAGE_KEY = 'tb_booking_correlation_id';
8
-
9
- function newCorrelationId(): string {
10
- try {
11
- if (typeof crypto !== 'undefined' && crypto.randomUUID) {
12
- return crypto.randomUUID();
13
- }
14
- } catch {
15
- /* fall through */
16
- }
17
- return `${Date.now()}-${Math.random().toString(36).slice(2, 12)}`;
18
- }
19
-
20
- /** Stable for the lifetime of this tab's sessionStorage (until the tab closes / storage cleared). */
21
- export function getOrCreateBookingCorrelationId(): string {
22
- if (typeof window === 'undefined') return '';
23
- try {
24
- let id = sessionStorage.getItem(STORAGE_KEY);
25
- if (!id) {
26
- id = newCorrelationId();
27
- sessionStorage.setItem(STORAGE_KEY, id);
28
- }
29
- return id;
30
- } catch {
31
- return newCorrelationId();
32
- }
33
- }
34
-
35
- /** Merge correlation header into outbound API headers (browser only). */
36
- export function withBookingCorrelationId(
37
- headers: Record<string, string>
38
- ): Record<string, string> {
39
- if (typeof window === 'undefined') return headers;
40
- const id = getOrCreateBookingCorrelationId();
41
- if (!id) return headers;
42
- return {
43
- ...headers,
44
- [BOOKING_CORRELATION_HEADER]: id,
45
- };
46
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * i18n Configuration
3
- *
4
- * This file sets up the internationalization configuration.
5
- * Currently supports English (en) as default, ready to add more languages.
6
- */
7
-
8
- export const locales = ['en', 'fr'] as const;
9
- export type Locale = (typeof locales)[number];
10
-
11
- export const defaultLocale: Locale = 'en';
12
-
13
- // Language display names
14
- export const languageNames: Record<Locale, string> = {
15
- en: 'English',
16
- fr: 'Français',
17
- // Add more languages here:
18
- // es: 'Español',
19
- // de: 'Deutsch',
20
- };
21
-
@@ -1,144 +0,0 @@
1
- 'use client';
2
-
3
- /**
4
- * i18n Utilities
5
- *
6
- * Simple translation utilities for client components.
7
- * For server components, use next-intl directly.
8
- */
9
-
10
- import { useState, useEffect, createContext, useContext } from 'react';
11
- import type { ReactNode } from 'react';
12
- import messagesEn from './messages/en.json';
13
- import messagesFr from './messages/fr.json';
14
- import { defaultLocale, locales, type Locale } from './config';
15
-
16
- type Messages = typeof messagesEn;
17
-
18
- const messages: Record<Locale, Messages> = {
19
- en: messagesEn,
20
- fr: messagesFr,
21
- };
22
-
23
- // Context for locale
24
- const LocaleContext = createContext<{
25
- locale: Locale;
26
- setLocale: (locale: Locale) => void;
27
- }>({
28
- locale: defaultLocale,
29
- setLocale: () => {},
30
- });
31
-
32
- // Provider component
33
- export function LocaleProvider({ children }: { children: ReactNode }) {
34
- // Always start with default locale to ensure server/client match
35
- const [locale, setLocaleState] = useState<Locale>(defaultLocale);
36
-
37
- // Load from localStorage after hydration to avoid SSR mismatch
38
- useEffect(() => {
39
- try {
40
- const saved = localStorage.getItem('booking-locale') as Locale | null;
41
- // Validate that saved locale is in our supported locales array
42
- if (saved && locales.includes(saved)) {
43
- setLocaleState(saved);
44
- }
45
- } catch (error) {
46
- // localStorage might be disabled or throw errors
47
- console.warn('Failed to read locale from localStorage:', error);
48
- }
49
- }, []);
50
-
51
- const setLocale = (newLocale: Locale) => {
52
- // Validate locale before setting
53
- if (!locales.includes(newLocale)) {
54
- console.warn(`Invalid locale: ${newLocale}. Falling back to ${defaultLocale}`);
55
- setLocaleState(defaultLocale);
56
- return;
57
- }
58
-
59
- setLocaleState(newLocale);
60
- if (typeof window !== 'undefined') {
61
- try {
62
- localStorage.setItem('booking-locale', newLocale);
63
- } catch (error) {
64
- // localStorage might be disabled or full
65
- console.warn('Failed to save locale to localStorage:', error);
66
- }
67
- }
68
- };
69
-
70
- return (
71
- <LocaleContext.Provider value={{ locale, setLocale }}>
72
- {children}
73
- </LocaleContext.Provider>
74
- );
75
- }
76
-
77
- // Hook to use translations
78
- export function useTranslations() {
79
- const { locale } = useContext(LocaleContext);
80
-
81
- // Ensure we have a valid locale, fallback to default if invalid
82
- const validLocale = locales.includes(locale) ? locale : defaultLocale;
83
- const currentMessages = messages[validLocale] || messages[defaultLocale];
84
-
85
- const t = (key: string, params?: Record<string, string | number>): string => {
86
- if (!key || typeof key !== 'string') {
87
- console.warn('Invalid translation key:', key);
88
- return String(key || '');
89
- }
90
-
91
- const keys = key.split('.');
92
- let value: unknown = currentMessages;
93
-
94
- for (const k of keys) {
95
- if (value === null || value === undefined) {
96
- break;
97
- }
98
- // Safe property access on unknown type
99
- value = (value as Record<string, unknown>)[k];
100
- }
101
-
102
- if (value === undefined || value === null) {
103
- // In development, show the key to help identify missing translations
104
- if (process.env.NODE_ENV === 'development') {
105
- console.warn(`Translation key not found: ${key} (locale: ${validLocale})`);
106
- }
107
- return key;
108
- }
109
-
110
- // Ensure value is a string
111
- if (typeof value !== 'string') {
112
- console.warn(`Translation value is not a string for key: ${key}`);
113
- return key;
114
- }
115
-
116
- // Simple parameter replacement
117
- if (params) {
118
- return value.replace(/\{(\w+)\}/g, (match, paramKey) => {
119
- const paramValue = params[paramKey];
120
- return paramValue !== undefined && paramValue !== null
121
- ? String(paramValue)
122
- : match;
123
- });
124
- }
125
-
126
- return value;
127
- };
128
-
129
- return { t };
130
- }
131
-
132
- // Hook to use locale switching
133
- export function useLocale() {
134
- return useContext(LocaleContext);
135
- }
136
-
137
- // Type-safe translation key helper
138
- export type TranslationKey =
139
- | `common.${keyof Messages['common']}`
140
- | `booking.${keyof Messages['booking']}`
141
- | `pickup.${keyof Messages['pickup']}`
142
- | `calendar.${keyof Messages['calendar']}`
143
- | `products.${keyof Messages['products']}`;
144
-
@@ -1,236 +0,0 @@
1
- {
2
- "common": {
3
- "back": "Back",
4
- "continue": "Continue",
5
- "select": "Select",
6
- "change": "Change",
7
- "cancel": "Cancel",
8
- "close": "Close",
9
- "videoPause": "Pause video",
10
- "videoPlay": "Play video",
11
- "videoMute": "Mute",
12
- "videoUnmute": "Unmute",
13
- "loading": "Loading...",
14
- "error": "Error",
15
- "total": "Total",
16
- "email": "Email",
17
- "emailPlaceholder": "your@email.com",
18
- "emailForConfirmation": "Email (for confirmation)"
19
- },
20
- "booking": {
21
- "selectDate": "Select Date",
22
- "selectPickupTime": "Select Pickup Time",
23
- "requestDifferentTime": "Request different time",
24
- "preferredPickupTime": "Preferred pickup time",
25
- "selectReturnTime": "Select Return Time",
26
- "selectPhotoSessionTime": "Select session time",
27
- "dapPhotoSessionAddOn": "Photo session (add-on)",
28
- "dapYourCurrentItinerary": "Your current itinerary",
29
- "dapRefItineraryLoading": "Looking up your booking…",
30
- "dapRefItineraryEmpty": "We didn’t get shuttle times for this reference yet. Your booking may still be valid — choose a session length (if needed) and load available times.",
31
- "dapRefItineraryLookupFailed": "We couldn’t find a booking with that reference, or it isn’t eligible for this add-on. Double-check the code from your confirmation.",
32
- "dapItineraryFallbackFoot": "After you pay, you’ll see this add-on with your full itinerary in Manage booking.",
33
- "mostPopular": "Most popular",
34
- "pickupAtTourStart": "<b>Your pickup time depends on your pickup location.</b><br>Your exact pickup time will be confirmed once you have confirmed your pickup location. Pickups start in Canmore and end in Lake Louise.",
35
- "pickupAtTourStartLocation": "tour start location",
36
- "pickupLocationUnknown": "I don't know",
37
- "arrivalTimeMessage": "You'll arrive at {destination} around <b>{time}</b>.",
38
- "yourItinerary": "Your Itinerary",
39
- "buildYourItinerary": "Build Your Itinerary",
40
- "selectPickupTimeToSeeItinerary": "Select a pickup time below to see your schedule.",
41
- "selectTourOption": "Select Tour Option",
42
- "selectTourOptionToSeeItinerary": "Select a tour option below to see your itinerary.",
43
- "timesToBeDetermined": "times to be determined/confirmed…",
44
- "proposedStops": "Proposed stops",
45
- "orderAndTimesToBeConfirmed": "(order and times to be confirmed by our team)",
46
- "startingAtPerShuttle": "Starting at {price} per shuttle",
47
- "hoursTour": "{hours} hr tour",
48
- "hoursTourStarting": "Tour starting with {hours} hours",
49
- "startingAtForHours": "Starting at {price} per shuttle for {hours}.",
50
- "hoursUnit": "hours",
51
- "additionalHoursAvailable": "Additional hours available for a fee.",
52
- "pickupAt": "Pickup at",
53
- "pickupAtPrefix": "Pickup at ",
54
- "pickupAtLocation": "Pickup at {location}",
55
- "arriveAt": "Arrive at",
56
- "arriveAtPlace": "Arrive at {place}",
57
- "departFrom": "Depart",
58
- "departFromPlace": "Depart {place}",
59
- "dropOffAt": "Drop off at {location}",
60
- "dropOffAtPrefix": "Drop off at ",
61
- "tripEnd": "Trip ends",
62
- "stopAtPlaceTbd": "Stop at {place} (time TBD)",
63
- "placeTheDestination": "the destination",
64
- "dropOffAtPickup": "Arrive at {pickupLocation}",
65
- "yourPickupLocation": "your pickup location",
66
- "tickets": "Tickets",
67
- "overbookingWarnDeparture": "WARN OVERBOOKING: Only {count} seats available on {time} departure.",
68
- "overbookingWarnReturn": "WARN OVERBOOKING: Only {count} seats available on {time} return.",
69
- "overbookingWarnBoth": "WARN OVERBOOKING: Only {count} seats available on both trip directions.",
70
- "overbookingResourcesSuffix": "({count} shared resources.)",
71
- "adminBookingLoadLine1": "Booking {projected} /",
72
- "adminBookingLoadLine2": "{total} total",
73
- "available": "available",
74
- "soldOut": "Sold out",
75
- "continueToPayment": "Continue to Payment",
76
- "continueToSecurePayment": "Continue to secure payment",
77
- "preparingCheckout": "Preparing…",
78
- "creatingReservation": "Creating reservation...",
79
- "securePayment": "Secure payment powered by Stripe",
80
- "selectTimeAndTickets": "Please select a time and at least one ticket",
81
- "selectPickupLocation": "Please select a pickup location",
82
- "loadingTimes": "Loading available times...",
83
- "noAvailability": "No availability found for the next 30 days. Please check back later.",
84
- "seeFullTourDescription": "See full tour description",
85
- "seeFullAddOnDescription": "See full experience details",
86
- "communicationPreference": "How would you like to receive future communication (confirmation, reminders, etc.)?",
87
- "communicationEmail": "Email",
88
- "communicationEmailDesc": "Send confirmation via email",
89
- "communicationWhatsApp": "WhatsApp",
90
- "communicationWhatsAppDesc": "Send confirmation via WhatsApp",
91
- "emailForConfirmation": "Email",
92
- "phoneNumberForConfirmation": "WhatsApp Phone Number",
93
- "phoneNumberPlaceholder": "(555) 123-4567",
94
- "invalidEmail": "Please enter a valid email address",
95
- "invalidPhoneNumber": "Please enter a valid phone number",
96
- "selectCommunicationPreference": "Please select how you would like to receive your confirmation",
97
- "enterEmail": "Please enter your email address",
98
- "enterFirstName": "Please enter your first name",
99
- "enterLastName": "Please enter your last name",
100
- "enterPhoneNumber": "Please enter your phone number",
101
- "firstName": "First Name",
102
- "firstNamePlaceholder": "Jane",
103
- "lastName": "Last Name",
104
- "lastNamePlaceholder": "Smith",
105
- "dapNoLastNameOnFile": "We couldn’t find a last name on this booking in our system. Please contact us, or use Manage booking with the last name from your confirmation email.",
106
- "dapCancellationPolicyHeading": "Cancellation policy",
107
- "dapCancellationPolicyBody": "You may cancel this add-on for a full refund up to {days} {daysUnit} before your scheduled photo session. Cancellations made after that deadline may forfeit the entire add-on cost.",
108
- "dapCancellationPolicyDayUnit": "day",
109
- "dapCancellationPolicyDaysUnit": "days",
110
- "noActiveOption": "No active product options available",
111
- "people": "people",
112
- "person": "person",
113
- "rounding": "Rounding",
114
- "deposit": "Deposit",
115
- "totalOwedForBookingChange": "Total owed for booking difference",
116
- "subtotal": "Subtotal",
117
- "tax": "Taxes and fees",
118
- "returnOption": "Return Option",
119
- "fromPrice": "From {price}",
120
- "communicationPermission": "By providing your contact information, you give permission to receive booking confirmations, reminders, and updates via this method.",
121
- "communicationPermissionCheckbox": "I give permission to receive communication via this method",
122
- "communicationPermissionRequired": "Please select at least one communication method",
123
- "emailPermissionCheckbox": "Contact me by email (we will only send you communication relevant to your booking)",
124
- "whatsappPermissionCheckbox": "Contact me by WhatsApp (we will only send you communication relevant to your booking)",
125
- "reviewAndPay": "Review & pay",
126
- "payNow": "Pay now",
127
- "paying": "Paying...",
128
- "checkout": "Checkout",
129
- "paymentNotConfigured": "Payment is not configured. Please use the standard checkout.",
130
- "loadingPayment": "Loading payment form...",
131
- "promoCode": "Promo code",
132
- "optionalPromoCode": "Promo / voucher / gift card",
133
- "promoCodePlaceholder": "Enter code",
134
- "applyPromo": "Apply",
135
- "removePromo": "Remove",
136
- "promoApplied": "Applied: {{code}}",
137
- "invalidPromoCode": "Invalid or expired promo code",
138
- "promoCodesCannotStackWithDiscounts": "Promo codes cannot be stacked with deals",
139
- "discount": "Discount",
140
- "cancellationPolicy": "Cancellation policy",
141
- "promoIncludesCancellationPolicy": "This promo includes {label} cancellation policy",
142
- "cancellationRefundTierDays": "Cancel <b>{days} days before</b> for <b>{percent}% refund</b>",
143
- "cancellationRefundTierHours": "Cancel <b>{hours} hours before</b> for <b>{percent}% refund</b>",
144
- "cancellationNoRefunds": "<b>No cancellation, no refunds</b>. You can make changes to your booking up to <b>{days} days before</b>.",
145
- "cancellationNoRefundsNoDays": "<b>No cancellation, no refunds</b>. You can make changes to your booking before your booking date.",
146
- "cancellationStandard": "Standard cancellation",
147
- "included": "Included",
148
- "flexibleCancellation": "Flexible cancellation",
149
- "depositPaymentNotice": "You're paying the deposit today.",
150
- "balanceChargeNotice": "The remaining balance will be charged {days} days before your booking. You can also pay it earlier from your Manage Booking page.",
151
- "balancePayEarlier": "You can pay the remaining balance anytime from your Manage Booking page.",
152
- "remainingBalance": "Remaining Balance"
153
- },
154
- "pickup": {
155
- "title": "Select your pickup location",
156
- "yesAddNow": "I know where I want to be picked up",
157
- "dontKnow": "I don't know yet",
158
- "pickupLocation": "Pickup Location",
159
- "enterAddress": "Enter your pickup address",
160
- "searchingLocation": "Searching for location...",
161
- "locationNotFound": "Could not find that location. Please try a different address.",
162
- "chooseNearby": "Choose a pickup location nearby",
163
- "exactMatch": "Exact match found",
164
- "locationsInCity": "Pickup locations in {{city}}",
165
- "selectThisLocation": "Select This Location",
166
- "yourLocation": "Your Location",
167
- "chooseClosest": "Choose a pickup location below to see the closest option.",
168
- "useThisAddress": "Use this address",
169
- "away": "away",
170
- "walk": "walk",
171
- "drive": "drive",
172
- "switchUnits": "Switch to {unit} units",
173
- "metric": "metric",
174
- "imperial": "imperial",
175
- "dontKnowSubtext": "We will send you reminders to select your pickup location.",
176
- "yesAddNowSubtext": "You can change this later.",
177
- "skipWarningTitle": "Important Notice",
178
- "skipWarningMessage": "You are not guaranteed to be picked up if you do not <b>update your booking with your pickup location at least 12 hours prior</b>.",
179
- "iUnderstand": "I understand",
180
- "nevermindSelectLocation": "Nevermind, I'll select my location",
181
- "outsideServiceArea": "This address is outside our service area. We offer pickups between Lake Louise and Kananaskis. Please choose a preset location or search for an address in that area."
182
- },
183
- "calendar": {
184
- "previousWeeks": "Previous 2 weeks",
185
- "nextWeeks": "Next 2 weeks",
186
- "soldOut": "Sold out",
187
- "left": "{count} left",
188
- "timesAvailable": "{count} times",
189
- "spotsAvailable": "{count} available",
190
- "available": "Available",
191
- "days": {
192
- "sun": "SUN",
193
- "mon": "MON",
194
- "tue": "TUE",
195
- "wed": "WED",
196
- "thu": "THU",
197
- "fri": "FRI",
198
- "sat": "SAT"
199
- },
200
- "months": {
201
- "january": "January",
202
- "february": "February",
203
- "march": "March",
204
- "april": "April",
205
- "may": "May",
206
- "june": "June",
207
- "july": "July",
208
- "august": "August",
209
- "september": "September",
210
- "october": "October",
211
- "november": "November",
212
- "december": "December"
213
- }
214
- },
215
- "products": {
216
- "backToExperiences": "Back to experiences",
217
- "from": "From",
218
- "noDescription": "No description available",
219
- "productGridFilters": {
220
- "all": "All",
221
- "moraineLake": "Moraine Lake",
222
- "lakeLouise": "Lake Louise",
223
- "emeraldLake": "Emerald Lake",
224
- "private": "Private",
225
- "sunrise": "Sunrise"
226
- }
227
- },
228
- "terms": {
229
- "title": "Terms & Conditions",
230
- "viewTerms": "Terms & Conditions",
231
- "acceptPrefix": "I accept the",
232
- "acceptAndClose": "I've read and accept",
233
- "content": "By completing this booking you agree to the following terms and conditions.\n\n1. Booking and payment\nYour reservation is confirmed once payment has been processed. You will receive a confirmation by email or the contact method you selected.\n\n2. Cancellation and changes\nCancellation and change policies depend on the option you selected at checkout. Please refer to your confirmation for the policy that applies to your booking.\n\n3. Participation\nYou are responsible for arriving at the designated time and location. Late arrival may result in forfeiting the experience without refund.\n\n4. Liability\nThe operator is not liable for loss or damage beyond what is required by applicable law. Participation is at your own risk where activities involve inherent risk.\n\n5. Contact\nFor questions or changes to your booking, use the contact details provided in your confirmation."
234
- }
235
- }
236
-