payment-kit 1.18.37 → 1.18.39

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 (51) hide show
  1. package/api/src/integrations/stripe/handlers/invoice.ts +22 -0
  2. package/api/src/integrations/stripe/handlers/payment-intent.ts +9 -1
  3. package/api/src/integrations/stripe/handlers/subscription.ts +137 -1
  4. package/api/src/queues/payment.ts +4 -0
  5. package/api/src/routes/subscriptions.ts +24 -17
  6. package/blocklet.yml +1 -1
  7. package/package.json +20 -20
  8. package/src/app.tsx +124 -125
  9. package/src/components/chart.tsx +19 -5
  10. package/src/components/customer/notification-preference.tsx +6 -5
  11. package/src/components/date-range-picker.tsx +1 -16
  12. package/src/components/drawer-form.tsx +4 -3
  13. package/src/components/filter-toolbar.tsx +49 -34
  14. package/src/components/info-card.tsx +9 -7
  15. package/src/components/invoice-pdf/pdf.tsx +1 -1
  16. package/src/components/layout/admin.tsx +2 -2
  17. package/src/components/metadata/form.tsx +3 -2
  18. package/src/components/metadata/list.tsx +1 -1
  19. package/src/components/payment-link/chrome.tsx +0 -1
  20. package/src/components/payment-link/item.tsx +1 -1
  21. package/src/components/payment-link/preview.tsx +3 -1
  22. package/src/components/price/currency-select.tsx +1 -1
  23. package/src/components/pricing-table/payment-settings.tsx +1 -1
  24. package/src/components/pricing-table/preview.tsx +3 -1
  25. package/src/components/pricing-table/product-item.tsx +1 -1
  26. package/src/components/subscription/portal/actions.tsx +134 -24
  27. package/src/components/subscription/portal/list.tsx +3 -2
  28. package/src/components/uploader.tsx +2 -1
  29. package/src/components/webhook/attempts.tsx +1 -1
  30. package/src/global.css +0 -7
  31. package/src/pages/admin/developers/webhooks/detail.tsx +2 -2
  32. package/src/pages/admin/index.tsx +2 -2
  33. package/src/pages/admin/overview.tsx +1 -1
  34. package/src/pages/admin/payments/intents/detail.tsx +5 -2
  35. package/src/pages/admin/payments/payouts/detail.tsx +1 -1
  36. package/src/pages/admin/payments/refunds/detail.tsx +1 -1
  37. package/src/pages/admin/products/prices/list.tsx +7 -2
  38. package/src/pages/admin/products/pricing-tables/create.tsx +2 -2
  39. package/src/pages/admin/settings/payment-methods/index.tsx +7 -4
  40. package/src/pages/admin/settings/vault-config/index.tsx +3 -2
  41. package/src/pages/checkout/pricing-table.tsx +1 -1
  42. package/src/pages/customer/index.tsx +4 -3
  43. package/src/pages/customer/invoice/detail.tsx +1 -1
  44. package/src/pages/customer/payout/detail.tsx +1 -1
  45. package/src/pages/customer/recharge/account.tsx +3 -4
  46. package/src/pages/customer/recharge/subscription.tsx +3 -4
  47. package/src/pages/customer/subscription/detail.tsx +4 -1
  48. package/src/pages/customer/subscription/embed.tsx +2 -2
  49. package/src/pages/integrations/donations/preview.tsx +12 -10
  50. package/src/pages/integrations/index.tsx +1 -1
  51. package/src/pages/integrations/overview.tsx +2 -4
@@ -1,9 +1,11 @@
1
1
  import { forwardRef, useImperativeHandle, useRef } from 'react';
2
2
  import { useFullscreen, useSize } from 'ahooks';
3
3
  import IframeResizer from 'iframe-resizer-react';
4
+ import { useTheme } from '@mui/material';
4
5
  import Chrome from './chrome';
5
6
 
6
7
  const PaymentLinkPreview = forwardRef(({ id, version = 1 }: { id: string; version?: number }, ref) => {
8
+ const theme = useTheme();
7
9
  const innerRef = useRef(null);
8
10
  const size = useSize(innerRef);
9
11
  const scale = (size?.width || 0) / 1280;
@@ -18,7 +20,7 @@ const PaymentLinkPreview = forwardRef(({ id, version = 1 }: { id: string; versio
18
20
  return (
19
21
  <div ref={innerRef}>
20
22
  {fullscreen ? (
21
- <div style={{ width: '100%', height: '100%', background: '#fff' }}>
23
+ <div style={{ width: '100%', height: '100%', background: theme.palette.background.paper || '#fff' }}>
22
24
  <IframeResizer
23
25
  style={{ width: '100%', height: '100vh', overflow: 'hidden', border: 'none' }}
24
26
  src={`${window.blocklet.prefix}checkout/pay/${id}?preview=1&version=${version}`}
@@ -67,7 +67,7 @@ export default function CurrencySelect({
67
67
  }}
68
68
  sx={{ cursor: canSelect ? 'pointer' : 'default', display: 'inline-flex' }}>
69
69
  {selectedCurrency?.symbol} ({selectedPaymentMethod?.name})
70
- {canSelect && <ArrowDropDown sx={{ color: 'rgba(0, 0, 0, 0.54)', fontSize: 21 }} />}
70
+ {canSelect && <ArrowDropDown sx={{ color: 'text.secondary', fontSize: 21 }} />}
71
71
  </Typography>
72
72
  );
73
73
  }
@@ -227,7 +227,7 @@ export function ProductPaymentSettings({ product, prices }: { product: TProduct;
227
227
  });
228
228
 
229
229
  return (
230
- <Box sx={{ px: 2, py: 0, border: '1px solid #eee', borderRadius: 2 }}>
230
+ <Box sx={{ px: 2, py: 0, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
231
231
  <IconCollapse
232
232
  key={product.id}
233
233
  expanded
@@ -1,11 +1,13 @@
1
1
  import { forwardRef, useImperativeHandle, useRef } from 'react';
2
2
  import { useFullscreen, useSize } from 'ahooks';
3
3
  import IframeResizer from 'iframe-resizer-react';
4
+ import { useTheme } from '@mui/material';
4
5
  import Chrome from '../payment-link/chrome';
5
6
 
6
7
  const PricingTablePreview = forwardRef(({ id, version = 1 }: { id: string; version?: number }, ref) => {
7
8
  const innerRef = useRef(null);
8
9
  const size = useSize(innerRef);
10
+ const theme = useTheme();
9
11
  const scale = (size?.width || 0) / 1280;
10
12
  const [fullscreen, { toggleFullscreen }] = useFullscreen(innerRef);
11
13
 
@@ -18,7 +20,7 @@ const PricingTablePreview = forwardRef(({ id, version = 1 }: { id: string; versi
18
20
  return (
19
21
  <div ref={innerRef}>
20
22
  {fullscreen ? (
21
- <div style={{ width: '100%', height: '100%', background: '#fff' }}>
23
+ <div style={{ width: '100%', height: '100%', background: theme.palette.background.paper || '#fff' }}>
22
24
  <IframeResizer
23
25
  style={{ width: '100%', height: '100vh', overflow: 'hidden', border: 'none' }}
24
26
  src={`${window.blocklet.prefix}checkout/pricing-table/${id}?preview=1&version=${version}`}
@@ -46,7 +46,7 @@ export default function ProductItem({ product, prices, valid, onUpdate, onRemove
46
46
  p: 2,
47
47
  borderWidth: valid ? 1 : 2,
48
48
  borderStyle: 'solid',
49
- borderColor: valid ? '#eee' : 'error.main',
49
+ borderColor: valid ? 'grey.100' : 'error.main',
50
50
  borderRadius: 2,
51
51
  position: 'relative',
52
52
  }}>
@@ -10,15 +10,18 @@ import {
10
10
  getSubscriptionAction,
11
11
  usePaymentContext,
12
12
  OverdueInvoicePayment,
13
+ formatBNStr,
13
14
  } from '@blocklet/payment-react';
14
15
  import type { TSubscriptionExpanded } from '@blocklet/payment-types';
15
- import { Button, Link, Stack, Tooltip } from '@mui/material';
16
+ import { Button, Link, Stack, Tooltip, Typography, Box, Alert } from '@mui/material';
16
17
  import { useRequest, useSetState } from 'ahooks';
17
18
  import isEmpty from 'lodash/isEmpty';
18
- import { useEffect, useState } from 'react';
19
+ import { useEffect, useState, ReactNode } from 'react';
19
20
  import { FormProvider, useForm, useFormContext } from 'react-hook-form';
20
21
  import { useNavigate } from 'react-router-dom';
21
22
  import { joinURL } from 'ufo';
23
+ import { BN } from '@ocap/util';
24
+ import DID from '@arcblock/ux/lib/DID';
22
25
  import CustomerCancelForm from './cancel';
23
26
  import OverdraftProtectionDialog from '../../customer/overdraft-protection';
24
27
  import Actions from '../../actions';
@@ -28,7 +31,7 @@ import { isWillCanceled } from '../../../libs/util';
28
31
  interface ActionConfig {
29
32
  key: string;
30
33
  show: boolean;
31
- label: string;
34
+ label: string | ReactNode | (() => ReactNode);
32
35
  tooltip?: string;
33
36
  onClick: (e?: React.MouseEvent) => void;
34
37
  variant?: 'text' | 'outlined' | 'contained';
@@ -65,6 +68,7 @@ type Props = {
65
68
  subscription: TSubscriptionExpanded;
66
69
  showExtra?: boolean;
67
70
  showRecharge?: boolean;
71
+ showBalanceInfo?: boolean;
68
72
  showOverdraftProtection?:
69
73
  | boolean
70
74
  | {
@@ -82,6 +86,7 @@ type Props = {
82
86
  SubscriptionActions.defaultProps = {
83
87
  showExtra: false,
84
88
  showRecharge: false,
89
+ showBalanceInfo: false,
85
90
  showOverdraftProtection: false,
86
91
  showDelegation: false,
87
92
  onChange: null,
@@ -138,6 +143,7 @@ export function SubscriptionActionsInner({
138
143
  actionProps,
139
144
  mode,
140
145
  setUp,
146
+ showBalanceInfo,
141
147
  }: Props) {
142
148
  const { t, locale } = useLocaleContext();
143
149
  const { reset, getValues } = useFormContext();
@@ -149,6 +155,23 @@ export function SubscriptionActionsInner({
149
155
 
150
156
  const { data: extraActions } = useRequest(() => fetchExtraActions({ id: subscription.id, showExtra: !!showExtra }));
151
157
 
158
+ const { data: upcoming = {} } = useRequest(
159
+ () => api.get(`/api/subscriptions/${subscription.id}/upcoming`).then((res) => res.data),
160
+ {
161
+ ready: !!(showRecharge && supportRecharge(subscription)) && showBalanceInfo,
162
+ }
163
+ );
164
+
165
+ const { data: payerValue = {} } = useRequest(
166
+ () => api.get(`/api/subscriptions/${subscription.id}/payer-token`).then((res) => res.data),
167
+ {
168
+ ready: !!(showRecharge && supportRecharge(subscription)) && showBalanceInfo,
169
+ }
170
+ );
171
+
172
+ const isInsufficientBalance =
173
+ upcoming?.amount && payerValue?.token && new BN(payerValue.token || '0').lt(new BN(upcoming.amount || '0'));
174
+
152
175
  const [state, setState] = useSetState({
153
176
  action: '',
154
177
  subscription: '',
@@ -359,7 +382,73 @@ export function SubscriptionActionsInner({
359
382
  {
360
383
  key: 'recharge',
361
384
  show: !!(showRecharge && supportRecharge(subscription)),
362
- label: t('customer.recharge.title'),
385
+ label: () => {
386
+ const balanceDisplay = (
387
+ <Stack direction="row" spacing={0.5} alignItems="center">
388
+ {t('customer.recharge.title')}
389
+ </Stack>
390
+ );
391
+
392
+ if (showBalanceInfo && subscription.paymentCurrency) {
393
+ const formattedBalance = formatBNStr(payerValue?.token || '0', subscription.paymentCurrency.decimal);
394
+ const formattedUpcoming = formatBNStr(upcoming?.amount || '0', subscription.paymentCurrency.decimal);
395
+
396
+ return (
397
+ <Tooltip
398
+ componentsProps={{
399
+ tooltip: {
400
+ sx: {
401
+ bgcolor: 'background.paper',
402
+ color: 'text.primary',
403
+ boxShadow: 2,
404
+ padding: '10px 16px',
405
+ maxWidth: 480,
406
+ minWidth: 350,
407
+ wordBreak: 'break-word',
408
+ },
409
+ },
410
+ }}
411
+ title={
412
+ <Box>
413
+ {isInsufficientBalance && (
414
+ <Alert severity="error" sx={{ py: 0, mb: 1 }}>
415
+ {t('admin.subscription.insufficientBalance')}
416
+ </Alert>
417
+ )}
418
+ <Stack spacing={0.5}>
419
+ <Box display="flex" justifyContent="space-between">
420
+ <Typography sx={{ color: 'text.secondary' }}>
421
+ {t('admin.subscription.currentBalance')}
422
+ </Typography>
423
+ <Typography>
424
+ {formattedBalance} {subscription.paymentCurrency.symbol}
425
+ </Typography>
426
+ </Box>
427
+ <Box display="flex" justifyContent="space-between">
428
+ <Typography sx={{ color: 'text.secondary' }}>
429
+ {t('admin.subscription.nextInvoiceAmount')}
430
+ </Typography>
431
+ <Typography>
432
+ {formattedUpcoming} {subscription.paymentCurrency.symbol}
433
+ </Typography>
434
+ </Box>
435
+ <Box display="flex" justifyContent="space-between">
436
+ <Typography sx={{ color: 'text.secondary' }}>
437
+ {t('admin.subscription.paymentAddress')}
438
+ </Typography>
439
+ <DID did={payerValue?.paymentAddress} responsive={false} compact showAvatar={false} />
440
+ </Box>
441
+ </Stack>
442
+ </Box>
443
+ }
444
+ placement="top">
445
+ {balanceDisplay}
446
+ </Tooltip>
447
+ );
448
+ }
449
+
450
+ return balanceDisplay;
451
+ },
363
452
  onClick: (e) => {
364
453
  e?.stopPropagation();
365
454
  navigate(`/customer/subscription/${subscription.id}/recharge`);
@@ -367,6 +456,22 @@ export function SubscriptionActionsInner({
367
456
  variant: 'outlined',
368
457
  color: 'primary',
369
458
  primary: !isWillCanceled(subscription),
459
+ sx:
460
+ isInsufficientBalance || payerValue.token === '0'
461
+ ? {
462
+ '&::before': {
463
+ content: '""',
464
+ backgroundColor: 'error.main',
465
+ borderRadius: '50%',
466
+ position: 'absolute',
467
+ top: '-4px',
468
+ right: '-4px',
469
+ width: '8px',
470
+ height: '8px',
471
+ zIndex: 1,
472
+ },
473
+ }
474
+ : {},
370
475
  },
371
476
  {
372
477
  key: 'changePlan',
@@ -442,26 +547,30 @@ export function SubscriptionActionsInner({
442
547
  divider: item.divider,
443
548
  });
444
549
 
445
- const toButton = (item: ActionConfig) => (
446
- <Button
447
- key={item.key}
448
- variant={item.variant}
449
- color={item.color}
450
- onClick={item.onClick}
451
- component={item.component}
452
- href={item.href}
453
- target={item.target}
454
- sx={item.sx}
455
- size="small">
456
- {item.tooltip ? (
457
- <Tooltip title={item.tooltip}>
458
- <span>{item.label}</span>
459
- </Tooltip>
460
- ) : (
461
- item.label
462
- )}
463
- </Button>
464
- );
550
+ const toButton = (item: ActionConfig) => {
551
+ const labelContent = typeof item.label === 'function' ? item.label() : item.label;
552
+
553
+ return (
554
+ <Button
555
+ key={item.key}
556
+ variant={item.variant}
557
+ color={item.color}
558
+ onClick={item.onClick}
559
+ component={item.component}
560
+ href={item.href}
561
+ target={item.target}
562
+ sx={item.sx}
563
+ size="small">
564
+ {item.tooltip ? (
565
+ <Tooltip title={item.tooltip}>
566
+ <span>{labelContent}</span>
567
+ </Tooltip>
568
+ ) : (
569
+ labelContent
570
+ )}
571
+ </Button>
572
+ );
573
+ };
465
574
  if (mode === 'menu-only') {
466
575
  return <Actions actions={visibleActions.map(toMenuItem)} variant="outlined" />;
467
576
  }
@@ -566,6 +675,7 @@ SubscriptionActionsInner.defaultProps = {
566
675
  showExtra: false,
567
676
  showRecharge: false,
568
677
  showOverdraftProtection: false,
678
+ showBalanceInfo: false,
569
679
  showDelegation: false,
570
680
  showUnsubscribe: true,
571
681
  onChange: null,
@@ -120,9 +120,9 @@ export default function CurrentSubscriptions({
120
120
  }}
121
121
  sx={{
122
122
  padding: 1.5,
123
- background: 'var(--backgrounds-bg-subtle, #F9FAFB)',
123
+ backgroundColor: 'grey.50',
124
124
  '&:hover': {
125
- backgroundColor: 'var(--backgrounds-bg-highlight, #eff6ff)',
125
+ backgroundColor: 'grey.100',
126
126
  transition: 'background-color 200ms linear',
127
127
  cursor: 'pointer',
128
128
  },
@@ -216,6 +216,7 @@ export default function CurrentSubscriptions({
216
216
  }}
217
217
  showUnsubscribe={false}
218
218
  showRecharge={!isWillCanceled(subscription)}
219
+ showBalanceInfo
219
220
  actionProps={{
220
221
  cancel: {
221
222
  variant: 'outlined',
@@ -157,7 +157,8 @@ Uploader.defaultProps = {
157
157
  };
158
158
 
159
159
  const Div = styled(Box)`
160
- border: 1px solid var(--stroke-border-base, #eff1f5);
160
+ border: 1px solid;
161
+ border-color: ${({ theme }) => theme.palette.grey[100]};
161
162
  border-radius: 4px;
162
163
  cursor: pointer;
163
164
  width: 120px;
@@ -135,7 +135,7 @@ export default function WebhookAttempts({ event_id, webhook_endpoint_id, event }
135
135
  </Grid>
136
136
  <Grid item xs={12} md={8}>
137
137
  {selected && (
138
- <Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid #eee' }}>
138
+ <Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid', borderColor: 'grey.100' }}>
139
139
  <Typography variant="h6">{event_id ? selected.endpoint.url : selected.event.type}</Typography>
140
140
  <Box>
141
141
  <Typography variant="h6">Response ({selected.response_status})</Typography>
package/src/global.css CHANGED
@@ -12,7 +12,6 @@ a:has(> div) {
12
12
  font-weight: 500;
13
13
  font-size: 0.875rem;
14
14
  line-height: 1.3125rem;
15
- border-color: #ccc;
16
15
  }
17
16
 
18
17
  .MuiTab-root {
@@ -28,17 +27,12 @@ a:has(> div) {
28
27
  margin-bottom: 8px;
29
28
  }
30
29
 
31
- .MuiTabs-scroller {
32
- border-bottom: 1px solid #eee;
33
- }
34
-
35
30
  .MuiCheckbox-root {
36
31
  padding: 0;
37
32
  padding-right: 4px;
38
33
  }
39
34
 
40
35
  .MuiFormLabel-root {
41
- color: var(--foregrounds-fg-base, #010714);
42
36
  display: block;
43
37
  margin-bottom: 4px;
44
38
  font-weight: 500;
@@ -71,7 +65,6 @@ th.MuiTableCell-head {
71
65
  padding-top: 16px;
72
66
  }
73
67
 
74
-
75
68
  .MuiFormHelperText-root {
76
69
  margin-left: 0;
77
70
  }
@@ -63,7 +63,7 @@ export default function WebhookDetail(props: { id: string }) {
63
63
  spacing={3}
64
64
  justifyContent="flex-start"
65
65
  flexWrap="wrap"
66
- sx={{ pt: 2, mt: 2, borderTop: '1px solid #eee' }}>
66
+ sx={{ pt: 2, mt: 2, borderTop: '1px solid', borderColor: 'grey.100' }}>
67
67
  <InfoMetric
68
68
  label={t('common.status')}
69
69
  value={<Status label={data.status} color={getWebhookStatusColor(data.status)} />}
@@ -83,7 +83,7 @@ export default function WebhookDetail(props: { id: string }) {
83
83
  ))}
84
84
  </ul>
85
85
  }>
86
- <Typography sx={{ backgroundColor: '#eee', paddingX: 0.5, borderRadius: 0.5 }}>
86
+ <Typography sx={{ backgroundColor: 'grey.100', paddingX: 0.5, borderRadius: 0.5 }}>
87
87
  {data.enabled_events.length} events
88
88
  </Typography>
89
89
  </Tooltip>
@@ -34,7 +34,7 @@ const renderNav = (group: string, onChange: Function, groups: { label: string; v
34
34
  fontWeight: 600,
35
35
  border: 'none',
36
36
  cursor: 'pointer',
37
- '&:hover': group === x.value ? {} : { backgroundColor: '#eee' },
37
+ '&:hover': group === x.value ? {} : { backgroundColor: 'grey.100' },
38
38
  }}
39
39
  />
40
40
  ));
@@ -93,7 +93,7 @@ function Admin() {
93
93
  fontWeight: '500',
94
94
  color: 'text.lighter',
95
95
  '&.Mui-selected': {
96
- color: 'text.primary',
96
+ color: 'primary.main',
97
97
  },
98
98
  },
99
99
  '.MuiTouchRipple-root': {
@@ -284,7 +284,7 @@ export default function Overview() {
284
284
  position: 'relative',
285
285
  '&:hover': {
286
286
  backgroundColor: 'action.hover',
287
- boxShadow: 1,
287
+ boxShadow: 2,
288
288
  '& .MuiSvgIcon-root': {
289
289
  opacity: 1,
290
290
  transform: 'translateX(0)',
@@ -137,10 +137,13 @@ export default function PaymentIntentDetail(props: { id: string }) {
137
137
  src={data.paymentCurrency.logo}
138
138
  alt={data.paymentCurrency.symbol}
139
139
  variant="square"
140
- sx={{ width: '52px', height: '52px', borderRadius: 'var(--radius-s, 4px)' }}
140
+ sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
141
141
  />
142
142
  <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
143
- <Amount amount={received} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />
143
+ <Amount
144
+ amount={data?.amount_received === '0' ? total : received}
145
+ sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }}
146
+ />
144
147
  <Copyable text={props.id} />
145
148
  </Stack>
146
149
  </Stack>
@@ -160,7 +160,7 @@ export default function PayoutDetail(props: { id: string }) {
160
160
  src={data.paymentCurrency.logo}
161
161
  alt={data.paymentCurrency.symbol}
162
162
  variant="square"
163
- sx={{ width: '52px', height: '52px', borderRadius: 'var(--radius-s, 4px)' }}
163
+ sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
164
164
  />
165
165
  <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
166
166
  <Amount amount={total} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />
@@ -135,7 +135,7 @@ export default function RefundDetail(props: { id: string }) {
135
135
  src={data.paymentCurrency.logo}
136
136
  alt={data.paymentCurrency.symbol}
137
137
  variant="square"
138
- sx={{ width: '52px', height: '52px', borderRadius: 'var(--radius-s, 4px)' }}
138
+ sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
139
139
  />
140
140
  <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
141
141
  <Amount amount={amount} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />
@@ -10,7 +10,7 @@ import {
10
10
  findCurrency,
11
11
  } from '@blocklet/payment-react';
12
12
  import { LockOutlined } from '@mui/icons-material';
13
- import { Stack, Tooltip, Typography } from '@mui/material';
13
+ import { Stack, Tooltip, Typography, useTheme } from '@mui/material';
14
14
  import { Link } from 'react-router-dom';
15
15
 
16
16
  import Copyable from '../../../../components/copyable';
@@ -20,6 +20,7 @@ import PriceActions from './actions';
20
20
  export default function PricesList({ product, onChange }: { product: Product; onChange: Function }) {
21
21
  const { t, locale } = useLocaleContext();
22
22
  const { settings } = usePaymentContext();
23
+ const theme = useTheme();
23
24
  const query = getQueryParams(window.location.href);
24
25
 
25
26
  const columns = [
@@ -35,6 +36,7 @@ export default function PricesList({ product, onChange }: { product: Product; on
35
36
  const priceCurrency = showHighlight
36
37
  ? findCurrency(settings.paymentMethods, query.currency_id || '')
37
38
  : price.currency;
39
+ const highlightColor = theme.mode === 'dark' ? '#2e3035' : '#FFF9C4';
38
40
  return (
39
41
  <Link to={`/admin/products/${price.id}`} color="text.primary">
40
42
  <Stack direction="row" alignItems="center" spacing={1}>
@@ -45,7 +47,10 @@ export default function PricesList({ product, onChange }: { product: Product; on
45
47
  )}
46
48
  <Typography
47
49
  component="span"
48
- sx={{ backgroundColor: showHighlight ? '#FFF9C4' : 'transparent', whiteSpace: 'nowrap' }}>
50
+ sx={{
51
+ backgroundColor: showHighlight ? highlightColor : 'transparent',
52
+ whiteSpace: 'nowrap',
53
+ }}>
49
54
  {formatPrice(price, priceCurrency || price.currency, '', 1, true, locale)}
50
55
  </Typography>
51
56
  <Typography component="span">
@@ -122,7 +122,7 @@ export default function CreatePricingTable() {
122
122
  <FormProvider {...methods}>
123
123
  <ProductsProvider>
124
124
  <Stack height="92vh" spacing={2} direction="row">
125
- <Box flex={2} sx={{ borderRight: '1px solid #eee' }} position="relative">
125
+ <Box flex={2} sx={{ borderRight: '1px solid', borderColor: 'grey.100' }} position="relative">
126
126
  <Stack height="100%" spacing={2}>
127
127
  <Box overflow="auto" sx={{ pr: 2, pb: 8 }}>
128
128
  {step === 0 && <PricingTableProductSettings triggerError={triggerError} />}
@@ -137,7 +137,7 @@ export default function CreatePricingTable() {
137
137
  alignItems="center"
138
138
  justifyContent="flex-end"
139
139
  position="absolute"
140
- sx={{ borderTop: '1px solid #eee', left: 0, bottom: 0 }}>
140
+ sx={{ borderTop: '1px solid', borderColor: 'grey.100', left: 0, bottom: 0 }}>
141
141
  <Button variant="text" color="inherit" disabled={step === 0} onClick={onPrevious}>
142
142
  {t('common.previous')}
143
143
  </Button>
@@ -30,6 +30,7 @@ import {
30
30
  TextField,
31
31
  Tooltip,
32
32
  Typography,
33
+ useTheme,
33
34
  } from '@mui/material';
34
35
  import { useRequest, useSessionStorageState, useSetState } from 'ahooks';
35
36
  import useBus from 'use-bus';
@@ -308,8 +309,9 @@ function PaymentMethodSkeleton() {
308
309
  <Box
309
310
  sx={{
310
311
  py: 1,
311
- borderTop: '1px solid #eee',
312
- borderBottom: '1px solid #eee',
312
+ borderTop: '1px solid',
313
+ borderBottom: '1px solid',
314
+ borderColor: 'divider',
313
315
  mb: 1,
314
316
  }}>
315
317
  <Stack direction="row" justifyContent="space-between" alignItems="center">
@@ -330,6 +332,7 @@ function PaymentMethodSkeleton() {
330
332
 
331
333
  export default function PaymentMethods() {
332
334
  const { t } = useLocaleContext();
335
+ const { palette } = useTheme();
333
336
  const [expandedId, setExpandedId] = useSessionStorageState('payment-method-expanded-id', {
334
337
  defaultValue: '',
335
338
  });
@@ -442,8 +445,8 @@ export default function PaymentMethods() {
442
445
  }
443
446
  style={{
444
447
  py: 1,
445
- borderTop: '1px solid #eee',
446
- borderBottom: '1px solid #eee',
448
+ borderTop: `1px solid ${palette.divider}`,
449
+ borderBottom: `1px solid ${palette.divider}`,
447
450
  '& :hover': { color: 'text.primary' },
448
451
  }}
449
452
  value={method.id}
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
2
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
3
3
  import { api, ConfirmDialog, formatBNStr, Link, parseMarkedText, Table, useMobile } from '@blocklet/payment-react';
4
- import { Alert, Avatar, Box, Button, CircularProgress, Stack, Tooltip, Typography } from '@mui/material';
4
+ import { Alert, Avatar, Box, Button, CircularProgress, Stack, Tooltip, Typography, useTheme } from '@mui/material';
5
5
  import { useRequest, useSetState } from 'ahooks';
6
6
  import Empty from '@arcblock/ux/lib/Empty';
7
7
  import { HelpOutline } from '@mui/icons-material';
@@ -31,6 +31,7 @@ export default function VaultConfig() {
31
31
  const { t } = useLocaleContext();
32
32
  const { session } = useSessionContext();
33
33
  const { isMobile } = useMobile();
34
+ const theme = useTheme();
34
35
  const isOwner = session?.user?.role === 'owner';
35
36
 
36
37
  const [state, setState] = useSetState({
@@ -324,7 +325,7 @@ export default function VaultConfig() {
324
325
  <Link
325
326
  key={part.content}
326
327
  to={`${window.location.origin}/.well-known/service/admin/operations/advanced`}
327
- style={{ color: '#3b82f6' }}>
328
+ style={{ color: theme.palette.text.link }}>
328
329
  {part.content}
329
330
  </Link>
330
331
  )
@@ -26,7 +26,7 @@ export default function PricingTablePage({ id }: Props) {
26
26
  theme={undefined}
27
27
  hideNavMenu={undefined}
28
28
  maxWidth={false}
29
- sx={{ borderBottom: '1px solid var(--stroke-border-base, #EFF1F5)' }}
29
+ sx={{ borderBottom: '1px solid', borderColor: 'grey.100' }}
30
30
  />
31
31
 
32
32
  <Stack
@@ -233,7 +233,7 @@ const getCardIcon = (type: CardType) => {
233
233
  balance: <AccountBalanceWalletOutlined color="success" fontSize="small" />,
234
234
  spent: <CreditCardOutlined color="warning" fontSize="small" />,
235
235
  stake: <AccountBalanceOutlined fontSize="small" color="info" />,
236
- refund: <AssignmentReturnOutlined fontSize="small" sx={{ color: 'var(--tags-tag-purple-icon, #7c3aed)' }} />,
236
+ refund: <AssignmentReturnOutlined fontSize="small" sx={{ color: 'chip.secondary.text' }} />,
237
237
  due: <InfoOutlined fontSize="small" color="error" />,
238
238
  };
239
239
  return iconMap[type];
@@ -419,7 +419,8 @@ export default function CustomerHome() {
419
419
  key={c.id}
420
420
  sx={{
421
421
  pb: 2,
422
- borderBottom: '1px solid var(--stroke-border-base, #EFF1F5)',
422
+ borderBottom: '1px solid',
423
+ borderColor: 'grey.100',
423
424
  '&:last-child': { borderBottom: 'none', pb: 0 },
424
425
  }}>
425
426
  <Box alignItems="center" display="flex" gap={1}>
@@ -478,7 +479,7 @@ export default function CustomerHome() {
478
479
  top: 0,
479
480
  bottom: 0,
480
481
  width: '1px',
481
- backgroundColor: 'var(--stroke-border-base, #EFF1F5)',
482
+ backgroundColor: 'grey.100',
482
483
  zIndex: 1,
483
484
  },
484
485
  '&:has(+ .placeholder)::after': {
@@ -155,7 +155,7 @@ export default function CustomerInvoiceDetail() {
155
155
  variant="outlined"
156
156
  color="primary"
157
157
  size="small"
158
- sx={{ borderColor: 'var(--stroke-border-base, #EFF1F5)' }}
158
+ sx={{ borderColor: 'grey.100' }}
159
159
  disabled={state.paying}
160
160
  onClick={onPay}>
161
161
  {t('payment.customer.invoice.pay')}
@@ -113,7 +113,7 @@ export default function PayoutDetail() {
113
113
  src={data.paymentCurrency.logo}
114
114
  alt={data.paymentCurrency.symbol}
115
115
  variant="square"
116
- sx={{ width: '52px', height: '52px', borderRadius: 'var(--radius-s, 4px)' }}
116
+ sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
117
117
  />
118
118
  <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
119
119
  <Amount amount={total} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />