payment-kit 1.19.4 → 1.19.6

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.
@@ -2,7 +2,8 @@
2
2
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
3
3
  import { formatPrice, Table, TruncatedText, useMobile } from '@blocklet/payment-react';
4
4
  import type { TPaymentCurrency, TSubscriptionItemExpanded } from '@blocklet/payment-types';
5
- import { Avatar, Stack, Typography } from '@mui/material';
5
+ import { Avatar, Stack, Typography, Box } from '@mui/material';
6
+ import { styled } from '@mui/system';
6
7
 
7
8
  import { Link } from 'react-router-dom';
8
9
  import Copyable from '../../copyable';
@@ -41,59 +42,74 @@ export default function SubscriptionItemList({ data, currency, mode = 'customer'
41
42
  sm: 2,
42
43
  },
43
44
  }}>
44
- {item.price.product.images.length > 0 ? (
45
- // @ts-ignore
46
- <Avatar
47
- key={item.price.product_id}
48
- src={item.price.product.images[0]}
49
- alt={item.price.product.name}
50
- variant="rounded"
51
- sx={size}
52
- />
53
- ) : (
54
- <Avatar key={item.price.product_id} variant="rounded" sx={size}>
55
- {item.price.product.name.slice(0, 1)}
56
- </Avatar>
57
- )}
58
- {isAdmin ? (
59
- <>
60
- <Typography
61
- sx={{
62
- color: 'text.primary',
63
- fontWeight: 600,
64
- }}>
65
- <Link to={`/admin/products/${item?.price.product_id}`}>
45
+ <Box order={isMobile ? 2 : 1}>
46
+ {item.price.product.images.length > 0 ? (
47
+ // @ts-ignore
48
+ <Avatar
49
+ key={item.price.product_id}
50
+ src={item.price.product.images[0]}
51
+ alt={item.price.product.name}
52
+ variant="rounded"
53
+ sx={size}
54
+ />
55
+ ) : (
56
+ <Avatar key={item.price.product_id} variant="rounded" sx={size}>
57
+ {item.price.product.name.slice(0, 1)}
58
+ </Avatar>
59
+ )}
60
+ </Box>
61
+ <Box order={isMobile ? 1 : 2}>
62
+ {isAdmin ? (
63
+ <>
64
+ <Typography
65
+ sx={{
66
+ color: 'text.primary',
67
+ fontWeight: 600,
68
+ }}>
69
+ <Link to={`/admin/products/${item?.price.product_id}`}>
70
+ <TruncatedText text={item?.price.product.name} maxLength={isMobile ? 20 : 50} useWidth />
71
+ </Link>
72
+ </Typography>
73
+ <Typography
74
+ sx={{
75
+ color: 'text.secondary',
76
+ whiteSpace: 'nowrap',
77
+ }}>
78
+ <Link to={`/admin/products/${item?.price.id}`}>
79
+ {formatPrice(item.price, currency, item?.price.product.unit_label)}
80
+ </Link>
81
+ </Typography>
82
+ </>
83
+ ) : (
84
+ <Box
85
+ sx={
86
+ isMobile
87
+ ? {
88
+ display: 'flex',
89
+ flexDirection: 'column',
90
+ alignItems: 'flex-end',
91
+ gap: 0.5,
92
+ flex: 1,
93
+ }
94
+ : {}
95
+ }>
96
+ <Typography
97
+ sx={{
98
+ color: 'text.primary',
99
+ fontWeight: 600,
100
+ }}>
66
101
  <TruncatedText text={item?.price.product.name} maxLength={isMobile ? 20 : 50} useWidth />
67
- </Link>
68
- </Typography>
69
- <Typography
70
- sx={{
71
- color: 'text.secondary',
72
- whiteSpace: 'nowrap',
73
- }}>
74
- <Link to={`/admin/products/${item?.price.id}`}>
102
+ </Typography>
103
+ <Typography
104
+ sx={{
105
+ color: 'text.secondary',
106
+ whiteSpace: 'nowrap',
107
+ }}>
75
108
  {formatPrice(item.price, currency, item?.price.product.unit_label)}
76
- </Link>
77
- </Typography>
78
- </>
79
- ) : (
80
- <>
81
- <Typography
82
- sx={{
83
- color: 'text.primary',
84
- fontWeight: 600,
85
- }}>
86
- <TruncatedText text={item?.price.product.name} maxLength={isMobile ? 20 : 50} useWidth />
87
- </Typography>
88
- <Typography
89
- sx={{
90
- color: 'text.secondary',
91
- whiteSpace: 'nowrap',
92
- }}>
93
- {formatPrice(item.price, currency, item?.price.product.unit_label)}
94
- </Typography>
95
- </>
96
- )}
109
+ </Typography>
110
+ </Box>
111
+ )}
112
+ </Box>
97
113
  </Stack>
98
114
  );
99
115
  },
@@ -153,22 +169,42 @@ export default function SubscriptionItemList({ data, currency, mode = 'customer'
153
169
  ].filter(Boolean);
154
170
 
155
171
  return (
156
- <Table
157
- data={data}
158
- columns={columns}
159
- loading={false}
160
- footer={false}
161
- toolbar={false}
162
- components={{
163
- TableToolbar: () => null,
164
- TableFooter: () => null,
165
- }}
166
- options={{
167
- count: data.length,
168
- page: 0,
169
- rowsPerPage: 100,
170
- }}
171
- emptyNodeText={t('customer.product.empty')}
172
- />
172
+ <InvoiceTableRoot>
173
+ <Table
174
+ data={data}
175
+ columns={columns}
176
+ loading={false}
177
+ footer={false}
178
+ toolbar={false}
179
+ components={{
180
+ TableToolbar: () => null,
181
+ TableFooter: () => null,
182
+ }}
183
+ mobileTDFlexDirection="row"
184
+ options={{
185
+ count: data.length,
186
+ page: 0,
187
+ rowsPerPage: 100,
188
+ }}
189
+ emptyNodeText={t('customer.product.empty')}
190
+ />
191
+ </InvoiceTableRoot>
173
192
  );
174
193
  }
194
+
195
+ const InvoiceTableRoot = styled(Box)`
196
+ @media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
197
+ .MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > td.MuiTableCell-root {
198
+ align-items: center;
199
+ padding: 4px 0;
200
+ > div {
201
+ width: fit-content;
202
+ flex: inherit;
203
+ font-size: 14px;
204
+ }
205
+ }
206
+ .invoice-summary {
207
+ padding-right: 20px;
208
+ }
209
+ }
210
+ `;
@@ -1,5 +1,5 @@
1
1
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
2
- import { api, formatBNStr, formatTime } from '@blocklet/payment-react';
2
+ import { api, formatBNStr, formatTime, useMobile } from '@blocklet/payment-react';
3
3
  import type { TSubscriptionExpanded, CreditGrantSummary } from '@blocklet/payment-types';
4
4
  import { useRequest } from 'ahooks';
5
5
 
@@ -41,6 +41,8 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
41
41
  const { data: upcoming, loading: upcomingLoading } = useRequest(() => fetchUpcoming(subscription.id));
42
42
  const navigate = useNavigate();
43
43
 
44
+ const { isMobile } = useMobile();
45
+
44
46
  const { data: payerValue, loading: payerLoading } = useRequest(() => fetchPayer(subscription.id), {
45
47
  ready: showBalance,
46
48
  });
@@ -83,9 +85,15 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
83
85
  <Button
84
86
  component="a"
85
87
  color="error"
88
+ sx={{
89
+ height: 24,
90
+ pt: 0,
91
+ pb: 0,
92
+ ...(isMobile ? { textAlign: 'right', maxWidth: 160 } : {}),
93
+ }}
86
94
  onClick={() => navigate(`/customer/subscription/${subscription.id}/recharge`)}>
87
95
  {t('admin.subscription.insufficientBalance')}
88
- <ArrowForward sx={{ fontSize: '14px' }} />
96
+ <ArrowForward sx={{ fontSize: 14 }} />
89
97
  </Button>
90
98
  );
91
99
  }
@@ -113,7 +121,7 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
113
121
  alignItems: 'baseline',
114
122
  }}>
115
123
  {formatBNStr(balance, subscription.paymentCurrency.decimal)}
116
- <Typography sx={{ fontSize: '14px', ml: 0.5 }}>{subscription.paymentCurrency.symbol}</Typography>
124
+ <Typography sx={{ fontSize: 14, ml: 0.5 }}>{subscription.paymentCurrency.symbol}</Typography>
117
125
  </Box>
118
126
  </Stack>
119
127
  );
@@ -136,6 +144,8 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
136
144
  display: 'flex',
137
145
  alignItems: 'center',
138
146
  gap: 0.5,
147
+ fontSize: 14,
148
+ fontWeight: 500,
139
149
  }}>
140
150
  {t('admin.subscription.nextInvoiceAmount')}
141
151
  <Tooltip title={t('admin.subscription.nextInvoiceAmountTip')} placement="top" arrow>
@@ -157,8 +167,11 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
157
167
  spacing={1}
158
168
  sx={{
159
169
  alignItems: 'center',
170
+ fontWeight: 500,
160
171
  }}>
161
- <Typography>{t('admin.subscription.currentBalance')}</Typography>
172
+ <Typography fontWeight={500} sx={{ fontSize: 14 }}>
173
+ {t('admin.subscription.currentBalance')}
174
+ </Typography>
162
175
  <Tooltip
163
176
  title={
164
177
  <Typography sx={{ fontFamily: 'monospace', fontSize: '13px' }}>
@@ -18,7 +18,7 @@ import {
18
18
  } from '@blocklet/payment-react';
19
19
  import type { TCheckoutSession, TInvoiceExpanded, TPaymentLink } from '@blocklet/payment-types';
20
20
  import { ArrowBackOutlined } from '@mui/icons-material';
21
- import { Alert, Box, Button, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
21
+ import { Alert, Box, Button, CircularProgress, Divider, Stack, Tooltip, Typography, useTheme } from '@mui/material';
22
22
  import { styled } from '@mui/system';
23
23
  import { useRequest, useSetState } from 'ahooks';
24
24
  import { useEffect } from 'react';
@@ -51,6 +51,7 @@ export default function CustomerInvoiceDetail() {
51
51
  const { isMobile } = useMobile();
52
52
  const { connect } = usePaymentContext();
53
53
  const params = useParams<{ id: string }>();
54
+ const muiTheme = useTheme();
54
55
  const [state, setState] = useSetState({
55
56
  downloading: false,
56
57
  paying: false,
@@ -179,8 +180,11 @@ export default function CustomerInvoiceDetail() {
179
180
  </Stack>
180
181
  <Box
181
182
  sx={{
182
- mt: 4,
183
+ mt: isMobile ? '0 !important' : 4,
183
184
  display: 'flex',
185
+ border: isMobile ? `1px solid ${muiTheme.palette.divider}` : 'none',
186
+ borderRadius: isMobile ? 1 : 0,
187
+ p: isMobile ? 2 : 0,
184
188
 
185
189
  gap: {
186
190
  xs: 2,
@@ -227,6 +231,9 @@ export default function CustomerInvoiceDetail() {
227
231
  'hr.MuiDivider-root:last-child': {
228
232
  display: 'none',
229
233
  },
234
+ '.info-metric-label': {
235
+ mb: isMobile ? 0.5 : 1,
236
+ },
230
237
 
231
238
  flexDirection: {
232
239
  xs: 'column',
@@ -288,7 +295,14 @@ export default function CustomerInvoiceDetail() {
288
295
  </Stack>
289
296
  </Box>
290
297
  <Divider />
291
- <Box className="section" sx={{ containerType: 'inline-size' }}>
298
+ <Box
299
+ className="section"
300
+ sx={{
301
+ containerType: 'inline-size',
302
+ border: isMobile ? (theme) => `1px solid ${theme.palette.divider}` : 'none',
303
+ borderRadius: isMobile ? 1 : 0,
304
+ p: isMobile ? 2 : 0,
305
+ }}>
292
306
  <Typography
293
307
  variant="h3"
294
308
  className="section-header"
@@ -300,6 +314,7 @@ export default function CustomerInvoiceDetail() {
300
314
  <InfoRowGroup
301
315
  sx={{
302
316
  display: 'grid',
317
+ columnGap: 16,
303
318
  gridTemplateColumns: {
304
319
  xs: 'repeat(1, 1fr)',
305
320
  lg: 'repeat(2, 1fr)',
@@ -308,7 +323,7 @@ export default function CustomerInvoiceDetail() {
308
323
  gridTemplateColumns: 'repeat(2, 1fr)',
309
324
  },
310
325
  '.info-row-wrapper': {
311
- gap: 1,
326
+ gap: isMobile ? 0.5 : 1,
312
327
  flexDirection: {
313
328
  xs: 'column',
314
329
  lg: 'row',
@@ -324,11 +339,17 @@ export default function CustomerInvoiceDetail() {
324
339
  },
325
340
  '.currency-name': {
326
341
  color: 'text.secondary',
342
+ fontSize: 14,
343
+ lineHeight: 1,
344
+ },
345
+ '.tx-link-text': {
346
+ fontSize: 14,
347
+ lineHeight: 1,
327
348
  },
328
349
  }}>
329
350
  <InfoRow
330
351
  label={t('admin.invoice.billTo')}
331
- value={<CustomerLink customer={data.customer} linked={false} size={isMobile ? 'default' : 'small'} />}
352
+ value={<CustomerLink customer={data.customer} linked={false} size="small" />}
332
353
  />
333
354
  <InfoRow label={t('admin.invoice.from')} value={data.statement_descriptor || blocklet.appName} />
334
355
  <InfoRow
@@ -30,6 +30,7 @@ import {
30
30
  Link as MuiLink,
31
31
  IconButton,
32
32
  Tooltip,
33
+ useTheme,
33
34
  } from '@mui/material';
34
35
  import { useRequest } from 'ahooks';
35
36
  import { Link, useNavigate, useParams } from 'react-router-dom';
@@ -86,6 +87,8 @@ export default function CustomerSubscriptionDetail() {
86
87
  ready: overdraftProtectionReady,
87
88
  });
88
89
 
90
+ const muiTheme = useTheme();
91
+
89
92
  const {
90
93
  data: cycleAmount = {
91
94
  amount: '0',
@@ -170,6 +173,9 @@ export default function CustomerSubscriptionDetail() {
170
173
  size="small"
171
174
  sx={{
172
175
  fontSize: '13px',
176
+ pt: 0,
177
+ pb: 0,
178
+ height: 3,
173
179
  color: 'text.link',
174
180
  '&:hover': { backgroundColor: 'primary.lighter' },
175
181
  }}
@@ -208,34 +214,32 @@ export default function CustomerSubscriptionDetail() {
208
214
  direction="row"
209
215
  sx={{
210
216
  alignItems: 'center',
217
+ flexWrap: 'wrap',
218
+ justifyContent: 'flex-end',
219
+ columnGap: 0.5,
211
220
  }}>
212
221
  <Stack
213
222
  direction="row"
214
- spacing={1}
223
+ spacing={0.5}
215
224
  sx={{
216
225
  alignItems: 'center',
217
226
  }}>
218
- <Stack
219
- direction="row"
220
- spacing={0.5}
227
+ <CheckCircle
221
228
  sx={{
222
- alignItems: 'center',
229
+ fontSize: '16px',
230
+ color: 'success.main',
231
+ verticalAlign: 'middle',
232
+ }}
233
+ />
234
+ <Typography
235
+ sx={{
236
+ color: 'success.main',
237
+ fontWeight: 500,
223
238
  }}>
224
- <CheckCircle
225
- sx={{
226
- fontSize: '16px',
227
- color: 'success.main',
228
- verticalAlign: 'middle',
229
- }}
230
- />
231
- <Typography
232
- sx={{
233
- color: 'success.main',
234
- fontWeight: 500,
235
- }}>
236
- {t('customer.overdraftProtection.enabled')}
237
- </Typography>
238
- </Stack>
239
+ {t('customer.overdraftProtection.enabled')}
240
+ </Typography>
241
+ </Stack>
242
+ {!isMobile && (
239
243
  <Divider
240
244
  orientation="vertical"
241
245
  flexItem
@@ -244,36 +248,32 @@ export default function CustomerSubscriptionDetail() {
244
248
  borderColor: 'divider',
245
249
  }}
246
250
  />
247
- <Typography
251
+ )}
252
+ <Typography
253
+ sx={{
254
+ color: 'text.primary',
255
+ display: 'flex',
256
+ alignItems: 'center',
257
+ gap: 0.5,
258
+ fontWeight: 500,
259
+ }}>
260
+ <Avatar src={data.paymentCurrency?.logo} sx={{ width: 16, height: 16 }} alt={data.paymentCurrency?.symbol} />
261
+ <Box
248
262
  sx={{
249
- color: 'text.primary',
250
263
  display: 'flex',
251
- alignItems: 'center',
252
- gap: 0.5,
253
- fontWeight: 500,
264
+ alignItems: 'baseline',
254
265
  }}>
255
- <Avatar
256
- src={data.paymentCurrency?.logo}
257
- sx={{ width: 16, height: 16 }}
258
- alt={data.paymentCurrency?.symbol}
259
- />
260
- <Box
266
+ {formatBNStr(overdraftProtection?.unused, data.paymentCurrency.decimal)}
267
+ <Typography
261
268
  sx={{
262
- display: 'flex',
263
- alignItems: 'baseline',
269
+ color: 'text.secondary',
270
+ fontSize: '14px',
271
+ ml: 0.5,
264
272
  }}>
265
- {formatBNStr(overdraftProtection?.unused, data.paymentCurrency.decimal)}
266
- <Typography
267
- sx={{
268
- color: 'text.secondary',
269
- fontSize: '14px',
270
- ml: 0.5,
271
- }}>
272
- {data.paymentCurrency.symbol}({formatEstimatedDuration(Math.ceil(remainingStake / estimateAmount))})
273
- </Typography>
274
- </Box>
275
- </Typography>
276
- </Stack>
273
+ {data.paymentCurrency.symbol}({formatEstimatedDuration(Math.ceil(remainingStake / estimateAmount))})
274
+ </Typography>
275
+ </Box>
276
+ </Typography>
277
277
  {data?.overdraft_protection?.enabled && (
278
278
  <Tooltip title={t('customer.overdraftProtection.setting')} placement="top">
279
279
  <IconButton
@@ -377,8 +377,11 @@ export default function CustomerSubscriptionDetail() {
377
377
  </Stack>
378
378
  <Box
379
379
  sx={{
380
- mt: 4,
380
+ mt: isMobile ? 2 : 4,
381
381
  display: 'flex',
382
+ border: isMobile ? `1px solid ${muiTheme.palette.divider}` : 'none',
383
+ borderRadius: isMobile ? 1 : 0,
384
+ p: isMobile ? 2 : 0,
382
385
 
383
386
  gap: {
384
387
  xs: 2,
@@ -421,6 +424,8 @@ export default function CustomerSubscriptionDetail() {
421
424
  sx={{
422
425
  justifyContent: 'flex-start',
423
426
  flexWrap: 'wrap',
427
+ flex: 1,
428
+ width: '100%',
424
429
 
425
430
  'hr.MuiDivider-root:last-child': {
426
431
  display: 'none',
@@ -450,7 +455,9 @@ export default function CustomerSubscriptionDetail() {
450
455
  sx={{
451
456
  alignItems: 'center',
452
457
  }}>
453
- <Typography component="span">{t('customer.overdraftProtection.title')}</Typography>
458
+ <Typography component="span" fontSize={14} fontWeight={500}>
459
+ {t('customer.overdraftProtection.title')}
460
+ </Typography>
454
461
  <MuiLink
455
462
  href="https://www.arcblock.io/content/blog/en/payment-kit-v117-sub-guard#listen-to-the-audio-overview"
456
463
  target="_blank"
@@ -517,8 +524,15 @@ export default function CustomerSubscriptionDetail() {
517
524
  </Stack>
518
525
  </Box>
519
526
  </Box>
520
- <Divider />
521
- <Box className="section" sx={{ containerType: 'inline-size' }}>
527
+ {!isMobile ? <Divider /> : null}
528
+ <Box
529
+ className="section"
530
+ sx={{
531
+ containerType: 'inline-size',
532
+ border: isMobile ? `1px solid ${muiTheme.palette.divider}` : 'none',
533
+ borderRadius: isMobile ? 1 : 0,
534
+ p: isMobile ? 2 : 0,
535
+ }}>
522
536
  <Typography
523
537
  variant="h3"
524
538
  className="section-header"
@@ -538,7 +552,7 @@ export default function CustomerSubscriptionDetail() {
538
552
  gridTemplateColumns: 'repeat(2, 1fr)',
539
553
  },
540
554
  '.info-row-wrapper': {
541
- gap: 1,
555
+ gap: isMobile ? 0.5 : 1,
542
556
  flexDirection: {
543
557
  xs: 'column',
544
558
  xl: 'row',
@@ -554,11 +568,17 @@ export default function CustomerSubscriptionDetail() {
554
568
  },
555
569
  '.currency-name': {
556
570
  color: 'text.secondary',
571
+ lineHeight: 1,
572
+ fontSize: 14,
573
+ },
574
+ '.tx-link-text': {
575
+ fontSize: 14,
576
+ lineHeight: 1,
557
577
  },
558
578
  }}>
559
579
  <InfoRow
560
580
  label={t('common.customer')}
561
- value={<CustomerLink customer={data.customer} linked={false} size={isMobile ? 'default' : 'small'} />}
581
+ value={<CustomerLink customer={data.customer} linked={false} size="small" />}
562
582
  />
563
583
  <InfoRow label={t('common.createdAt')} value={formatTime(data.created_at)} />
564
584
 
@@ -585,17 +605,17 @@ export default function CustomerSubscriptionDetail() {
585
605
 
586
606
  <InfoRow
587
607
  label={t('admin.paymentMethod._name')}
588
- value={<Currency logo={data.paymentMethod?.logo} name={data.paymentMethod?.name} />}
608
+ value={<Currency logo={data.paymentMethod?.logo} name={data.paymentMethod?.name} size={16} />}
589
609
  />
590
610
  <InfoRow
591
611
  label={t('admin.paymentCurrency.name')}
592
612
  value={
593
613
  <Stack direction="row" spacing={2}>
594
- <Currency logo={data.paymentCurrency.logo} name={data.paymentCurrency.symbol} />
614
+ <Currency logo={data.paymentCurrency.logo} name={data.paymentCurrency.symbol} size={16} />
595
615
  {canChangePaymentMethod(data) && (
596
616
  <Button
597
617
  variant="text"
598
- sx={{ color: 'text.link' }}
618
+ sx={{ color: 'text.link', fontSize: 14 }}
599
619
  size="small"
600
620
  onClick={async () => {
601
621
  // only check unpaid invoices when overdraft protection is enabled
@@ -617,7 +637,7 @@ export default function CustomerSubscriptionDetail() {
617
637
  {data.payment_details && hasDelegateTxHash(data.payment_details, data.paymentMethod) && (
618
638
  <InfoRow
619
639
  label={t('common.delegateTxHash')}
620
- value={<TxLink details={data.payment_details} method={data.paymentMethod} />}
640
+ value={<TxLink details={data.payment_details} method={data.paymentMethod} size={16} />}
621
641
  />
622
642
  )}
623
643
  {data.paymentMethod?.type === 'arcblock' && data.payment_details?.arcblock?.staking?.tx_hash && (
@@ -633,6 +653,7 @@ export default function CustomerSubscriptionDetail() {
633
653
  <TxLink
634
654
  details={{ arcblock: { tx_hash: data.payment_details?.arcblock?.staking?.tx_hash, payer: '' } }}
635
655
  method={data.paymentMethod}
656
+ size={16}
636
657
  />
637
658
  </Box>
638
659
  }