@blocklet/payment-react 1.18.6 → 1.18.8
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/README.md +394 -341
- package/es/checkout/donate.d.ts +29 -4
- package/es/checkout/donate.js +193 -95
- package/es/components/livemode.js +1 -1
- package/es/components/loading-button.d.ts +10 -0
- package/es/components/loading-button.js +75 -0
- package/es/components/pricing-table.js +2 -3
- package/es/components/table.js +1 -1
- package/es/index.d.ts +2 -1
- package/es/index.js +3 -1
- package/es/libs/util.d.ts +1 -0
- package/es/libs/util.js +10 -1
- package/es/payment/amount.js +1 -1
- package/es/payment/form/index.js +14 -12
- package/es/payment/form/stripe/form.js +20 -5
- package/es/payment/index.js +0 -1
- package/es/payment/product-card.js +2 -2
- package/es/payment/product-item.js +1 -1
- package/es/payment/product-skeleton.js +2 -2
- package/es/payment/skeleton/donation.js +1 -1
- package/es/payment/skeleton/overview.js +1 -1
- package/es/payment/skeleton/payment.js +1 -1
- package/es/payment/summary.js +2 -2
- package/es/theme/index.js +5 -3
- package/es/theme/typography.js +8 -8
- package/lib/checkout/donate.d.ts +29 -4
- package/lib/checkout/donate.js +197 -136
- package/lib/components/livemode.js +1 -1
- package/lib/components/loading-button.d.ts +10 -0
- package/lib/components/loading-button.js +86 -0
- package/lib/components/pricing-table.js +3 -4
- package/lib/components/table.js +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +8 -0
- package/lib/libs/util.d.ts +1 -0
- package/lib/libs/util.js +7 -0
- package/lib/payment/amount.js +1 -1
- package/lib/payment/form/index.js +14 -15
- package/lib/payment/form/stripe/form.js +25 -6
- package/lib/payment/index.js +0 -1
- package/lib/payment/product-card.js +2 -2
- package/lib/payment/product-item.js +1 -1
- package/lib/payment/product-skeleton.js +2 -2
- package/lib/payment/skeleton/donation.js +1 -1
- package/lib/payment/skeleton/overview.js +1 -1
- package/lib/payment/skeleton/payment.js +1 -1
- package/lib/payment/summary.js +4 -4
- package/lib/theme/index.js +5 -3
- package/lib/theme/typography.js +8 -8
- package/package.json +8 -8
- package/src/checkout/donate.tsx +209 -128
- package/src/components/livemode.tsx +1 -1
- package/src/components/loading-button.tsx +100 -0
- package/src/components/pricing-table.tsx +3 -3
- package/src/components/table.tsx +1 -1
- package/src/index.ts +2 -0
- package/src/libs/util.ts +11 -1
- package/src/payment/amount.tsx +1 -1
- package/src/payment/form/index.tsx +65 -60
- package/src/payment/form/stripe/form.tsx +21 -6
- package/src/payment/index.tsx +0 -1
- package/src/payment/product-card.tsx +2 -2
- package/src/payment/product-item.tsx +1 -1
- package/src/payment/product-skeleton.tsx +2 -2
- package/src/payment/skeleton/donation.tsx +1 -1
- package/src/payment/skeleton/overview.tsx +1 -1
- package/src/payment/skeleton/payment.tsx +1 -1
- package/src/payment/summary.tsx +2 -2
- package/src/theme/index.tsx +3 -1
- package/src/theme/typography.ts +8 -8
package/src/checkout/donate.tsx
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
/* eslint-disable react/no-unused-prop-types */
|
|
1
2
|
/* eslint-disable react/require-default-props */
|
|
2
3
|
/* eslint-disable @typescript-eslint/indent */
|
|
3
4
|
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
4
5
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
5
6
|
import type {
|
|
6
7
|
DonationSettings,
|
|
8
|
+
PaymentBeneficiary,
|
|
7
9
|
PaymentDetails,
|
|
8
10
|
TCheckoutSessionExpanded,
|
|
9
11
|
TPaymentCurrency,
|
|
@@ -12,20 +14,14 @@ import type {
|
|
|
12
14
|
TSetting,
|
|
13
15
|
} from '@blocklet/payment-types';
|
|
14
16
|
import {
|
|
15
|
-
Alert,
|
|
16
17
|
Avatar,
|
|
17
18
|
AvatarGroup,
|
|
18
19
|
Box,
|
|
19
20
|
Button,
|
|
20
21
|
CircularProgress,
|
|
21
|
-
Hidden,
|
|
22
22
|
IconButton,
|
|
23
23
|
Popover,
|
|
24
24
|
Stack,
|
|
25
|
-
Table,
|
|
26
|
-
TableBody,
|
|
27
|
-
TableCell,
|
|
28
|
-
TableRow,
|
|
29
25
|
Typography,
|
|
30
26
|
Tooltip,
|
|
31
27
|
type ButtonProps as MUIButtonProps,
|
|
@@ -36,14 +32,13 @@ import uniqBy from 'lodash/unionBy';
|
|
|
36
32
|
import { useEffect, useRef, useState } from 'react';
|
|
37
33
|
import { Settings } from '@mui/icons-material';
|
|
38
34
|
|
|
39
|
-
import TxLink from '../components/blockchain/tx';
|
|
40
35
|
import api from '../libs/api';
|
|
41
36
|
import {
|
|
42
37
|
formatAmount,
|
|
43
38
|
formatBNStr,
|
|
44
|
-
formatDateTime,
|
|
45
|
-
formatError,
|
|
46
39
|
getCustomerAvatar,
|
|
40
|
+
getTxLink,
|
|
41
|
+
getUserProfileLink,
|
|
47
42
|
lazyLoad,
|
|
48
43
|
openDonationSettings,
|
|
49
44
|
} from '../libs/util';
|
|
@@ -59,22 +54,43 @@ export type DonateHistory = {
|
|
|
59
54
|
supporters: TCheckoutSessionExpanded[];
|
|
60
55
|
currency: TPaymentCurrency;
|
|
61
56
|
method: TPaymentMethod;
|
|
62
|
-
|
|
57
|
+
total?: number;
|
|
63
58
|
totalAmount: string;
|
|
64
59
|
};
|
|
65
|
-
export type RequiredDonationSettings = Pick<
|
|
66
|
-
DonationSettings,
|
|
67
|
-
'target' | 'title' | 'description' | 'reference' | 'beneficiaries'
|
|
68
|
-
>;
|
|
69
|
-
type OptionalDonationSettings = Partial<Omit<DonationSettings, keyof RequiredDonationSettings>>;
|
|
70
60
|
|
|
61
|
+
export type CheckoutDonateSettings = {
|
|
62
|
+
target: string;
|
|
63
|
+
title: string;
|
|
64
|
+
description: string;
|
|
65
|
+
reference: string;
|
|
66
|
+
beneficiaries: PaymentBeneficiary[];
|
|
67
|
+
amount?: {
|
|
68
|
+
presets?: string[];
|
|
69
|
+
preset?: string;
|
|
70
|
+
minimum?: string;
|
|
71
|
+
maximum?: string;
|
|
72
|
+
custom?: boolean;
|
|
73
|
+
};
|
|
74
|
+
appearance?: {
|
|
75
|
+
button?: {
|
|
76
|
+
text?: any;
|
|
77
|
+
icon?: any;
|
|
78
|
+
size?: string;
|
|
79
|
+
color?: string;
|
|
80
|
+
variant?: string;
|
|
81
|
+
};
|
|
82
|
+
history?: {
|
|
83
|
+
variant?: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
71
87
|
export interface ButtonType extends Omit<MUIButtonProps, 'text' | 'icon'> {
|
|
72
88
|
text?: string | React.ReactNode;
|
|
73
89
|
icon: React.ReactNode;
|
|
74
90
|
}
|
|
75
91
|
|
|
76
92
|
export type DonateProps = Pick<CheckoutProps, 'onPaid' | 'onError'> & {
|
|
77
|
-
settings:
|
|
93
|
+
settings: CheckoutDonateSettings;
|
|
78
94
|
livemode?: boolean;
|
|
79
95
|
timeout?: number;
|
|
80
96
|
mode?: 'inline' | 'default' | 'custom';
|
|
@@ -129,124 +145,174 @@ const emojiFont = {
|
|
|
129
145
|
'Avenir, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
|
|
130
146
|
};
|
|
131
147
|
|
|
148
|
+
function DonateDetails({ supporters = [], currency, method }: DonateHistory) {
|
|
149
|
+
const { locale } = useLocaleContext();
|
|
150
|
+
return (
|
|
151
|
+
<Stack
|
|
152
|
+
sx={{
|
|
153
|
+
width: '100%',
|
|
154
|
+
minWidth: '256px',
|
|
155
|
+
maxWidth: 'calc(100vw - 32px)',
|
|
156
|
+
maxHeight: '300px',
|
|
157
|
+
overflowX: 'hidden',
|
|
158
|
+
overflowY: 'auto',
|
|
159
|
+
margin: '0 auto',
|
|
160
|
+
}}>
|
|
161
|
+
{supporters.map((x) => (
|
|
162
|
+
<Box
|
|
163
|
+
key={x.id}
|
|
164
|
+
sx={{
|
|
165
|
+
padding: '6px',
|
|
166
|
+
'&:hover': {
|
|
167
|
+
backgroundColor: 'var(--backgrounds-bg-highlight, #eff6ff)',
|
|
168
|
+
transition: 'background-color 200ms linear',
|
|
169
|
+
cursor: 'pointer',
|
|
170
|
+
},
|
|
171
|
+
borderBottom: '1px solid var(--stroke-border-base, #EFF1F5)',
|
|
172
|
+
display: 'flex',
|
|
173
|
+
justifyContent: 'space-between',
|
|
174
|
+
alignItems: 'center',
|
|
175
|
+
}}
|
|
176
|
+
onClick={() => {
|
|
177
|
+
const { link, text } = getTxLink(method, x.payment_details as PaymentDetails);
|
|
178
|
+
if (link && text) {
|
|
179
|
+
window.open(link, '_blank');
|
|
180
|
+
}
|
|
181
|
+
}}>
|
|
182
|
+
<Stack
|
|
183
|
+
direction="row"
|
|
184
|
+
alignItems="center"
|
|
185
|
+
spacing={0.5}
|
|
186
|
+
sx={{
|
|
187
|
+
flex: 3,
|
|
188
|
+
overflow: 'hidden',
|
|
189
|
+
}}>
|
|
190
|
+
<Avatar
|
|
191
|
+
key={x.id}
|
|
192
|
+
src={getCustomerAvatar(x.customer?.did, x?.updated_at ? new Date(x.updated_at).toISOString() : '', 20)}
|
|
193
|
+
alt={x.customer?.name}
|
|
194
|
+
variant="circular"
|
|
195
|
+
sx={{ width: 20, height: 20 }}
|
|
196
|
+
onClick={(e) => {
|
|
197
|
+
e.stopPropagation();
|
|
198
|
+
if (x.customer?.did) {
|
|
199
|
+
window.open(getUserProfileLink(x.customer?.did, locale), '_blank');
|
|
200
|
+
}
|
|
201
|
+
}}
|
|
202
|
+
/>
|
|
203
|
+
<Typography
|
|
204
|
+
sx={{
|
|
205
|
+
ml: '8px !important',
|
|
206
|
+
fontSize: '0.875rem',
|
|
207
|
+
fontWeight: '500',
|
|
208
|
+
overflow: 'hidden',
|
|
209
|
+
whiteSpace: 'nowrap',
|
|
210
|
+
textOverflow: 'ellipsis',
|
|
211
|
+
}}
|
|
212
|
+
onClick={(e) => {
|
|
213
|
+
e.stopPropagation();
|
|
214
|
+
if (x.customer?.did) {
|
|
215
|
+
window.open(getUserProfileLink(x.customer?.did, locale), '_blank');
|
|
216
|
+
}
|
|
217
|
+
}}>
|
|
218
|
+
{x.customer?.name}
|
|
219
|
+
</Typography>
|
|
220
|
+
</Stack>
|
|
221
|
+
<Stack direction="row" alignItems="center" justifyContent="flex-end" spacing={0.5} sx={{ flex: 1 }}>
|
|
222
|
+
<Avatar
|
|
223
|
+
key={x.id}
|
|
224
|
+
src={currency?.logo}
|
|
225
|
+
alt={currency?.symbol}
|
|
226
|
+
variant="circular"
|
|
227
|
+
sx={{ width: 16, height: 16 }}
|
|
228
|
+
/>
|
|
229
|
+
<Typography sx={{ color: 'text.secondary' }}>{formatBNStr(x.amount_total, currency.decimal)}</Typography>
|
|
230
|
+
<Typography sx={{ color: 'text.secondary' }}>{currency.symbol}</Typography>
|
|
231
|
+
</Stack>
|
|
232
|
+
</Box>
|
|
233
|
+
))}
|
|
234
|
+
</Stack>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
132
238
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
133
|
-
function SupporterAvatar({
|
|
134
|
-
|
|
239
|
+
function SupporterAvatar({
|
|
240
|
+
supporters = [],
|
|
241
|
+
totalAmount = '0',
|
|
242
|
+
currency,
|
|
243
|
+
method,
|
|
244
|
+
showDonateDetails = false,
|
|
245
|
+
}: DonateHistory & { showDonateDetails?: boolean }) {
|
|
246
|
+
const [open, setOpen] = useState(false);
|
|
135
247
|
const customers = uniqBy(supporters, 'customer_did');
|
|
136
248
|
const customersNum = customers.length;
|
|
249
|
+
if (customersNum === 0) return null;
|
|
137
250
|
return (
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
alignItems="center"
|
|
142
|
-
sx={{
|
|
143
|
-
'.MuiAvatar-root': {
|
|
144
|
-
width: '32px',
|
|
145
|
-
height: '32px',
|
|
146
|
-
},
|
|
147
|
-
}}
|
|
148
|
-
gap={{
|
|
149
|
-
xs: 0.5,
|
|
150
|
-
sm: 1,
|
|
151
|
-
}}>
|
|
152
|
-
<Typography component="p" color="text.secondary">
|
|
153
|
-
{customersNum === 0 ? (
|
|
154
|
-
<span style={emojiFont}>{t('payment.checkout.donation.empty')}</span>
|
|
155
|
-
) : (
|
|
156
|
-
t('payment.checkout.donation.summary', {
|
|
157
|
-
total: customersNum,
|
|
158
|
-
symbol: currency.symbol,
|
|
159
|
-
totalAmount: formatAmount(totalAmount || '0', currency.decimal),
|
|
160
|
-
})
|
|
161
|
-
)}
|
|
162
|
-
</Typography>
|
|
163
|
-
<AvatarGroup total={customersNum} max={20}>
|
|
164
|
-
{customers.map((x) => (
|
|
251
|
+
<Stack flexDirection="row" justifyContent="center" alignItems="center">
|
|
252
|
+
<AvatarGroup max={5}>
|
|
253
|
+
{customers.slice(0, 5).map((supporter) => (
|
|
165
254
|
<Avatar
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
255
|
+
src={getCustomerAvatar(
|
|
256
|
+
supporter.customer?.did,
|
|
257
|
+
supporter?.updated_at ? new Date(supporter.updated_at).toISOString() : '',
|
|
258
|
+
24
|
|
259
|
+
)}
|
|
260
|
+
alt={supporter.customer?.name}
|
|
261
|
+
key={supporter.customer?.id}
|
|
262
|
+
sx={{
|
|
263
|
+
width: '24px',
|
|
264
|
+
height: '24px',
|
|
265
|
+
}}
|
|
172
266
|
/>
|
|
173
267
|
))}
|
|
174
268
|
</AvatarGroup>
|
|
175
|
-
|
|
269
|
+
<Box
|
|
270
|
+
sx={{
|
|
271
|
+
fontSize: '14px',
|
|
272
|
+
color: 'text.secondary',
|
|
273
|
+
pl: 1.5,
|
|
274
|
+
pr: 1,
|
|
275
|
+
ml: -1,
|
|
276
|
+
borderRadius: '8px',
|
|
277
|
+
backgroundColor: '#f4f4f5',
|
|
278
|
+
height: '24px',
|
|
279
|
+
...(showDonateDetails
|
|
280
|
+
? {
|
|
281
|
+
cursor: 'pointer',
|
|
282
|
+
'&:hover': {
|
|
283
|
+
backgroundColor: '#e5e7eb',
|
|
284
|
+
},
|
|
285
|
+
}
|
|
286
|
+
: {}),
|
|
287
|
+
}}
|
|
288
|
+
onClick={() => showDonateDetails && setOpen(true)}>
|
|
289
|
+
{`${customersNum} supporter${customersNum > 1 ? 's' : ''} (${formatAmount(totalAmount || '0', currency?.decimal)} ${currency.symbol})`}
|
|
290
|
+
</Box>
|
|
291
|
+
<Dialog
|
|
292
|
+
open={open}
|
|
293
|
+
onClose={() => setOpen(false)}
|
|
294
|
+
sx={{
|
|
295
|
+
'.MuiDialogContent-root': {
|
|
296
|
+
width: '450px',
|
|
297
|
+
padding: '8px',
|
|
298
|
+
},
|
|
299
|
+
}}
|
|
300
|
+
title={`${customersNum} supporter${customersNum > 1 ? 's' : ''}`}>
|
|
301
|
+
<DonateDetails supporters={supporters} currency={currency} method={method} totalAmount={totalAmount} />
|
|
302
|
+
</Dialog>
|
|
303
|
+
</Stack>
|
|
176
304
|
);
|
|
177
305
|
}
|
|
178
306
|
|
|
179
307
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
180
308
|
function SupporterTable({ supporters = [], totalAmount = '0', currency, method }: DonateHistory) {
|
|
181
|
-
const { t } = useLocaleContext();
|
|
182
309
|
const customers = uniqBy(supporters, 'customer_did');
|
|
183
310
|
const customersNum = customers.length;
|
|
311
|
+
if (customersNum === 0) return null;
|
|
184
312
|
return (
|
|
185
313
|
<Box display="flex" flexDirection="column" alignItems="center" gap={{ xs: 0.5, sm: 1 }}>
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
<span style={emojiFont}>{t('payment.checkout.donation.empty')}</span>
|
|
189
|
-
) : (
|
|
190
|
-
t('payment.checkout.donation.summary', {
|
|
191
|
-
total: customersNum,
|
|
192
|
-
symbol: currency.symbol,
|
|
193
|
-
totalAmount: formatAmount(totalAmount || '0', currency.decimal),
|
|
194
|
-
})
|
|
195
|
-
)}
|
|
196
|
-
</Typography>
|
|
197
|
-
<Table size="small" sx={{ width: '100%', overflow: 'hidden' }}>
|
|
198
|
-
<TableBody>
|
|
199
|
-
{supporters.map((x) => (
|
|
200
|
-
<TableRow
|
|
201
|
-
key={x.id}
|
|
202
|
-
sx={{
|
|
203
|
-
'> td': {
|
|
204
|
-
padding: '8px 16px 8px 0',
|
|
205
|
-
borderTop: '1px solid #e0e0e0',
|
|
206
|
-
borderBottom: '1px solid #e0e0e0',
|
|
207
|
-
},
|
|
208
|
-
'> td:last-of-type': {
|
|
209
|
-
paddingRight: '0',
|
|
210
|
-
},
|
|
211
|
-
}}>
|
|
212
|
-
<TableCell>
|
|
213
|
-
<Stack direction="row" alignItems="center" spacing={0.5}>
|
|
214
|
-
<Avatar
|
|
215
|
-
key={x.id}
|
|
216
|
-
src={getCustomerAvatar(
|
|
217
|
-
x.customer?.did,
|
|
218
|
-
x?.updated_at ? new Date(x.updated_at).toISOString() : '',
|
|
219
|
-
48
|
|
220
|
-
)}
|
|
221
|
-
alt={x.customer?.name}
|
|
222
|
-
variant="circular"
|
|
223
|
-
sx={{ width: 24, height: 24 }}
|
|
224
|
-
/>
|
|
225
|
-
<Hidden smDown>
|
|
226
|
-
<Typography>{x.customer?.name}</Typography>
|
|
227
|
-
</Hidden>
|
|
228
|
-
</Stack>
|
|
229
|
-
</TableCell>
|
|
230
|
-
<TableCell align="right">
|
|
231
|
-
<Stack direction="row" alignItems="center" justifyContent="flex-end" spacing={0.5}>
|
|
232
|
-
<Typography fontWeight={500} component="strong">
|
|
233
|
-
{formatBNStr(x.amount_total, currency.decimal)}
|
|
234
|
-
</Typography>
|
|
235
|
-
<Typography component="span">{currency.symbol}</Typography>
|
|
236
|
-
</Stack>
|
|
237
|
-
</TableCell>
|
|
238
|
-
<Hidden smDown>
|
|
239
|
-
<TableCell align="right">
|
|
240
|
-
<Typography>{formatDateTime(x.created_at)}</Typography>
|
|
241
|
-
</TableCell>
|
|
242
|
-
</Hidden>
|
|
243
|
-
<TableCell align="right">
|
|
244
|
-
<TxLink method={method} details={x.payment_details as PaymentDetails} mode="customer" align="right" />
|
|
245
|
-
</TableCell>
|
|
246
|
-
</TableRow>
|
|
247
|
-
))}
|
|
248
|
-
</TableBody>
|
|
249
|
-
</Table>
|
|
314
|
+
<SupporterAvatar supporters={supporters} totalAmount={totalAmount} currency={currency} method={method} />
|
|
315
|
+
<DonateDetails supporters={supporters} totalAmount={totalAmount} currency={currency} method={method} />
|
|
250
316
|
</Box>
|
|
251
317
|
);
|
|
252
318
|
}
|
|
@@ -300,11 +366,7 @@ const defaultDonateAmount = {
|
|
|
300
366
|
maximum: '100',
|
|
301
367
|
custom: true,
|
|
302
368
|
};
|
|
303
|
-
function useDonation(
|
|
304
|
-
settings: RequiredDonationSettings & OptionalDonationSettings,
|
|
305
|
-
livemode: boolean,
|
|
306
|
-
mode = 'default'
|
|
307
|
-
) {
|
|
369
|
+
function useDonation(settings: CheckoutDonateSettings, livemode: boolean, mode = 'default') {
|
|
308
370
|
const [state, setState] = useSetState({
|
|
309
371
|
open: false,
|
|
310
372
|
supporterLoaded: false,
|
|
@@ -425,7 +487,7 @@ function CheckoutDonateInner({
|
|
|
425
487
|
};
|
|
426
488
|
|
|
427
489
|
if (donation.error) {
|
|
428
|
-
return
|
|
490
|
+
return null;
|
|
429
491
|
}
|
|
430
492
|
|
|
431
493
|
const handlePopoverOpen = (event: any) => {
|
|
@@ -523,11 +585,29 @@ function CheckoutDonateInner({
|
|
|
523
585
|
<Button
|
|
524
586
|
size={(donateSettings.appearance?.button?.size || 'medium') as any}
|
|
525
587
|
color={(donateSettings.appearance?.button?.color || 'primary') as any}
|
|
526
|
-
variant={(donateSettings.appearance?.button?.variant || '
|
|
588
|
+
variant={(donateSettings.appearance?.button?.variant || 'outlined') as any}
|
|
589
|
+
sx={{
|
|
590
|
+
...(!donateSettings.appearance?.button?.variant
|
|
591
|
+
? {
|
|
592
|
+
color: 'var(--foregrounds-fg-base, #010714)',
|
|
593
|
+
borderColor: 'var(--stroke-button-secondary-border, #E5E7EB)',
|
|
594
|
+
'&:hover': {
|
|
595
|
+
backgroundColor: 'var(--buttons-button-neutral-hover, #F3F4F6)',
|
|
596
|
+
borderColor: 'var(--stroke-button-secondary-border, #E5E7EB)',
|
|
597
|
+
},
|
|
598
|
+
}
|
|
599
|
+
: {}),
|
|
600
|
+
// @ts-ignore
|
|
601
|
+
...(donateSettings.appearance?.button?.sx || {}),
|
|
602
|
+
}}
|
|
527
603
|
{...donateSettings.appearance?.button}
|
|
528
604
|
onClick={() => startDonate()}>
|
|
529
605
|
<Stack direction="row" alignItems="center" spacing={0.5}>
|
|
530
|
-
{donateSettings.appearance.button.icon
|
|
606
|
+
{donateSettings.appearance.button.icon && (
|
|
607
|
+
<Typography sx={{ mr: 0.5, display: 'inline-flex', alignItems: 'center' }}>
|
|
608
|
+
{donateSettings.appearance.button.icon}
|
|
609
|
+
</Typography>
|
|
610
|
+
)}
|
|
531
611
|
{typeof donateSettings.appearance.button.text === 'string' ? (
|
|
532
612
|
<Typography>{donateSettings.appearance.button.text}</Typography>
|
|
533
613
|
) : (
|
|
@@ -536,7 +616,7 @@ function CheckoutDonateInner({
|
|
|
536
616
|
</Stack>
|
|
537
617
|
</Button>
|
|
538
618
|
{supporters.data && donateSettings.appearance.history.variant === 'avatar' && (
|
|
539
|
-
<SupporterAvatar {...(supporters.data as DonateHistory)} />
|
|
619
|
+
<SupporterAvatar {...(supporters.data as DonateHistory)} showDonateDetails />
|
|
540
620
|
)}
|
|
541
621
|
{supporters.data && donateSettings.appearance.history.variant === 'table' && (
|
|
542
622
|
<SupporterTable {...(supporters.data as DonateHistory)} />
|
|
@@ -555,7 +635,7 @@ function CheckoutDonateInner({
|
|
|
555
635
|
`${formatAmount(
|
|
556
636
|
(supporters.data as DonateHistory)?.totalAmount || '0',
|
|
557
637
|
(supporters.data as DonateHistory)?.currency?.decimal
|
|
558
|
-
)} ${(supporters.data as DonateHistory)?.currency?.symbol}`,
|
|
638
|
+
)} ${(supporters.data as DonateHistory)?.currency?.symbol || ''}`,
|
|
559
639
|
(supporters.data as DonateHistory) || {},
|
|
560
640
|
!!supporters.loading,
|
|
561
641
|
donateSettings
|
|
@@ -563,7 +643,8 @@ function CheckoutDonateInner({
|
|
|
563
643
|
</>
|
|
564
644
|
) : (
|
|
565
645
|
<Typography>
|
|
566
|
-
Please provide a valid render function
|
|
646
|
+
Please provide a valid render function{' '}
|
|
647
|
+
<pre>{'(openDonate, donateTotalAmount, supporters, loading, donateSettings) => ReactNode'}</pre>
|
|
567
648
|
</Typography>
|
|
568
649
|
);
|
|
569
650
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
type ButtonProps,
|
|
4
|
+
CircularProgress,
|
|
5
|
+
type CircularProgressProps,
|
|
6
|
+
SxProps,
|
|
7
|
+
Theme,
|
|
8
|
+
Typography,
|
|
9
|
+
} from '@mui/material';
|
|
10
|
+
import { forwardRef } from 'react';
|
|
11
|
+
|
|
12
|
+
export interface LoadingButtonProps extends ButtonProps {
|
|
13
|
+
loading?: boolean;
|
|
14
|
+
loadingIndicator?: React.ReactNode;
|
|
15
|
+
loadingPosition?: 'start' | 'center' | 'end';
|
|
16
|
+
loadingProps?: Partial<CircularProgressProps>;
|
|
17
|
+
loadingOnly?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const LoadingButton = forwardRef<HTMLButtonElement, LoadingButtonProps>(
|
|
21
|
+
(
|
|
22
|
+
{
|
|
23
|
+
children,
|
|
24
|
+
loading,
|
|
25
|
+
loadingPosition = 'start',
|
|
26
|
+
loadingIndicator,
|
|
27
|
+
loadingProps = {},
|
|
28
|
+
onClick,
|
|
29
|
+
sx,
|
|
30
|
+
loadingOnly = false,
|
|
31
|
+
...props
|
|
32
|
+
},
|
|
33
|
+
ref
|
|
34
|
+
) => {
|
|
35
|
+
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
36
|
+
if (loading) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
onClick?.(e);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const getPositionStyles = (position: string) => {
|
|
43
|
+
return {
|
|
44
|
+
color: 'inherit',
|
|
45
|
+
...(position === 'start' && { mr: 1 }),
|
|
46
|
+
...(position === 'end' && { ml: 1 }),
|
|
47
|
+
...(position === 'center' && {
|
|
48
|
+
position: 'absolute',
|
|
49
|
+
left: '50%',
|
|
50
|
+
transform: 'translateY(-50%) translateX(-50%)',
|
|
51
|
+
top: '50%',
|
|
52
|
+
}),
|
|
53
|
+
display: 'inline-flex',
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
} as const;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const defaultIndicator = (
|
|
59
|
+
<CircularProgress size={16} {...loadingProps} sx={{ color: 'inherit', ...(loadingProps?.sx || {}) }} />
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const indicator = (
|
|
63
|
+
<Typography sx={getPositionStyles(loadingPosition) as SxProps<Theme>}>
|
|
64
|
+
{loadingIndicator || defaultIndicator}
|
|
65
|
+
</Typography>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Button
|
|
70
|
+
ref={ref}
|
|
71
|
+
disabled={props.disabled}
|
|
72
|
+
onClick={handleClick}
|
|
73
|
+
sx={{
|
|
74
|
+
position: 'relative',
|
|
75
|
+
display: 'inline-flex',
|
|
76
|
+
alignItems: 'center',
|
|
77
|
+
justifyContent: 'center',
|
|
78
|
+
...sx,
|
|
79
|
+
}}
|
|
80
|
+
{...props}>
|
|
81
|
+
{loading && loadingPosition === 'start' && indicator}
|
|
82
|
+
<Typography sx={{ visibility: loading && loadingOnly ? 'hidden' : 'visible' }}>{children}</Typography>
|
|
83
|
+
{loading && loadingPosition === 'center' && indicator}
|
|
84
|
+
{loading && loadingPosition === 'end' && indicator}
|
|
85
|
+
</Button>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
LoadingButton.displayName = 'LoadingButton';
|
|
91
|
+
|
|
92
|
+
LoadingButton.defaultProps = {
|
|
93
|
+
loading: false,
|
|
94
|
+
loadingIndicator: undefined,
|
|
95
|
+
loadingPosition: 'start',
|
|
96
|
+
loadingProps: {},
|
|
97
|
+
loadingOnly: false,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export default LoadingButton;
|
|
@@ -3,7 +3,6 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
|
3
3
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
4
|
import type { PriceCurrency, PriceRecurring, TPricingTableExpanded, TPricingTableItem } from '@blocklet/payment-types';
|
|
5
5
|
import { CheckOutlined } from '@mui/icons-material';
|
|
6
|
-
import { LoadingButton } from '@mui/lab';
|
|
7
6
|
import {
|
|
8
7
|
Avatar,
|
|
9
8
|
Box,
|
|
@@ -36,6 +35,7 @@ import {
|
|
|
36
35
|
} from '../libs/util';
|
|
37
36
|
import { useMobile } from '../hooks/mobile';
|
|
38
37
|
import TruncatedText from './truncated-text';
|
|
38
|
+
import LoadingButton from './loading-button';
|
|
39
39
|
|
|
40
40
|
type SortOrder = { [key: string]: number };
|
|
41
41
|
|
|
@@ -322,7 +322,6 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
322
322
|
justifyContent={alignItems === 'center' ? 'center' : 'flex-start'}
|
|
323
323
|
sx={{
|
|
324
324
|
flex: '0 1 auto',
|
|
325
|
-
overflow: 'auto',
|
|
326
325
|
pb: 2.5,
|
|
327
326
|
}}
|
|
328
327
|
className="price-table-wrap">
|
|
@@ -354,7 +353,8 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
354
353
|
'0px 0px 0px 1px rgba(3, 7, 18, 0.08), 0px 1px 2px -1px rgba(3, 7, 18, 0.08), 0px 2px 4px rgba(3, 7, 18, 0.04)',
|
|
355
354
|
'&:hover': {
|
|
356
355
|
borderColor: mode === 'select' && x.is_selected ? 'primary.main' : '#ddd',
|
|
357
|
-
boxShadow:
|
|
356
|
+
boxShadow:
|
|
357
|
+
'0px 0px 0px 1px var(--shadows-card-hover-1, rgba(2, 7, 19, 0.08)),0px 1px 2px -1px var(--shadows-card-hover-2, rgba(2, 7, 19, 0.08)),0px 2px 8px 0px var(--shadows-card-hover-3, rgba(2, 7, 19, 0.10))',
|
|
358
358
|
},
|
|
359
359
|
width: {
|
|
360
360
|
xs: '100%',
|
package/src/components/table.tsx
CHANGED
package/src/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import Link from './components/link';
|
|
|
30
30
|
import { createLazyComponent } from './components/lazy-loader';
|
|
31
31
|
import OverdueInvoicePayment from './components/over-due-invoice-payment';
|
|
32
32
|
import PaymentBeneficiaries from './components/payment-beneficiaries';
|
|
33
|
+
import LoadingButton from './components/loading-button';
|
|
33
34
|
|
|
34
35
|
export { PaymentThemeProvider } from './theme';
|
|
35
36
|
|
|
@@ -79,4 +80,5 @@ export {
|
|
|
79
80
|
Link,
|
|
80
81
|
OverdueInvoicePayment,
|
|
81
82
|
PaymentBeneficiaries,
|
|
83
|
+
LoadingButton,
|
|
82
84
|
};
|
package/src/libs/util.ts
CHANGED
|
@@ -22,7 +22,7 @@ import numbro from 'numbro';
|
|
|
22
22
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
23
23
|
import stringWidth from 'string-width';
|
|
24
24
|
import { defaultCountries } from 'react-international-phone';
|
|
25
|
-
import { joinURL } from 'ufo';
|
|
25
|
+
import { joinURL, withQuery } from 'ufo';
|
|
26
26
|
|
|
27
27
|
import { t } from '../locales';
|
|
28
28
|
import dayjs from './dayjs';
|
|
@@ -1184,3 +1184,13 @@ export function openDonationSettings(openInNewTab: boolean = false) {
|
|
|
1184
1184
|
window.open(`${window.location.origin}${mountPoint}/integrations/donations`, openInNewTab ? '_blank' : '_self');
|
|
1185
1185
|
}
|
|
1186
1186
|
}
|
|
1187
|
+
|
|
1188
|
+
export function getUserProfileLink(userDid: string, locale = 'en') {
|
|
1189
|
+
return joinURL(
|
|
1190
|
+
window.location.origin,
|
|
1191
|
+
withQuery('.well-known/service/user', {
|
|
1192
|
+
locale,
|
|
1193
|
+
did: userDid,
|
|
1194
|
+
})
|
|
1195
|
+
);
|
|
1196
|
+
}
|
package/src/payment/amount.tsx
CHANGED