payment-kit 1.19.4 → 1.19.5
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/blocklet.yml +1 -1
- package/package.json +8 -8
- package/src/components/currency.tsx +4 -2
- package/src/components/info-metric.tsx +9 -2
- package/src/components/subscription/items/index.tsx +105 -69
- package/src/components/subscription/metrics.tsx +17 -4
- package/src/pages/customer/index.tsx +1 -1
- package/src/pages/customer/invoice/detail.tsx +26 -5
- package/src/pages/customer/subscription/detail.tsx +76 -55
- package/src/pages/customer/subscription/embed.tsx +22 -7
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.5",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
|
|
@@ -46,17 +46,17 @@
|
|
|
46
46
|
"@abtnode/cron": "^1.16.46",
|
|
47
47
|
"@arcblock/did": "^1.20.15",
|
|
48
48
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
49
|
-
"@arcblock/did-connect": "^3.0.
|
|
49
|
+
"@arcblock/did-connect": "^3.0.26",
|
|
50
50
|
"@arcblock/did-util": "^1.20.15",
|
|
51
51
|
"@arcblock/jwt": "^1.20.15",
|
|
52
|
-
"@arcblock/ux": "^3.0.
|
|
52
|
+
"@arcblock/ux": "^3.0.26",
|
|
53
53
|
"@arcblock/validator": "^1.20.15",
|
|
54
|
-
"@blocklet/did-space-js": "^1.1.
|
|
54
|
+
"@blocklet/did-space-js": "^1.1.6",
|
|
55
55
|
"@blocklet/js-sdk": "^1.16.46",
|
|
56
56
|
"@blocklet/logger": "^1.16.46",
|
|
57
|
-
"@blocklet/payment-react": "1.19.
|
|
57
|
+
"@blocklet/payment-react": "1.19.5",
|
|
58
58
|
"@blocklet/sdk": "^1.16.46",
|
|
59
|
-
"@blocklet/ui-react": "^3.0.
|
|
59
|
+
"@blocklet/ui-react": "^3.0.26",
|
|
60
60
|
"@blocklet/uploader": "^0.2.4",
|
|
61
61
|
"@blocklet/xss": "^0.2.2",
|
|
62
62
|
"@mui/icons-material": "^7.1.2",
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"devDependencies": {
|
|
123
123
|
"@abtnode/types": "^1.16.46",
|
|
124
124
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
125
|
-
"@blocklet/payment-types": "1.19.
|
|
125
|
+
"@blocklet/payment-types": "1.19.5",
|
|
126
126
|
"@types/cookie-parser": "^1.4.9",
|
|
127
127
|
"@types/cors": "^2.8.19",
|
|
128
128
|
"@types/debug": "^4.1.12",
|
|
@@ -168,5 +168,5 @@
|
|
|
168
168
|
"parser": "typescript"
|
|
169
169
|
}
|
|
170
170
|
},
|
|
171
|
-
"gitHead": "
|
|
171
|
+
"gitHead": "b2cb3888b7efa2cc71591f75240616c36e945b09"
|
|
172
172
|
}
|
|
@@ -4,12 +4,14 @@ type Props = {
|
|
|
4
4
|
logo: string;
|
|
5
5
|
name: string;
|
|
6
6
|
sx?: SxProps;
|
|
7
|
+
size?: number;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
export default function Currency({ logo, name, sx = {} }: Props) {
|
|
10
|
+
export default function Currency({ logo, name, sx = {}, size = 20 }: Props) {
|
|
10
11
|
return (
|
|
11
12
|
<Stack
|
|
12
13
|
direction="row"
|
|
14
|
+
alignItems="center"
|
|
13
15
|
spacing={0.5}
|
|
14
16
|
sx={[
|
|
15
17
|
{
|
|
@@ -17,7 +19,7 @@ export default function Currency({ logo, name, sx = {} }: Props) {
|
|
|
17
19
|
},
|
|
18
20
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
19
21
|
]}>
|
|
20
|
-
<Avatar src={logo} alt={name} sx={{ width:
|
|
22
|
+
<Avatar src={logo} alt={name} sx={{ width: size, height: size }} />
|
|
21
23
|
<Typography
|
|
22
24
|
className="currency-name"
|
|
23
25
|
sx={{
|
|
@@ -19,13 +19,19 @@ export default function InfoMetric(rawProps: Props) {
|
|
|
19
19
|
rawProps
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
+
const stackSx = {
|
|
23
|
+
display: 'flex',
|
|
24
|
+
flexDirection: 'column',
|
|
25
|
+
alignItems: 'flex-start',
|
|
26
|
+
};
|
|
27
|
+
|
|
22
28
|
const { t } = useLocaleContext();
|
|
23
29
|
// eslint-disable-next-line react/prop-types
|
|
24
30
|
const isNone = isEmptyExceptNumber(props.value);
|
|
25
31
|
return (
|
|
26
32
|
<>
|
|
27
|
-
<Stack
|
|
28
|
-
<Typography component="div" variant="subtitle2" mb={1} color="text.primary">
|
|
33
|
+
<Stack sx={stackSx}>
|
|
34
|
+
<Typography className="info-metric-label" component="div" variant="subtitle2" mb={1} color="text.primary">
|
|
29
35
|
{/* eslint-disable-next-line react/prop-types */}
|
|
30
36
|
{props.label}
|
|
31
37
|
{/* eslint-disable-next-line react/prop-types */}
|
|
@@ -38,6 +44,7 @@ export default function InfoMetric(rawProps: Props) {
|
|
|
38
44
|
)}
|
|
39
45
|
</Typography>
|
|
40
46
|
<Typography
|
|
47
|
+
className="info-metric-value"
|
|
41
48
|
component="div"
|
|
42
49
|
variant="body1"
|
|
43
50
|
color={isNone ? 'text.disabled' : 'text.secondary'}
|
|
@@ -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
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{item.price.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
</
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
</
|
|
77
|
-
</
|
|
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
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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:
|
|
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:
|
|
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
|
|
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' }}>
|
|
@@ -488,6 +488,7 @@ export default function CustomerHome() {
|
|
|
488
488
|
</Box>
|
|
489
489
|
<CreditOverview customerId={data?.id || ''} settings={settings} />
|
|
490
490
|
</Box>
|
|
491
|
+
<Divider />
|
|
491
492
|
</ConditionalSection>
|
|
492
493
|
);
|
|
493
494
|
|
|
@@ -585,7 +586,6 @@ export default function CustomerHome() {
|
|
|
585
586
|
{SummaryCard}
|
|
586
587
|
{SummaryCard && <Divider />}
|
|
587
588
|
{CreditCard}
|
|
588
|
-
{CreditCard && <Divider />}
|
|
589
589
|
{SubscriptionCard}
|
|
590
590
|
{SubscriptionCard && <Divider />}
|
|
591
591
|
{InvoiceCard}
|
|
@@ -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
|
|
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=
|
|
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={
|
|
223
|
+
spacing={0.5}
|
|
215
224
|
sx={{
|
|
216
225
|
alignItems: 'center',
|
|
217
226
|
}}>
|
|
218
|
-
<
|
|
219
|
-
direction="row"
|
|
220
|
-
spacing={0.5}
|
|
227
|
+
<CheckCircle
|
|
221
228
|
sx={{
|
|
222
|
-
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
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: '
|
|
252
|
-
gap: 0.5,
|
|
253
|
-
fontWeight: 500,
|
|
264
|
+
alignItems: 'baseline',
|
|
254
265
|
}}>
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
263
|
-
|
|
269
|
+
color: 'text.secondary',
|
|
270
|
+
fontSize: '14px',
|
|
271
|
+
ml: 0.5,
|
|
264
272
|
}}>
|
|
265
|
-
{
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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"
|
|
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
|
|
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=
|
|
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
|
}
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
Box,
|
|
28
28
|
Button,
|
|
29
29
|
CircularProgress,
|
|
30
|
-
Divider,
|
|
31
30
|
Link,
|
|
32
31
|
List,
|
|
33
32
|
ListItem,
|
|
@@ -35,6 +34,7 @@ import {
|
|
|
35
34
|
Stack,
|
|
36
35
|
Tooltip,
|
|
37
36
|
Typography,
|
|
37
|
+
useTheme,
|
|
38
38
|
} from '@mui/material';
|
|
39
39
|
import { useRequest, useSetState } from 'ahooks';
|
|
40
40
|
import SplitButton from '@arcblock/ux/lib/SplitButton';
|
|
@@ -111,6 +111,7 @@ export default function SubscriptionEmbed() {
|
|
|
111
111
|
refreshDeps: [subscriptionId, authToken, subscription?.customer_id],
|
|
112
112
|
}
|
|
113
113
|
);
|
|
114
|
+
const muiTheme = useTheme();
|
|
114
115
|
|
|
115
116
|
const subscriptionPageUrl: string = useMemo(() => {
|
|
116
117
|
if (!subscription) {
|
|
@@ -256,7 +257,7 @@ export default function SubscriptionEmbed() {
|
|
|
256
257
|
<Typography component="h2" sx={{ textAlign: 'center' }} variant="h3" gutterBottom>
|
|
257
258
|
{t('payment.customer.subscriptions.current')}
|
|
258
259
|
</Typography>
|
|
259
|
-
<Box sx={{ display: 'flex', flexDirection: 'column'
|
|
260
|
+
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
|
260
261
|
{infoList.map(({ name, value }) => {
|
|
261
262
|
return (
|
|
262
263
|
<InfoRow
|
|
@@ -264,6 +265,8 @@ export default function SubscriptionEmbed() {
|
|
|
264
265
|
value={value}
|
|
265
266
|
sx={{
|
|
266
267
|
mb: 0,
|
|
268
|
+
py: 1.5,
|
|
269
|
+
borderBottom: `1px solid ${muiTheme.palette.divider}`,
|
|
267
270
|
'.info-row-label': {
|
|
268
271
|
whiteSpace: 'nowrap',
|
|
269
272
|
},
|
|
@@ -278,7 +281,6 @@ export default function SubscriptionEmbed() {
|
|
|
278
281
|
);
|
|
279
282
|
})}
|
|
280
283
|
</Box>
|
|
281
|
-
<Divider />
|
|
282
284
|
<Box sx={{ flex: 1, overflow: 'hidden' }}>
|
|
283
285
|
<List sx={{ height: '100%', display: 'flex', flexDirection: 'column' }} className="mini-invoice-list">
|
|
284
286
|
<ListSubheader disableGutters sx={{ padding: 0 }}>
|
|
@@ -286,7 +288,8 @@ export default function SubscriptionEmbed() {
|
|
|
286
288
|
component="h2"
|
|
287
289
|
variant="h6"
|
|
288
290
|
sx={{
|
|
289
|
-
fontSize:
|
|
291
|
+
fontSize: 14,
|
|
292
|
+
color: 'text.primary',
|
|
290
293
|
}}>
|
|
291
294
|
{t('payment.customer.invoices')}
|
|
292
295
|
</Typography>
|
|
@@ -329,10 +332,11 @@ export default function SubscriptionEmbed() {
|
|
|
329
332
|
sx={{
|
|
330
333
|
justifyContent: 'center',
|
|
331
334
|
mt: 2,
|
|
335
|
+
width: '100%',
|
|
332
336
|
}}>
|
|
333
337
|
{subscription.service_actions
|
|
334
338
|
?.filter((x: any) => x?.type !== 'notification')
|
|
335
|
-
?.map((x) => (
|
|
339
|
+
?.map((x: any) => (
|
|
336
340
|
// @ts-ignore
|
|
337
341
|
<Button
|
|
338
342
|
component={Link}
|
|
@@ -342,7 +346,11 @@ export default function SubscriptionEmbed() {
|
|
|
342
346
|
href={x.link}
|
|
343
347
|
size="small"
|
|
344
348
|
target="_blank"
|
|
345
|
-
sx={{
|
|
349
|
+
sx={{
|
|
350
|
+
textDecoration: 'none !important',
|
|
351
|
+
flex: 1,
|
|
352
|
+
minWidth: 0,
|
|
353
|
+
}}>
|
|
346
354
|
{x.text[locale] || x.text.en || x.name}
|
|
347
355
|
</Button>
|
|
348
356
|
))}
|
|
@@ -351,6 +359,10 @@ export default function SubscriptionEmbed() {
|
|
|
351
359
|
size="small"
|
|
352
360
|
color="error"
|
|
353
361
|
variant="contained"
|
|
362
|
+
sx={{
|
|
363
|
+
flex: 1,
|
|
364
|
+
minWidth: 0,
|
|
365
|
+
}}
|
|
354
366
|
menu={[
|
|
355
367
|
<SplitButton.Item key="view-subscription" component={Link} target="_blank" href={subscriptionPageUrl}>
|
|
356
368
|
{t('payment.customer.subscriptions.view')}
|
|
@@ -365,7 +377,10 @@ export default function SubscriptionEmbed() {
|
|
|
365
377
|
) : (
|
|
366
378
|
<Button
|
|
367
379
|
variant="contained"
|
|
368
|
-
sx={{
|
|
380
|
+
sx={{
|
|
381
|
+
flex: 1,
|
|
382
|
+
minWidth: 0,
|
|
383
|
+
}}
|
|
369
384
|
target="_blank"
|
|
370
385
|
href={subscriptionPageUrl}>
|
|
371
386
|
{t('payment.customer.subscriptions.view')}
|