tf-checkout-react 2.0.0-beta.1 → 2.0.0-beta.2
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/dist/index.esm.js +473 -263
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +473 -263
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/EmbeddedCheckout.tsx +6 -1
- package/src/auth/AuthModal.tsx +3 -3
- package/src/auth/ForgotPasswordForm.tsx +4 -6
- package/src/auth/LoginForm.tsx +2 -2
- package/src/auth/RegisterForm.tsx +2 -2
- package/src/auth/ResetPasswordForm.tsx +7 -7
- package/src/configure.ts +1 -5
- package/src/confirmer.ts +1 -5
- package/src/sections/AddOns.tsx +14 -7
- package/src/sections/BillingInfo.tsx +40 -33
- package/src/sections/Confirmation.tsx +8 -6
- package/src/sections/OrderSummary.tsx +7 -5
- package/src/sections/Payment.tsx +17 -13
- package/src/sections/Tickets.tsx +32 -15
- package/src/sections/billing/BillingAddressFields.tsx +19 -13
- package/src/sections/billing/TicketHoldersCard.tsx +103 -94
- package/src/ui/CheckoutProvider.tsx +5 -1
- package/src/ui/InstallmentPicker.tsx +4 -2
- package/src/ui/PaymentMethods.tsx +82 -76
- package/src/ui/TimerBanner.tsx +7 -3
|
@@ -9,15 +9,13 @@
|
|
|
9
9
|
import React, { type FC, type ReactNode } from 'react'
|
|
10
10
|
|
|
11
11
|
import { cx } from './cx'
|
|
12
|
+
import { useT } from './I18nProvider'
|
|
12
13
|
import { Field, Input } from './Field'
|
|
13
14
|
|
|
14
15
|
// The method descriptor + row shape live in the SDK so both platforms render
|
|
15
16
|
// the SAME option list. Imported for local use and re-exported for consumers
|
|
16
17
|
// that already import them from here.
|
|
17
|
-
import type {
|
|
18
|
-
PaymentMethodId,
|
|
19
|
-
PaymentMethodOption,
|
|
20
|
-
} from 'tf-checkout-shared'
|
|
18
|
+
import type { PaymentMethodId, PaymentMethodOption } from 'tf-checkout-shared'
|
|
21
19
|
|
|
22
20
|
export type { PaymentMethodId, PaymentMethodOption }
|
|
23
21
|
|
|
@@ -55,79 +53,87 @@ export const PaymentMethods: FC<PaymentMethodsProps> = ({
|
|
|
55
53
|
children,
|
|
56
54
|
inputSlotFor,
|
|
57
55
|
className,
|
|
58
|
-
}) =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<input
|
|
82
|
-
type="radio"
|
|
83
|
-
name="tf-pay-method"
|
|
84
|
-
className="tf-checkout-payment__method-radio"
|
|
85
|
-
checked={isSelected}
|
|
86
|
-
onChange={() => onSelect(o.value)}
|
|
87
|
-
/>
|
|
88
|
-
{o.iconUrl && (
|
|
89
|
-
<img className="tf-checkout-payment__method-icon" src={o.iconUrl} alt="" />
|
|
56
|
+
}) => {
|
|
57
|
+
const t = useT()
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
className={cx('tf-checkout-payment__methods', className)}
|
|
62
|
+
role="radiogroup"
|
|
63
|
+
aria-label={t('payment.method')}
|
|
64
|
+
>
|
|
65
|
+
{options.map((o) => {
|
|
66
|
+
const isSelected = o.value === selected
|
|
67
|
+
const extraValue =
|
|
68
|
+
o.extra === 'phoneNumber'
|
|
69
|
+
? extraValues[o.value]?.phoneNumber
|
|
70
|
+
: extraValues[o.value]?.cashtag
|
|
71
|
+
const extraInvalid =
|
|
72
|
+
Boolean(isSelected && o.extra && showValidation) && !extraValue?.trim()
|
|
73
|
+
return (
|
|
74
|
+
<label
|
|
75
|
+
key={o.value}
|
|
76
|
+
className={cx(
|
|
77
|
+
'tf-checkout-payment__method',
|
|
78
|
+
isSelected && 'tf-checkout-payment__method--selected'
|
|
90
79
|
)}
|
|
91
|
-
|
|
92
|
-
|
|
80
|
+
>
|
|
81
|
+
<span className="tf-checkout-payment__method-head">
|
|
82
|
+
<input
|
|
83
|
+
type="radio"
|
|
84
|
+
name="tf-pay-method"
|
|
85
|
+
className="tf-checkout-payment__method-radio"
|
|
86
|
+
checked={isSelected}
|
|
87
|
+
onChange={() => onSelect(o.value)}
|
|
88
|
+
/>
|
|
89
|
+
{o.iconUrl && (
|
|
90
|
+
<img
|
|
91
|
+
className="tf-checkout-payment__method-icon"
|
|
92
|
+
src={o.iconUrl}
|
|
93
|
+
alt=""
|
|
94
|
+
/>
|
|
95
|
+
)}
|
|
96
|
+
<span className="tf-checkout-payment__method-label">{o.label}</span>
|
|
97
|
+
</span>
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
invalid={extraInvalid}
|
|
102
|
-
>
|
|
103
|
-
<Input
|
|
104
|
-
inputMode={o.extra === 'phoneNumber' ? 'tel' : 'text'}
|
|
105
|
-
required
|
|
99
|
+
{isSelected && (o.value === inputSlotFor || o.extra) && (
|
|
100
|
+
<div className="tf-checkout-payment__method-body">
|
|
101
|
+
{o.value === inputSlotFor && children}
|
|
102
|
+
{o.extra && (
|
|
103
|
+
<Field
|
|
104
|
+
label={`${EXTRA_LABEL[o.extra]} *`}
|
|
105
|
+
error={extraInvalid ? t('billing.fieldRequired') : undefined}
|
|
106
106
|
invalid={extraInvalid}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
o.extra === 'phoneNumber' ? '
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
onExtraChange(
|
|
118
|
-
o.value,
|
|
107
|
+
>
|
|
108
|
+
<Input
|
|
109
|
+
inputMode={o.extra === 'phoneNumber' ? 'tel' : 'text'}
|
|
110
|
+
required
|
|
111
|
+
invalid={extraInvalid}
|
|
112
|
+
aria-invalid={extraInvalid}
|
|
113
|
+
placeholder={
|
|
114
|
+
o.extra === 'phoneNumber' ? 'e.g. 081234567890' : '$cashtag'
|
|
115
|
+
}
|
|
116
|
+
value={
|
|
119
117
|
o.extra === 'phoneNumber'
|
|
120
|
-
?
|
|
121
|
-
:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
)
|
|
118
|
+
? (extraValues[o.value]?.phoneNumber ?? '')
|
|
119
|
+
: (extraValues[o.value]?.cashtag ?? '')
|
|
120
|
+
}
|
|
121
|
+
onChange={(e) =>
|
|
122
|
+
onExtraChange(
|
|
123
|
+
o.value,
|
|
124
|
+
o.extra === 'phoneNumber'
|
|
125
|
+
? { phoneNumber: e.target.value }
|
|
126
|
+
: { cashtag: e.target.value }
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
/>
|
|
130
|
+
</Field>
|
|
131
|
+
)}
|
|
132
|
+
</div>
|
|
133
|
+
)}
|
|
134
|
+
</label>
|
|
135
|
+
)
|
|
136
|
+
})}
|
|
137
|
+
</div>
|
|
138
|
+
)
|
|
139
|
+
}
|
package/src/ui/TimerBanner.tsx
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import React, { useState, type FC } from 'react'
|
|
8
8
|
|
|
9
9
|
import { cx } from './cx'
|
|
10
|
+
import { useT } from './I18nProvider'
|
|
10
11
|
|
|
11
12
|
const clock = (s: number) => {
|
|
12
13
|
const m = String(Math.floor(s / 60)).padStart(2, '0')
|
|
@@ -25,9 +26,10 @@ export interface TimerBannerProps {
|
|
|
25
26
|
export const TimerBanner: FC<TimerBannerProps> = ({
|
|
26
27
|
seconds,
|
|
27
28
|
urgentAt = 60,
|
|
28
|
-
message
|
|
29
|
+
message,
|
|
29
30
|
className,
|
|
30
31
|
}) => {
|
|
32
|
+
const t = useT()
|
|
31
33
|
const [dismissed, setDismissed] = useState(false)
|
|
32
34
|
if (seconds === undefined || seconds <= 0 || dismissed) return null
|
|
33
35
|
const urgent = seconds <= urgentAt
|
|
@@ -40,12 +42,14 @@ export const TimerBanner: FC<TimerBannerProps> = ({
|
|
|
40
42
|
className
|
|
41
43
|
)}
|
|
42
44
|
>
|
|
43
|
-
<span className="tf-checkout-timerbanner__msg">
|
|
45
|
+
<span className="tf-checkout-timerbanner__msg">
|
|
46
|
+
{message ?? t('timer.completePurchase')}
|
|
47
|
+
</span>
|
|
44
48
|
<span className="tf-checkout-timerbanner__clock">{clock(seconds)}</span>
|
|
45
49
|
<button
|
|
46
50
|
type="button"
|
|
47
51
|
className="tf-checkout-timerbanner__close"
|
|
48
|
-
aria-label=
|
|
52
|
+
aria-label={t('common.dismiss')}
|
|
49
53
|
onClick={() => setDismissed(true)}
|
|
50
54
|
>
|
|
51
55
|
×
|