payment-kit 1.15.23 → 1.15.24
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/index.html +19 -13
- package/package.json +23 -18
- package/src/app.tsx +4 -1
- package/src/components/copyable.tsx +1 -0
- package/src/components/customer/form.tsx +4 -12
- package/src/components/invoice-pdf/pdf.tsx +102 -169
- package/src/components/invoice-pdf/styles.ts +134 -0
- package/src/components/invoice-pdf/template.tsx +127 -0
- package/src/components/invoice-pdf/types.ts +11 -0
- package/src/components/invoice-pdf/utils.ts +41 -0
- package/src/components/pricing-table/payment-settings.tsx +4 -0
- package/src/components/uploader.tsx +32 -26
- package/src/components/webhook/attempts.tsx +3 -0
- package/src/pages/admin/billing/index.tsx +4 -0
- package/src/pages/admin/customers/index.tsx +4 -0
- package/src/pages/admin/developers/index.tsx +10 -1
- package/src/pages/admin/index.tsx +4 -0
- package/src/pages/admin/payments/index.tsx +4 -0
- package/src/pages/admin/products/index.tsx +4 -0
- package/src/pages/admin/products/links/create.tsx +4 -0
- package/src/pages/admin/settings/index.tsx +4 -0
- package/src/pages/customer/index.tsx +1 -1
- package/vite.config.ts +43 -2
- package/src/components/invoice-pdf/compose.ts +0 -173
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { formatTime } from '@blocklet/payment-react';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import type { InvoicePDFProps } from './types';
|
|
4
|
+
import { composeStyles } from './utils';
|
|
5
|
+
import { getInvoiceRows } from '../invoice/table';
|
|
6
|
+
import { applyStyles } from './styles';
|
|
7
|
+
|
|
8
|
+
export function InvoiceTemplate({ data, t }: InvoicePDFProps) {
|
|
9
|
+
const { detail, summary } = getInvoiceRows(data);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
applyStyles();
|
|
13
|
+
}, []);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div id="invoice-template" style={composeStyles('template')}>
|
|
17
|
+
{/* Header */}
|
|
18
|
+
<div
|
|
19
|
+
style={{
|
|
20
|
+
width: '100%',
|
|
21
|
+
display: 'flex',
|
|
22
|
+
justifyContent: 'space-between',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
gap: '20px',
|
|
25
|
+
marginBottom: '40px',
|
|
26
|
+
}}>
|
|
27
|
+
<div style={composeStyles('fs-20 bold')}>{t('admin.invoice.name')}</div>
|
|
28
|
+
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
|
|
29
|
+
<img src={window.blocklet.appLogo.split('?')[0]} style={composeStyles('logo')} alt="logo" />
|
|
30
|
+
<span style={composeStyles('block p-10')}>{window.blocklet.appName}</span>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
{/* Bill Info */}
|
|
35
|
+
<div style={composeStyles('flex mt-60')}>
|
|
36
|
+
<div style={composeStyles('w-60')}>
|
|
37
|
+
<span style={composeStyles('bold dark mb-5')}>{t('admin.invoice.billTo')}</span>
|
|
38
|
+
<span style={composeStyles('block mb-5')}>{data.customer.name}</span>
|
|
39
|
+
<span style={composeStyles('bold fs-12')}>{`DID:ABT:${data.customer.did}`}</span>
|
|
40
|
+
</div>
|
|
41
|
+
<div style={composeStyles('w-40')}>
|
|
42
|
+
<div style={composeStyles('flex mb-5')}>
|
|
43
|
+
<div style={composeStyles('w-40')}>
|
|
44
|
+
<span style={composeStyles('bold')}>{t('admin.invoice.number')}</span>
|
|
45
|
+
</div>
|
|
46
|
+
<div style={composeStyles('w-60')}>
|
|
47
|
+
<span style={composeStyles('gray')}>{data.number}</span>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div style={composeStyles('flex mb-5')}>
|
|
51
|
+
<div style={composeStyles('w-40')}>
|
|
52
|
+
<span style={composeStyles('bold')}>{t('admin.invoice.paidAt')}</span>
|
|
53
|
+
</div>
|
|
54
|
+
<div style={composeStyles('w-60')}>
|
|
55
|
+
<span style={composeStyles('gray')}>{formatTime(data.period_start * 1000)}</span>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<div style={composeStyles('flex mb-5')}>
|
|
59
|
+
<div style={composeStyles('w-40')}>
|
|
60
|
+
<span style={composeStyles('bold')}>{t('admin.invoice.dueDate')}</span>
|
|
61
|
+
</div>
|
|
62
|
+
<div style={composeStyles('w-60')}>
|
|
63
|
+
<span style={composeStyles('gray')}>{formatTime(data.period_end * 1000)}</span>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{/* Table Header */}
|
|
70
|
+
<div style={composeStyles('mt-40 row flex')}>
|
|
71
|
+
<div style={composeStyles('w-48 p-4-8')}>
|
|
72
|
+
<span style={composeStyles('bold')}>{t('admin.subscription.product')}</span>
|
|
73
|
+
</div>
|
|
74
|
+
<div style={composeStyles('w-17 p-4-8')}>
|
|
75
|
+
<span style={composeStyles('bold right')}>{t('common.quantity')}</span>
|
|
76
|
+
</div>
|
|
77
|
+
<div style={composeStyles('w-17 p-4-8')}>
|
|
78
|
+
<span style={composeStyles('bold right')}>{t('payment.customer.invoice.unitPrice')}</span>
|
|
79
|
+
</div>
|
|
80
|
+
<div style={composeStyles('w-18 p-4-8')}>
|
|
81
|
+
<span style={composeStyles('bold right')}>{t('common.amount')}</span>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
{/* Table Content */}
|
|
86
|
+
{detail.map((line) => (
|
|
87
|
+
<div key={line.id} style={composeStyles('row flex')}>
|
|
88
|
+
<div style={composeStyles('w-48 p-4-8 pb-15')}>
|
|
89
|
+
<span style={composeStyles('dark')}>{line.product}</span>
|
|
90
|
+
</div>
|
|
91
|
+
<div style={composeStyles('w-17 p-4-8 pb-15')}>
|
|
92
|
+
<span style={composeStyles('dark right')}>{line.quantity}</span>
|
|
93
|
+
</div>
|
|
94
|
+
<div style={composeStyles('w-17 p-4-8 pb-15')}>
|
|
95
|
+
<span style={composeStyles('dark right')}>
|
|
96
|
+
{line.price ? `${line.price} ${data.paymentCurrency.symbol}` : ''}
|
|
97
|
+
</span>
|
|
98
|
+
</div>
|
|
99
|
+
<div style={composeStyles('w-18 p-4-8 pb-15')}>
|
|
100
|
+
<span style={composeStyles('dark right')}>
|
|
101
|
+
{line.amount} {data.paymentCurrency.symbol}
|
|
102
|
+
</span>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
))}
|
|
106
|
+
|
|
107
|
+
{/* Summary */}
|
|
108
|
+
<div style={composeStyles('flex')}>
|
|
109
|
+
<div style={composeStyles('w-60 mt-20')} />
|
|
110
|
+
<div style={composeStyles('w-40 mt-20')}>
|
|
111
|
+
{summary.map((line) => (
|
|
112
|
+
<div style={composeStyles('flex')} key={line.key}>
|
|
113
|
+
<div style={composeStyles('w-60 p-5')}>
|
|
114
|
+
<span style={composeStyles('bold')}>{t(line.key)}</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div style={composeStyles('w-40 p-5')}>
|
|
117
|
+
<span style={composeStyles('right bold dark')}>
|
|
118
|
+
{line.value} {data.paymentCurrency.symbol}
|
|
119
|
+
</span>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
))}
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TInvoiceExpanded } from '@blocklet/payment-types';
|
|
2
|
+
import type { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
export interface InvoiceStyles {
|
|
5
|
+
[key: string]: CSSProperties;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface InvoicePDFProps {
|
|
9
|
+
data: TInvoiceExpanded;
|
|
10
|
+
t: (key: string) => string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getPrefix } from '@blocklet/payment-react';
|
|
2
|
+
import { joinURL } from 'ufo';
|
|
3
|
+
import { pdfStyles } from './styles';
|
|
4
|
+
|
|
5
|
+
const fontUrl = joinURL(getPrefix(), '/fonts/noto-sans-sc-chinese-simplified-500-normal.ttf');
|
|
6
|
+
export const fontFamily = 'Noto Sans SC';
|
|
7
|
+
|
|
8
|
+
export async function loadFont(): Promise<boolean> {
|
|
9
|
+
try {
|
|
10
|
+
const font = new FontFace(fontFamily, `url(${fontUrl})`);
|
|
11
|
+
const loadedFont = await font.load();
|
|
12
|
+
document.fonts.add(loadedFont);
|
|
13
|
+
return true;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('Font loading failed:', error);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function loadImage(url: string): Promise<HTMLImageElement> {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const img = new Image();
|
|
23
|
+
img.crossOrigin = 'anonymous';
|
|
24
|
+
img.onload = () => resolve(img);
|
|
25
|
+
img.onerror = reject;
|
|
26
|
+
img.src = url;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function composeStyles(classNames: string): React.CSSProperties {
|
|
31
|
+
return classNames
|
|
32
|
+
.split(' ')
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.reduce(
|
|
35
|
+
(acc, className) => ({
|
|
36
|
+
...acc,
|
|
37
|
+
...pdfStyles[className],
|
|
38
|
+
}),
|
|
39
|
+
{}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -230,9 +230,13 @@ export function ProductPaymentSettings({ product, prices }: { product: TProduct;
|
|
|
230
230
|
expanded
|
|
231
231
|
trigger={<Typography variant="h6">{product.name}</Typography>}
|
|
232
232
|
style={{ py: 1 }}>
|
|
233
|
+
{/* @ts-ignore */}
|
|
233
234
|
<Tabs
|
|
235
|
+
// @ts-ignore
|
|
234
236
|
tabs={tabs}
|
|
237
|
+
// @ts-ignore
|
|
235
238
|
current={current}
|
|
239
|
+
// @ts-ignore
|
|
236
240
|
onChange={(v: string) => setCurrent(v)}
|
|
237
241
|
style={{ width: '100%' }}
|
|
238
242
|
scrollButtons="auto"
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Avatar, Box, Button } from '@mui/material';
|
|
2
2
|
import { Stack, styled } from '@mui/system';
|
|
3
|
-
import { lazy, useCallback, useEffect, useRef } from 'react';
|
|
3
|
+
import { lazy, Suspense, useCallback, useEffect, useRef } from 'react';
|
|
4
4
|
import { CloudUpload, Delete, Edit } from '@mui/icons-material';
|
|
5
5
|
|
|
6
|
-
const UploaderComponent = lazy(() =>
|
|
6
|
+
const UploaderComponent = lazy(() =>
|
|
7
|
+
import(/* webpackChunkName: "blocklet-uploader" */ '@blocklet/uploader').then((res) => ({
|
|
8
|
+
default: res.Uploader,
|
|
9
|
+
}))
|
|
10
|
+
);
|
|
7
11
|
|
|
8
12
|
type Props = {
|
|
9
13
|
onUploaded: (result: any) => void;
|
|
@@ -95,30 +99,32 @@ export default function Uploader({ onUploaded, preview, maxFileSize, maxNumberOf
|
|
|
95
99
|
</Div>
|
|
96
100
|
)}
|
|
97
101
|
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
102
|
+
<Suspense fallback={null}>
|
|
103
|
+
<UploaderComponent
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
ref={uploaderRef}
|
|
106
|
+
popup
|
|
107
|
+
onUploadFinish={(result: any) => onUploaded({ url: result.data.url })}
|
|
108
|
+
uploadedProps={{
|
|
109
|
+
onSelectedFiles: (files: any[]) => {
|
|
110
|
+
if (files.length) {
|
|
111
|
+
onUploaded({ url: files[0].fileUrl });
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
}}
|
|
115
|
+
coreProps={{
|
|
116
|
+
restrictions: {
|
|
117
|
+
allowedFileExts,
|
|
118
|
+
maxFileSize,
|
|
119
|
+
maxNumberOfFiles,
|
|
120
|
+
},
|
|
121
|
+
}}
|
|
122
|
+
apiPathProps={{
|
|
123
|
+
uploader: '/api/uploads',
|
|
124
|
+
companion: '/api/companion',
|
|
125
|
+
}}
|
|
126
|
+
/>
|
|
127
|
+
</Suspense>
|
|
122
128
|
</>
|
|
123
129
|
);
|
|
124
130
|
}
|
|
@@ -168,10 +168,12 @@ export default function WebhookAttempts({ event_id, webhook_endpoint_id, event }
|
|
|
168
168
|
<Typography variant="h6">{event_id ? selected.endpoint.url : selected.event.type}</Typography>
|
|
169
169
|
<Box>
|
|
170
170
|
<Typography variant="h6">Response ({selected.response_status})</Typography>
|
|
171
|
+
{/* @ts-ignore */}
|
|
171
172
|
<CodeBlock language="json">{JSON.stringify(selected.response_body, null, 2)}</CodeBlock>
|
|
172
173
|
</Box>
|
|
173
174
|
<Box>
|
|
174
175
|
<Typography variant="h6">Request</Typography>
|
|
176
|
+
{/* @ts-ignore */}
|
|
175
177
|
<CodeBlock language="json">{JSON.stringify(selected.event, null, 2)}</CodeBlock>
|
|
176
178
|
</Box>
|
|
177
179
|
</Stack>
|
|
@@ -266,6 +268,7 @@ export default function WebhookAttempts({ event_id, webhook_endpoint_id, event }
|
|
|
266
268
|
</Popper>
|
|
267
269
|
</>
|
|
268
270
|
</Stack>
|
|
271
|
+
{/* @ts-ignore */}
|
|
269
272
|
<CodeBlock language="json">{JSON.stringify(event.data, null, 2)}</CodeBlock>
|
|
270
273
|
</Box>
|
|
271
274
|
)}
|
|
@@ -46,9 +46,13 @@ export default function BillingIndex() {
|
|
|
46
46
|
{/* <Typography variant="h5" sx={{ mb: 1, fontWeight: 600 }}>
|
|
47
47
|
{t('admin.billing')}
|
|
48
48
|
</Typography> */}
|
|
49
|
+
{/* @ts-ignore */}
|
|
49
50
|
<Tabs
|
|
51
|
+
// @ts-ignore
|
|
50
52
|
tabs={tabs}
|
|
53
|
+
// @ts-ignore
|
|
51
54
|
current={page}
|
|
55
|
+
// @ts-ignore
|
|
52
56
|
onChange={onTabChange}
|
|
53
57
|
scrollButtons="auto"
|
|
54
58
|
sx={{
|
|
@@ -33,9 +33,13 @@ export default function CustomerIndex() {
|
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<div>
|
|
36
|
+
{/* @ts-ignore */}
|
|
36
37
|
<Tabs
|
|
38
|
+
// @ts-ignore
|
|
37
39
|
tabs={tabs}
|
|
40
|
+
// @ts-ignore
|
|
38
41
|
current={page}
|
|
42
|
+
// @ts-ignore
|
|
39
43
|
onChange={onTabChange}
|
|
40
44
|
scrollButtons="auto"
|
|
41
45
|
variant="scrollable"
|
|
@@ -50,7 +50,16 @@ export default function DevelopersIndex() {
|
|
|
50
50
|
<Typography variant="h5" sx={{ mb: 1, fontWeight: 600 }}>
|
|
51
51
|
{t('admin.developers')}
|
|
52
52
|
</Typography>
|
|
53
|
-
|
|
53
|
+
{/* @ts-ignore */}
|
|
54
|
+
<Tabs
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
tabs={tabs}
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
current={page}
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
onChange={onTabChange}
|
|
61
|
+
scrollButtons="auto"
|
|
62
|
+
/>
|
|
54
63
|
{isValidElement(TabComponent) ? TabComponent : <TabComponent />}
|
|
55
64
|
</div>
|
|
56
65
|
);
|
|
@@ -75,9 +75,13 @@ function Admin() {
|
|
|
75
75
|
<ProgressBar pending={isPending} />
|
|
76
76
|
<Stack direction="row" alignItems="center" justifyContent="end" flexWrap="wrap" spacing={1} sx={{ mt: 1, pb: 2 }}>
|
|
77
77
|
{/* <Box>{renderNav(group, onTabChange, group1)}</Box> */}
|
|
78
|
+
{/* @ts-ignore */}
|
|
78
79
|
<Tabs
|
|
80
|
+
// @ts-ignore
|
|
79
81
|
tabs={group1}
|
|
82
|
+
// @ts-ignore
|
|
80
83
|
current={group}
|
|
84
|
+
// @ts-ignore
|
|
81
85
|
onChange={onTabChange}
|
|
82
86
|
scrollButtons="auto"
|
|
83
87
|
variant="scrollable"
|
|
@@ -49,9 +49,13 @@ export default function PaymentIndex() {
|
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
51
|
<div>
|
|
52
|
+
{/* @ts-ignore */}
|
|
52
53
|
<Tabs
|
|
54
|
+
// @ts-ignore
|
|
53
55
|
tabs={tabs}
|
|
56
|
+
// @ts-ignore
|
|
54
57
|
current={page}
|
|
58
|
+
// @ts-ignore
|
|
55
59
|
onChange={onTabChange}
|
|
56
60
|
scrollButtons="auto"
|
|
57
61
|
variant="scrollable"
|
|
@@ -66,9 +66,13 @@ export default function Products() {
|
|
|
66
66
|
return (
|
|
67
67
|
<>
|
|
68
68
|
<Stack direction="row" alignItems="flex-start" justifyContent="end" flexWrap="wrap" spacing={1}>
|
|
69
|
+
{/* @ts-ignore */}
|
|
69
70
|
<Tabs
|
|
71
|
+
// @ts-ignore
|
|
70
72
|
tabs={tabs}
|
|
73
|
+
// @ts-ignore
|
|
71
74
|
current={page}
|
|
75
|
+
// @ts-ignore
|
|
72
76
|
onChange={(newTab: string) => startTransition(() => navigate(`/admin/products/${newTab}`))}
|
|
73
77
|
scrollButtons="auto"
|
|
74
78
|
variant="scrollable"
|
|
@@ -153,9 +153,13 @@ export default function CreatePaymentLink() {
|
|
|
153
153
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 600 }}>
|
|
154
154
|
{t('common.setup')}
|
|
155
155
|
</Typography>
|
|
156
|
+
{/* @ts-ignore */}
|
|
156
157
|
<Tabs
|
|
158
|
+
// @ts-ignore
|
|
157
159
|
tabs={tabs}
|
|
160
|
+
// @ts-ignore
|
|
158
161
|
current={current}
|
|
162
|
+
// @ts-ignore
|
|
159
163
|
onChange={(v: string) => setCurrent(v)}
|
|
160
164
|
style={{ width: '100%' }}
|
|
161
165
|
scrollButtons="auto"
|
|
@@ -42,9 +42,13 @@ export default function SettingsIndex() {
|
|
|
42
42
|
return (
|
|
43
43
|
<>
|
|
44
44
|
<Stack direction="row" alignItems="flex-start" justifyContent="end" flexWrap="wrap" spacing={1}>
|
|
45
|
+
{/* @ts-ignore */}
|
|
45
46
|
<Tabs
|
|
47
|
+
// @ts-ignore
|
|
46
48
|
tabs={tabs}
|
|
49
|
+
// @ts-ignore
|
|
47
50
|
current={page}
|
|
51
|
+
// @ts-ignore
|
|
48
52
|
onChange={onTabChange}
|
|
49
53
|
scrollButtons="auto"
|
|
50
54
|
variant="scrollable"
|
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
Grid,
|
|
23
23
|
MenuItem,
|
|
24
24
|
Select,
|
|
25
|
-
SelectChangeEvent,
|
|
26
25
|
Stack,
|
|
27
26
|
Tooltip,
|
|
28
27
|
Typography,
|
|
29
28
|
} from '@mui/material';
|
|
29
|
+
import type { SelectChangeEvent } from '@mui/material/Select';
|
|
30
30
|
import { styled, SxProps } from '@mui/system';
|
|
31
31
|
import { useSetState } from 'ahooks';
|
|
32
32
|
import { flatten, isEmpty } from 'lodash';
|
package/vite.config.ts
CHANGED
|
@@ -4,18 +4,59 @@ import { defineConfig } from 'vite';
|
|
|
4
4
|
import { createBlockletPlugin } from 'vite-plugin-blocklet';
|
|
5
5
|
import svgr from 'vite-plugin-svgr';
|
|
6
6
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
7
|
+
import { visualizer } from 'rollup-plugin-visualizer';
|
|
7
8
|
import path from 'path';
|
|
8
9
|
|
|
9
10
|
// https://vitejs.dev/config/
|
|
10
11
|
export default defineConfig(({ mode }) => {
|
|
12
|
+
const isProduction = mode === 'production';
|
|
11
13
|
return {
|
|
12
|
-
plugins: [
|
|
14
|
+
plugins: [
|
|
15
|
+
tsconfigPaths(),
|
|
16
|
+
react({
|
|
17
|
+
babel: {
|
|
18
|
+
plugins: isProduction ? [['lodash']] : [],
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
createBlockletPlugin(),
|
|
22
|
+
svgr(),
|
|
23
|
+
process.env.ANALYZE && visualizer({ open: true, gzipSize: true, brotliSize: true }),
|
|
24
|
+
].filter(Boolean),
|
|
25
|
+
|
|
13
26
|
build: {
|
|
14
|
-
// 禁止 preload 可以解决 js 的请求没有 referer 的问题
|
|
15
27
|
cssCodeSplit: false,
|
|
28
|
+
minify: 'terser',
|
|
29
|
+
terserOptions: {
|
|
30
|
+
compress: {
|
|
31
|
+
drop_debugger: true,
|
|
32
|
+
pure_funcs: ['assert', 'debug'],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
reportCompressedSize: false,
|
|
36
|
+
chunkSizeWarningLimit: 1000,
|
|
16
37
|
commonjsOptions: {
|
|
38
|
+
include: [/node_modules/],
|
|
17
39
|
transformMixedEsModules: true,
|
|
18
40
|
},
|
|
41
|
+
rollupOptions: {
|
|
42
|
+
external: [],
|
|
43
|
+
output: {
|
|
44
|
+
manualChunks: {
|
|
45
|
+
'vendor-react': ['react', 'react-dom', 'react-router-dom'],
|
|
46
|
+
'vendor-mui': ['@mui/material', '@mui/system', '@mui/icons-material'],
|
|
47
|
+
utils: ['dayjs', 'numbro', 'bn.js'],
|
|
48
|
+
hooks: ['ahooks', 'use-bus'],
|
|
49
|
+
'vendor-arcblock': ['@arcblock/did-connect'],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
optimizeDeps: {
|
|
55
|
+
include: ['react', 'react-dom', 'react/jsx-runtime'],
|
|
56
|
+
esbuildOptions: {
|
|
57
|
+
mainFields: ['module', 'main'],
|
|
58
|
+
resolveExtensions: ['.ts', '.tsx', '.js', '.jsx'],
|
|
59
|
+
},
|
|
19
60
|
},
|
|
20
61
|
...(mode === 'development' && {
|
|
21
62
|
resolve: {
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
const compose = (classes: string) => {
|
|
2
|
-
const css = {};
|
|
3
|
-
|
|
4
|
-
const classesArray: string[] = classes.replace(/\s+/g, ' ').split(' ');
|
|
5
|
-
|
|
6
|
-
classesArray.forEach((className) => {
|
|
7
|
-
if (typeof styles[className] !== undefined) {
|
|
8
|
-
Object.assign(css, styles[className]);
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
return css;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const colorDark = '#222';
|
|
16
|
-
const colorDark2 = '#888';
|
|
17
|
-
const colorGray = '#e3e3e3';
|
|
18
|
-
const colorWhite = '#fff';
|
|
19
|
-
|
|
20
|
-
const styles: any = {
|
|
21
|
-
dark: {
|
|
22
|
-
color: colorDark,
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
white: {
|
|
26
|
-
color: colorWhite,
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
gray: {
|
|
30
|
-
color: colorDark2,
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
'bg-dark': {
|
|
34
|
-
backgroundColor: colorDark2,
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
'bg-gray': {
|
|
38
|
-
backgroundColor: colorGray,
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
flex: {
|
|
42
|
-
display: 'flex',
|
|
43
|
-
flexDirection: 'row',
|
|
44
|
-
flexWrap: 'nowrap',
|
|
45
|
-
alignItems: 'start',
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
bold: {
|
|
49
|
-
fontWeight: 'bold',
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
'w-auto': {
|
|
53
|
-
flex: 1,
|
|
54
|
-
paddingRight: '8px',
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
'flex-1': {
|
|
58
|
-
flex: 1,
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
'w-100': {
|
|
62
|
-
width: '100%',
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
'w-50': {
|
|
66
|
-
width: '50%',
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
'w-55': {
|
|
70
|
-
width: '55%',
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
'w-45': {
|
|
74
|
-
width: '45%',
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
'w-60': {
|
|
78
|
-
width: '60%',
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
'w-40': {
|
|
82
|
-
width: '30%',
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
'w-48': {
|
|
86
|
-
width: '48%',
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
'w-17': {
|
|
90
|
-
width: '17%',
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
'w-18': {
|
|
94
|
-
width: '18%',
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
row: {
|
|
98
|
-
borderBottom: `1px solid ${colorGray}`,
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
'mt-40': {
|
|
102
|
-
marginTop: '40px',
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
'mt-30': {
|
|
106
|
-
marginTop: '30px',
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
'mt-20': {
|
|
110
|
-
marginTop: '20px',
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
'mt-10': {
|
|
114
|
-
marginTop: '10px',
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
'mb-5': {
|
|
118
|
-
marginBottom: '5px',
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
'p-4-8': {
|
|
122
|
-
padding: '4px 8px',
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
'p-5': {
|
|
126
|
-
padding: '5px',
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
'pb-10': {
|
|
130
|
-
paddingBottom: '10px',
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
right: {
|
|
134
|
-
textAlign: 'right',
|
|
135
|
-
},
|
|
136
|
-
center: {
|
|
137
|
-
textAlign: 'right',
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
'fs-20': {
|
|
141
|
-
fontSize: '20px',
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
'fs-30': {
|
|
145
|
-
fontSize: '30px',
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
'fs-12': {
|
|
149
|
-
fontSize: '11px',
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
page: {
|
|
153
|
-
fontFamily: 'Noto Sans SC',
|
|
154
|
-
fontSize: '11px',
|
|
155
|
-
color: '#555',
|
|
156
|
-
padding: '40px 35px',
|
|
157
|
-
fontWeight: 'bold',
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
span: {
|
|
161
|
-
padding: '4px 12px 4px 0',
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
logo: {
|
|
165
|
-
display: 'block',
|
|
166
|
-
borderRadius: '10px',
|
|
167
|
-
width: '60px',
|
|
168
|
-
height: '60px',
|
|
169
|
-
textAlign: 'center',
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
export default compose;
|