payment-kit 1.14.21 → 1.14.23

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 (79) hide show
  1. package/blocklet.yml +1 -1
  2. package/package.json +19 -19
  3. package/src/app.tsx +13 -12
  4. package/src/components/balance-list.tsx +12 -2
  5. package/src/components/copyable.tsx +3 -2
  6. package/src/components/customer/edit.tsx +25 -21
  7. package/src/components/customer/form.tsx +18 -28
  8. package/src/components/customer/link.tsx +1 -2
  9. package/src/components/date-range-picker.tsx +21 -0
  10. package/src/components/drawer-form.tsx +27 -4
  11. package/src/components/event/list.tsx +3 -2
  12. package/src/components/filter-toolbar.tsx +11 -4
  13. package/src/components/info-card.tsx +4 -2
  14. package/src/components/info-metric.tsx +2 -2
  15. package/src/components/info-row.tsx +33 -26
  16. package/src/components/invoice/list.tsx +2 -2
  17. package/src/components/invoice/table.tsx +148 -85
  18. package/src/components/invoice-pdf/pdf.tsx +5 -1
  19. package/src/components/layout/admin.tsx +8 -2
  20. package/src/components/metadata/editor.tsx +25 -18
  21. package/src/components/metadata/form.tsx +83 -25
  22. package/src/components/metadata/list.tsx +22 -6
  23. package/src/components/payment-intent/list.tsx +3 -3
  24. package/src/components/payment-link/preview.tsx +42 -24
  25. package/src/components/payouts/list.tsx +2 -3
  26. package/src/components/price/form.tsx +28 -15
  27. package/src/components/price/upsell.tsx +1 -4
  28. package/src/components/pricing-table/preview.tsx +42 -23
  29. package/src/components/product/cross-sell-select.tsx +1 -1
  30. package/src/components/product/cross-sell.tsx +3 -4
  31. package/src/components/product/edit-price.tsx +0 -1
  32. package/src/components/refund/list.tsx +9 -4
  33. package/src/components/section/header.tsx +11 -4
  34. package/src/components/subscription/description.tsx +10 -6
  35. package/src/components/subscription/items/index.tsx +28 -6
  36. package/src/components/subscription/list.tsx +2 -2
  37. package/src/components/subscription/metrics.tsx +10 -8
  38. package/src/components/subscription/portal/actions.tsx +37 -11
  39. package/src/components/subscription/portal/list.tsx +131 -70
  40. package/src/components/subscription/status.tsx +9 -3
  41. package/src/global.css +1 -1
  42. package/src/hooks/mobile.ts +3 -3
  43. package/src/libs/util.ts +6 -2
  44. package/src/locales/en.tsx +37 -1
  45. package/src/locales/zh.tsx +37 -1
  46. package/src/pages/admin/billing/index.tsx +24 -4
  47. package/src/pages/admin/billing/invoices/detail.tsx +302 -147
  48. package/src/pages/admin/billing/subscriptions/detail.tsx +259 -134
  49. package/src/pages/admin/customers/customers/detail.tsx +358 -175
  50. package/src/pages/admin/customers/customers/index.tsx +8 -5
  51. package/src/pages/admin/customers/index.tsx +22 -5
  52. package/src/pages/admin/developers/webhooks/index.tsx +2 -2
  53. package/src/pages/admin/index.tsx +24 -10
  54. package/src/pages/admin/overview.tsx +1 -1
  55. package/src/pages/admin/payments/index.tsx +22 -7
  56. package/src/pages/admin/payments/intents/detail.tsx +263 -121
  57. package/src/pages/admin/payments/payouts/detail.tsx +235 -102
  58. package/src/pages/admin/payments/refunds/detail.tsx +286 -133
  59. package/src/pages/admin/products/index.tsx +28 -12
  60. package/src/pages/admin/products/links/create.tsx +16 -6
  61. package/src/pages/admin/products/links/detail.tsx +280 -176
  62. package/src/pages/admin/products/links/index.tsx +4 -7
  63. package/src/pages/admin/products/passports/index.tsx +6 -3
  64. package/src/pages/admin/products/prices/detail.tsx +260 -139
  65. package/src/pages/admin/products/prices/list.tsx +7 -3
  66. package/src/pages/admin/products/pricing-tables/create.tsx +17 -5
  67. package/src/pages/admin/products/pricing-tables/detail.tsx +221 -121
  68. package/src/pages/admin/products/pricing-tables/index.tsx +1 -2
  69. package/src/pages/admin/products/products/detail.tsx +262 -119
  70. package/src/pages/admin/products/products/index.tsx +1 -2
  71. package/src/pages/admin/settings/index.tsx +27 -7
  72. package/src/pages/customer/index.tsx +431 -143
  73. package/src/pages/customer/invoice/detail.tsx +138 -26
  74. package/src/pages/customer/refund/list.tsx +193 -4
  75. package/src/pages/customer/subscription/change-payment.tsx +20 -20
  76. package/src/pages/customer/subscription/detail.tsx +168 -34
  77. package/src/pages/customer/subscription/embed.tsx +22 -19
  78. package/src/pages/home.tsx +7 -1
  79. package/src/components/table.tsx +0 -93
@@ -13,14 +13,13 @@ import {
13
13
  getPayoutStatusColor,
14
14
  } from '@blocklet/payment-react';
15
15
  import type { TPayoutExpanded } from '@blocklet/payment-types';
16
- import { ArrowBackOutlined, Edit, InfoOutlined } from '@mui/icons-material';
17
- import { Alert, Box, Button, CircularProgress, Stack, Tooltip, Typography } from '@mui/material';
16
+ import { ArrowBackOutlined, InfoOutlined } from '@mui/icons-material';
17
+ import { Alert, Avatar, Box, Button, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
18
18
  import { styled } from '@mui/system';
19
19
  import { useRequest, useSetState } from 'ahooks';
20
20
  import { Link } from 'react-router-dom';
21
21
 
22
22
  import Copyable from '../../../../components/copyable';
23
- import Currency from '../../../../components/currency';
24
23
  import CustomerLink from '../../../../components/customer/link';
25
24
  import EventList from '../../../../components/event/list';
26
25
  import InfoMetric from '../../../../components/info-metric';
@@ -34,6 +33,9 @@ const fetchData = (id: string): Promise<TPayoutExpanded> => {
34
33
  return api.get(`/api/payouts/${id}`).then((res) => res.data);
35
34
  };
36
35
 
36
+ const InfoDirection = 'column';
37
+ const InfoAlignItems = 'flex-start';
38
+
37
39
  export default function PayoutDetail(props: { id: string }) {
38
40
  const { t } = useLocaleContext();
39
41
  const [state, setState] = useSetState({
@@ -80,6 +82,10 @@ export default function PayoutDetail(props: { id: string }) {
80
82
  const currency = data.paymentCurrency;
81
83
  const total = [formatBNStr(data?.amount, currency.decimal), currency.symbol].join(' ');
82
84
 
85
+ const handleEditMetadata = () => {
86
+ setState((prev) => ({ editing: { ...prev.editing, metadata: true } }));
87
+ };
88
+
83
89
  return (
84
90
  <Root direction="column" spacing={4} mb={4}>
85
91
  <Box>
@@ -94,120 +100,247 @@ export default function PayoutDetail(props: { id: string }) {
94
100
  {t('admin.payouts')}
95
101
  </Typography>
96
102
  </Stack>
97
- <Copyable text={props.id} style={{ marginLeft: 4 }} />
98
103
  </Stack>
99
- <Box mt={2}>
104
+ <Box
105
+ mt={4}
106
+ mb={3}
107
+ sx={{
108
+ display: 'flex',
109
+ gap: {
110
+ xs: 2,
111
+ sm: 2,
112
+ md: 5,
113
+ },
114
+ flexWrap: 'wrap',
115
+ flexDirection: {
116
+ xs: 'column',
117
+ sm: 'column',
118
+ md: 'row',
119
+ },
120
+ alignItems: {
121
+ xs: 'flex-start',
122
+ sm: 'flex-start',
123
+ md: 'center',
124
+ },
125
+ }}>
100
126
  <Stack direction="row" justifyContent="space-between" alignItems="center">
101
127
  <Stack direction="row" alignItems="center">
102
- <Amount amount={total} sx={{ my: 0, fontSize: '2rem', lineHeight: '1rem' }} />
103
- <Status label={data.status} color={getPayoutStatusColor(data.status)} sx={{ ml: 2 }} />
128
+ <Stack direction="row" alignItems="center" spacing={1}>
129
+ <Avatar
130
+ src={data.paymentCurrency.logo}
131
+ alt={data.paymentCurrency.symbol}
132
+ variant="square"
133
+ sx={{ width: '52px', height: '52px', borderRadius: 'var(--radius-s, 4px)' }}
134
+ />
135
+ <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
136
+ <Amount amount={total} sx={{ my: 0, fontSize: '2rem', lineHeight: '32px' }} />
137
+ <Copyable text={props.id} />
138
+ </Stack>
139
+ </Stack>
104
140
  </Stack>
105
141
  </Stack>
106
142
  <Stack
107
143
  className="section-body"
108
- direction="row"
109
- spacing={3}
110
144
  justifyContent="flex-start"
111
145
  flexWrap="wrap"
112
- sx={{ pt: 2, mt: 2, borderTop: '1px solid #eee' }}>
113
- <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider />
114
- <InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} divider />
146
+ sx={{
147
+ 'hr.MuiDivider-root:last-child': {
148
+ display: 'none',
149
+ },
150
+ flexDirection: {
151
+ xs: 'column',
152
+ sm: 'column',
153
+ md: 'row',
154
+ },
155
+ alignItems: {
156
+ xs: 'flex-start',
157
+ sm: 'flex-start',
158
+ md: 'center',
159
+ },
160
+ gap: {
161
+ xs: 1,
162
+ sm: 1,
163
+ md: 3,
164
+ },
165
+ }}>
166
+ <InfoMetric
167
+ label={t('common.status')}
168
+ value={<Status label={data.status} color={getPayoutStatusColor(data.status)} />}
169
+ divider
170
+ />
171
+ {/* <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider /> */}
172
+ {/* <InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} divider /> */}
115
173
  </Stack>
116
174
  </Box>
175
+ <Divider />
117
176
  </Box>
118
- <Box className="section">
119
- <SectionHeader title={t('admin.details')} />
120
- <Stack>
121
- <InfoRow label={t('common.amount')} value={total} />
122
- <InfoRow
123
- label={t('common.status')}
124
- value={
125
- <Stack direction="row" alignItems="center" spacing={1}>
126
- <Status label={data.status} color={getPayoutStatusColor(data.status)} />
127
- {data.last_attempt_error && (
128
- <Tooltip title={<pre>{JSON.stringify(data.last_attempt_error, null, 2)}</pre>}>
129
- <InfoOutlined fontSize="small" color="error" />
130
- </Tooltip>
131
- )}
132
- </Stack>
133
- }
134
- />
135
- <InfoRow label={t('common.description')} value={data.description} />
136
- <InfoRow label={t('common.createdAt')} value={formatTime(data.created_at)} />
137
- <InfoRow label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
138
- <InfoRow
139
- label={t('common.customer')}
140
- value={data.customer ? <CustomerLink customer={data.customer} /> : data.destination}
141
- />
142
- </Stack>
143
- </Box>
144
- <Box className="section">
145
- <SectionHeader title={t('admin.paymentMethod._name')} />
146
- <Stack>
147
- <InfoRow label={t('common.id')} value={data.paymentMethod.id} />
148
- <InfoRow label={t('admin.paymentMethod.type')} value={data.paymentMethod.type} />
149
- <InfoRow
150
- label={t('admin.paymentCurrency.name')}
151
- value={
152
- <Currency
153
- logo={data.paymentCurrency.logo}
154
- name={`${data.paymentCurrency.symbol} (${data.paymentMethod.name})`}
177
+ <Stack
178
+ sx={{
179
+ flexDirection: {
180
+ xs: 'column',
181
+ lg: 'row',
182
+ },
183
+ gap: 4,
184
+ '.payment-link-column-1': {
185
+ minWidth: {
186
+ xs: '100%',
187
+ lg: '600px',
188
+ },
189
+ },
190
+ '.payment-link-column-2': {
191
+ width: {
192
+ xs: '100%',
193
+ md: '100%',
194
+ lg: '580px',
195
+ },
196
+ maxWidth: {
197
+ xs: '100%',
198
+ md: '33%',
199
+ },
200
+ },
201
+ }}>
202
+ <Box flex={1} className="payment-link-column-1" sx={{ gap: 4, display: 'flex', flexDirection: 'column' }}>
203
+ <Box className="section">
204
+ <SectionHeader title={t('admin.details')} />
205
+ <Stack
206
+ sx={{
207
+ display: 'grid',
208
+ gridTemplateColumns: {
209
+ xs: 'repeat(1, 1fr)',
210
+ sm: 'repeat(1, 1fr)',
211
+ md: 'repeat(2, 1fr)',
212
+ lg: 'repeat(3, 1fr)',
213
+ },
214
+ }}>
215
+ <InfoRow label={t('common.amount')} value={total} direction={InfoDirection} alignItems={InfoAlignItems} />
216
+ <InfoRow
217
+ label={t('common.status')}
218
+ value={
219
+ <Stack direction="row" alignItems="center" spacing={1}>
220
+ <Status label={data.status} color={getPayoutStatusColor(data.status)} />
221
+ {data.last_attempt_error && (
222
+ <Tooltip title={<pre>{JSON.stringify(data.last_attempt_error, null, 2)}</pre>}>
223
+ <InfoOutlined fontSize="small" color="error" />
224
+ </Tooltip>
225
+ )}
226
+ </Stack>
227
+ }
228
+ direction={InfoDirection}
229
+ alignItems={InfoAlignItems}
155
230
  />
156
- }
157
- />
158
- {!!data.payment_details?.ethereum && (
159
- <InfoRow
160
- label={t('common.txGas')}
161
- value={<TxGas details={data.payment_details as any} method={data.paymentMethod} />}
162
- />
163
- )}
164
- <InfoRow
165
- label={t(`common.${data.payment_details?.arcblock?.type || 'transfer'}TxHash`)}
166
- value={<TxLink details={data.payment_details as any} method={data.paymentMethod} />}
167
- />
168
- </Stack>
169
- </Box>
170
- <Box className="section">
171
- <SectionHeader title={t('common.metadata.label')}>
172
- <Button
173
- variant="outlined"
174
- color="inherit"
175
- size="small"
176
- disabled={state.editing.metadata}
177
- onClick={() => setState((prev) => ({ editing: { ...prev.editing, metadata: true } }))}>
178
- <Edit fontSize="small" sx={{ mr: 0.5 }} />
179
- {t('common.metadata.edit')}
180
- </Button>
181
- </SectionHeader>
182
- <Box className="section-body">
183
- {!state.editing.metadata && <MetadataList data={data.metadata} />}
184
- {state.editing.metadata && (
185
- <MetadataEditor
186
- data={data}
187
- loading={state.loading.metadata}
188
- onSave={onUpdateMetadata}
189
- onCancel={() => setState((prev) => ({ editing: { ...prev.editing, metadata: false } }))}
190
- />
191
- )}
231
+ <InfoRow
232
+ label={t('common.description')}
233
+ value={data.description}
234
+ direction={InfoDirection}
235
+ alignItems={InfoAlignItems}
236
+ />
237
+ <InfoRow
238
+ label={t('common.createdAt')}
239
+ value={formatTime(data.created_at)}
240
+ direction={InfoDirection}
241
+ alignItems={InfoAlignItems}
242
+ />
243
+ <InfoRow
244
+ label={t('common.updatedAt')}
245
+ value={formatTime(data.updated_at)}
246
+ direction={InfoDirection}
247
+ alignItems={InfoAlignItems}
248
+ />
249
+ <InfoRow
250
+ label={t('common.customer')}
251
+ value={data.customer ? <CustomerLink customer={data.customer} /> : data.destination}
252
+ direction={InfoDirection}
253
+ alignItems={InfoAlignItems}
254
+ />
255
+ </Stack>
256
+ </Box>
257
+ <Divider />
258
+ <Box className="section">
259
+ <SectionHeader title={t('admin.events')} />
260
+ <Box className="section-body">
261
+ <EventList features={{ toolbar: false }} object_id={data.id} />
262
+ </Box>
263
+ </Box>
192
264
  </Box>
193
- </Box>
194
- <Box className="section">
195
- <SectionHeader title={t('admin.connections')} />
196
- <Stack>
197
- {data.payment_intent_id && (
198
- <InfoRow
199
- label={t('admin.paymentIntent.name')}
200
- value={<Link to={`/admin/payments/${data.paymentIntent.id}`}>{data.paymentIntent.id}</Link>}
201
- />
202
- )}
203
- </Stack>
204
- </Box>
205
- <Box className="section">
206
- <SectionHeader title={t('admin.events')} />
207
- <Box className="section-body">
208
- <EventList features={{ toolbar: false }} object_id={data.id} />
265
+ <Box className="payment-link-column-2" sx={{ gap: 3, display: 'flex', flexDirection: 'column' }}>
266
+ <Box className="section">
267
+ <SectionHeader title={t('admin.paymentMethod._name')} />
268
+ <Stack>
269
+ <InfoRow
270
+ label={t('common.id')}
271
+ value={data.paymentMethod?.id}
272
+ direction={InfoDirection}
273
+ alignItems={InfoAlignItems}
274
+ />
275
+ <InfoRow
276
+ label={t('admin.paymentMethod.type')}
277
+ value={data.paymentMethod?.type}
278
+ direction={InfoDirection}
279
+ alignItems={InfoAlignItems}
280
+ />
281
+ <InfoRow
282
+ label={t('admin.paymentCurrency.name')}
283
+ value={`${data.paymentCurrency.symbol} (${data.paymentMethod?.name})`}
284
+ direction={InfoDirection}
285
+ alignItems={InfoAlignItems}
286
+ />
287
+ {!!data.payment_details?.ethereum && (
288
+ <InfoRow
289
+ label={t('common.txGas')}
290
+ value={<TxGas details={data.payment_details as any} method={data.paymentMethod} />}
291
+ direction={InfoDirection}
292
+ alignItems={InfoAlignItems}
293
+ />
294
+ )}
295
+ <InfoRow
296
+ label={t(`common.${data.payment_details?.arcblock?.type || 'transfer'}TxHash`)}
297
+ value={<TxLink details={data.payment_details as any} method={data.paymentMethod} />}
298
+ direction={InfoDirection}
299
+ alignItems={InfoAlignItems}
300
+ />
301
+ </Stack>
302
+ </Box>
303
+ <Divider />
304
+ <Box className="section">
305
+ <SectionHeader title={t('admin.connections')} />
306
+ <Stack>
307
+ {data.payment_intent_id && (
308
+ <InfoRow
309
+ label={t('admin.paymentIntent.name')}
310
+ value={<Link to={`/admin/payments/${data.paymentIntent.id}`}>{data.paymentIntent.id}</Link>}
311
+ direction={InfoDirection}
312
+ alignItems={InfoAlignItems}
313
+ />
314
+ )}
315
+ </Stack>
316
+ </Box>
317
+ <Divider />
318
+ <Box className="section">
319
+ <SectionHeader title={t('common.metadata.label')}>
320
+ <Button
321
+ variant="text"
322
+ color="inherit"
323
+ size="small"
324
+ sx={{ color: 'text.link' }}
325
+ disabled={state.editing.metadata}
326
+ onClick={handleEditMetadata}>
327
+ {t('common.edit')}
328
+ </Button>
329
+ </SectionHeader>
330
+ <Box className="section-body">
331
+ <MetadataList data={data.metadata} handleEditMetadata={handleEditMetadata} />
332
+ {state.editing.metadata && (
333
+ <MetadataEditor
334
+ data={data}
335
+ loading={state.loading.metadata}
336
+ onSave={onUpdateMetadata}
337
+ onCancel={() => setState((prev) => ({ editing: { ...prev.editing, metadata: false } }))}
338
+ />
339
+ )}
340
+ </Box>
341
+ </Box>
209
342
  </Box>
210
- </Box>
343
+ </Stack>
211
344
  </Root>
212
345
  );
213
346
  }