@ticketboothapp/booking 1.2.126 → 1.2.127

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticketboothapp/booking",
3
- "version": "1.2.126",
3
+ "version": "1.2.127",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -185,6 +185,7 @@ export function PrivateShuttleBookingFlow({
185
185
  activePromoCode,
186
186
  promoCodeError,
187
187
  promoCodeValidating,
188
+ forcedCancellationPolicy,
188
189
  handlePromoInputChange,
189
190
  handleApplyPromo,
190
191
  handleRemovePromo,
@@ -197,6 +198,7 @@ export function PrivateShuttleBookingFlow({
197
198
  resourceCount: Math.ceil(passengerCount / PRIVATE_SHUTTLE_RESOURCE_CAPACITY),
198
199
  productCompanyId: product.companyId,
199
200
  productId: product.productId,
201
+ setCancellationPolicyId,
200
202
  onPromoChangesAvailability: () => clearFetchedAvailabilityRangesRef.current(),
201
203
  t,
202
204
  });
@@ -943,6 +945,7 @@ export function PrivateShuttleBookingFlow({
943
945
  }}
944
946
  cancellationPolicies={pricingConfig?.cancellationPolicies}
945
947
  cancellationPolicyId={cancellationPolicyId}
948
+ forcedCancellationPolicy={forcedCancellationPolicy}
946
949
  onCancellationPolicySelect={setCancellationPolicyId}
947
950
  skipConfirmationCommunications={skipConfirmationCommunications}
948
951
  disableAutoCommunications={disableAutoCommunications}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { formatCurrencyAmount } from '../../lib/currency';
4
- import type { PricingConfig } from '../../lib/booking-api';
4
+ import type { PricingConfig, RefundTierOption } from '../../lib/booking-api';
5
5
  import type { Currency } from './CurrencySwitcher';
6
6
  import type { Locale } from '../../lib/booking/i18n/config';
7
7
  import { CancellationPolicySelector } from './CancellationPolicySelector';
@@ -46,6 +46,12 @@ interface PrivateShuttleCheckoutSectionProps {
46
46
  onPhoneNumberChange: (value: string) => void;
47
47
  cancellationPolicies?: PricingConfig['cancellationPolicies'];
48
48
  cancellationPolicyId: string | null;
49
+ forcedCancellationPolicy?: {
50
+ id: string;
51
+ label: string;
52
+ refundTiers?: RefundTierOption[];
53
+ changeWindowHoursBefore?: number | null;
54
+ } | null;
49
55
  onCancellationPolicySelect: (policyId: string) => void;
50
56
  skipConfirmationCommunications: boolean;
51
57
  disableAutoCommunications: boolean;
@@ -97,6 +103,7 @@ export function PrivateShuttleCheckoutSection({
97
103
  onPhoneNumberChange,
98
104
  cancellationPolicies,
99
105
  cancellationPolicyId,
106
+ forcedCancellationPolicy,
100
107
  onCancellationPolicySelect,
101
108
  skipConfirmationCommunications,
102
109
  disableAutoCommunications,
@@ -117,7 +124,7 @@ export function PrivateShuttleCheckoutSection({
117
124
  }: PrivateShuttleCheckoutSectionProps) {
118
125
  const amountDueToday = depositInfo ? depositInfo.depositAmount : totalPrice;
119
126
  const formattedAmountDueToday = formatCurrencyAmount(amountDueToday, currency, locale);
120
- const hasCancellationPolicies = Boolean(cancellationPolicies?.length);
127
+ const hasCancellationPolicies = Boolean(cancellationPolicies?.length || forcedCancellationPolicy);
121
128
 
122
129
  return (
123
130
  <>
@@ -241,6 +248,7 @@ export function PrivateShuttleCheckoutSection({
241
248
  locale={locale}
242
249
  t={t}
243
250
  onPolicySelect={onCancellationPolicySelect}
251
+ forcedPolicy={forcedCancellationPolicy}
244
252
  rowSubtitle={
245
253
  <>
246
254
  <b>Your deposit today is 100% refundable</b> - only once we align on an itinerary
@@ -2,10 +2,18 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  validatePromoCode,
4
4
  type Availability,
5
+ type RefundTierOption,
5
6
  } from '../../lib/booking-api';
6
7
 
7
8
  type TranslationFn = (key: string) => string;
8
9
 
10
+ export type PrivateShuttleForcedCancellationPolicy = {
11
+ id: string;
12
+ label: string;
13
+ refundTiers?: RefundTierOption[];
14
+ changeWindowHoursBefore?: number | null;
15
+ } | null;
16
+
9
17
  export interface UsePrivateShuttlePromoControllerParams {
10
18
  initialPromoCode?: string | null;
11
19
  isAdmin: boolean;
@@ -15,6 +23,7 @@ export interface UsePrivateShuttlePromoControllerParams {
15
23
  resourceCount: number;
16
24
  productCompanyId?: string | null;
17
25
  productId: string;
26
+ setCancellationPolicyId: (policyId: string | null) => void;
18
27
  onPromoChangesAvailability: () => void;
19
28
  t: TranslationFn;
20
29
  }
@@ -28,6 +37,7 @@ export function usePrivateShuttlePromoController({
28
37
  resourceCount,
29
38
  productCompanyId,
30
39
  productId,
40
+ setCancellationPolicyId,
31
41
  onPromoChangesAvailability,
32
42
  t,
33
43
  }: UsePrivateShuttlePromoControllerParams) {
@@ -37,6 +47,8 @@ export function usePrivateShuttlePromoController({
37
47
  );
38
48
  const [promoCodeError, setPromoCodeError] = useState('');
39
49
  const [promoCodeValidating, setPromoCodeValidating] = useState(false);
50
+ const [forcedCancellationPolicy, setForcedCancellationPolicy] =
51
+ useState<PrivateShuttleForcedCancellationPolicy>(null);
40
52
  const lastValidatedInputRef = useRef<string | null>(null);
41
53
 
42
54
  const activePromoCode = isAdmin ? appliedPromoCode : null;
@@ -64,9 +76,21 @@ export function usePrivateShuttlePromoController({
64
76
  productCompanyId,
65
77
  productId,
66
78
  hasOngoingDiscount,
79
+ selectedAvailability?.dateTime,
67
80
  );
68
81
  if (result.valid) {
69
82
  setAppliedPromoCode(code);
83
+ if (result.forcedCancellationPolicyId && result.forcedCancellationPolicyLabel) {
84
+ setForcedCancellationPolicy({
85
+ id: result.forcedCancellationPolicyId,
86
+ label: result.forcedCancellationPolicyLabel,
87
+ refundTiers: result.forcedCancellationPolicyRefundTiers,
88
+ changeWindowHoursBefore: result.forcedChangeWindowHoursBefore ?? undefined,
89
+ });
90
+ setCancellationPolicyId(result.forcedCancellationPolicyId);
91
+ } else {
92
+ setForcedCancellationPolicy(null);
93
+ }
70
94
  onPromoChangesAvailability();
71
95
  } else {
72
96
  setPromoCodeError(
@@ -87,6 +111,8 @@ export function usePrivateShuttlePromoController({
87
111
  productCompanyId,
88
112
  productId,
89
113
  hasOngoingDiscount,
114
+ selectedAvailability?.dateTime,
115
+ setCancellationPolicyId,
90
116
  t,
91
117
  onPromoChangesAvailability,
92
118
  ]);
@@ -102,10 +128,12 @@ export function usePrivateShuttlePromoController({
102
128
  const handleRemovePromo = useCallback(() => {
103
129
  lastValidatedInputRef.current = null;
104
130
  setAppliedPromoCode(null);
131
+ setForcedCancellationPolicy(null);
132
+ setCancellationPolicyId(null);
105
133
  setPromoCodeInput('');
106
134
  setPromoCodeError('');
107
135
  onPromoChangesAvailability();
108
- }, [onPromoChangesAvailability]);
136
+ }, [setCancellationPolicyId, onPromoChangesAvailability]);
109
137
 
110
138
  useEffect(() => {
111
139
  if (!isAdmin) return;
@@ -136,6 +164,7 @@ export function usePrivateShuttlePromoController({
136
164
  activePromoCode,
137
165
  promoCodeError,
138
166
  promoCodeValidating,
167
+ forcedCancellationPolicy,
139
168
  handlePromoInputChange,
140
169
  handleApplyPromo,
141
170
  handleRemovePromo,